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

Daily Rate Limiter #889

Merged
merged 11 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,9 @@
[submodule "protocol-units/tokens/mock/testnet/holesky/lib/openzeppelin-contracts"]
path = protocol-units/tokens/mock/testnet/holesky/lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
[submodule "lib/BokkyPooBahsDateTimeLibrary"]
path = lib/BokkyPooBahsDateTimeLibrary
url = https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary
[submodule "protocol-units/bridge/contracts/lib/BokkyPooBahsDateTimeLibrary"]
path = protocol-units/bridge/contracts/lib/BokkyPooBahsDateTimeLibrary
url = https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary
2 changes: 1 addition & 1 deletion protocol-units/bridge/contracts/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ src = "src"
out = "out"
libs = ["lib"]

solc = "0.8.26"
solc = "0.8.27"
evm_version = "cancun"

# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
Expand Down
10 changes: 7 additions & 3 deletions protocol-units/bridge/contracts/remappings.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/
@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/
ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/
erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/
@DateTimeLibrary/=lib/BokkyPooBahsDateTimeLibrary/
ds-test/=lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/
erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/
forge-std/=lib/forge-std/src/
openzeppelin-contracts/=lib/openzeppelin-contracts/
halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/
openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/
openzeppelin-contracts/=lib/openzeppelin-contracts/
5 changes: 5 additions & 0 deletions protocol-units/bridge/contracts/src/INativeBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,18 @@ interface INativeBridge {
uint256 nonce
);

event InsuranceFundUpdated(address insuranceFund);
event PauseToggled(bool paused);

error ZeroAmount();
error MOVETransferFailed();
error ZeroAddress();
error InvalidLenghts();
error InvalidBridgeTransferId();
error CompletedBridgeTransferId();
error InvalidNonce();
error OutboundRateLimitExceeded();
error InboundRateLimitExceeded();

/**
* @dev Creates a new bridge
Expand Down
34 changes: 30 additions & 4 deletions protocol-units/bridge/contracts/src/NativeBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ contract NativeBridge is AccessControlUpgradeable, PausableUpgradeable, INativeB

mapping(uint256 nonce => OutboundTransfer) public noncesToOutboundTransfers;
mapping(bytes32 bridgeTransferId => uint256 nonce) public idsToInboundNonces;
mapping(uint256 day => uint256 amount) public outboundRateLimitBudget;
mapping(uint256 day => uint256 amount) public inboundRateLimitBudget;

address public insuranceFund;
IERC20 public moveToken;
bytes32 public constant RELAYER_ROLE = keccak256(abi.encodePacked("RELAYER_ROLE"));
uint256 private _nonce;
Expand All @@ -37,12 +40,17 @@ contract NativeBridge is AccessControlUpgradeable, PausableUpgradeable, INativeB
* @param _relayer The address of the relayer role
* @param _maintainer The address of the maintainer role
*/
function initialize(address _moveToken, address _admin, address _relayer, address _maintainer) public initializer {
function initialize(address _moveToken, address _admin, address _relayer, address _maintainer, address _insuranceFund) public initializer {
require(_moveToken != address(0) && _admin != address(0) && _relayer != address(0), ZeroAddress());
__Pausable_init();
moveToken = IERC20(_moveToken);
_grantRole(DEFAULT_ADMIN_ROLE, _admin);
_grantRole(RELAYER_ROLE, _relayer);

// Set insurance fund
insuranceFund = _insuranceFund;

// Maintainer is optional
_grantRole(RELAYER_ROLE, _maintainer);
}

Expand All @@ -60,7 +68,7 @@ contract NativeBridge is AccessControlUpgradeable, PausableUpgradeable, INativeB
{
// Ensure there is a valid amount
require(amount > 0, ZeroAmount());
// _l1l2RateLimit(amount);
_rateLimitOutbound(amount);
address initiator = msg.sender;

// Transfer the MOVE tokens from the user to the contract
Expand All @@ -79,7 +87,7 @@ contract NativeBridge is AccessControlUpgradeable, PausableUpgradeable, INativeB
/**
* @dev Completes the bridging of funds. Only the relayer can call this function.
* @param bridgeTransferId Unique identifier for the BridgeTransfer
* @param originator The address on the other chain that originated the transfer of funds
* @param initiator The address on the other chain that originated the transfer of funds
* @param recipient The address on this chain to which to transfer funds
* @param amount The amount to transfer
* @param nonce The seed nonce to generate the bridgeTransferId
Expand Down Expand Up @@ -129,7 +137,7 @@ contract NativeBridge is AccessControlUpgradeable, PausableUpgradeable, INativeB
uint256 amount,
uint256 nonce
) internal {
// _l2l1RateLimit(amount);
_rateLimitInbound(amount);
// Ensure the bridge transfer has not already been completed
require(nonce > 0, InvalidNonce());
require(idsToInboundNonces[bridgeTransferId] == 0, CompletedBridgeTransferId());
Expand All @@ -148,7 +156,25 @@ contract NativeBridge is AccessControlUpgradeable, PausableUpgradeable, INativeB
emit BridgeTransferCompleted(bridgeTransferId, initiator, recipient, amount, nonce);
}

function setInsuranceFund(address _insuranceFund) external onlyRole(DEFAULT_ADMIN_ROLE) {
insuranceFund = _insuranceFund;
emit InsuranceFundUpdated(_insuranceFund);
}

function togglePause() external onlyRole(DEFAULT_ADMIN_ROLE) {
paused() ? _pause() : _unpause();
emit PauseToggled(paused());
}

function _rateLimitOutbound(uint256 amount) internal {
uint256 day = block.timestamp / 1 days;
outboundRateLimitBudget[day] += amount;
require(outboundRateLimitBudget[day] < moveToken.balanceOf(insuranceFund) / 4, OutboundRateLimitExceeded());
}

function _rateLimitInbound(uint256 amount) internal {
uint256 day = block.timestamp / 1 days;
inboundRateLimitBudget[day] += amount;
require(inboundRateLimitBudget[day] < moveToken.balanceOf(insuranceFund) / 4, InboundRateLimitExceeded());
}
}
Loading
Loading