Skip to content

Commit

Permalink
CCIP-4329 modify setChainRateLimiterConfig file for setting multiple … (
Browse files Browse the repository at this point in the history
#1569)

…rate limits (#15386)

* modify setChainRateLimiterConfig file for setting multiple rate limits

* Update gethwrappers

* [Bot] Update changeset file with jira issues

* snapshot fix

* fix wrappers after merge

* fix test that was broken in merge

* fix liquidityManager snapshot which is affected by token pool changes

* fix broken integration tests from removing critical setup function

* add array length check for setChainRateLimitConfigs

* formatting and snapshot fix

* Update gethwrappers

* simplify test setups

* Update gethwrappers

* update wrappers and snapshots which were broken in merge

* Update gethwrappers

* update wrappers and snapshot

* changeset

* snapshot update

* Delete contracts/.changeset/orange-buckets-live.md

* attempt fix changeset

* attempt changeset fix with update pnpm package

* re-add function that was removed early in PR to prevent any required
tooling changes

* update liquidityManager snapshot because of changes to token pools

---------

## Motivation


## Solution

---------

Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com>
  • Loading branch information
1 parent 06914db commit 478f0e5
Show file tree
Hide file tree
Showing 13 changed files with 381 additions and 136 deletions.
5 changes: 5 additions & 0 deletions contracts/.changeset/small-countries-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@chainlink/contracts': patch
---

Modify TokenPool.sol function setChainRateLimiterConfig to now accept an array of configs and set sequentially. Requested by front-end. PR issue CCIP-4329 #bugfix
231 changes: 117 additions & 114 deletions contracts/gas-snapshots/ccip.gas-snapshot

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions contracts/gas-snapshots/liquiditymanager.gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ LiquidityManager_addLiquidity:test_addLiquiditySuccess() (gas: 279154)
LiquidityManager_rebalanceLiquidity:test_InsufficientLiquidityReverts() (gas: 206745)
LiquidityManager_rebalanceLiquidity:test_InvalidRemoteChainReverts() (gas: 192319)
LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess() (gas: 9141768)
LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess_AlreadyFinalized() (gas: 9306597)
LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_MultiStageFinalization() (gas: 9301803)
LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_NativeRewrap() (gas: 9231693)
LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess_AlreadyFinalized() (gas: 9435588)
LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_MultiStageFinalization() (gas: 9430794)
LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_NativeRewrap() (gas: 9360684)
LiquidityManager_rebalanceLiquidity:test_rebalanceLiquiditySuccess() (gas: 382880)
LiquidityManager_receive:test_receive_success() (gas: 21182)
LiquidityManager_removeLiquidity:test_InsufficientLiquidityReverts() (gas: 184869)
Expand All @@ -19,7 +19,7 @@ LiquidityManager_setFinanceRole:test_OnlyOwnerReverts() (gas: 10987)
LiquidityManager_setFinanceRole:test_setFinanceRoleSuccess() (gas: 21836)
LiquidityManager_setLocalLiquidityContainer:test_OnlyOwnerReverts() (gas: 11052)
LiquidityManager_setLocalLiquidityContainer:test_ReverstWhen_CalledWithTheZeroAddress() (gas: 10643)
LiquidityManager_setLocalLiquidityContainer:test_setLocalLiquidityContainerSuccess() (gas: 3847225)
LiquidityManager_setLocalLiquidityContainer:test_setLocalLiquidityContainerSuccess() (gas: 3976172)
LiquidityManager_setMinimumLiquidity:test_OnlyOwnerReverts() (gas: 10925)
LiquidityManager_setMinimumLiquidity:test_setMinimumLiquiditySuccess() (gas: 36389)
LiquidityManager_withdrawERC20:test_withdrawERC20Reverts() (gas: 180359)
Expand Down
20 changes: 20 additions & 0 deletions contracts/src/v0.8/ccip/pools/TokenPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ abstract contract TokenPool is IPoolV1, Ownable2StepMsgSender {
error PoolAlreadyAdded(uint64 remoteChainSelector, bytes remotePoolAddress);
error InvalidRemotePoolForChain(uint64 remoteChainSelector, bytes remotePoolAddress);
error InvalidRemoteChainDecimals(bytes sourcePoolData);
error MismatchedArrayLengths();
error OverflowDetected(uint8 remoteDecimals, uint8 localDecimals, uint256 remoteAmount);
error InvalidDecimalArgs(uint8 expected, uint8 actual);

Expand Down Expand Up @@ -533,6 +534,25 @@ abstract contract TokenPool is IPoolV1, Ownable2StepMsgSender {
return s_remoteChainConfigs[remoteChainSelector].inboundRateLimiterConfig._currentTokenBucketState();
}

/// @notice Sets multiple chain rate limiter configs.
/// @param remoteChainSelectors The remote chain selector for which the rate limits apply.
/// @param outboundConfigs The new outbound rate limiter config, meaning the onRamp rate limits for the given chain.
/// @param inboundConfigs The new inbound rate limiter config, meaning the offRamp rate limits for the given chain.
function setChainRateLimiterConfigs(
uint64[] calldata remoteChainSelectors,
RateLimiter.Config[] calldata outboundConfigs,
RateLimiter.Config[] calldata inboundConfigs
) external {
if (msg.sender != s_rateLimitAdmin && msg.sender != owner()) revert Unauthorized(msg.sender);
if (remoteChainSelectors.length != outboundConfigs.length || remoteChainSelectors.length != inboundConfigs.length) {
revert MismatchedArrayLengths();
}

for (uint256 i = 0; i < remoteChainSelectors.length; ++i) {
_setRateLimitConfig(remoteChainSelectors[i], outboundConfigs[i], inboundConfigs[i]);
}
}

/// @notice Sets the chain rate limiter config.
/// @param remoteChainSelector The remote chain selector for which the rate limits apply.
/// @param outboundConfig The new outbound rate limiter config, meaning the onRamp rate limits for the given chain.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.24;

import {RateLimiter} from "../../../libraries/RateLimiter.sol";
import {TokenPool} from "../../../pools/TokenPool.sol";
import {TokenPoolSetup} from "./TokenPoolSetup.t.sol";

contract TokenPool_setChainRateLimiterConfigs is TokenPoolSetup {
uint64 internal s_remoteChainSelector;

function setUp() public virtual override {
TokenPoolSetup.setUp();

bytes[] memory remotePoolAddresses = new bytes[](1);
remotePoolAddresses[0] = abi.encode(address(2));

TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1);
s_remoteChainSelector = 123124;
chainUpdates[0] = TokenPool.ChainUpdate({
remoteChainSelector: s_remoteChainSelector,
remotePoolAddresses: remotePoolAddresses,
remoteTokenAddress: abi.encode(address(3)),
outboundRateLimiterConfig: _getOutboundRateLimiterConfig(),
inboundRateLimiterConfig: _getInboundRateLimiterConfig()
});
s_tokenPool.applyChainUpdates(new uint64[](0), chainUpdates);
}

function testFuzz_SetChainRateLimiterConfigs_Success(uint128 capacity, uint128 rate, uint32 newTime) public {
// Cap the lower bound to 4 so 4/2 is still >= 2
vm.assume(capacity >= 4);
// Cap the lower bound to 2 so 2/2 is still >= 1
rate = uint128(bound(rate, 2, capacity - 2));
// Bucket updates only work on increasing time
newTime = uint32(bound(newTime, block.timestamp + 1, type(uint32).max));
vm.warp(newTime);

uint256 oldOutboundTokens = s_tokenPool.getCurrentOutboundRateLimiterState(DEST_CHAIN_SELECTOR).tokens;
uint256 oldInboundTokens = s_tokenPool.getCurrentInboundRateLimiterState(DEST_CHAIN_SELECTOR).tokens;

RateLimiter.Config memory newOutboundConfig = RateLimiter.Config({isEnabled: true, capacity: capacity, rate: rate});
RateLimiter.Config memory newInboundConfig =
RateLimiter.Config({isEnabled: true, capacity: capacity / 2, rate: rate / 2});

uint64[] memory chainSelectors = new uint64[](1);
chainSelectors[0] = DEST_CHAIN_SELECTOR;

RateLimiter.Config[] memory newOutboundConfigs = new RateLimiter.Config[](1);
newOutboundConfigs[0] = newOutboundConfig;

RateLimiter.Config[] memory newInboundConfigs = new RateLimiter.Config[](1);
newInboundConfigs[0] = newInboundConfig;

vm.expectEmit();
emit RateLimiter.ConfigChanged(newOutboundConfig);
vm.expectEmit();
emit RateLimiter.ConfigChanged(newInboundConfig);
vm.expectEmit();
emit TokenPool.ChainConfigured(DEST_CHAIN_SELECTOR, newOutboundConfig, newInboundConfig);

s_tokenPool.setChainRateLimiterConfigs(chainSelectors, newOutboundConfigs, newInboundConfigs);

uint256 expectedTokens = RateLimiter._min(newOutboundConfig.capacity, oldOutboundTokens);

RateLimiter.TokenBucket memory bucket = s_tokenPool.getCurrentOutboundRateLimiterState(DEST_CHAIN_SELECTOR);
assertEq(bucket.capacity, newOutboundConfig.capacity);
assertEq(bucket.rate, newOutboundConfig.rate);
assertEq(bucket.tokens, expectedTokens);
assertEq(bucket.lastUpdated, newTime);

expectedTokens = RateLimiter._min(newInboundConfig.capacity, oldInboundTokens);

bucket = s_tokenPool.getCurrentInboundRateLimiterState(DEST_CHAIN_SELECTOR);
assertEq(bucket.capacity, newInboundConfig.capacity);
assertEq(bucket.rate, newInboundConfig.rate);
assertEq(bucket.tokens, expectedTokens);
assertEq(bucket.lastUpdated, newTime);
}

// Reverts

function test_OnlyOwnerOrRateLimitAdmin_Revert() public {
uint64[] memory chainSelectors = new uint64[](1);
chainSelectors[0] = DEST_CHAIN_SELECTOR;

RateLimiter.Config[] memory newOutboundConfigs = new RateLimiter.Config[](1);
newOutboundConfigs[0] = _getOutboundRateLimiterConfig();

RateLimiter.Config[] memory newInboundConfigs = new RateLimiter.Config[](1);
newInboundConfigs[0] = _getInboundRateLimiterConfig();

vm.startPrank(STRANGER);

vm.expectRevert(abi.encodeWithSelector(TokenPool.Unauthorized.selector, STRANGER));
s_tokenPool.setChainRateLimiterConfigs(chainSelectors, newOutboundConfigs, newInboundConfigs);
}

function test_NonExistentChain_Revert() public {
uint64 wrongChainSelector = 9084102894;

uint64[] memory chainSelectors = new uint64[](1);
chainSelectors[0] = wrongChainSelector;

RateLimiter.Config[] memory newOutboundConfigs = new RateLimiter.Config[](1);
RateLimiter.Config[] memory newInboundConfigs = new RateLimiter.Config[](1);

vm.expectRevert(abi.encodeWithSelector(TokenPool.NonExistentChain.selector, wrongChainSelector));
s_tokenPool.setChainRateLimiterConfigs(chainSelectors, newOutboundConfigs, newInboundConfigs);
}

function test_MismatchedArrayLengths_Revert() public {
uint64[] memory chainSelectors = new uint64[](1);

RateLimiter.Config[] memory newOutboundConfigs = new RateLimiter.Config[](1);
RateLimiter.Config[] memory newInboundConfigs = new RateLimiter.Config[](2);

// test mismatched array lengths between rate limiters
vm.expectRevert(abi.encodeWithSelector(TokenPool.MismatchedArrayLengths.selector));
s_tokenPool.setChainRateLimiterConfigs(chainSelectors, newOutboundConfigs, newInboundConfigs);

newInboundConfigs = new RateLimiter.Config[](1);
chainSelectors = new uint64[](2);

// test mismatched array lengths between chain selectors and rate limiters
vm.expectRevert(abi.encodeWithSelector(TokenPool.MismatchedArrayLengths.selector));
s_tokenPool.setChainRateLimiterConfigs(chainSelectors, newOutboundConfigs, newInboundConfigs);
}
}

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

16 changes: 15 additions & 1 deletion core/gethwrappers/ccip/generated/token_pool/token_pool.go

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
GETH_VERSION: 1.13.8
burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin 642919607d5642aa98713b88f737c918487adba682535cf630b7c7d5fd80dc43
burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 054d95f302a142f7b64eea27237e0889bee6c9eb8a487579c7279c09646dc42b
burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin 76c31f52fe1df85528c08b2e772e37dcf99ca1ec492d83a221abc1d5ec833694
burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 1c78cd3118b3c9ca82f8cb77ffc1137619ea4e8e503c460f2dafb659d0dd766b
burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin 717c079d5d13300cf3c3ee871c6e5bf9af904411f204fb081a9f3b263cca1391
burn_with_from_mint_rebasing_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintRebasingTokenPool/BurnWithFromMintRebasingTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintRebasingTokenPool/BurnWithFromMintRebasingTokenPool.bin ec9b95105a33de14b078c1261d9cd9d6f3011e940a819b52f11a963951d4bb89
burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin c3f723e7f6394297c095a9d9696f1bceec4a2e85b5be2159f7a21d257eb6b480
burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin eab9c19ef27b245e5ef0216ab1080c9dd89c96013b7dc978bf610288d5e82b00
burn_with_from_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.bin 1ed5c299f928529081dc01b7a46db2b5e6728001767863495a7675d8db99a9e2
ccip_encoding_utils: ../../../contracts/solc/v0.8.24/ICCIPEncodingUtils/ICCIPEncodingUtils.abi ../../../contracts/solc/v0.8.24/ICCIPEncodingUtils/ICCIPEncodingUtils.bin 2e6fa009821d30a24efdc9f9d14b2269fb9a51cb7d536ea8b2d29d97dd8b591c
ccip_home: ../../../contracts/solc/v0.8.24/CCIPHome/CCIPHome.abi ../../../contracts/solc/v0.8.24/CCIPHome/CCIPHome.bin c570b86f8ae7697d3478e70625e06f0f682e75c1f0b7538f4b6f581b0d294b2b
Expand All @@ -14,7 +14,7 @@ ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/Ether
evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin b0d77babbe635cd6ba04c2af049badc9e9d28a4b6ed6bb75f830ad902a618beb
evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin 5c02c2b167946b3467636ff2bb58594cb4652fc63d8bdfee2488ed562e2a3e50
fee_quoter: ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.abi ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.bin 503823a939ff99fe3bdaaef7a89cd4bbe475e260d3921335dbf9c80d4f584b76
lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin 1067f557abeb5570f1da7f050ea982ffad0f35dc064e668a8a0e6af128df490c
lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin 04b40584830294fb603cc2a250af7d831d05a04650a8c2fc9e3af5a78c471be6
lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin e632b08be0fbd1d013e8b3a9d75293d0d532b83071c531ff2be1deec1fa48ec1
maybe_revert_message_receiver: ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin d73956c26232ebcc4a5444429fa99cbefed960e323be9b5a24925885c2e477d5
message_hasher: ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.abi ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.bin 0a2661da24147160383ad61d56a258515d1cc07f5e0f471ec5cbb4bccaf82389
Expand All @@ -36,6 +36,6 @@ rmn_remote: ../../../contracts/solc/v0.8.24/RMNRemote/RMNRemote.abi ../../../con
router: ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin 2e4f0a7826c8abb49d882bb49fc5ff20a186dbd3137624b9097ffed903ae4888
self_funded_ping_pong: ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.abi ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.bin 8ea5d75dbc3f8afd90d22c4a665a94e02892259cd16520c1c6b4cf0dc80c9148
token_admin_registry: ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin 942be7d1681ac102e0615bee13f76838ebb0b261697cf1270d2bf82c12e57aeb
token_pool: ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin da86a1407f31134e7246bde63c80ce8c78ce7d7b44e267f3c1f6030441ff4252
usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin b688126b13353f7aab7481f3f6b8f79cd2cace96be71eace70237d402823493a
token_pool: ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin 793d65f336929becdcf8bc3f2208a5b6de93774215fe2e863bef64df419cfdb0
usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin a9fef4db2c901302c0293b139eb77017b18da8543b7623e17f2932efbb8e3011
weth9: ../../../contracts/solc/v0.8.24/WETH9/WETH9.abi ../../../contracts/solc/v0.8.24/WETH9/WETH9.bin 2970d79a0ca6dd6279cde130de45e56c8790ed695eae477fb5ba4c1bb75b720d
7 changes: 6 additions & 1 deletion integration-tests/ccip-tests/contracts/contract_models.go
Original file line number Diff line number Diff line change
Expand Up @@ -504,8 +504,13 @@ func (w TokenPoolWrapper) ApplyChainUpdates(opts *bind.TransactOpts, update []to
}

func (w TokenPoolWrapper) SetChainRateLimiterConfig(opts *bind.TransactOpts, selector uint64, out token_pool.RateLimiterConfig, in token_pool.RateLimiterConfig) (*types.Transaction, error) {

if w.Latest != nil && w.Latest.PoolInterface != nil {
return w.Latest.PoolInterface.SetChainRateLimiterConfig(opts, selector, out, in)
selectors := []uint64{selector}
out := []token_pool.RateLimiterConfig{out}
in := []token_pool.RateLimiterConfig{in}

return w.Latest.PoolInterface.SetChainRateLimiterConfigs(opts, selectors, out, in)
}
if w.V1_4_0 != nil && w.V1_4_0.PoolInterface != nil {
return w.V1_4_0.PoolInterface.SetChainRateLimiterConfig(opts, selector,
Expand Down

0 comments on commit 478f0e5

Please sign in to comment.