Skip to content

Commit

Permalink
Changes from review
Browse files Browse the repository at this point in the history
  • Loading branch information
justinkaseman committed Apr 12, 2024
1 parent c9de21c commit 488a841
Show file tree
Hide file tree
Showing 12 changed files with 217 additions and 200 deletions.
102 changes: 52 additions & 50 deletions contracts/gas-snapshots/ccip.gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -97,69 +97,71 @@ CommitStore_verify:testPausedReverts() (gas: 18438)
CommitStore_verify:testTooManyLeavesReverts() (gas: 36830)
DefensiveExampleTest:testHappyPathSuccess() (gas: 207184)
DefensiveExampleTest:testRecovery() (gas: 431320)
E2E:testE2E_3MessagesSuccess_gas() (gas: 991841)
EVM2EVMOffRamp__releaseOrMintTokens:test_RateLimitErrors_Reverts() (gas: 625164)
EVM2EVMOffRamp__releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 143685)
EVM2EVMOffRamp__releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAContract_Reverts() (gas: 27261)
EVM2EVMOffRamp__releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 31714)
EVM2EVMOffRamp__releaseOrMintTokens:test_fuzz__releaseOrMintTokens_AnyRevertIsCaught_Success(uint256) (runs: 256, μ: 23177, ~: 23903)
EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 157516)
EVM2EVMOffRamp__report:testReportSuccess() (gas: 127460)
E2E:testE2E_3MessagesSuccess_gas() (gas: 991819)
EVM2EVMOffRamp__releaseOrMintTokens:test_RateLimitErrors_Reverts() (gas: 625054)
EVM2EVMOffRamp__releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 143663)
EVM2EVMOffRamp__releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAContract_Reverts() (gas: 27239)
EVM2EVMOffRamp__releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 31692)
EVM2EVMOffRamp__releaseOrMintTokens:test_fuzz__releaseOrMintTokens_AnyRevertIsCaught_Success(uint256) (runs: 256, μ: 23127, ~: 23881)
EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 157494)
EVM2EVMOffRamp__report:testReportSuccess() (gas: 127438)
EVM2EVMOffRamp__trialExecute:testRateLimitErrorSuccess() (gas: 195843)
EVM2EVMOffRamp__trialExecute:testTokenHandlingErrorIsCaughtSuccess() (gas: 204499)
EVM2EVMOffRamp__trialExecute:test_trialExecuteSuccess() (gas: 259973)
EVM2EVMOffRamp__updateRateLimitTokens:testNonOwnerReverts() (gas: 12160)
EVM2EVMOffRamp__updateRateLimitTokens:test_updateRateLimitTokensSuccess() (gas: 156261)
EVM2EVMOffRamp_ccipReceive:testReverts() (gas: 17043)
EVM2EVMOffRamp_constructor:testCommitStoreAlreadyInUseReverts() (gas: 158125)
EVM2EVMOffRamp_constructor:testConstructorSuccess() (gas: 5178349)
EVM2EVMOffRamp_constructor:testConstructorSuccess() (gas: 5189210)
EVM2EVMOffRamp_constructor:testZeroOnRampAddressReverts() (gas: 148872)
EVM2EVMOffRamp_execute:testAlreadyExecutedReverts() (gas: 137483)
EVM2EVMOffRamp_execute:testEmptyReportReverts() (gas: 19038)
EVM2EVMOffRamp_execute:testInvalidMessageIdReverts() (gas: 34134)
EVM2EVMOffRamp_execute:testInvalidSourceChainReverts() (gas: 49417)
EVM2EVMOffRamp_execute:testInvalidSourcePoolAddressSuccess() (gas: 409903)
EVM2EVMOffRamp_execute:testManualExecutionNotYetEnabledReverts() (gas: 44164)
EVM2EVMOffRamp_execute:testMessageTooLargeReverts() (gas: 150204)
EVM2EVMOffRamp_execute:testPausedReverts() (gas: 99235)
EVM2EVMOffRamp_execute:testReceiverErrorSuccess() (gas: 164545)
EVM2EVMOffRamp_execute:testRootNotCommittedReverts() (gas: 39062)
EVM2EVMOffRamp_execute:testRouterYULCallReverts() (gas: 413890)
EVM2EVMOffRamp_execute:testSingleMessageNoTokensSuccess() (gas: 174116)
EVM2EVMOffRamp_execute:testSingleMessageToNonCCIPReceiverSuccess() (gas: 246354)
EVM2EVMOffRamp_execute:testSingleMessagesNoTokensSuccess_gas() (gas: 114745)
EVM2EVMOffRamp_execute:testSkippedIncorrectNonceStillExecutesSuccess() (gas: 354522)
EVM2EVMOffRamp_execute:testSkippedIncorrectNonceSuccess() (gas: 51950)
EVM2EVMOffRamp_execute:testStrictUntouchedToSuccessSuccess() (gas: 131724)
EVM2EVMOffRamp_execute:testTokenDataMismatchReverts() (gas: 49773)
EVM2EVMOffRamp_execute:testTwoMessagesWithTokensAndGESuccess() (gas: 480492)
EVM2EVMOffRamp_execute:testTwoMessagesWithTokensSuccess_gas() (gas: 419323)
EVM2EVMOffRamp_execute:testUnexpectedTokenDataReverts() (gas: 33092)
EVM2EVMOffRamp_execute:testUnhealthyReverts() (gas: 468475)
EVM2EVMOffRamp_execute:testUnsupportedNumberOfTokensReverts() (gas: 61498)
EVM2EVMOffRamp_execute:testAlreadyExecutedReverts() (gas: 137439)
EVM2EVMOffRamp_execute:testEmptyReportReverts() (gas: 19016)
EVM2EVMOffRamp_execute:testInvalidMessageIdReverts() (gas: 34112)
EVM2EVMOffRamp_execute:testInvalidSourceChainReverts() (gas: 49373)
EVM2EVMOffRamp_execute:testInvalidSourcePoolAddressSuccess() (gas: 409837)
EVM2EVMOffRamp_execute:testManualExecutionNotYetEnabledReverts() (gas: 44142)
EVM2EVMOffRamp_execute:testMessageTooLargeReverts() (gas: 150160)
EVM2EVMOffRamp_execute:testPausedReverts() (gas: 99213)
EVM2EVMOffRamp_execute:testReceiverErrorSuccess() (gas: 164501)
EVM2EVMOffRamp_execute:testRootNotCommittedReverts() (gas: 39040)
EVM2EVMOffRamp_execute:testRouterYULCallReverts() (gas: 413846)
EVM2EVMOffRamp_execute:testSingleMessageNoTokensSuccess() (gas: 174050)
EVM2EVMOffRamp_execute:testSingleMessageToNonCCIPReceiverSuccess() (gas: 246310)
EVM2EVMOffRamp_execute:testSingleMessagesNoTokensSuccess_gas() (gas: 114723)
EVM2EVMOffRamp_execute:testSkippedIncorrectNonceStillExecutesSuccess() (gas: 354478)
EVM2EVMOffRamp_execute:testSkippedIncorrectNonceSuccess() (gas: 51906)
EVM2EVMOffRamp_execute:testStrictUntouchedToSuccessSuccess() (gas: 131680)
EVM2EVMOffRamp_execute:testTokenDataMismatchReverts() (gas: 49751)
EVM2EVMOffRamp_execute:testTwoMessagesWithTokensAndGESuccess() (gas: 480448)
EVM2EVMOffRamp_execute:testTwoMessagesWithTokensSuccess_gas() (gas: 419301)
EVM2EVMOffRamp_execute:testUnexpectedTokenDataReverts() (gas: 33070)
EVM2EVMOffRamp_execute:testUnhealthyReverts() (gas: 468431)
EVM2EVMOffRamp_execute:testUnsupportedNumberOfTokensReverts() (gas: 61454)
EVM2EVMOffRamp_executeSingleMessage:testMessageSenderReverts() (gas: 20583)
EVM2EVMOffRamp_executeSingleMessage:testNonContractSuccess() (gas: 20121)
EVM2EVMOffRamp_executeSingleMessage:testNonContractWithTokensSuccess() (gas: 227589)
EVM2EVMOffRamp_executeSingleMessage:testTokenHandlingErrorReverts() (gas: 180163)
EVM2EVMOffRamp_executeSingleMessage:testZeroGasDONExecutionReverts() (gas: 48637)
EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48110)
EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 262006)
EVM2EVMOffRamp_execute_upgrade:testV2NonceNewSenderStartsAtZeroSuccess() (gas: 233029)
EVM2EVMOffRamp_execute_upgrade:testV2NonceStartsAtV1NonceSuccess() (gas: 281429)
EVM2EVMOffRamp_execute_upgrade:testV2OffRampNonceSkipsIfMsgInFlightSuccess() (gas: 262582)
EVM2EVMOffRamp_execute_upgrade:testV2SenderNoncesReadsPreviousRampSuccess() (gas: 229263)
EVM2EVMOffRamp_execute_upgrade:testV2Success() (gas: 131524)
EVM2EVMOffRamp_getExecutionState:testFillExecutionStateSuccess() (gas: 3343429)
EVM2EVMOffRamp_getExecutionState:test_GetExecutionStateSuccess() (gas: 82666)
EVM2EVMOffRamp_manuallyExecute:testLowGasLimitManualExecSuccess() (gas: 497153)
EVM2EVMOffRamp_manuallyExecute:testManualExecFailedTxReverts() (gas: 188051)
EVM2EVMOffRamp_manuallyExecute:testManualExecForkedChainReverts() (gas: 25984)
EVM2EVMOffRamp_manuallyExecute:testManualExecGasLimitMismatchReverts() (gas: 43480)
EVM2EVMOffRamp_manuallyExecute:testManualExecInvalidGasLimitReverts() (gas: 26003)
EVM2EVMOffRamp_manuallyExecute:testManualExecSuccess() (gas: 189749)
EVM2EVMOffRamp_manuallyExecute:testManualExecWithGasOverrideSuccess() (gas: 190420)
EVM2EVMOffRamp_manuallyExecute:testReentrancyManualExecuteFails() (gas: 2042576)
EVM2EVMOffRamp_metadataHash:testMetadataHashSuccess() (gas: 8960)
EVM2EVMOffRamp_setDynamicConfig:testNonOwnerReverts() (gas: 40310)
EVM2EVMOffRamp_setDynamicConfig:testRouterZeroAddressReverts() (gas: 38520)
EVM2EVMOffRamp_execute_upgrade:testV2NonceNewSenderStartsAtZeroSuccess() (gas: 232963)
EVM2EVMOffRamp_execute_upgrade:testV2NonceStartsAtV1NonceSuccess() (gas: 281319)
EVM2EVMOffRamp_execute_upgrade:testV2OffRampNonceSkipsIfMsgInFlightSuccess() (gas: 262450)
EVM2EVMOffRamp_execute_upgrade:testV2SenderNoncesReadsPreviousRampSuccess() (gas: 229131)
EVM2EVMOffRamp_execute_upgrade:testV2Success() (gas: 131502)
EVM2EVMOffRamp_getExecutionState:testFillExecutionStateSuccess() (gas: 3360325)
EVM2EVMOffRamp_getExecutionState:test_GetExecutionStateSuccess() (gas: 82776)
EVM2EVMOffRamp_manuallyExecute:testLowGasLimitManualExecSuccess() (gas: 497174)
EVM2EVMOffRamp_manuallyExecute:testManualExecFailedTxReverts() (gas: 188072)
EVM2EVMOffRamp_manuallyExecute:testManualExecForkedChainReverts() (gas: 26049)
EVM2EVMOffRamp_manuallyExecute:testManualExecGasLimitMismatchReverts() (gas: 43675)
EVM2EVMOffRamp_manuallyExecute:testManualExecInvalidGasLimitReverts() (gas: 26068)
EVM2EVMOffRamp_manuallyExecute:testManualExecSuccess() (gas: 189770)
EVM2EVMOffRamp_manuallyExecute:testManualExecWithGasOverrideSuccess() (gas: 190441)
EVM2EVMOffRamp_manuallyExecute:testReentrancyManualExecuteFails() (gas: 2042684)
EVM2EVMOffRamp_metadataHash:testMetadataHashSuccess() (gas: 8938)
EVM2EVMOffRamp_setDynamicConfig:testNonOwnerReverts() (gas: 40332)
EVM2EVMOffRamp_setDynamicConfig:testRouterZeroAddressReverts() (gas: 38542)
EVM2EVMOffRamp_setDynamicConfig:testSetDynamicConfigSuccess() (gas: 144167)
EVM2EVMOnRamp_constructor:testConstructorSuccess() (gas: 5516252)
EVM2EVMOnRamp_forwardFromRouter:testCannotSendZeroTokensReverts() (gas: 31723)
Expand Down
18 changes: 18 additions & 0 deletions contracts/src/v0.8/ccip/AggregateRateLimiter.sol
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.19;

