Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

INTAUTO-306 Add ccip message assertions e2e tests #16107

Merged
merged 11 commits into from
Jan 31, 2025
5 changes: 5 additions & 0 deletions contracts/.changeset/smart-bats-repair.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@chainlink/contracts': patch
---

Update mayberevertmessagereceiver contract to emit message received event and allow token withdrawal
88 changes: 44 additions & 44 deletions contracts/gas-snapshots/ccip.gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ CCIPHome_setCandidate:test_setCandidate() (gas: 1365392)
CCIPHome_supportsInterface:test_supportsInterface() (gas: 9885)
DefensiveExampleTest:test_HappyPath() (gas: 200535)
DefensiveExampleTest:test_Recovery() (gas: 424996)
E2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1495937)
ERC165CheckerReverting_supportsInterfaceReverting:test__supportsInterfaceReverting() (gas: 10445)
E2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1514547)
ERC165CheckerReverting_supportsInterfaceReverting:test__supportsInterfaceReverting() (gas: 10517)
EtherSenderReceiverTest_ccipReceive:test_ccipReceive_fallbackToWethTransfer() (gas: 96964)
EtherSenderReceiverTest_ccipReceive:test_ccipReceive_happyPath() (gas: 49797)
EtherSenderReceiverTest_ccipReceive:test_ccipReceive_wrongToken() (gas: 17460)
Expand Down Expand Up @@ -203,11 +203,11 @@ NonceManager_applyPreviousRampsUpdates:test_MultipleRampsUpdates() (gas: 123617)
NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySet_overrideAllowed() (gas: 45935)
NonceManager_applyPreviousRampsUpdates:test_SingleRampUpdate() (gas: 66937)
NonceManager_applyPreviousRampsUpdates:test_ZeroInput() (gas: 12123)
NonceManager_getInboundNonce:test_getInboundNonce_NoPrevOffRampForChain() (gas: 179167)
NonceManager_getInboundNonce:test_getInboundNonce_Upgraded() (gas: 146356)
NonceManager_getInboundNonce:test_getInboundNonce_UpgradedNonceNewSenderStartsAtZero() (gas: 182637)
NonceManager_getInboundNonce:test_getInboundNonce_UpgradedNonceStartsAtV1Nonce() (gas: 245611)
NonceManager_getInboundNonce:test_getInboundNonce_UpgradedOffRampNonceSkipsIfMsgInFlight() (gas: 214256)
NonceManager_getInboundNonce:test_getInboundNonce_NoPrevOffRampForChain() (gas: 183777)
NonceManager_getInboundNonce:test_getInboundNonce_Upgraded() (gas: 150965)
NonceManager_getInboundNonce:test_getInboundNonce_UpgradedNonceNewSenderStartsAtZero() (gas: 187248)
NonceManager_getInboundNonce:test_getInboundNonce_UpgradedNonceStartsAtV1Nonce() (gas: 254856)
NonceManager_getInboundNonce:test_getInboundNonce_UpgradedOffRampNonceSkipsIfMsgInFlight() (gas: 218870)
NonceManager_getInboundNonce:test_getInboundNonce_UpgradedSenderNoncesReadsPreviousRamp() (gas: 60418)
NonceManager_getIncrementedOutboundNonce:test_getIncrementedOutboundNonce() (gas: 37974)
NonceManager_getIncrementedOutboundNonce:test_incrementInboundNonce() (gas: 38746)
Expand All @@ -225,12 +225,12 @@ OffRamp_applySourceChainConfigUpdates:test_ApplyZeroUpdates() (gas: 16671)
OffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChain() (gas: 180998)
OffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChainOnRamp() (gas: 168513)
OffRamp_applySourceChainConfigUpdates:test_allowNonOnRampUpdateAfterLaneIsUsed() (gas: 284861)
OffRamp_batchExecute:test_MultipleReportsDifferentChains() (gas: 326824)
OffRamp_batchExecute:test_MultipleReportsDifferentChainsSkipCursedChain() (gas: 171115)
OffRamp_batchExecute:test_MultipleReportsSameChain() (gas: 270123)
OffRamp_batchExecute:test_MultipleReportsSkipDuplicate() (gas: 162336)
OffRamp_batchExecute:test_SingleReport() (gas: 149878)
OffRamp_batchExecute:test_Unhealthy() (gas: 533860)
OffRamp_batchExecute:test_MultipleReportsDifferentChains() (gas: 340742)
OffRamp_batchExecute:test_MultipleReportsDifferentChainsSkipCursedChain() (gas: 175741)
OffRamp_batchExecute:test_MultipleReportsSameChain() (gas: 284041)
OffRamp_batchExecute:test_MultipleReportsSkipDuplicate() (gas: 166949)
OffRamp_batchExecute:test_SingleReport() (gas: 154488)
OffRamp_batchExecute:test_Unhealthy() (gas: 546735)
OffRamp_commit:test_OnlyGasPriceUpdates() (gas: 112995)
OffRamp_commit:test_OnlyTokenPriceUpdates() (gas: 112949)
OffRamp_commit:test_PriceSequenceNumberCleared() (gas: 355405)
Expand All @@ -240,52 +240,52 @@ OffRamp_commit:test_RootWithRMNDisabled() (gas: 153873)
OffRamp_commit:test_StaleReportWithRoot() (gas: 232057)
OffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot() (gas: 206722)
OffRamp_constructor:test_Constructor() (gas: 6340113)
OffRamp_execute:test_LargeBatch() (gas: 3383493)
OffRamp_execute:test_MultipleReports() (gas: 292253)
OffRamp_execute:test_MultipleReportsWithPartialValidationFailures() (gas: 365622)
OffRamp_execute:test_SingleReport() (gas: 169111)
OffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens() (gas: 51610)
OffRamp_execute:test_LargeBatch() (gas: 3537781)
OffRamp_execute:test_MultipleReports() (gas: 306193)
OffRamp_execute:test_MultipleReportsWithPartialValidationFailures() (gas: 370270)
OffRamp_execute:test_SingleReport() (gas: 173724)
OffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens() (gas: 55443)
OffRamp_executeSingleMessage:test_executeSingleMessage_NonContract() (gas: 20514)
OffRamp_executeSingleMessage:test_executeSingleMessage_NonContractWithTokens() (gas: 230418)
OffRamp_executeSingleMessage:test_executeSingleMessage_WithMessageInterceptor() (gas: 87465)
OffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens() (gas: 259935)
OffRamp_executeSingleReport:test_InvalidSourcePoolAddress() (gas: 455918)
OffRamp_executeSingleReport:test_ReceiverError() (gas: 181083)
OffRamp_executeSingleReport:test_SingleMessageNoTokens() (gas: 205792)
OffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain() (gas: 241879)
OffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered() (gas: 185785)
OffRamp_executeSingleMessage:test_executeSingleMessage_WithMessageInterceptor() (gas: 91298)
OffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens() (gas: 265210)
OffRamp_executeSingleReport:test_InvalidSourcePoolAddress() (gas: 462329)
OffRamp_executeSingleReport:test_ReceiverError() (gas: 181094)
OffRamp_executeSingleReport:test_SingleMessageNoTokens() (gas: 215033)
OffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain() (gas: 249545)
OffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered() (gas: 195030)
OffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver() (gas: 244181)
OffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 134917)
OffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 139526)
OffRamp_executeSingleReport:test_SkippedIncorrectNonce() (gas: 58558)
OffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes() (gas: 392884)
OffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE() (gas: 562962)
OffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 511342)
OffRamp_executeSingleReport:test_Unhealthy() (gas: 529483)
OffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain() (gas: 439833)
OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage() (gas: 158559)
OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered() (gas: 128943)
OffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes() (gas: 399284)
OffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE() (gas: 575811)
OffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 524188)
OffRamp_executeSingleReport:test_Unhealthy() (gas: 542355)
OffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain() (gas: 450383)
OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage() (gas: 163171)
OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered() (gas: 133556)
OffRamp_getExecutionState:test_FillExecutionState() (gas: 3955662)
OffRamp_getExecutionState:test_GetDifferentChainExecutionState() (gas: 121311)
OffRamp_getExecutionState:test_GetExecutionState() (gas: 90102)
OffRamp_manuallyExecute:test_manuallyExecute() (gas: 212915)
OffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched() (gas: 166028)
OffRamp_manuallyExecute:test_manuallyExecute() (gas: 212742)
OffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched() (gas: 166042)
OffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit() (gas: 479692)
OffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails() (gas: 2230185)
OffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride() (gas: 213465)
OffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride() (gas: 735042)
OffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages() (gas: 338095)
OffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride() (gas: 213292)
OffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride() (gas: 753781)
OffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages() (gas: 347264)
OffRamp_releaseOrMintSingleToken:test__releaseOrMintSingleToken() (gas: 94629)
OffRamp_releaseOrMintTokens:test_releaseOrMintTokens() (gas: 161157)
OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_WithGasOverride() (gas: 163023)
OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals() (gas: 174276)
OffRamp_setDynamicConfig:test_SetDynamicConfig() (gas: 25442)
OffRamp_setDynamicConfig:test_SetDynamicConfigWithInterceptor() (gas: 47493)
OffRamp_trialExecute:test_trialExecute() (gas: 263680)
OffRamp_trialExecute:test_trialExecute() (gas: 268955)
OffRamp_trialExecute:test_trialExecute_RateLimitError() (gas: 120710)
OffRamp_trialExecute:test_trialExecute_RevertsWhen_SenderIsGasEstimator_InsufficientGasForToCompleteTx() (gas: 67132)
OffRamp_trialExecute:test_trialExecute_SenderIsNotGasEstimator_CallWithExactGasReverts() (gas: 24573)
OffRamp_trialExecute:test_trialExecute_TokenHandlingErrorIsCaught() (gas: 131998)
OffRamp_trialExecute:test_trialExecute_TokenPoolIsNotAContract() (gas: 281305)
OffRamp_trialExecute:test_trialExecute_TokenPoolIsNotAContract() (gas: 286580)
OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy() (gas: 245211)
OnRampWithMessageTransformer_executeSingleMessage:test_forwardFromRouter() (gas: 122477)
OnRampWithMessageTransformer_setMessageTransformer:test_setMessageTransformer() (gas: 701204)
Expand Down Expand Up @@ -342,7 +342,7 @@ RateLimiter_setTokenBucketConfig:test_SetRateLimiterConfig() (gas: 38645)
RegistryModuleOwnerCustom_registerAccessControlDefaultAdmin:test_registerAccessControlDefaultAdmin() (gas: 130641)
RegistryModuleOwnerCustom_registerAdminViaGetCCIPAdmin:test_registerAdminViaGetCCIPAdmin() (gas: 130136)
RegistryModuleOwnerCustom_registerAdminViaOwner:test_registerAdminViaOwner() (gas: 129941)
Router_applyRampUpdates:test_applyRampUpdates_OffRampUpdatesWithRouting() (gas: 10413055)
Router_applyRampUpdates:test_applyRampUpdates_OffRampUpdatesWithRouting() (gas: 10864375)
Router_applyRampUpdates:test_applyRampUpdates_OnRampDisable() (gas: 56445)
Router_ccipSend:test_CCIPSendLinkFeeNoTokenSuccess_gas() (gas: 126090)
Router_ccipSend:test_CCIPSendLinkFeeOneTokenSuccess_gas() (gas: 213515)
Expand All @@ -359,9 +359,9 @@ Router_constructor:test_Constructor() (gas: 13170)
Router_getArmProxy:test_getArmProxy() (gas: 10573)
Router_getFee:test_GetFeeSupportedChain() (gas: 52367)
Router_recoverTokens:test_RecoverTokens() (gas: 52686)
Router_routeMessage:test_routeMessage_AutoExec() (gas: 38071)
Router_routeMessage:test_routeMessage_ExecutionEvent() (gas: 153593)
Router_routeMessage:test_routeMessage_ManualExec() (gas: 31120)
Router_routeMessage:test_routeMessage_AutoExec() (gas: 41832)
Router_routeMessage:test_routeMessage_ExecutionEvent() (gas: 157232)
Router_routeMessage:test_routeMessage_ManualExec() (gas: 34881)
SiloedLockReleaseTokenPool_lockOrBurn:test_lockOrBurn_SiloedFunds() (gas: 76874)
SiloedLockReleaseTokenPool_lockOrBurn:test_lockOrBurn_UnsiloedFunds() (gas: 76104)
SiloedLockReleaseTokenPool_provideLiqudity:test_ProvideLiquidity_LegacyProvideLiquiditySelector() (gas: 91873)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,43 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.24;

