Skip to content

Commit

Permalink
CCIP-4329 modify setChainRateLimiterConfig file for setting multiple …
Browse files Browse the repository at this point in the history
…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

---------

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 99b666f commit 62c2376
Show file tree
Hide file tree
Showing 13 changed files with 329 additions and 84 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
127 changes: 65 additions & 62 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: 279198)
LiquidityManager_rebalanceLiquidity:test_InsufficientLiquidityReverts() (gas: 206764)
LiquidityManager_rebalanceLiquidity:test_InvalidRemoteChainReverts() (gas: 192374)
LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess() (gas: 9141798)
LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess_AlreadyFinalized() (gas: 9306766)
LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_MultiStageFinalization() (gas: 9301906)
LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_NativeRewrap() (gas: 9231739)
LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess_AlreadyFinalized() (gas: 9435757)
LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_MultiStageFinalization() (gas: 9430897)
LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_NativeRewrap() (gas: 9360730)
LiquidityManager_rebalanceLiquidity:test_rebalanceLiquiditySuccess() (gas: 382928)
LiquidityManager_receive:test_receive_success() (gas: 21182)
LiquidityManager_removeLiquidity:test_InsufficientLiquidityReverts() (gas: 184959)
Expand All @@ -19,7 +19,7 @@ LiquidityManager_setFinanceRole:test_OnlyOwnerReverts() (gas: 10987)
LiquidityManager_setFinanceRole:test_setFinanceRoleSuccess() (gas: 21836)
LiquidityManager_setLocalLiquidityContainer:test_OnlyOwnerReverts() (gas: 11030)
LiquidityManager_setLocalLiquidityContainer:test_ReverstWhen_CalledWithTheZeroAddress() (gas: 10621)
LiquidityManager_setLocalLiquidityContainer:test_setLocalLiquidityContainerSuccess() (gas: 3847203)
LiquidityManager_setLocalLiquidityContainer:test_setLocalLiquidityContainerSuccess() (gas: 3976150)
LiquidityManager_setMinimumLiquidity:test_OnlyOwnerReverts() (gas: 10925)
LiquidityManager_setMinimumLiquidity:test_setMinimumLiquiditySuccess() (gas: 36389)
LiquidityManager_withdrawERC20:test_withdrawERC20Reverts() (gas: 180396)
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 @@ -52,6 +52,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 @@ -536,6 +537,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,13 +1,13 @@
GETH_VERSION: 1.14.11
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_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin c3f723e7f6394297c095a9d9696f1bceec4a2e85b5be2159f7a21d257eb6b480
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_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin eab9c19ef27b245e5ef0216ab1080c9dd89c96013b7dc978bf610288d5e82b00
ccip_encoding_utils: ../../../contracts/solc/v0.8.24/ICCIPEncodingUtils/ICCIPEncodingUtils.abi ../../../contracts/solc/v0.8.24/ICCIPEncodingUtils/ICCIPEncodingUtils.bin 9971fc93c34442a0989570d3dab90a125de31e6e60754ad972807ce6ad4dfba0
ccip_home: ../../../contracts/solc/v0.8.24/CCIPHome/CCIPHome.abi ../../../contracts/solc/v0.8.24/CCIPHome/CCIPHome.bin 02cb75b4274a5be7f4006cf2b72cc09e77eb6dba4c1a9c720af86668ff8ea1df
ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin b368699ae7dbee7c21d049a641642837f18ce2cc8d4ece69509f205de673108e
ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de
fee_quoter: ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.abi ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.bin aee49c9246d5903e68b175516b3cdfdec5df23e25d53d604cd382b6bc0bf34f7
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
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 ec2d3a92348d8e7b8f0d359b62a45157b9d2c750c01fbcf991826c4392f6e218
mock_usdc_token_messenger: ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.bin d976651d36b33ac2196b32b9d2f4fa6690c6a18d41b621365659fce1c1d1e737
Expand All @@ -26,7 +26,7 @@ rmn_proxy_contract: ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../
rmn_remote: ../../../contracts/solc/v0.8.24/RMNRemote/RMNRemote.abi ../../../contracts/solc/v0.8.24/RMNRemote/RMNRemote.bin 941118dfdc6bb042c339cfe8d8e0c7a0b486afb731a785d58a64994e7a13c459
router: ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin 2e4f0a7826c8abb49d882bb49fc5ff20a186dbd3137624b9097ffed903ae4888
token_admin_registry: ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin 397bc7be08c2848c0f4715f90b16206d6367f78ffb7cd48e2b1dfc0ccc5aea26
token_pool: ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin da86a1407f31134e7246bde63c80ce8c78ce7d7b44e267f3c1f6030441ff4252
token_pool: ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin 793d65f336929becdcf8bc3f2208a5b6de93774215fe2e863bef64df419cfdb0
usdc_reader_tester: ../../../contracts/solc/v0.8.24/USDCReaderTester/USDCReaderTester.abi ../../../contracts/solc/v0.8.24/USDCReaderTester/USDCReaderTester.bin 672a07c9218fd6ad7c04dde583088b0f5ffc8d55a46f4be1714008dd3409438b
usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin b688126b13353f7aab7481f3f6b8f79cd2cace96be71eace70237d402823493a
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 @@ -503,8 +503,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 62c2376

Please sign in to comment.