Skip to content

Commit

Permalink
add rate limiter
Browse files Browse the repository at this point in the history
  • Loading branch information
Primata committed Nov 20, 2024
1 parent 0e4d472 commit 227675d
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 5 deletions.
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
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/
4 changes: 4 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,17 @@ interface INativeBridge {
uint256 nonce
);

event RateLimitsUpdated(uint256 outboundNewRateLimit, uint256 inboundNewRateLimit);

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

/**
* @dev Creates a new bridge
Expand Down
31 changes: 29 additions & 2 deletions protocol-units/bridge/contracts/src/NativeBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/acce
import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
import {INativeBridge} from "./INativeBridge.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {BokkyPooBahsDateTimeLibrary} from "@DateTimeLibrary/contracts/BookyPooBahsDateTimeLibrary.sol";

// import {RateLimiter} from "./RateLimiter.sol";

contract NativeBridge is AccessControlUpgradeable, PausableUpgradeable, INativeBridge {
using BokkyPooBahsDateTimeLibrary for uint256;
struct OutgoingTransfer {
bytes32 bridgeTransferId;
address initiator;
Expand All @@ -19,7 +21,11 @@ contract NativeBridge is AccessControlUpgradeable, PausableUpgradeable, INativeB

mapping(uint256 nonce => OutgoingTransfer) public noncesToOutgoingTransfers;
mapping(bytes32 bridgeTransferId => uint256 nonce) public idsToIncomingNonces;
mapping(uint256 year => mapping(uint256 month => (uint256 day => uint256 amount))) public outboundRateLimitBudget;
mapping(uint256 year => mapping(uint256 month => (uint256 day => uint256 amount))) public incomingRateLimitBudget;

uint256 public outboundRateLimit;
uint256 public incomingRateLimit;
IERC20 public moveToken;
bytes32 public constant RELAYER_ROLE = keccak256(abi.encodePacked("RELAYER_ROLE"));
uint256 private _nonce;
Expand All @@ -30,13 +36,17 @@ contract NativeBridge is AccessControlUpgradeable, PausableUpgradeable, INativeB
}
// TODO: include rate limit

function initialize(address _moveToken, address _admin, address _relayer, address _maintainer) public initializer {
function initialize(address _moveToken, address _admin, address _relayer, address _maintainer, uint256 _outboundRateLimit, uint256 _incomingRateLimit) 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 the rate limits
outboundRateLimit = _outboundRateLimit;
incomingRateLimit = _incomingRateLimit;

// Maintainer is optional
_grantRole(RELAYER_ROLE, _maintainer);
}
Expand All @@ -48,6 +58,7 @@ contract NativeBridge is AccessControlUpgradeable, PausableUpgradeable, INativeB
{
// Ensure there is a valid amount
require(amount > 0, ZeroAmount());
_outboundRateLimit(amount);
// _l1l2RateLimit(amount);
address initiator = msg.sender;

Expand Down Expand Up @@ -101,7 +112,7 @@ contract NativeBridge is AccessControlUpgradeable, PausableUpgradeable, INativeB
uint256 amount,
uint256 nonce
) internal {
// _l2l1RateLimit(amount);
_incomingRateLimit(amount);
// Ensure the bridge transfer has not already been completed
require(nonce > 0, InvalidNonce());
require(idsToIncomingNonces[bridgeTransferId] == 0, CompletedBridgeTransferId());
Expand All @@ -120,7 +131,23 @@ contract NativeBridge is AccessControlUpgradeable, PausableUpgradeable, INativeB
emit BridgeTransferCompleted(bridgeTransferId, initiator, recipient, amount, nonce);
}

function setRateLimits(uint256 _outboundRateLimit, uint256 _incomingRateLimit) external onlyRole(DEFAULT_ADMIN_ROLE) {
outboundRateLimit = _outboundRateLimit;
incomingRateLimit = _incomingRateLimit;
emit RateLimitsUpdated(_outboundRateLimit, _incomingRateLimit);
}

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

_rateLimitOutbound(uint256 amount) internal {
(uint256 year, uint256 month, uint256 day) = block.timestamp.timestampToDate();
require(outboundRateLimitBudget[year][month][day] + amount <= outboundRateLimit, OutboundRateLimitExceeded());
}

_rateLimitIncoming(uint256 amount) internal {
(uint256 year, uint256 month, uint256 day) = block.timestamp.timestampToDate();
require(incomingRateLimitBudget[year][month][day] + amount <= incomingRateLimit, IncomingRateLimitExceeded());
}
}

0 comments on commit 227675d

Please sign in to comment.