import {IPriceRegistry} from "./interfaces/IPriceRegistry.sol";

import {OwnerIsCreator} from "./../shared/access/OwnerIsCreator.sol";
import {Client} from "./libraries/Client.sol";
import {RateLimiter} from "./libraries/RateLimiter.sol";
import {USDPriceWith18Decimals} from "./libraries/USDPriceWith18Decimals.sol";

/// @notice The aggregate rate limiter is a wrapper of the token bucket rate limiter
/// which permits rate limiting based on the aggregate value of a group of
/// token transfers, using a price registry to convert to a numeraire asset (e.g. USD).
contract AggregateRateLimiter is OwnerIsCreator {
using RateLimiter for RateLimiter.TokenBucket;
using USDPriceWith18Decimals for uint224;

error PriceNotFoundForToken(address token);

event AdminSet(address newAdmin);

Expand All @@ -35,6 +42,17 @@ contract AggregateRateLimiter is OwnerIsCreator {
s_rateLimiter._consume(value, address(0));
}

function _getTokenValue(
Client.EVMTokenAmount memory tokenAmount,
IPriceRegistry priceRegistry
) internal view returns (uint256) {
// not fetching validated price, as price staleness is not important for value-based rate limiting
// we only need to verify the price is not 0
uint224 pricePerToken = priceRegistry.getTokenPrice(tokenAmount.token).value;
if (pricePerToken == 0) revert PriceNotFoundForToken(tokenAmount.token);
return pricePerToken._calcUSDValueFromTokenAmount(tokenAmount.amount);
}

/// @notice Gets the token bucket with its values for the block it was requested at.
/// @return The token bucket.
function currentRateLimiterState() external view returns (RateLimiter.TokenBucket memory) {
Expand Down
47 changes: 14 additions & 33 deletions contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,14 @@ import {IRouter} from "../interfaces/IRouter.sol";
import {IPool} from "../interfaces/pools/IPool.sol";

import {CallWithExactGas} from "../../shared/call/CallWithExactGas.sol";
import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol";
import {AggregateRateLimiter} from "../AggregateRateLimiter.sol";
import {Client} from "../libraries/Client.sol";
import {Internal} from "../libraries/Internal.sol";
import {RateLimiter} from "../libraries/RateLimiter.sol";
import {USDPriceWith18Decimals} from "../libraries/USDPriceWith18Decimals.sol";
import {OCR2BaseNoChecks} from "../ocr/OCR2BaseNoChecks.sol";

import {ERC165Checker} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165Checker.sol";
import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol";

/// @notice EVM2EVMOffRamp enables OCR networks to execute multiple messages
/// in an OffRamp in a single transaction.
Expand All @@ -31,7 +30,6 @@ import {ERC165Checker} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts
contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersion, OCR2BaseNoChecks {
using ERC165Checker for address;
using EnumerableSet for EnumerableSet.AddressSet;
using USDPriceWith18Decimals for uint224;

error AlreadyAttempted(uint64 sequenceNumber);
error AlreadyExecuted(uint64 sequenceNumber);
Expand All @@ -55,7 +53,6 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio
error InvalidMessageId();
error InvalidAddress(bytes encodedAddress);
error InvalidNewState(uint64 sequenceNumber, Internal.MessageExecutionState newState);
error PriceNotFoundForToken(address token);

/// @dev Atlas depends on this event, if changing, please notify Atlas.
event ConfigSet(StaticConfig staticConfig, DynamicConfig dynamicConfig);
Expand Down Expand Up @@ -146,7 +143,10 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio

i_metadataHash = _metadataHash(Internal.EVM_2_EVM_MESSAGE_HASH);

_addRateLimitedTokens(rateLimitedTokens);
for (uint256 i = 0; i < rateLimitedTokens.length; ++i) {
bool success = s_rateLimitedTokens.add(rateLimitedTokens[i]);
if (success) emit TokenAggregateRateLimitAdded(rateLimitedTokens[i]);
}
}

// ================================================================
Expand Down Expand Up @@ -489,29 +489,21 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio

/// @notice Get all tokens which are included in Aggregate Rate Limiting.
/// @return rateLimitedTokens Array of Aggregate Rate Limited tokens.
function getAllRateLimitedTokens() external view returns (address[] memory) {
function getAllRateLimitTokens() external view returns (address[] memory) {
return s_rateLimitedTokens.values();
}

/// @notice Adds tokens from being used in Aggregate Rate Limiting.
/// @param adds A list of one or more tokens to be added.
function addRateLimitedTokens(address[] memory adds) external onlyOwner {
_addRateLimitedTokens(adds);
}

function _addRateLimitedTokens(address[] memory adds) internal {
/// @notice Adds or removes tokens from being used in Aggregate Rate Limiting.
/// @param adds - A list of one or more tokens to be added.
/// @param removes - A list of one or more tokens to be removed.
function updateRateLimitTokens(address[] memory removes, address[] memory adds) external onlyOwner {
for (uint256 i = 0; i < adds.length; ++i) {
s_rateLimitedTokens.add(adds[i]);
emit TokenAggregateRateLimitAdded(adds[i]);
bool success = s_rateLimitedTokens.add(adds[i]);
if (success) emit TokenAggregateRateLimitAdded(adds[i]);
}
}

/// @notice Removes tokens from being used in Aggregate Rate Limiting.
/// @param removes A list of one or more tokens to be removed.
function removeRateLimitedTokens(address[] memory removes) external onlyOwner {
for (uint256 i = 0; i < removes.length; ++i) {
s_rateLimitedTokens.remove(removes[i]);
emit TokenAggregateRateLimitRemoved(removes[i]);
bool success = s_rateLimitedTokens.remove(removes[i]);
if (success) emit TokenAggregateRateLimitRemoved(removes[i]);
}
}

Expand Down Expand Up @@ -591,17 +583,6 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio
return address(uint160(decodedAddress));
}

function _getTokenValue(
Client.EVMTokenAmount memory tokenAmount,
IPriceRegistry priceRegistry
) internal view returns (uint256) {
// not fetching validated price, as price staleness is not important for value-based rate limiting
// we only need to verify the price is not 0
uint224 pricePerToken = priceRegistry.getTokenPrice(tokenAmount.token).value;
if (pricePerToken == 0) revert PriceNotFoundForToken(tokenAmount.token);
return pricePerToken._calcUSDValueFromTokenAmount(tokenAmount.amount);
}

// ================================================================
// │ Access and ARM │
// ================================================================
Expand Down
12 changes: 0 additions & 12 deletions contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter,
error CannotSendZeroTokens();
error SourceTokenDataTooLarge(address token);
error InvalidChainSelector(uint64 chainSelector);
error PriceNotFoundForToken(address token);

event ConfigSet(StaticConfig staticConfig, DynamicConfig dynamicConfig);
event NopPaid(address indexed nop, uint256 amount);
Expand Down Expand Up @@ -459,17 +458,6 @@ contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter,
return ITokenAdminRegistry(s_dynamicConfig.tokenAdminRegistry).getAllConfiguredTokens();
}

function _getTokenValue(
Client.EVMTokenAmount memory tokenAmount,
IPriceRegistry priceRegistry
) internal view returns (uint256) {
// not fetching validated price, as price staleness is not important for value-based rate limiting
// we only need to verify the price is not 0
uint224 pricePerToken = priceRegistry.getTokenPrice(tokenAmount.token).value;
if (pricePerToken == 0) revert PriceNotFoundForToken(tokenAmount.token);
return pricePerToken._calcUSDValueFromTokenAmount(tokenAmount.amount);
}

// ================================================================
// │ Fees │
// ================================================================
Expand Down
Loading

0 comments on commit 488a841

Please sign in to comment.