Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[review] MIP-74: Rate-Limiter for the Lock/Mint-type Native Bridge + MD-74: Rate-Limiter for the Lock/Mint-type Native Bridge #74

Open
wants to merge 39 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
cc0fe99
init
apenzk Dec 17, 2024
d168ef6
md
apenzk Dec 18, 2024
5a83b4a
codeowners
apenzk Dec 18, 2024
a725ac4
mip
apenzk Dec 18, 2024
046b70d
png
apenzk Dec 18, 2024
ac3efab
risks and mitigation strategies
apenzk Dec 18, 2024
59c70ef
Use change log instea dof errata.
franck44 Dec 18, 2024
004ed90
Add to Abstract and Motivation.
franck44 Dec 18, 2024
dcad5e0
Add L2 definition.
franck44 Dec 18, 2024
49be30c
Remove redundant definition of L2-Minter.
franck44 Dec 18, 2024
003dc8a
Use window for interval.
franck44 Dec 18, 2024
7071a7c
Re-factor sections in Rate-limiter.
franck44 Dec 18, 2024
ecbcdb9
Add principle for the rate-limiter.
franck44 Dec 19, 2024
88dd2e7
Minor changes.
franck44 Dec 19, 2024
e91a3c9
address review comments
apenzk Dec 19, 2024
bb95565
Merge branch 'main' into mip/rate-limiter-lock-mint-bridge
apenzk Dec 19, 2024
4a65007
update fig
apenzk Dec 19, 2024
9679333
minor fix
apenzk Dec 19, 2024
f81f244
Governance Operator
apenzk Dec 19, 2024
dc8cab3
Add to verification.
franck44 Dec 20, 2024
76c1c3f
Minor typo
franck44 Dec 20, 2024
6ac10e6
Minor add
franck44 Dec 20, 2024
0006da6
Fix missing The.
franck44 Jan 5, 2025
0f13196
Use NOTE to display key words.
franck44 Jan 5, 2025
5503feb
Use (Native) instesd of Natiev for conssitency with figure 1.
franck44 Jan 5, 2025
62def7a
Minor changes.
franck44 Jan 5, 2025
2a83a53
Minor fixes in risk and mitigation.
franck44 Jan 5, 2025
17897df
Minor changes Expected Prop and Intro Rate Limiter.
franck44 Jan 5, 2025
846e67e
fix typos
apenzk Jan 7, 2025
8034e18
remove optimisation algo for relayer
apenzk Jan 7, 2025
f1ac661
revert accidental removal
apenzk Jan 7, 2025
eb38182
update figure
apenzk Jan 7, 2025
d367149
improve rate limit on target chain
apenzk Jan 7, 2025
2fa892b
improve rate limit on source chain description
apenzk Jan 7, 2025
0a4b7e2
implementation recommendation
apenzk Jan 7, 2025
16cc7e0
add alternative options to the appendix
apenzk Jan 7, 2025
ad96d14
minor fixes
apenzk Jan 8, 2025
e40537c
fix $MOVE
apenzk Jan 13, 2025
f434253
Merge branch 'main' into mip/rate-limiter-lock-mint-bridge
apenzk Jan 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@
/MD/md-15/ @l-monninger @apenzk
/MIP/mip-39/ @franck44
/MIP/mip-53/ @l-monninger
/MD/md-74/ @apenzk
/MIP/mip-74/ @apenzk
31 changes: 31 additions & 0 deletions MD/md-74/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# MD-74: Rate-Limiter for the Lock/Mint-type Native Bridge
- **Description**: A rate limitation mechanism for the Lock/Mint-type Native Bridge.
- **Authors**: [Andreas Penzkofer](mailto:[email protected])

## Overview

