Skip to content

Commit

Permalink
Return gas on callWithExactGas (#265)
Browse files Browse the repository at this point in the history
  • Loading branch information
RensR authored Nov 7, 2023
1 parent 35feee9 commit 9627023
Show file tree
Hide file tree
Showing 17 changed files with 338 additions and 253 deletions.
82 changes: 39 additions & 43 deletions contracts/gas-snapshots/ccip.gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,6 @@ BurnWithFromMintTokenPool_lockOrBurn:testPermissionsErrorReverts() (gas: 12761)
BurnWithFromMintTokenPool_lockOrBurn:testPoolBurnRevertNotHealthyReverts() (gas: 54151)
BurnWithFromMintTokenPool_lockOrBurn:testPoolBurnSuccess() (gas: 201193)
CCIPClientExample_sanity:testExamples() (gas: 2218000)
CallWithExactGas_callWithExactGas:test_CallWithExactGasSuccess() (gas: 22403)
CallWithExactGas_callWithExactGas:test_NoContractReverts() (gas: 10465)
CallWithExactGas_callWithExactGas:test_NoGasForCallExactCheckReverts() (gas: 14036)
CallWithExactGas_callWithExactGas:test_NotEnoughGasForCallReverts() (gas: 15120)
CommitStore_constructor:testConstructorSuccess() (gas: 3344466)
CommitStore_isUnpausedAndARMHealthy:testARMSuccess() (gas: 71321)
CommitStore_report:testInvalidIntervalMinLargerThanMaxReverts() (gas: 26324)
Expand Down Expand Up @@ -99,15 +95,15 @@ CommitStore_verify:testPausedReverts() (gas: 18438)
CommitStore_verify:testTooManyLeavesReverts() (gas: 36830)
DefensiveExampleTest:testHappyPathSuccess() (gas: 174862)
DefensiveExampleTest:testRecovery() (gas: 399786)
E2E:testE2E_3MessagesSuccess_gas() (gas: 887468)
EVM2EVMOffRamp__releaseOrMintTokens:testRateLimitErrorsReverts() (gas: 443866)
EVM2EVMOffRamp__releaseOrMintTokens:testTokenHandlingErrorReverts() (gas: 103420)
E2E:testE2E_3MessagesSuccess_gas() (gas: 887723)
EVM2EVMOffRamp__releaseOrMintTokens:testRateLimitErrorsReverts() (gas: 443946)
EVM2EVMOffRamp__releaseOrMintTokens:testTokenHandlingErrorReverts() (gas: 103436)
EVM2EVMOffRamp__releaseOrMintTokens:testUnsupportedTokenReverts() (gas: 18202)
EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokensSuccess() (gas: 140615)
EVM2EVMOffRamp__report:testReportSuccess() (gas: 127168)
EVM2EVMOffRamp__trialExecute:testRateLimitErrorSuccess() (gas: 174918)
EVM2EVMOffRamp__trialExecute:testTokenHandlingErrorIsCaughtSuccess() (gas: 183240)
EVM2EVMOffRamp__trialExecute:test_trialExecuteSuccess() (gas: 236708)
EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokensSuccess() (gas: 140631)
EVM2EVMOffRamp__report:testReportSuccess() (gas: 127236)
EVM2EVMOffRamp__trialExecute:testRateLimitErrorSuccess() (gas: 174934)
EVM2EVMOffRamp__trialExecute:testTokenHandlingErrorIsCaughtSuccess() (gas: 183256)
EVM2EVMOffRamp__trialExecute:test_trialExecuteSuccess() (gas: 236792)
EVM2EVMOffRamp_applyPoolUpdates:testApplyPoolUpdatesSuccess() (gas: 2435136)
EVM2EVMOffRamp_applyPoolUpdates:testInvalidTokenPoolConfigReverts() (gas: 17445)
EVM2EVMOffRamp_applyPoolUpdates:testOnlyCallableByOwnerReverts() (gas: 16012)
Expand All @@ -116,56 +112,56 @@ EVM2EVMOffRamp_applyPoolUpdates:testPoolDoesNotExistReverts() (gas: 2399537)
EVM2EVMOffRamp_applyPoolUpdates:testTokenPoolMismatchReverts() (gas: 4928727)
EVM2EVMOffRamp_ccipReceive:testReverts() (gas: 17072)
EVM2EVMOffRamp_constructor:testCommitStoreAlreadyInUseReverts() (gas: 168848)
EVM2EVMOffRamp_constructor:testConstructorSuccess() (gas: 5728147)
EVM2EVMOffRamp_constructor:testConstructorSuccess() (gas: 5730956)
EVM2EVMOffRamp_constructor:testTokenConfigMismatchReverts() (gas: 145215)
EVM2EVMOffRamp_constructor:testZeroOnRampAddressReverts() (gas: 2538111)
EVM2EVMOffRamp_execute:testAlreadyExecutedReverts() (gas: 137220)
EVM2EVMOffRamp_execute:testAlreadyExecutedReverts() (gas: 137288)
EVM2EVMOffRamp_execute:testEmptyReportReverts() (gas: 19016)
EVM2EVMOffRamp_execute:testInvalidMessageIdReverts() (gas: 34063)
EVM2EVMOffRamp_execute:testInvalidSourceChainReverts() (gas: 49347)
EVM2EVMOffRamp_execute:testManualExecutionNotYetEnabledReverts() (gas: 44104)
EVM2EVMOffRamp_execute:testMessageTooLargeReverts() (gas: 150111)
EVM2EVMOffRamp_execute:testPausedReverts() (gas: 74942)
EVM2EVMOffRamp_execute:testReceiverErrorSuccess() (gas: 163586)
EVM2EVMOffRamp_execute:testReceiverErrorSuccess() (gas: 163658)
EVM2EVMOffRamp_execute:testRootNotCommittedReverts() (gas: 38980)
EVM2EVMOffRamp_execute:testRouterYULCallReverts() (gas: 413655)
EVM2EVMOffRamp_execute:testSingleMessageNoTokensSuccess() (gas: 173329)
EVM2EVMOffRamp_execute:testRouterYULCallReverts() (gas: 413652)
EVM2EVMOffRamp_execute:testSingleMessageNoTokensSuccess() (gas: 173465)
EVM2EVMOffRamp_execute:testSingleMessageToNonCCIPReceiverSuccess() (gas: 246243)
EVM2EVMOffRamp_execute:testSingleMessagesNoTokensSuccess_gas() (gas: 114564)
EVM2EVMOffRamp_execute:testSkippedIncorrectNonceStillExecutesSuccess() (gas: 323987)
EVM2EVMOffRamp_execute:testSingleMessagesNoTokensSuccess_gas() (gas: 114632)
EVM2EVMOffRamp_execute:testSkippedIncorrectNonceStillExecutesSuccess() (gas: 324071)
EVM2EVMOffRamp_execute:testSkippedIncorrectNonceSuccess() (gas: 51868)
EVM2EVMOffRamp_execute:testStrictUntouchedToSuccessSuccess() (gas: 130786)
EVM2EVMOffRamp_execute:testStrictUntouchedToSuccessSuccess() (gas: 130854)
EVM2EVMOffRamp_execute:testTokenDataMismatchReverts() (gas: 49702)
EVM2EVMOffRamp_execute:testTwoMessagesWithTokensAndGESuccess() (gas: 443148)
EVM2EVMOffRamp_execute:testTwoMessagesWithTokensSuccess_gas() (gas: 402322)
EVM2EVMOffRamp_execute:testTwoMessagesWithTokensAndGESuccess() (gas: 443316)
EVM2EVMOffRamp_execute:testTwoMessagesWithTokensSuccess_gas() (gas: 402490)
EVM2EVMOffRamp_execute:testUnexpectedTokenDataReverts() (gas: 33032)
EVM2EVMOffRamp_execute:testUnhealthyReverts() (gas: 419749)
EVM2EVMOffRamp_execute:testUnhealthyReverts() (gas: 419917)
EVM2EVMOffRamp_execute:testUnsupportedNumberOfTokensReverts() (gas: 61416)
EVM2EVMOffRamp_execute:testUnsupportedTokenReverts() (gas: 130374)
EVM2EVMOffRamp_executeSingleMessage:testMessageSenderReverts() (gas: 20545)
EVM2EVMOffRamp_executeSingleMessage:testNoTokensSuccess() (gas: 47965)
EVM2EVMOffRamp_executeSingleMessage:testNoTokensSuccess() (gas: 48033)
EVM2EVMOffRamp_executeSingleMessage:testNonContractSuccess() (gas: 20105)
EVM2EVMOffRamp_executeSingleMessage:testNonContractWithTokensSuccess() (gas: 205101)
EVM2EVMOffRamp_executeSingleMessage:testTokenHandlingErrorReverts() (gas: 140016)
EVM2EVMOffRamp_executeSingleMessage:testTokensSuccess() (gas: 233993)
EVM2EVMOffRamp_executeSingleMessage:testZeroGasDONExecutionReverts() (gas: 48513)
EVM2EVMOffRamp_execute_upgrade:testV2NonceNewSenderStartsAtZeroSuccess() (gas: 231891)
EVM2EVMOffRamp_execute_upgrade:testV2NonceStartsAtV1NonceSuccess() (gas: 279708)
EVM2EVMOffRamp_execute_upgrade:testV2OffRampNonceSkipsIfMsgInFlightSuccess() (gas: 260943)
EVM2EVMOffRamp_execute_upgrade:testV2SenderNoncesReadsPreviousRampSuccess() (gas: 224998)
EVM2EVMOffRamp_execute_upgrade:testV2Success() (gas: 131301)
EVM2EVMOffRamp_executeSingleMessage:testNonContractWithTokensSuccess() (gas: 205117)
EVM2EVMOffRamp_executeSingleMessage:testTokenHandlingErrorReverts() (gas: 140032)
EVM2EVMOffRamp_executeSingleMessage:testTokensSuccess() (gas: 234077)
EVM2EVMOffRamp_executeSingleMessage:testZeroGasDONExecutionReverts() (gas: 48581)
EVM2EVMOffRamp_execute_upgrade:testV2NonceNewSenderStartsAtZeroSuccess() (gas: 232027)
EVM2EVMOffRamp_execute_upgrade:testV2NonceStartsAtV1NonceSuccess() (gas: 279912)
EVM2EVMOffRamp_execute_upgrade:testV2OffRampNonceSkipsIfMsgInFlightSuccess() (gas: 261079)
EVM2EVMOffRamp_execute_upgrade:testV2SenderNoncesReadsPreviousRampSuccess() (gas: 225202)
EVM2EVMOffRamp_execute_upgrade:testV2Success() (gas: 131369)
EVM2EVMOffRamp_getDestinationToken:testGetDestinationTokenSuccess() (gas: 32786)
EVM2EVMOffRamp_getDestinationToken:testUnsupportedTokenReverts() (gas: 13763)
EVM2EVMOffRamp_getDestinationTokens:testGetDestinationTokensSuccess() (gas: 26091)
EVM2EVMOffRamp_getExecutionState:testFillExecutionStateSuccess() (gas: 3047481)
EVM2EVMOffRamp_getExecutionState:test_GetExecutionStateSuccess() (gas: 76354)
EVM2EVMOffRamp_manuallyExecute:testLowGasLimitManualExecSuccess() (gas: 496743)
EVM2EVMOffRamp_manuallyExecute:testLowGasLimitManualExecSuccess() (gas: 496879)
EVM2EVMOffRamp_manuallyExecute:testManualExecForkedChainReverts() (gas: 25977)
EVM2EVMOffRamp_manuallyExecute:testManualExecGasLimitMismatchReverts() (gas: 43615)
EVM2EVMOffRamp_manuallyExecute:testManualExecInvalidGasLimitReverts() (gas: 26018)
EVM2EVMOffRamp_manuallyExecute:testManualExecSuccess() (gas: 189423)
EVM2EVMOffRamp_manuallyExecute:testManualExecWithGasOverrideSuccess() (gas: 190050)
EVM2EVMOffRamp_manuallyExecute:testReentrancyManualExecuteFAILS() (gas: 1856134)
EVM2EVMOffRamp_manuallyExecute:testManualExecSuccess() (gas: 189562)
EVM2EVMOffRamp_manuallyExecute:testManualExecWithGasOverrideSuccess() (gas: 190189)
EVM2EVMOffRamp_manuallyExecute:testReentrancyManualExecuteFAILS() (gas: 1856211)
EVM2EVMOffRamp_metadataHash:testMetadataHashSuccess() (gas: 6086)
EVM2EVMOffRamp_setDynamicConfig:testNonOwnerReverts() (gas: 44539)
EVM2EVMOffRamp_setDynamicConfig:testRouterZeroAddressReverts() (gas: 38587)
Expand Down Expand Up @@ -346,7 +342,7 @@ RateLimiter_currentTokenBucketState:testCurrentTokenBucketStateSuccess() (gas: 3
RateLimiter_currentTokenBucketState:testRefillSuccess() (gas: 41673)
RateLimiter_setTokenBucketConfig:testSetRateLimiterConfigSuccess() (gas: 35459)
Router_applyRampUpdates:testOffRampMismatchReverts() (gas: 89355)
Router_applyRampUpdates:testOffRampUpdatesWithRouting() (gas: 8494015)
Router_applyRampUpdates:testOffRampUpdatesWithRouting() (gas: 8510939)
Router_applyRampUpdates:testOnRampDisable() (gas: 52544)
Router_applyRampUpdates:testOnlyOwnerReverts() (gas: 12305)
Router_ccipSend:testCCIPSendLinkFeeNoTokenSuccess_gas() (gas: 110664)
Expand Down Expand Up @@ -374,11 +370,11 @@ Router_recoverTokens:testRecoverTokensNoFundsReverts() (gas: 17770)
Router_recoverTokens:testRecoverTokensNonOwnerReverts() (gas: 15354)
Router_recoverTokens:testRecoverTokensSuccess() (gas: 48644)
Router_recoverTokens:testRecoverTokensValueReceiverReverts() (gas: 444763)
Router_routeMessage:testAutoExecSuccess() (gas: 39367)
Router_routeMessage:testExecutionEventSuccess() (gas: 210301)
Router_routeMessage:testManualExecSuccess() (gas: 31419)
Router_routeMessage:testOnlyOffRampReverts() (gas: 27315)
Router_routeMessage:testWhenNotHealthyReverts() (gas: 43002)
Router_routeMessage:testAutoExecSuccess() (gas: 39512)
Router_routeMessage:testExecutionEventSuccess() (gas: 210701)
Router_routeMessage:testManualExecSuccess() (gas: 31555)
Router_routeMessage:testOnlyOffRampReverts() (gas: 27340)
Router_routeMessage:testWhenNotHealthyReverts() (gas: 43027)
Router_setWrappedNative:testOnlyOwnerReverts() (gas: 10978)
SelfFundedPingPong_ccipReceive:test_FundingIfNotANopReverts() (gas: 53509)
SelfFundedPingPong_ccipReceive:test_FundingSuccess() (gas: 403626)
Expand Down
4 changes: 4 additions & 0 deletions contracts/gas-snapshots/shared.gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ BurnMintERC677_mint:testSenderNotMinterReverts() (gas: 11195)
BurnMintERC677_supportsInterface:testConstructorSuccess() (gas: 8685)
BurnMintERC677_transfer:testInvalidAddressReverts() (gas: 10639)
BurnMintERC677_transfer:testTransferSuccess() (gas: 39462)
CallWithExactGas__callWithExactGasSafeReturnData:test_CallWithExactGasSafeReturnDataExactGas() (gas: 18955)
CallWithExactGas__callWithExactGasSafeReturnData:test_NoContractReverts() (gas: 12313)
CallWithExactGas__callWithExactGasSafeReturnData:test_NoGasForCallExactCheckReverts() (gas: 13177)
CallWithExactGas__callWithExactGasSafeReturnData:test_NotEnoughGasForCallReverts() (gas: 13608)
EnumerableMapAddresses_at:testAtSuccess() (gas: 98813)
EnumerableMapAddresses_contains:testContainsSuccess() (gas: 97480)
EnumerableMapAddresses_get:testGetSuccess() (gas: 98781)
Expand Down
14 changes: 7 additions & 7 deletions contracts/src/v0.8/ccip/Router.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import {IAny2EVMMessageReceiver} from "./interfaces/IAny2EVMMessageReceiver.sol"

import {Client} from "./libraries/Client.sol";
import {Internal} from "./libraries/Internal.sol";
import {CallWithExactGas} from "./libraries/CallWithExactGas.sol";
import {OwnerIsCreator} from "./../shared/access/OwnerIsCreator.sol";
import {CallWithExactGas} from "../shared/call/CallWithExactGas.sol";
import {OwnerIsCreator} from "../shared/access/OwnerIsCreator.sol";

import {EnumerableSet} from "../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/structs/EnumerableSet.sol";
import {SafeERC20} from "../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol";
Expand Down Expand Up @@ -156,24 +156,24 @@ contract Router is IRouter, IRouterClient, ITypeAndVersion, OwnerIsCreator {
uint16 gasForCallExactCheck,
uint256 gasLimit,
address receiver
) external override whenHealthy returns (bool success, bytes memory retData) {
) external override whenHealthy returns (bool success, bytes memory retData, uint256 gasUsed) {
// We only permit offRamps to call this function.
if (!isOffRamp(message.sourceChainSelector, msg.sender)) revert OnlyOffRamp();

// We encode here instead of the offRamps to constrain specifically what functions
// can be called from the router.
bytes memory data = abi.encodeWithSelector(IAny2EVMMessageReceiver.ccipReceive.selector, message);

(success, retData) = CallWithExactGas._callWithExactGas(
(success, retData, gasUsed) = CallWithExactGas._callWithExactGasSafeReturnData(
data,
receiver,
gasLimit,
Internal.MAX_RET_BYTES,
gasForCallExactCheck
gasForCallExactCheck,
Internal.MAX_RET_BYTES
);

emit MessageExecuted(message.messageId, message.sourceChainSelector, msg.sender, keccak256(data));
return (success, retData);
return (success, retData, gasUsed);
}

// @notice Merges a chain selector and offRamp address into a single uint256 by shifting the
Expand Down
3 changes: 2 additions & 1 deletion contracts/src/v0.8/ccip/interfaces/IRouter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ interface IRouter {
/// the contract is called. If not, only tokens are transferred.
/// @return success A boolean value indicating whether the ccip message was received without errors.
/// @return retBytes A bytes array containing return data form CCIP receiver.
/// @return gasUsed the gas used by the external customer call. Does not include any overhead.
function routeMessage(
Client.Any2EVMMessage calldata message,
uint16 gasForCallExactCheck,
uint256 gasLimit,
address receiver
) external returns (bool success, bytes memory retBytes);
) external returns (bool success, bytes memory retBytes, uint256 gasUsed);
}
10 changes: 5 additions & 5 deletions contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {IAny2EVMOffRamp} from "../interfaces/IAny2EVMOffRamp.sol";
import {Client} from "../libraries/Client.sol";
import {Internal} from "../libraries/Internal.sol";
import {RateLimiter} from "../libraries/RateLimiter.sol";
import {CallWithExactGas} from "../libraries/CallWithExactGas.sol";
import {CallWithExactGas} from "../../shared/call/CallWithExactGas.sol";
import {OCR2BaseNoChecks} from "../ocr/OCR2BaseNoChecks.sol";
import {AggregateRateLimiter} from "../AggregateRateLimiter.sol";
import {EnumerableMapAddresses} from "../../shared/enumerable/EnumerableMapAddresses.sol";
Expand Down Expand Up @@ -430,7 +430,7 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio
!message.receiver.isContract() || !message.receiver.supportsInterface(type(IAny2EVMMessageReceiver).interfaceId)
) return;

(bool success, bytes memory returnData) = IRouter(s_dynamicConfig.router).routeMessage(
(bool success, bytes memory returnData, ) = IRouter(s_dynamicConfig.router).routeMessage(
Internal._toAny2EVMMessage(message, destTokenAmounts),
Internal.GAS_FOR_CALL_EXACT_CHECK,
message.gasLimit,
Expand Down Expand Up @@ -602,7 +602,7 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio
// Call the pool with exact gas to increase resistance against malicious tokens or token pools.
// _callWithExactGas also protects against return data bombs by capping the return data size
// at MAX_RET_BYTES.
(bool success, bytes memory returnData) = CallWithExactGas._callWithExactGas(
(bool success, bytes memory returnData, ) = CallWithExactGas._callWithExactGasSafeReturnData(
abi.encodeWithSelector(
pool.releaseOrMint.selector,
originalSender,
Expand All @@ -613,8 +613,8 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio
),
address(pool),
s_dynamicConfig.maxPoolReleaseOrMintGas,
Internal.MAX_RET_BYTES,
Internal.GAS_FOR_CALL_EXACT_CHECK
Internal.GAS_FOR_CALL_EXACT_CHECK,
Internal.MAX_RET_BYTES
);

// wrap and rethrow the error so we can catch it lower in the stack
Expand Down
22 changes: 0 additions & 22 deletions contracts/src/v0.8/ccip/test/helpers/CallWithExactGasHelper.sol

This file was deleted.

Loading

0 comments on commit 9627023

Please sign in to comment.