import {IERC20} from "../../../../vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/IERC20.sol";
import {IERC165} from "../../../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol";
import {IAny2EVMMessageReceiver} from "../../../interfaces/IAny2EVMMessageReceiver.sol";
import {Client} from "../../../libraries/Client.sol";

import {IERC165} from "../../../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol";

contract MaybeRevertMessageReceiver is IAny2EVMMessageReceiver, IERC165 {
error ReceiveRevert();
error CustomError(bytes err);
error Unauthorized();
error InsufficientBalance(uint256 available, uint256 required);
error TransferFailed();

event ValueReceived(uint256 amount);
event MessageReceived();
event NativeFundsWithdrawn(address indexed owner, uint256 amount);
event TokensWithdrawn(address indexed token, address indexed owner, uint256 amount);
event MessageReceived(
bytes32 messageId, uint64 sourceChainSelector, bytes sender, bytes data, Client.EVMTokenAmount[] destTokenAmounts
);

address private s_manager;
address private immutable i_manager;
bool public s_toRevert;
bytes private s_err;

constructor(
bool toRevert
) {
s_manager = msg.sender;
i_manager = msg.sender;
s_toRevert = toRevert;
}

modifier onlyManager() {
if (msg.sender != i_manager) {
revert Unauthorized();
}
_;
}

function setRevert(
bool toRevert
) external {
Expand All @@ -46,12 +60,15 @@ contract MaybeRevertMessageReceiver is IAny2EVMMessageReceiver, IERC165 {
}

function ccipReceive(
Client.Any2EVMMessage calldata
Client.Any2EVMMessage calldata message
) external override {
if (s_toRevert) {
revert CustomError(s_err);
}
emit MessageReceived();

emit MessageReceived(
message.messageId, message.sourceChainSelector, message.sender, message.data, message.destTokenAmounts
);
}

// solhint-disable-next-line no-complex-fallback
Expand All @@ -62,4 +79,44 @@ contract MaybeRevertMessageReceiver is IAny2EVMMessageReceiver, IERC165 {

emit ValueReceived(msg.value);
}

/// @notice Allows the manager (deployer) to withdraw all Ether from the contract
function withdrawFunds() external onlyManager {
uint256 balance = address(this).balance;

(bool success,) = i_manager.call{value: balance}("");
if (!success) {
revert TransferFailed();
}

emit NativeFundsWithdrawn(i_manager, balance);
}

/// @notice Allows the manager to withdraw ERC-20 tokens from the contract
/// @param token The address of the ERC-20 token contract
/// @param amount The amount of tokens to withdraw
function withdrawTokens(address token, uint256 amount) external onlyManager {
IERC20 erc20 = IERC20(token);
uint256 balance = erc20.balanceOf(address(this));
if (balance < amount) {
revert InsufficientBalance(balance, amount);
}

bool success = erc20.transfer(i_manager, amount);
if (!success) {
revert TransferFailed();
}

emit TokensWithdrawn(token, i_manager, amount);
}

/// @notice Fetches the balance of an ERC-20 token held by the contract
/// @param token The address of the ERC-20 token contract
/// @return The balance of the specified ERC-20 token
function balanceOfToken(
address token
) external view returns (uint256) {
IERC20 erc20 = IERC20(token);
return erc20.balanceOf(address(this));
}
}
Loading
Loading