The Lock/Mint-type Native Bridge (hereafter called the "Native Bridge"), see [MIP-58](https://github.com/movementlabsxyz/MIP/pull/58), must be protected against faulty components and attacks. A Rate-Limiter is a mechanism that can help to protect the Native Bridge. It limits the volume of transferred value, the maximum value transferred with a given transfer, or the number of transactions.

## Desiderata

### D1: Specify the actors and their trust assumptions

**User Journey**: The developer should understand existing trust assumptions.

**Description**: The Native Bridge is operated via contracts, actors and components. What are the trust assumptions on these?

### D1: Specify the risks and threats from components

**User Journey**: The developer should understand the risks from components.

**Description**: We must ensure that risks are minimized even in the case that a component is compromised or faulty.

**Recommendations**: Address the risks by first identifying the relevant parties and their trust assumptions. Then, specify the risks and threats from these components. How can we restrict the risks?

### D3: Define the rate-limiting mechanism

**User Journey**: The developer should understand the rate-limiting mechanism.

**Description**: The rate-limiting mechanism should be defined in a way that it is clear how it works and how it can be adjusted. Moreover all components and their parameters should be defined. It should also be defined what is being rate-limited.

## Errata
159 changes: 159 additions & 0 deletions MIP/mip-74/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# MIP-74: Rate-Limiter for the Lock/Mint-type Native Bridge

- **Description**: A rate limitation mechanism for the Lock/Mint-type Native Bridge.
- **Authors**: [Andreas Penzkofer](mailto:[email protected])
- **Desiderata**: [MD-74](../../MD/md-74/README.md)

## Abstract

We propose a Rate-Limiter to protect the Lock/Mint-type Native Bridge, hereafter called the _Native Bridge_^[see [MIP-58](https://github.com/movementlabsxyz/MIP/pull/58)] against faulty or compromised behavior of the bridge components. It limits the volume of assets that can be transferred within a time window. This MIP proposes a solution to mitigate attacks and limit damages, and if paired with an insurance fund it may cover the potential losses incurred by our users.

## Motivation

There are several components and actors in control of the behavior of the Native Bridge including contracts (we may assume they are trusted, our relayer and of course the network. If an attacker can control one these components they can potentially mint and transfer assets thereby compromising the bridge.

A Rate-Limiter can help to protect the Native Bridge against faulty components (relayer or network) or attacks. It can limit the volume of transferred value per time interval, the maximum value transferred with a given transfer, or the number of transactions within a time window.

## Specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.

> [!WARNING]
> Hereafter we use **L2** for the **Move Chain** which is at Level 2 in the layered architecture of the Movement Network.
apenzk marked this conversation as resolved.
Show resolved Hide resolved

### Actors and components

The Native Bridge is operated via contracts, key holders and a relayer. The following actors and components are involved:

1. **User**: The user is the entity that interacts with the Native Bridge. The user can be a contract or an external account.
1. **L1 Native Bridge contract**: The L1 Native Bridge contract is the contract that is deployed on the L1 chain. It is responsible for locking and releasing (unlocking) assets on the L1 chain.
1. **L2 Native Bridge contract**: The L2 Native Bridge contract is the contract that is deployed on the L2 chain. It is responsible for minting and burning assets on the L2 chain.
<!-- 1. **L2-Minter**: The L2-Minter is an L2-contract that is responsible for minting assets on the L2 chain. -->
1. **Governance contract**: The governance contract is an L2 contract on L2 that is used to adjust the parameters of the Native Bridge components on L2.
1. **Governance Operator**: The governance operator is the entity that can adjust the parameters of the Native Bridge via the governance contract or directly. Hereafter we simply refer to the Operator.

In addition to protect the Native Bridge against faulty components, the Rate-Limiter and the Insurance Fund are introduced. Figure 1 shows the architecture of the Native Bridge including the following components:

1. **Insurance fund**: The insurance fund is a contract that is used to cover potential losses in case of a faulty component, see [MIP-50](https://github.com/movementlabsxyz/MIP/pull/50).
1. **Rate Limiter**: The Rate Limiter is a set of contracts (one on the L1 and one on the L2) that is used to limit the volume of transferred value per time window.

![alt text](overview.png)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Believe that we need to change the role that sets the rate limit to DEFAULT_ADMIN instead of RELAYER. We won't have access to setting limit because the relayer won't be accessible to us. There are other ADMIN functionalities that are at the same risk level. We can have a hot role for emergency PAUSER_ROLE. It could be assigned to all engineers so that anyone could pause initiate_bridge_transfer calls.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, the Bridge Operator should also set the rate limit.

the relayer could read programmatically the required data from L1, and thus set the rate limit programmatically.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not also, it should be exclusively done by DEFAULT ADMIN, that's what I meant

_Figure 1: Architecture of the Rate Limitation_
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@apenzk
In Figure 1, It is not clear to me what "sets parameters" means vs "sets limit".
I would simplify the figure as follows:

  • user "sends" (rather than "attempts")
  • is the governance a contract on L2? If not, it may located outside of the yellow box.
  • what are the parameters, and is limit a parameter? Are there any constriants between the different "limits"?
  • why is the opertor instructing the governance and not the opposite?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. replaced by "requests transfer"
  2. its on L2
  3. limit = f(insurance fund, reaction time, reduction factor), governance can set the latter two, the constraints between the limits are described in the text of the document. does it need improving?
  4. its the governance operator, will change operator -> governance operator

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@apenzk The figure has a few glitches:

  1. L2 Bridge Contract used in the picture but L2 Native Bridge Contract in the text
  2. L2 bridge contract on L1, should be L1 Bridge contract.

I have added () around thr Native attribute in the text, so that may fix 1. but I have not modified the figure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated figure and text.


### Actors, Components and Trust assumptions

We assume the following trust assumptions:

1. The Governance contract is implemented correctly.
1. The Bridge contract and the L2 Native Bridge contract are implemented correctly.
1. The Governance Operator is trusted. For example it COULD be a multisig human.
1. The Relayer is a trusted software component.

### Risks and mitigation strategies

The following risks are associated with the Native Bridge:

1. The trusted relayer is compromised or faulty. We thus want to ensure that the relayer has not unlimited power to release or mint assets. For this we MUST implement a rate limiter on the target chain.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That seems to contradict that the relayer is trusted.
If it can be faulty, it is not trusted.

Copy link
Contributor Author

@apenzk apenzk Dec 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"partially trusted" ?
"trusted (to a large extend)" ?

1. In order to rate limit the bridge (e.g. stop the bridge transfers entirely) there should be a higher instance than the relayer in setting rate limits. Thus the rate limit on the target chain SHOULD be set by the Operator.
apenzk marked this conversation as resolved.
Show resolved Hide resolved
1. The Relayer may go down, while the number of transactions and requested transfer value across the bridge still increases on the source chain. Due to rate limit on the target chain the Relayer may struggle to process all initiated transfers. Thus the Relayer or the Operator MUST rate limit the source chain as well.
apenzk marked this conversation as resolved.
Show resolved Hide resolved

### Objectives

The objectives of the rate-limiter are to guarantee the following properties:

- the value of assets being bridged MUST always be less than the insurance funds
- property 2
- property 3 ...

### Rate-Limiter
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@apenzk
Would it makes sense to list the expected properties (as per above) and what they guarantee to the operator and the user?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is the "Risks and mitigation strategy" section. Do you think it is to convoluted?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@apenzk
Can you confirm this is correct?
And add anything you think is relevant to tis section?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i have added several points to the "Objectives" section


In the Native Bridge, the Rate-Limiter MUST be implemented as part of the L1 Native Bridge contract and the L2 Native Bridge contract.
apenzk marked this conversation as resolved.
Show resolved Hide resolved

#### Insurance funds

We assume there is a Insurance Fund on both L1 and L2, with values `insurance_fund_L1` and `insurance_fund_L2`, respectively.
These values are considered constant in the sequel. There may be updated if needed or if new funds are added to the pools.

The Insurance Fund rate-limits the outbound transfers, i.e. for a given transfer from source chain to target chain the Insurance Fund on the target chain is responsible for the rate limit, and thus we will refer to the `insurance_fund_target`. I.e. for a transfer from L1 to L2 the `insurance_fund_target = insurance_fund_L2` is responsible for the rate limit. While for a transfer from L2 to L1 the `insurance_fund_target = insurance_fund_L1` is responsible for the rate limit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@apenzk
The important part seems to be that the insurance funds (total) limits the rate.
Is it necessary to consider two sides the L1 fund and the L2 fund or could we collapse them into one (at the design level)?
I understand that if we need to compensate users we may need two pools, oneon L1 and one on L2, but this may be separate to the actual logic.

Copy link
Contributor Author

@apenzk apenzk Dec 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the reason there are two pools is that each direction needs to be covered by an own value. the total rate in both direction is limited by the total amount in the insurance fund. we cannot use the insurance fund to secure twice and thus if we want to secure X in each direction the insurance fund must be 2X (if it would be on one Level only)

we initially had it on one side and i think this was advocated for by @Primata and @l-monninger .

the governance operator decides about the amount in the insurance fund as well as the reaction time. thus in principle we could simply trust it and allow it to set the value directly. however it adds additional assumptions on that the governance operator does not make errors.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@apenzk So in principle, the values for pools on L1 and L2 should be the same? We split the total insurance fund into the two pools?

Copy link
Contributor Author

@apenzk apenzk Jan 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we would want to have the same max rate in either direction, yes. But i dont think this is a requirement.

#### Rate limit on the target chain

The rate limit is dependent on the fund size in the Insurance Fund. In particular the maximum rate limit

`max_rate_limit_target = insurance_fund_target / reaction_time`,

where the `reaction_time` is the time it takes for the Operator to react to a faulty or compromised component. The `reaction_time` is a parameter that is set by the Operator. The Operator MAY set the actual rate limit lower than the `max_rate_limit_target`. However the Rate Limiter MUST NOT set the rate limit higher than the `max_rate_limit_target`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@apenzk
I suggest to break this into two independent parts:

  • property if the rate limit and max_rate limit etc
  • permissions: who can set what.

At the moment I find this section confusing with the Rate limier, the Operator etc so it may need to be clarified.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i tried to improve, wdyt?


The rate limit MAY also be adjusted by the Operator.

`rate_limit_target = rate_reduction_target * max_rate_limit_target`,

where `rate_reduction_target \in {0,1}` is a parameter that is set by the Operator. Note the `rate_limit_target` MUST not be larger than `max_rate_limit_target`.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it the inetrval [0,1] or 0 or 1?
In smart contracts, it is usually not easy to use real numbers (Solidity/EVM does not support it) and MoveVM does but computation is bit more expensive if I am correct than integers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. you r correct . it is [0,1]. will change it.
  2. i am not sure what would numerically be the most efficient way.. there is a maximum rate limit and the Operator could choose a smaller part of that (less than 100%).

The following are possible ways to adjust the rate limit:

1. The Operator can adjust the rate limit by adding or removing funds from the Insurance Fund.
1. The Operator may adjust the rate limit by changing the `reaction_time`.
1. The Operator may adjust the rate limit by changing the `rate_reduction_target`.

#### Rate limit on the source chain

On the source chain the rate limit MAY be lowered by the Relayer. This is to ensure that the rate limit on the target chain is not exceeded. It also permits the Relayer to catch up in case of the Relayer has been down for some time.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@apenzk
We may need to justify why there is a need for a rate limit on the source chain.
Could we have an example fo what can happen?

My understanding was that it is needed because of delays between transfers from L2 -> L1 (or vice versa) so we need to know what is requested to bridge and what is completed (the sum of the two should be lower than the insurance funds).

Copy link
Contributor Author

@apenzk apenzk Dec 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i have added a para

On the source chain the rate limit MUST be limited by the Governance Operator to match the rate limit on the target chain. if only the target chain would be rate limited users could successfully continue to request transfers on the source chain while the budget on the target chain is already consumed. Consequently the Relayer would not be capable to complete the transfers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rate limiter must react to chain based data, it is not possible for the source chain contract to know about the completed transactions nor the insurance fund on target. Thus we assume that clocks are correct and requested transfers < completed transfers AND trust that the operator updates on source the rate limit.

Primata marked this conversation as resolved.
Show resolved Hide resolved

`rate_limit_source = min{rate_reduction_source * rate_limit_target, rate_limit_operator_source}`,

where `rate_reduction_source \in {0,1}` is a parameter that is set by the Relayer. `rate_limit_operator_source` is a parameter that is set by the Operator. Note the `rate_limit_source` SHOULD not be larger than `rate_limit_operator_source`.

Copy link
Contributor

@franck44 franck44 Jan 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@apenzk So it looks like there is a need for synchronising the rate limits on both the source and traget and the relayer can do that. We could use this sync mechanism to simplify the rate limiter I think.

I would assume that as long as less than insurance_fund1 is currently "in-flight" we are OK, so we may try to measure that.
Assume we are bridging from L2 to L1.
If we know that an amount $S$ is currently bridged over (pending to be completed) to L1 and $S \leq $ insurance_fund1 then we can cover the loss (there is no need for a time window).
To know that this the case, we need to keep track of the completed Txs and another conponent can do that (or the Relayer).
When a bridge Tx from L2 to L1, anount $k$, is successfully completed we can decrease $S$ and update it to $S := S - k$.

On another note, I am a bit confused about the wording/naming here. Why do we need a rate?
If we have a unique Tx with the maximum amount insurance_fund1 we should first clear this Tx before we continue to process new ones.

Would it be the role of the Informer to do this kind of things (syncing L2 <-> L1)?

Copy link
Contributor Author

@apenzk apenzk Jan 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would assume that as long as less than insurance_fund1 is currently "in-flight" we are OK, so we may try to measure that.
...
To know that this the case, we need to keep track of the completed Txs and another conponent can do that (or the Relayer).

as discussed above with @Primata sliding windows or reseting budget based on completing transactions seems out of scope for this version. I suggest we move more complicated versions over to a new MIP.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

worth noting:

There is a valid case where the relayer should set the rate limit on the source chain: if the operator fails to adjust the rate limit on the source chain when ajusting the rate limit on the target chain (by changing insurance fund or reaction time).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the main thing for the relayer to implement is holding transaction until it's able to complete on target chain.

  1. Worst case scenario users need to wait for 24hrs.
  2. This would allow us to also inform the user on the source chain that there is a difference between source chain and target chain rate limit budget. That would be the in-flight value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the rate limit on the source chain is much larger than on the target chain, it is could be much more than 24h.

but yes, the relayer would need to be able to hold. or in a simple implementation he would just retry continuously which is handled by MIP-61

### Rate limitation algorithm

The rate limitation works as follows:

> [!NOTE]
> I can convert the following into pseudo code, after we have discussed the algorithm and it makes sense.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is not clear to me is how the time window is updated. And is it a sliding window? e.g the last 40 txs? or the last 10 minutes? Or the last ten blocks?
I would think that a per Tx window makes sense, does it? e.g., every 1000 tx we go to w new time window/interval.

Copy link
Contributor Author

@apenzk apenzk Dec 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets assume the simplest non-optimized case first : fixed timewindows, lets call them epochs. then (if not too expensive) every initiate transaction checks and resets the budget IF it is in the new epoch. would this work?

a sliding window seems more difficult. the easiest and most gas efficient may be that we approximate a sliding window. E.g. split the epoch into smaller parts, but maybe not the most elegant approach. We are restricted by the user having to update the bridge contract state

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Easiest and cheapest implementation is, taking the block timestamp. Divide it by 24hrs and you get a number, that is your time allocation to be checked against. IF we change the 24hrs fixed value it leads to an issue with time allocation, that's why I'd advise against it because to fix it we need some extra operations and logic that might lead to unexpected behaviors.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i agree with @Primata and suggest we leave sliding windows and such for future MIPs

**Algorithm for the Native Bridge contract on the source chain**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assumes to use MIP-58's design C, correct?

Copy link
Contributor Author

@apenzk apenzk Jan 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, i have moved the moved the alternative designs described in MIP-58 to the appendix here and added you consequently as an author.


1. A user wants to transfer value from source to target chain.
1. The user sends a transaction to the source chain Native Bridge contract.
1. The source chain Native Bridge contract checks if the rate limit `rate_limit_source` is exceeded if it would apply the transaction.
1. If the rate limit is exceeded the transaction is rejected.
1. Else the transaction is accepted.

**Algorithm for the Native Bridge contract on the target chain**

1. The target chain Native Bridge contract checks if the rate limit `rate_limit_target` is exceeded if it would apply the transaction.
1. If the rate limit is exceeded the transaction is rejected.
1. If the rate limit is not exceeded the transaction is accepted.

The following algorithm is a recommendation for the operation of the Relayer:

**(Optional) Algorithm for the Relayer**

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@apenzk I am not sure we need to do anything with the Relayer. If a transaction is not processed within a given amount of time (for any reason, network down etc), the Relayer should re-send it to ensure it evetually succeeds.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was to avoid excessive costs to the relayer incase the budget is consumed on the target chain but is not consumed on the source chain. i have removed it as it is an optimisation that we can handle once we discover it actually is an issue.

1. The Relayer receives an event that a transaction was accepted.
1. The Relayer checks if the rate limit `rate_limit_target` is exceeded if it would apply the transaction. (The Relayer may keep locally the budget on the target chain, or it could read the contract state).
1. If the rate limit is exceeded the transaction has to be put on hold.
1. Else the Relayer sends a transfer transaction to the target chain.

## Reference Implementation

## Verification

Needs discussion.

---

## Change Log

---

## Appendix

### A1

Nothing important here.

---

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).
Binary file added MIP/mip-74/overview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading