diff --git a/.changeset/early-readers-work.md b/.changeset/early-readers-work.md new file mode 100644 index 0000000000..6da59d5883 --- /dev/null +++ b/.changeset/early-readers-work.md @@ -0,0 +1,6 @@ +--- +"ccip": patch +--- + +New function on NetworkSelector to get ChainID #added +Align logs and include chainID #changed diff --git a/.changeset/wild-gifts-refuse.md b/.changeset/wild-gifts-refuse.md new file mode 100644 index 0000000000..88bf8b05eb --- /dev/null +++ b/.changeset/wild-gifts-refuse.md @@ -0,0 +1,5 @@ +--- +"ccip": patch +--- + +Increased gas limit for LM transmitter to 5e6 #changed diff --git a/.github/workflows/ci-scripts.yml b/.github/workflows/ci-scripts.yml index ef4e3c5e80..8497262977 100644 --- a/.github/workflows/ci-scripts.yml +++ b/.github/workflows/ci-scripts.yml @@ -14,6 +14,7 @@ jobs: with: id: scripts name: lint-scripts + version: v1.56 go-directory: core/scripts/ccip go-version-file: core/scripts/go.mod go-module-file: core/scripts/go.sum diff --git a/contracts/.changeset/gentle-spoons-vanish.md b/contracts/.changeset/gentle-spoons-vanish.md new file mode 100644 index 0000000000..38cfb5eff2 --- /dev/null +++ b/contracts/.changeset/gentle-spoons-vanish.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts-ccip': minor +--- + +#changed MultiOffRamp contract size optimizations diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index ed2660af39..8d8d99b2a1 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -34,6 +34,56 @@ BurnWithFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 28789) BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55208) BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 243659) BurnWithFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 24260) +CCIPCapabilityConfigurationSetup:test_getCapabilityConfiguration_Success() (gas: 9561) +CCIPCapabilityConfiguration_ConfigStateMachine:test__computeConfigDigest_Success() (gas: 70645) +CCIPCapabilityConfiguration_ConfigStateMachine:test__computeNewConfigWithMeta_InitToRunning_Success() (gas: 350565) +CCIPCapabilityConfiguration_ConfigStateMachine:test__computeNewConfigWithMeta_RunningToStaging_Success() (gas: 471510) +CCIPCapabilityConfiguration_ConfigStateMachine:test__computeNewConfigWithMeta_StagingToRunning_Success() (gas: 440232) +CCIPCapabilityConfiguration_ConfigStateMachine:test__groupByPluginType_TooManyOCR3Configs_Reverts() (gas: 37027) +CCIPCapabilityConfiguration_ConfigStateMachine:test__groupByPluginType_threeCommitConfigs_Reverts() (gas: 61043) +CCIPCapabilityConfiguration_ConfigStateMachine:test__groupByPluginType_threeExecutionConfigs_Reverts() (gas: 60963) +CCIPCapabilityConfiguration_ConfigStateMachine:test__stateFromConfigLength_Success() (gas: 11764) +CCIPCapabilityConfiguration_ConfigStateMachine:test__validateConfigStateTransition_Success() (gas: 9028) +CCIPCapabilityConfiguration_ConfigStateMachine:test__validateConfigTransition_InitToRunning_Success() (gas: 303038) +CCIPCapabilityConfiguration_ConfigStateMachine:test__validateConfigTransition_InitToRunning_WrongConfigCount_Reverts() (gas: 49619) +CCIPCapabilityConfiguration_ConfigStateMachine:test__validateConfigTransition_NonExistentConfigTransition_Reverts() (gas: 32253) +CCIPCapabilityConfiguration_ConfigStateMachine:test__validateConfigTransition_RunningToStaging_Success() (gas: 367516) +CCIPCapabilityConfiguration_ConfigStateMachine:test__validateConfigTransition_RunningToStaging_WrongConfigCount_Reverts() (gas: 120877) +CCIPCapabilityConfiguration_ConfigStateMachine:test__validateConfigTransition_RunningToStaging_WrongConfigDigestBlueGreen_Reverts() (gas: 156973) +CCIPCapabilityConfiguration_ConfigStateMachine:test__validateConfigTransition_StagingToRunning_Success() (gas: 367292) +CCIPCapabilityConfiguration_ConfigStateMachine:test__validateConfigTransition_StagingToRunning_WrongConfigDigest_Reverts() (gas: 157040) +CCIPCapabilityConfiguration_ConfigStateMachine:test_getCapabilityConfiguration_Success() (gas: 9648) +CCIPCapabilityConfiguration__updatePluginConfig:test__updatePluginConfig_InitToRunning_Success() (gas: 1044432) +CCIPCapabilityConfiguration__updatePluginConfig:test__updatePluginConfig_InvalidConfigLength_Reverts() (gas: 27539) +CCIPCapabilityConfiguration__updatePluginConfig:test__updatePluginConfig_InvalidConfigStateTransition_Reverts() (gas: 23118) +CCIPCapabilityConfiguration__updatePluginConfig:test__updatePluginConfig_RunningToStaging_Success() (gas: 1992348) +CCIPCapabilityConfiguration__updatePluginConfig:test__updatePluginConfig_StagingToRunning_Success() (gas: 2595930) +CCIPCapabilityConfiguration__updatePluginConfig:test_getCapabilityConfiguration_Success() (gas: 9626) +CCIPCapabilityConfiguration_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_CommitAndExecConfig_Success() (gas: 1834017) +CCIPCapabilityConfiguration_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_CommitConfigOnly_Success() (gas: 1055344) +CCIPCapabilityConfiguration_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_ExecConfigOnly_Success() (gas: 1055375) +CCIPCapabilityConfiguration_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_OnlyCapabilityRegistryCanCall_Reverts() (gas: 9576) +CCIPCapabilityConfiguration_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_ZeroLengthConfig_Success() (gas: 16070) +CCIPCapabilityConfiguration_beforeCapabilityConfigSet:test_getCapabilityConfiguration_Success() (gas: 9626) +CCIPCapabilityConfiguration_chainConfig:test__applyChainConfigUpdates_FChainNotPositive_Reverts() (gas: 182909) +CCIPCapabilityConfiguration_chainConfig:test_applyChainConfigUpdates_addChainConfigs_Success() (gas: 342472) +CCIPCapabilityConfiguration_chainConfig:test_applyChainConfigUpdates_nodeNotInRegistry_Reverts() (gas: 19116) +CCIPCapabilityConfiguration_chainConfig:test_applyChainConfigUpdates_removeChainConfigs_Success() (gas: 266071) +CCIPCapabilityConfiguration_chainConfig:test_applyChainConfigUpdates_selectorNotFound_Reverts() (gas: 14807) +CCIPCapabilityConfiguration_chainConfig:test_getCapabilityConfiguration_Success() (gas: 9604) +CCIPCapabilityConfiguration_validateConfig:test__validateConfig_ChainSelectorNotFound_Reverts() (gas: 285383) +CCIPCapabilityConfiguration_validateConfig:test__validateConfig_ChainSelectorNotSet_Reverts() (gas: 282501) +CCIPCapabilityConfiguration_validateConfig:test__validateConfig_FMustBePositive_Reverts() (gas: 283422) +CCIPCapabilityConfiguration_validateConfig:test__validateConfig_FTooHigh_Reverts() (gas: 283588) +CCIPCapabilityConfiguration_validateConfig:test__validateConfig_NodeNotInRegistry_Reverts() (gas: 287815) +CCIPCapabilityConfiguration_validateConfig:test__validateConfig_NotEnoughTransmitters_Reverts() (gas: 1068544) +CCIPCapabilityConfiguration_validateConfig:test__validateConfig_OfframpAddressCannotBeZero_Reverts() (gas: 282309) +CCIPCapabilityConfiguration_validateConfig:test__validateConfig_P2PIdsLengthNotMatching_Reverts() (gas: 284277) +CCIPCapabilityConfiguration_validateConfig:test__validateConfig_Success() (gas: 289222) +CCIPCapabilityConfiguration_validateConfig:test__validateConfig_TooManyBootstrapP2PIds_Reverts() (gas: 285518) +CCIPCapabilityConfiguration_validateConfig:test__validateConfig_TooManySigners_Reverts() (gas: 1120660) +CCIPCapabilityConfiguration_validateConfig:test__validateConfig_TooManyTransmitters_Reverts() (gas: 1119000) +CCIPCapabilityConfiguration_validateConfig:test_getCapabilityConfiguration_Success() (gas: 9540) CCIPClientExample_sanity:test_ImmutableExamples_Success() (gas: 2133850) CommitStore_constructor:test_Constructor_Success() (gas: 3091440) CommitStore_isUnpausedAndRMNHealthy:test_RMN_Success() (gas: 75331) @@ -66,174 +116,172 @@ CommitStore_verify:test_TooManyLeaves_Revert() (gas: 36785) DefensiveExampleTest:test_HappyPath_Success() (gas: 200018) DefensiveExampleTest:test_Recovery() (gas: 424253) E2E:test_E2E_3MessagesSuccess_gas() (gas: 1106837) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 263045) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 93686) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ApplyZeroUpdates_Success() (gas: 12334) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChainOnRampAndPrevOffRamp_Revert() (gas: 87721) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChainOnRamp_Revert() (gas: 87454) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChainPrevOffRamp_Revert() (gas: 87647) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChain_Success() (gas: 102154) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroOnRampAddress_Revert() (gas: 12423) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroSourceChainSelector_Revert() (gas: 12398) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 278879) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 224306) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 149627) -EVM2EVMMultiOffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 178945) -EVM2EVMMultiOffRamp_batchExecute:test_SingleReport_Success() (gas: 136157) -EVM2EVMMultiOffRamp_batchExecute:test_Unhealthy_Revert() (gas: 520361) -EVM2EVMMultiOffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10441) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 38297) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 108537) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_revert_Revert() (gas: 116989) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 262944) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 93628) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ApplyZeroUpdates_Success() (gas: 12398) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChainOnRampAndPrevOffRamp_Revert() (gas: 87827) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChainOnRamp_Revert() (gas: 87538) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChainPrevOffRamp_Revert() (gas: 87686) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChain_Success() (gas: 102183) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroOnRampAddress_Revert() (gas: 12487) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroSourceChainSelector_Revert() (gas: 12462) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 278563) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 223913) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 149702) +EVM2EVMMultiOffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 178741) +EVM2EVMMultiOffRamp_batchExecute:test_SingleReport_Success() (gas: 136083) +EVM2EVMMultiOffRamp_batchExecute:test_Unhealthy_Revert() (gas: 520278) +EVM2EVMMultiOffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10487) EVM2EVMMultiOffRamp_ccipReceive:test_Reverts() (gas: 17112) -EVM2EVMMultiOffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 7043083) -EVM2EVMMultiOffRamp_commit:test_NoConfig_Revert() (gas: 6626006) -EVM2EVMMultiOffRamp_commit:test_SingleReport_Success() (gas: 161050) -EVM2EVMMultiOffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 120903) -EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 7061858) -EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 6711837) -EVM2EVMMultiOffRamp_constructor:test_SourceChainSelector_Revert() (gas: 100030) -EVM2EVMMultiOffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 98610) -EVM2EVMMultiOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 100063) -EVM2EVMMultiOffRamp_constructor:test_ZeroRMNProxy_Revert() (gas: 96367) -EVM2EVMMultiOffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 96457) -EVM2EVMMultiOffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 7092600) -EVM2EVMMultiOffRamp_execute:test_NoConfig_Revert() (gas: 6675266) -EVM2EVMMultiOffRamp_execute:test_SingleReport_Success() (gas: 156875) -EVM2EVMMultiOffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 140719) -EVM2EVMMultiOffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 7454908) -EVM2EVMMultiOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 20642) -EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 255841) -EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 22871) -EVM2EVMMultiOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 208246) -EVM2EVMMultiOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 50914) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 50402) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 221352) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 77140) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 288038) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 81184) -EVM2EVMMultiOffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 37471) -EVM2EVMMultiOffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 21760) -EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidMessageId_Revert() (gas: 41784) -EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 448866) -EVM2EVMMultiOffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 53535) -EVM2EVMMultiOffRamp_executeSingleReport:test_MessageTooLarge_Revert() (gas: 154093) -EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingOnRampAddress_Revert() (gas: 44609) -EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingSourceChainSelector_Revert() (gas: 41676) -EVM2EVMMultiOffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 37730) -EVM2EVMMultiOffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 170541) -EVM2EVMMultiOffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 182146) -EVM2EVMMultiOffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 49176) -EVM2EVMMultiOffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 406064) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 233339) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 180915) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 251955) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 119124) -EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 383701) -EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 55923) -EVM2EVMMultiOffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 53355) -EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 528885) -EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 466412) -EVM2EVMMultiOffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35849) -EVM2EVMMultiOffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 518813) -EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 516211) -EVM2EVMMultiOffRamp_executeSingleReport:test_UnsupportedNumberOfTokens_Revert() (gas: 65466) -EVM2EVMMultiOffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 483429) -EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 147680) -EVM2EVMMultiOffRamp_execute_upgrade:test_NoPrevOffRampForChain_Success() (gas: 239585) -EVM2EVMMultiOffRamp_execute_upgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 239530) -EVM2EVMMultiOffRamp_execute_upgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 290102) -EVM2EVMMultiOffRamp_execute_upgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 270581) -EVM2EVMMultiOffRamp_execute_upgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 247819) -EVM2EVMMultiOffRamp_execute_upgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 235794) -EVM2EVMMultiOffRamp_execute_upgrade:test_UpgradedWithMultiRamp_Revert() (gas: 7627747) -EVM2EVMMultiOffRamp_execute_upgrade:test_Upgraded_Success() (gas: 136510) -EVM2EVMMultiOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3590746) -EVM2EVMMultiOffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 117760) -EVM2EVMMultiOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 86873) -EVM2EVMMultiOffRamp_isUnpausedAndRMNHealthy:test_RMN_Success() (gas: 75619) -EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 79972) -EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 28721) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 152516) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 198036) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 28254) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 160615) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 495948) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails() (gas: 2371462) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 200146) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 200742) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 642734) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 287749) -EVM2EVMMultiOffRamp_metadataHash:test_MetadataHashChangesOnOnRampAddress_Success() (gas: 11027) -EVM2EVMMultiOffRamp_metadataHash:test_MetadataHashChangesOnSourceChain_Success() (gas: 11080) -EVM2EVMMultiOffRamp_metadataHash:test_MetadataHash_Success() (gas: 9191) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 171896) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 33312) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 70902) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 50988) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 80934) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 192892) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 289884) -EVM2EVMMultiOffRamp_reportCommit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 58215) -EVM2EVMMultiOffRamp_reportCommit:test_InvalidInterval_Revert() (gas: 51845) -EVM2EVMMultiOffRamp_reportCommit:test_InvalidRootRevert() (gas: 50945) -EVM2EVMMultiOffRamp_reportCommit:test_OnlyGasPriceUpdates_Success() (gas: 64713) -EVM2EVMMultiOffRamp_reportCommit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 68997) -EVM2EVMMultiOffRamp_reportCommit:test_OnlyTokenPriceUpdates_Success() (gas: 64689) -EVM2EVMMultiOffRamp_reportCommit:test_Paused_Revert() (gas: 40466) -EVM2EVMMultiOffRamp_reportCommit:test_ReportAndPriceUpdate_Success() (gas: 119841) -EVM2EVMMultiOffRamp_reportCommit:test_ReportOnlyRootSuccess_gas() (gas: 80225) -EVM2EVMMultiOffRamp_reportCommit:test_RootAlreadyCommitted_Revert() (gas: 90494) -EVM2EVMMultiOffRamp_reportCommit:test_SourceChainNotEnabled_Revert() (gas: 51221) -EVM2EVMMultiOffRamp_reportCommit:test_StaleReportWithRoot_Success() (gas: 142995) -EVM2EVMMultiOffRamp_reportCommit:test_Unhealthy_Revert() (gas: 69784) -EVM2EVMMultiOffRamp_reportCommit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 140904) -EVM2EVMMultiOffRamp_reportCommit:test_ZeroEpochAndRound_Revert() (gas: 17735) -EVM2EVMMultiOffRamp_reportExec:test_IncorrectArrayType_Revert() (gas: 10004) -EVM2EVMMultiOffRamp_reportExec:test_LargeBatch_Success() (gas: 1471370) -EVM2EVMMultiOffRamp_reportExec:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 293483) -EVM2EVMMultiOffRamp_reportExec:test_MultipleReports_Success() (gas: 224678) -EVM2EVMMultiOffRamp_reportExec:test_NonArray_Revert() (gas: 22774) -EVM2EVMMultiOffRamp_reportExec:test_SingleReport_Success() (gas: 133819) -EVM2EVMMultiOffRamp_reportExec:test_ZeroReports_Revert() (gas: 9899) -EVM2EVMMultiOffRamp_resetUnblessedRoots:test_OnlyOwner_Revert() (gas: 11377) -EVM2EVMMultiOffRamp_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 155750) -EVM2EVMMultiOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14765) -EVM2EVMMultiOffRamp_setDynamicConfig:test_PriceRegistryZeroAddress_Revert() (gas: 12314) -EVM2EVMMultiOffRamp_setDynamicConfig:test_RouterZeroAddress_Revert() (gas: 14413) -EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 45435) -EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 40479) -EVM2EVMMultiOffRamp_setLatestPriceEpochAndRound:test_OnlyOwner_Revert() (gas: 11043) -EVM2EVMMultiOffRamp_setLatestPriceEpochAndRound:test_PriceEpochCleared_Success() (gas: 242916) -EVM2EVMMultiOffRamp_setLatestPriceEpochAndRound:test_SetLatestPriceEpochAndRound_Success() (gas: 20502) -EVM2EVMMultiOffRamp_trialExecute:test_RateLimitError_Success() (gas: 243932) -EVM2EVMMultiOffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 252523) -EVM2EVMMultiOffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 306347) -EVM2EVMMultiOffRamp_trialExecute:test_trialExecute_Success() (gas: 285955) -EVM2EVMMultiOffRamp_verify:test_Blessed_Success() (gas: 120913) -EVM2EVMMultiOffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 123006) -EVM2EVMMultiOffRamp_verify:test_NotBlessed_Success() (gas: 83460) -EVM2EVMMultiOffRamp_verify:test_Paused_Revert() (gas: 19039) -EVM2EVMMultiOffRamp_verify:test_TooManyLeaves_Revert() (gas: 53617) +EVM2EVMMultiOffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 66098) +EVM2EVMMultiOffRamp_commit:test_InvalidInterval_Revert() (gas: 59748) +EVM2EVMMultiOffRamp_commit:test_InvalidRootRevert() (gas: 58828) +EVM2EVMMultiOffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6589672) +EVM2EVMMultiOffRamp_commit:test_NoConfig_Revert() (gas: 6172841) +EVM2EVMMultiOffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 108294) +EVM2EVMMultiOffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 118230) +EVM2EVMMultiOffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 108270) +EVM2EVMMultiOffRamp_commit:test_ReportAndPriceUpdate_Success() (gas: 160084) +EVM2EVMMultiOffRamp_commit:test_ReportOnlyRootSuccess_gas() (gas: 135123) +EVM2EVMMultiOffRamp_commit:test_RootAlreadyCommitted_Revert() (gas: 136820) +EVM2EVMMultiOffRamp_commit:test_SourceChainNotEnabled_Revert() (gas: 59096) +EVM2EVMMultiOffRamp_commit:test_StaleReportWithRoot_Success() (gas: 225356) +EVM2EVMMultiOffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 119693) +EVM2EVMMultiOffRamp_commit:test_Unhealthy_Revert() (gas: 77594) +EVM2EVMMultiOffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 207937) +EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6584042) +EVM2EVMMultiOffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47717) +EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 6242606) +EVM2EVMMultiOffRamp_constructor:test_SourceChainSelector_Revert() (gas: 101021) +EVM2EVMMultiOffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 97965) +EVM2EVMMultiOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 101074) +EVM2EVMMultiOffRamp_constructor:test_ZeroRMNProxy_Revert() (gas: 95722) +EVM2EVMMultiOffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 95789) +EVM2EVMMultiOffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17299) +EVM2EVMMultiOffRamp_execute:test_LargeBatch_Success() (gas: 1490148) +EVM2EVMMultiOffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 330086) +EVM2EVMMultiOffRamp_execute:test_MultipleReports_Success() (gas: 247239) +EVM2EVMMultiOffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6640018) +EVM2EVMMultiOffRamp_execute:test_NoConfig_Revert() (gas: 6222985) +EVM2EVMMultiOffRamp_execute:test_NonArray_Revert() (gas: 30044) +EVM2EVMMultiOffRamp_execute:test_SingleReport_Success() (gas: 156627) +EVM2EVMMultiOffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 140575) +EVM2EVMMultiOffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 7002111) +EVM2EVMMultiOffRamp_execute:test_ZeroReports_Revert() (gas: 17174) +EVM2EVMMultiOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 20709) +EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 255851) +EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 22860) +EVM2EVMMultiOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 208240) +EVM2EVMMultiOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 50948) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 50458) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 235419) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 91241) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 288058) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 95351) +EVM2EVMMultiOffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 37472) +EVM2EVMMultiOffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 24087) +EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidMessageId_Revert() (gas: 41948) +EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 448634) +EVM2EVMMultiOffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 53653) +EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingOnRampAddress_Revert() (gas: 44740) +EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingSourceChainSelector_Revert() (gas: 41840) +EVM2EVMMultiOffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 37658) +EVM2EVMMultiOffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 170378) +EVM2EVMMultiOffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 182190) +EVM2EVMMultiOffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 47177) +EVM2EVMMultiOffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 405951) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 233102) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 180689) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 251836) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 119083) +EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 383789) +EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 56096) +EVM2EVMMultiOffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 51403) +EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 528700) +EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 466304) +EVM2EVMMultiOffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 38177) +EVM2EVMMultiOffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 518752) +EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 516084) +EVM2EVMMultiOffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 483321) +EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 147823) +EVM2EVMMultiOffRamp_execute_upgrade:test_NoPrevOffRampForChain_Success() (gas: 239478) +EVM2EVMMultiOffRamp_execute_upgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 239370) +EVM2EVMMultiOffRamp_execute_upgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 289847) +EVM2EVMMultiOffRamp_execute_upgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 270573) +EVM2EVMMultiOffRamp_execute_upgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 247753) +EVM2EVMMultiOffRamp_execute_upgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 235728) +EVM2EVMMultiOffRamp_execute_upgrade:test_UpgradedWithMultiRamp_Revert() (gas: 7174963) +EVM2EVMMultiOffRamp_execute_upgrade:test_Upgraded_Success() (gas: 136472) +EVM2EVMMultiOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3652910) +EVM2EVMMultiOffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 118102) +EVM2EVMMultiOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 87240) +EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 80029) +EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 28684) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 152312) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 199879) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 28213) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 160718) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 497791) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails() (gas: 2371474) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 201989) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 202563) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 651271) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 287191) +EVM2EVMMultiOffRamp_metadataHash:test_MetadataHashChangesOnOnRampAddress_Success() (gas: 10983) +EVM2EVMMultiOffRamp_metadataHash:test_MetadataHashChangesOnSourceChain_Success() (gas: 11029) +EVM2EVMMultiOffRamp_metadataHash:test_MetadataHash_Success() (gas: 9135) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 165404) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 26964) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 63569) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 44686) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 80707) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 185601) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 284048) +EVM2EVMMultiOffRamp_resetUnblessedRoots:test_OnlyOwner_Revert() (gas: 11420) +EVM2EVMMultiOffRamp_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 211875) +EVM2EVMMultiOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14223) +EVM2EVMMultiOffRamp_setDynamicConfig:test_PriceRegistryZeroAddress_Revert() (gas: 11729) +EVM2EVMMultiOffRamp_setDynamicConfig:test_RouterZeroAddress_Revert() (gas: 13885) +EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 55566) +EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 33576) +EVM2EVMMultiOffRamp_setLatestPriceSequenceNumber:test_OnlyOwner_Revert() (gas: 11033) +EVM2EVMMultiOffRamp_setLatestPriceSequenceNumber:test_PriceEpochCleared_Success() (gas: 242133) +EVM2EVMMultiOffRamp_setLatestPriceSequenceNumber:test_setLatestPriceSequenceNumber_Success() (gas: 20534) +EVM2EVMMultiOffRamp_trialExecute:test_RateLimitError_Success() (gas: 243929) +EVM2EVMMultiOffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 252586) +EVM2EVMMultiOffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 306761) +EVM2EVMMultiOffRamp_trialExecute:test_trialExecute_Success() (gas: 286008) +EVM2EVMMultiOffRamp_verify:test_Blessed_Success() (gas: 176393) +EVM2EVMMultiOffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178464) +EVM2EVMMultiOffRamp_verify:test_NotBlessed_Success() (gas: 138858) +EVM2EVMMultiOffRamp_verify:test_TooManyLeaves_Revert() (gas: 51501) EVM2EVMMultiOnRamp_applyDestChainConfigUpdates:test_InvalidDestBytesOverhead_Revert() (gas: 33520) EVM2EVMMultiOnRamp_applyDestChainConfigUpdates:test_InvalidDestChainConfigDestChainSelectorEqZero_Revert() (gas: 16645) EVM2EVMMultiOnRamp_applyDestChainConfigUpdates:test_InvalidDestChainConfigNewPrevOnRampOnExistingChain_Revert() (gas: 30418) EVM2EVMMultiOnRamp_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesDefaultTxGasLimitEqZero() (gas: 16695) EVM2EVMMultiOnRamp_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesZeroIntput() (gas: 12338) EVM2EVMMultiOnRamp_applyDestChainConfigUpdates:test_applyDestChainConfigUpdates_Success() (gas: 172172) -EVM2EVMMultiOnRamp_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeConfigByAdmin_Success() (gas: 48870) -EVM2EVMMultiOnRamp_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeConfig_Success() (gas: 90887) +EVM2EVMMultiOnRamp_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeConfigByAdmin_Success() (gas: 48867) +EVM2EVMMultiOnRamp_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeConfig_Success() (gas: 90881) EVM2EVMMultiOnRamp_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeZeroInput() (gas: 13116) EVM2EVMMultiOnRamp_applyTokenTransferFeeConfigUpdates:test_InvalidDestBytesOverhead_Revert() (gas: 17292) EVM2EVMMultiOnRamp_applyTokenTransferFeeConfigUpdates:test_OnlyCallableByOwnerOrAdmin_Revert() (gas: 14279) -EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigLinkChainSelectorEqZero_Revert() (gas: 186179) -EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigLinkTokenEqAddressZero_Revert() (gas: 181803) -EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() (gas: 184035) -EVM2EVMMultiOnRamp_constructor:test_Constructor_Success() (gas: 5244326) +EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigLinkChainSelectorEqZero_Revert() (gas: 188520) +EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigLinkTokenEqAddressZero_Revert() (gas: 184144) +EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigNonceManagerEqAddressZero_Revert() (gas: 186430) +EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() (gas: 191442) +EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigTokenAdminRegistryEqAddressZero_Revert() (gas: 186488) +EVM2EVMMultiOnRamp_constructor:test_Constructor_Success() (gas: 5301779) EVM2EVMMultiOnRamp_forwardFromRouter:test_CannotSendZeroTokens_Revert() (gas: 34352) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 151858) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessEmptyExtraArgs() (gas: 153908) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 159662) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 151495) -EVM2EVMMultiOnRamp_forwardFromRouter:test_InvalidAddressEncodePacked_Revert() (gas: 57970) -EVM2EVMMultiOnRamp_forwardFromRouter:test_InvalidAddress_Revert() (gas: 58232) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 159658) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessEmptyExtraArgs() (gas: 161709) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 167462) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 159295) +EVM2EVMMultiOnRamp_forwardFromRouter:test_InvalidAddressEncodePacked_Revert() (gas: 33001) +EVM2EVMMultiOnRamp_forwardFromRouter:test_InvalidAddress_Revert() (gas: 33263) EVM2EVMMultiOnRamp_forwardFromRouter:test_InvalidChainSelector_Revert() (gas: 28070) EVM2EVMMultiOnRamp_forwardFromRouter:test_InvalidExtraArgsTag_Revert() (gas: 28009) EVM2EVMMultiOnRamp_forwardFromRouter:test_MaxCapacityExceeded_Revert() (gas: 86613) @@ -241,23 +289,19 @@ EVM2EVMMultiOnRamp_forwardFromRouter:test_MessageGasLimitTooHigh_Revert() (gas: EVM2EVMMultiOnRamp_forwardFromRouter:test_MessageTooLarge_Revert() (gas: 108398) EVM2EVMMultiOnRamp_forwardFromRouter:test_MesssageFeeTooHigh_Revert() (gas: 32020) EVM2EVMMultiOnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 23173) -EVM2EVMMultiOnRamp_forwardFromRouter:test_OverValueWithARLOff_Success() (gas: 246680) -EVM2EVMMultiOnRamp_forwardFromRouter:test_Paused_Revert() (gas: 38638) +EVM2EVMMultiOnRamp_forwardFromRouter:test_OverValueWithARLOff_Success() (gas: 254478) +EVM2EVMMultiOnRamp_forwardFromRouter:test_Paused_Revert() (gas: 38951) EVM2EVMMultiOnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 25996) EVM2EVMMultiOnRamp_forwardFromRouter:test_PriceNotFoundForToken_Revert() (gas: 59783) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 197662) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 132675) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 159890) -EVM2EVMMultiOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3765048) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 210192) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 140475) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 167690) +EVM2EVMMultiOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3778087) EVM2EVMMultiOnRamp_forwardFromRouter:test_TooManyTokens_Revert() (gas: 30915) EVM2EVMMultiOnRamp_forwardFromRouter:test_Unhealthy_Revert() (gas: 44328) -EVM2EVMMultiOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 126426) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ZeroAddressReceiver_Revert() (gas: 510675) -EVM2EVMMultiOnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 89484) -EVM2EVMMultiOnRamp_forwardFromRouter_upgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 152050) -EVM2EVMMultiOnRamp_forwardFromRouter_upgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 198121) -EVM2EVMMultiOnRamp_forwardFromRouter_upgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 125905) -EVM2EVMMultiOnRamp_forwardFromRouter_upgrade:test_Upgrade_Success() (gas: 99417) +EVM2EVMMultiOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 134226) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ZeroAddressReceiver_Revert() (gas: 260985) +EVM2EVMMultiOnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 97284) EVM2EVMMultiOnRamp_getDataAvailabilityCost:test_EmptyMessageCalculatesDataAvailabilityCost_Success() (gas: 123791) EVM2EVMMultiOnRamp_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCostUnsupportedDestChainSelector_Success() (gas: 11968) EVM2EVMMultiOnRamp_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCost_Success() (gas: 24458) @@ -283,13 +327,13 @@ EVM2EVMMultiOnRamp_getTokenTransferCost:test_UnsupportedToken_Revert() (gas: 213 EVM2EVMMultiOnRamp_getTokenTransferCost:test_ValidatedPriceStaleness_Revert() (gas: 43578) EVM2EVMMultiOnRamp_getTokenTransferCost:test_WETHTokenBpsFee_Success() (gas: 41472) EVM2EVMMultiOnRamp_getTokenTransferCost:test_ZeroAmountTokenTransferChargesMinFeeAndGas_Success() (gas: 28464) -EVM2EVMMultiOnRamp_getTokenTransferCost:test_ZeroFeeConfigChargesMinFee_Success() (gas: 41285) +EVM2EVMMultiOnRamp_getTokenTransferCost:test_ZeroFeeConfigChargesMinFee_Success() (gas: 41282) EVM2EVMMultiOnRamp_getTokenTransferCost:test_getTokenTransferCost_selfServeUsesDefaults_Success() (gas: 31940) EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigInvalidConfigFeeAggregatorEqAddressZero_Revert() (gas: 11230) EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigInvalidConfigPriceRegistryEqAddressZero_Revert() (gas: 11196) EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 11187) EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 15989) -EVM2EVMMultiOnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 34496) +EVM2EVMMultiOnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 35363) EVM2EVMMultiOnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97209) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_NotACompatiblePool_Revert() (gas: 38076) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_Success() (gas: 108365) @@ -312,32 +356,32 @@ EVM2EVMOffRamp_ccipReceive:test_Reverts() (gas: 17096) EVM2EVMOffRamp_constructor:test_CommitStoreAlreadyInUse_Revert() (gas: 153464) EVM2EVMOffRamp_constructor:test_Constructor_Success() (gas: 5491136) EVM2EVMOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 144220) -EVM2EVMOffRamp_execute:test_EmptyReport_Revert() (gas: 21485) -EVM2EVMOffRamp_execute:test_InvalidMessageId_Revert() (gas: 36464) -EVM2EVMOffRamp_execute:test_InvalidSourceChain_Revert() (gas: 51767) -EVM2EVMOffRamp_execute:test_InvalidSourcePoolAddress_Success() (gas: 474062) -EVM2EVMOffRamp_execute:test_ManualExecutionNotYetEnabled_Revert() (gas: 46423) -EVM2EVMOffRamp_execute:test_MessageTooLarge_Revert() (gas: 152496) -EVM2EVMOffRamp_execute:test_Paused_Revert() (gas: 101289) -EVM2EVMOffRamp_execute:test_ReceiverError_Success() (gas: 165140) -EVM2EVMOffRamp_execute:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 177988) -EVM2EVMOffRamp_execute:test_RootNotCommitted_Revert() (gas: 41295) -EVM2EVMOffRamp_execute:test_RouterYULCall_Revert() (gas: 402660) -EVM2EVMOffRamp_execute:test_SingleMessageNoTokensUnordered_Success() (gas: 159781) -EVM2EVMOffRamp_execute:test_SingleMessageNoTokens_Success() (gas: 175004) -EVM2EVMOffRamp_execute:test_SingleMessageToNonCCIPReceiver_Success() (gas: 248776) -EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 115214) -EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 409600) -EVM2EVMOffRamp_execute:test_SkippedIncorrectNonce_Success() (gas: 54216) -EVM2EVMOffRamp_execute:test_StrictUntouchedToSuccess_Success() (gas: 132270) -EVM2EVMOffRamp_execute:test_TokenDataMismatch_Revert() (gas: 52165) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 560816) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 500116) -EVM2EVMOffRamp_execute:test_UnexpectedTokenData_Revert() (gas: 35486) -EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 548791) -EVM2EVMOffRamp_execute:test_UnsupportedNumberOfTokens_Revert() (gas: 64049) -EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 123455) -EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 143607) +EVM2EVMOffRamp_execute:test_EmptyReport_Revert() (gas: 21459) +EVM2EVMOffRamp_execute:test_InvalidMessageId_Revert() (gas: 36556) +EVM2EVMOffRamp_execute:test_InvalidSourceChain_Revert() (gas: 51824) +EVM2EVMOffRamp_execute:test_InvalidSourcePoolAddress_Success() (gas: 474330) +EVM2EVMOffRamp_execute:test_ManualExecutionNotYetEnabled_Revert() (gas: 46537) +EVM2EVMOffRamp_execute:test_MessageTooLarge_Revert() (gas: 152576) +EVM2EVMOffRamp_execute:test_Paused_Revert() (gas: 101560) +EVM2EVMOffRamp_execute:test_ReceiverError_Success() (gas: 165312) +EVM2EVMOffRamp_execute:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 178182) +EVM2EVMOffRamp_execute:test_RootNotCommitted_Revert() (gas: 41431) +EVM2EVMOffRamp_execute:test_RouterYULCall_Revert() (gas: 402717) +EVM2EVMOffRamp_execute:test_SingleMessageNoTokensUnordered_Success() (gas: 160103) +EVM2EVMOffRamp_execute:test_SingleMessageNoTokens_Success() (gas: 175334) +EVM2EVMOffRamp_execute:test_SingleMessageToNonCCIPReceiver_Success() (gas: 248878) +EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 115349) +EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 409892) +EVM2EVMOffRamp_execute:test_SkippedIncorrectNonce_Success() (gas: 54296) +EVM2EVMOffRamp_execute:test_StrictUntouchedToSuccess_Success() (gas: 132420) +EVM2EVMOffRamp_execute:test_TokenDataMismatch_Revert() (gas: 52323) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 561156) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 500392) +EVM2EVMOffRamp_execute:test_UnexpectedTokenData_Revert() (gas: 35556) +EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 549423) +EVM2EVMOffRamp_execute:test_UnsupportedNumberOfTokens_Revert() (gas: 64168) +EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 123671) +EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 143834) EVM2EVMOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 20615) EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 282106) EVM2EVMOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20264) @@ -371,9 +415,9 @@ EVM2EVMOffRamp_updateRateLimitTokens:test_updateRateLimitTokens_AddsAndRemoves_S EVM2EVMOffRamp_updateRateLimitTokens:test_updateRateLimitTokens_NonOwner_Revert() (gas: 16667) EVM2EVMOffRamp_updateRateLimitTokens:test_updateRateLimitTokens_Success() (gas: 197660) EVM2EVMOnRamp_applyPremiumMultiplierWeiPerEthUpdates:test_OnlyCallableByOwnerOrAdmin_Revert() (gas: 13485) -EVM2EVMOnRamp_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesByAdmin_Success() (gas: 86317) -EVM2EVMOnRamp_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesMultipleTokens_Success() (gas: 54115) -EVM2EVMOnRamp_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesSingleToken_Success() (gas: 44855) +EVM2EVMOnRamp_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesByAdmin_Success() (gas: 86311) +EVM2EVMOnRamp_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesMultipleTokens_Success() (gas: 54109) +EVM2EVMOnRamp_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesSingleToken_Success() (gas: 44852) EVM2EVMOnRamp_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesZeroInput() (gas: 12306) EVM2EVMOnRamp_constructor:test_Constructor_Success() (gas: 5635586) EVM2EVMOnRamp_forwardFromRouter:test_CannotSendZeroTokens_Revert() (gas: 35880) @@ -537,33 +581,26 @@ MultiAggregateRateLimiter__getTokenValue:test_NoTokenPrice_Reverts() (gas: 21180 MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_MultipleConfigsBothLanes_Success() (gas: 132031) MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_MultipleConfigs_Success() (gas: 312057) MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_OnlyCallableByOwner_Revert() (gas: 17717) -MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_SingleConfigOutgoing_Success() (gas: 75729) -MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_SingleConfig_Success() (gas: 75733) +MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_SingleConfigOutbound_Success() (gas: 75784) +MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_SingleConfig_Success() (gas: 75700) MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_UpdateExistingConfigWithNoDifference_Success() (gas: 38133) MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_UpdateExistingConfig_Success() (gas: 49092) MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_ZeroChainSelector_Revert() (gas: 17019) MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_ZeroConfigs_Success() (gas: 12295) -MultiAggregateRateLimiter_constructor:test_ConstructorNoAuthorizedCallers_Success() (gas: 1956183) -MultiAggregateRateLimiter_constructor:test_Constructor_Success() (gas: 2072477) +MultiAggregateRateLimiter_constructor:test_ConstructorNoAuthorizedCallers_Success() (gas: 1956976) +MultiAggregateRateLimiter_constructor:test_Constructor_Success() (gas: 2070424) MultiAggregateRateLimiter_getTokenBucket:test_GetTokenBucket_Success() (gas: 34248) MultiAggregateRateLimiter_getTokenBucket:test_Refill_Success() (gas: 47358) MultiAggregateRateLimiter_getTokenBucket:test_TimeUnderflow_Revert() (gas: 15806) -MultiAggregateRateLimiter_onIncomingMessage:test_ValidateMessageFromUnauthorizedCaller_Revert() (gas: 14532) -MultiAggregateRateLimiter_onIncomingMessage:test_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 189169) -MultiAggregateRateLimiter_onIncomingMessage:test_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 59823) -MultiAggregateRateLimiter_onIncomingMessage:test_ValidateMessageWithNoTokens_Success() (gas: 17562) -MultiAggregateRateLimiter_onIncomingMessage:test_ValidateMessageWithRateLimitDisabled_Success() (gas: 44848) -MultiAggregateRateLimiter_onIncomingMessage:test_ValidateMessageWithRateLimitExceeded_Revert() (gas: 50433) -MultiAggregateRateLimiter_onIncomingMessage:test_ValidateMessageWithRateLimitReset_Success() (gas: 78388) -MultiAggregateRateLimiter_onIncomingMessage:test_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 263156) -MultiAggregateRateLimiter_onIncomingMessage:test_ValidateMessageWithTokens_Success() (gas: 54607) -MultiAggregateRateLimiter_setAuthorizedCallers:test_AddAndRemove_Success() (gas: 125991) -MultiAggregateRateLimiter_setAuthorizedCallers:test_OnlyAdd_Success() (gas: 133140) -MultiAggregateRateLimiter_setAuthorizedCallers:test_OnlyOwner_Revert() (gas: 13570) -MultiAggregateRateLimiter_setAuthorizedCallers:test_OnlyRemove_Success() (gas: 45639) -MultiAggregateRateLimiter_setAuthorizedCallers:test_RemoveThenAdd_Success() (gas: 57929) -MultiAggregateRateLimiter_setAuthorizedCallers:test_SkipRemove_Success() (gas: 32576) -MultiAggregateRateLimiter_setAuthorizedCallers:test_ZeroAddressAdd_Revert() (gas: 12623) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageFromUnauthorizedCaller_Revert() (gas: 14527) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 189179) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 59828) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithNoTokens_Success() (gas: 17567) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitDisabled_Success() (gas: 44852) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitExceeded_Revert() (gas: 50437) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitReset_Success() (gas: 78406) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 263166) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokens_Success() (gas: 54612) MultiAggregateRateLimiter_setPriceRegistry:test_OnlyOwner_Revert() (gas: 11336) MultiAggregateRateLimiter_setPriceRegistry:test_Owner_Success() (gas: 19124) MultiAggregateRateLimiter_setPriceRegistry:test_ZeroAddress_Revert() (gas: 10608) @@ -574,38 +611,46 @@ MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokens_AddsA MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokens_RemoveNonExistentToken_Success() (gas: 28509) MultiAggregateRateLimiter_updateRateLimitTokens:test_ZeroDestToken_Revert() (gas: 17430) MultiAggregateRateLimiter_updateRateLimitTokens:test_ZeroSourceToken_Revert() (gas: 17485) -MultiOCR3Base_setOCR3Configs:test_FMustBePositive_Revert() (gas: 59396) -MultiOCR3Base_setOCR3Configs:test_FTooHigh_Revert() (gas: 44544) -MultiOCR3Base_setOCR3Configs:test_RepeatSignerAddress_Revert() (gas: 283912) -MultiOCR3Base_setOCR3Configs:test_RepeatTransmitterAddress_Revert() (gas: 423049) -MultiOCR3Base_setOCR3Configs:test_SetConfigIgnoreSigners_Success() (gas: 512762) -MultiOCR3Base_setOCR3Configs:test_SetConfigWithSigners_Success() (gas: 830661) -MultiOCR3Base_setOCR3Configs:test_SetConfigWithoutSigners_Success() (gas: 458492) -MultiOCR3Base_setOCR3Configs:test_SetConfigsZeroInput_Success() (gas: 12332) -MultiOCR3Base_setOCR3Configs:test_SetMultipleConfigs_Success() (gas: 2146686) -MultiOCR3Base_setOCR3Configs:test_SignerCannotBeZeroAddress_Revert() (gas: 141953) -MultiOCR3Base_setOCR3Configs:test_StaticConfigChange_Revert() (gas: 817933) -MultiOCR3Base_setOCR3Configs:test_TooManySigners_Revert() (gas: 171416) -MultiOCR3Base_setOCR3Configs:test_TooManyTransmitters_Revert() (gas: 30500) -MultiOCR3Base_setOCR3Configs:test_TransmitterCannotBeZeroAddress_Revert() (gas: 254663) -MultiOCR3Base_setOCR3Configs:test_UpdateConfigSigners_Success() (gas: 862620) -MultiOCR3Base_setOCR3Configs:test_UpdateConfigTransmittersWithoutSigners_Success() (gas: 476906) -MultiOCR3Base_transmit:test_ConfigDigestMismatch_Revert() (gas: 43809) -MultiOCR3Base_transmit:test_ForkedChain_Revert() (gas: 49355) -MultiOCR3Base_transmit:test_InsufficientSignatures_Revert() (gas: 81495) -MultiOCR3Base_transmit:test_NonUniqueSignature_Revert() (gas: 67118) -MultiOCR3Base_transmit:test_SignatureOutOfRegistration_Revert() (gas: 33474) -MultiOCR3Base_transmit:test_TooManySignatures_Revert() (gas: 85456) -MultiOCR3Base_transmit:test_TransmitSignersNonUniqueReports_gas_Success() (gas: 34208) -MultiOCR3Base_transmit:test_TransmitUniqueReportSigners_gas_Success() (gas: 53798) -MultiOCR3Base_transmit:test_TransmitWithExtraCalldataArgs_Revert() (gas: 47174) -MultiOCR3Base_transmit:test_TransmitWithLessCalldataArgs_Revert() (gas: 25720) -MultiOCR3Base_transmit:test_TransmitWithoutSignatureVerification_gas_Success() (gas: 18768) -MultiOCR3Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 24205) -MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 62379) -MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39969) -MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 33006) -MultiRampsE2E:test_E2E_3MessagesSuccess_gas() (gas: 1339048) +MultiOCR3Base_setOCR3Configs:test_FMustBePositive_Revert() (gas: 59331) +MultiOCR3Base_setOCR3Configs:test_FTooHigh_Revert() (gas: 44298) +MultiOCR3Base_setOCR3Configs:test_RepeatSignerAddress_Revert() (gas: 283711) +MultiOCR3Base_setOCR3Configs:test_RepeatTransmitterAddress_Revert() (gas: 422848) +MultiOCR3Base_setOCR3Configs:test_SetConfigIgnoreSigners_Success() (gas: 511694) +MultiOCR3Base_setOCR3Configs:test_SetConfigWithSigners_Success() (gas: 829593) +MultiOCR3Base_setOCR3Configs:test_SetConfigWithoutSigners_Success() (gas: 457446) +MultiOCR3Base_setOCR3Configs:test_SetConfigsZeroInput_Success() (gas: 12376) +MultiOCR3Base_setOCR3Configs:test_SetMultipleConfigs_Success() (gas: 2143220) +MultiOCR3Base_setOCR3Configs:test_SignerCannotBeZeroAddress_Revert() (gas: 141744) +MultiOCR3Base_setOCR3Configs:test_StaticConfigChange_Revert() (gas: 808478) +MultiOCR3Base_setOCR3Configs:test_TooManySigners_Revert() (gas: 171331) +MultiOCR3Base_setOCR3Configs:test_TooManyTransmitters_Revert() (gas: 30298) +MultiOCR3Base_setOCR3Configs:test_TransmitterCannotBeZeroAddress_Revert() (gas: 254454) +MultiOCR3Base_setOCR3Configs:test_UpdateConfigSigners_Success() (gas: 861521) +MultiOCR3Base_setOCR3Configs:test_UpdateConfigTransmittersWithoutSigners_Success() (gas: 475825) +MultiOCR3Base_transmit:test_ConfigDigestMismatch_Revert() (gas: 42837) +MultiOCR3Base_transmit:test_ForkedChain_Revert() (gas: 48442) +MultiOCR3Base_transmit:test_InsufficientSignatures_Revert() (gas: 76930) +MultiOCR3Base_transmit:test_NonUniqueSignature_Revert() (gas: 66127) +MultiOCR3Base_transmit:test_SignatureOutOfRegistration_Revert() (gas: 33419) +MultiOCR3Base_transmit:test_TooManySignatures_Revert() (gas: 79521) +MultiOCR3Base_transmit:test_TransmitSigners_gas_Success() (gas: 34131) +MultiOCR3Base_transmit:test_TransmitWithExtraCalldataArgs_Revert() (gas: 47114) +MultiOCR3Base_transmit:test_TransmitWithLessCalldataArgs_Revert() (gas: 25682) +MultiOCR3Base_transmit:test_TransmitWithoutSignatureVerification_gas_Success() (gas: 18726) +MultiOCR3Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 24191) +MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61409) +MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39890) +MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32973) +MultiRampsE2E:test_E2E_3MessagesSuccess_gas() (gas: 1412493) +NonceManagerTest_getIncrementedOutboundNonce:test_getIncrementedOutboundNonce_Success() (gas: 40392) +NonceManager_applyPreviousRampsUpdates:test_MultipleRampsUpdates() (gas: 68976) +NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOnRamp_Revert() (gas: 38712) +NonceManager_applyPreviousRampsUpdates:test_SingleRampUpdate() (gas: 39566) +NonceManager_applyPreviousRampsUpdates:test_ZeroInput() (gas: 12007) +NonceManager_onRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 176954) +NonceManager_onRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 226403) +NonceManager_onRampUpgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 125961) +NonceManager_onRampUpgrade:test_Upgrade_Success() (gas: 124321) OCR2BaseNoChecks_setOCR2Config:test_FMustBePositive_Revert() (gas: 12171) OCR2BaseNoChecks_setOCR2Config:test_RepeatAddress_Revert() (gas: 42233) OCR2BaseNoChecks_setOCR2Config:test_SetConfigSuccess_gas() (gas: 84124) diff --git a/contracts/gas-snapshots/shared.gas-snapshot b/contracts/gas-snapshots/shared.gas-snapshot index 25e116d7c4..c4660949bd 100644 --- a/contracts/gas-snapshots/shared.gas-snapshot +++ b/contracts/gas-snapshots/shared.gas-snapshot @@ -1,3 +1,12 @@ +AuthorizedCallers_applyAuthorizedCallerUpdates:test_AddAndRemove_Success() (gas: 125205) +AuthorizedCallers_applyAuthorizedCallerUpdates:test_OnlyAdd_Success() (gas: 133100) +AuthorizedCallers_applyAuthorizedCallerUpdates:test_OnlyCallableByOwner_Revert() (gas: 12350) +AuthorizedCallers_applyAuthorizedCallerUpdates:test_OnlyRemove_Success() (gas: 45064) +AuthorizedCallers_applyAuthorizedCallerUpdates:test_RemoveThenAdd_Success() (gas: 57241) +AuthorizedCallers_applyAuthorizedCallerUpdates:test_SkipRemove_Success() (gas: 32121) +AuthorizedCallers_applyAuthorizedCallerUpdates:test_ZeroAddressNotAllowed_Revert() (gas: 64473) +AuthorizedCallers_constructor:test_ZeroAddressNotAllowed_Revert() (gas: 64473) +AuthorizedCallers_constructor:test_constructor_Success() (gas: 720513) BurnMintERC677_approve:testApproveSuccess() (gas: 55512) BurnMintERC677_approve:testInvalidAddressReverts() (gas: 10663) BurnMintERC677_burn:testBasicBurnSuccess() (gas: 173939) diff --git a/contracts/scripts/native_solc_compile_all_ccip b/contracts/scripts/native_solc_compile_all_ccip index 31c4bfff6d..661de2b842 100755 --- a/contracts/scripts/native_solc_compile_all_ccip +++ b/contracts/scripts/native_solc_compile_all_ccip @@ -10,6 +10,7 @@ SOLC_VERSION="0.8.24" OPTIMIZE_RUNS=26000 OPTIMIZE_RUNS_OFFRAMP=18000 OPTIMIZE_RUNS_ONRAMP=3600 +OPTIMIZE_RUNS_MULTI_OFFRAMP=1800 SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" @@ -27,10 +28,14 @@ compileContract () { local optimize_runs=$OPTIMIZE_RUNS case $1 in - "ccip/offRamp/EVM2EVMOffRamp.sol" | "ccip/offRamp/EVM2EVMMultiOffRamp.sol") + "ccip/offRamp/EVM2EVMOffRamp.sol") echo "OffRamp uses $OPTIMIZE_RUNS_OFFRAMP optimizer runs." optimize_runs=$OPTIMIZE_RUNS_OFFRAMP ;; + "ccip/offRamp/EVM2EVMMultiOffRamp.sol") + echo "MultiOffRamp uses $OPTIMIZE_RUNS_MULTI_OFFRAMP optimizer runs." + optimize_runs=$OPTIMIZE_RUNS_MULTI_OFFRAMP + ;; "ccip/onRamp/EVM2EVMMultiOnRamp.sol" | "ccip/onRamp/EVM2EVMOnRamp.sol") echo "OnRamp uses $OPTIMIZE_RUNS_ONRAMP optimizer runs." optimize_runs=$OPTIMIZE_RUNS_ONRAMP @@ -70,6 +75,7 @@ compileContract ccip/RMN.sol compileContract ccip/ARMProxy.sol compileContract ccip/tokenAdminRegistry/TokenAdminRegistry.sol compileContract ccip/tokenAdminRegistry/RegistryModuleOwnerCustom.sol +compileContract ccip/capability/CCIPCapabilityConfiguration.sol # Test helpers compileContract ccip/test/helpers/BurnMintERC677Helper.sol diff --git a/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol b/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol index cfe2a6d15f..3cdb3d7be4 100644 --- a/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol +++ b/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.24; import {IMessageInterceptor} from "./interfaces/IMessageInterceptor.sol"; import {IPriceRegistry} from "./interfaces/IPriceRegistry.sol"; -import {OwnerIsCreator} from "./../shared/access/OwnerIsCreator.sol"; +import {AuthorizedCallers} from "../shared/access/AuthorizedCallers.sol"; import {EnumerableMapAddresses} from "./../shared/enumerable/EnumerableMapAddresses.sol"; import {Client} from "./libraries/Client.sol"; import {RateLimiter} from "./libraries/RateLimiter.sol"; @@ -17,23 +17,19 @@ import {EnumerableSet} from "./../vendor/openzeppelin-solidity/v4.7.3/contracts/ /// token transfers, using a price registry to convert to a numeraire asset (e.g. USD). /// The contract is a standalone multi-lane message validator contract, which can be called by authorized /// ramp contracts to apply rate limit changes to lanes, and revert when the rate limits get breached. -contract MultiAggregateRateLimiter is IMessageInterceptor, OwnerIsCreator { +contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers { using RateLimiter for RateLimiter.TokenBucket; using USDPriceWith18Decimals for uint224; using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytes32Map; using EnumerableSet for EnumerableSet.AddressSet; - error UnauthorizedCaller(address caller); error PriceNotFoundForToken(address token); - error ZeroAddressNotAllowed(); error ZeroChainSelectorNotAllowed(); - event RateLimiterConfigUpdated(uint64 indexed remoteChainSelector, bool isOutgoingLane, RateLimiter.Config config); + event RateLimiterConfigUpdated(uint64 indexed remoteChainSelector, bool isOutboundLane, RateLimiter.Config config); event PriceRegistrySet(address newPriceRegistry); event TokenAggregateRateLimitAdded(uint64 remoteChainSelector, bytes32 remoteToken, address localToken); event TokenAggregateRateLimitRemoved(uint64 remoteChainSelector, address localToken); - event AuthorizedCallerAdded(address caller); - event AuthorizedCallerRemoved(address caller); /// @notice RemoteRateLimitToken struct containing the local token address with the chain selector /// The struct is used for removals and updates, since the local -> remote token mappings are scoped per-chain @@ -48,23 +44,17 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, OwnerIsCreator { bytes32 remoteToken; // Token on the remote chain (for OnRamp - dest, of OffRamp - source) } - /// @notice Update args for changing the authorized callers - struct AuthorizedCallerArgs { - address[] addedCallers; - address[] removedCallers; - } - /// @notice Update args for a single rate limiter config update struct RateLimiterConfigArgs { uint64 remoteChainSelector; // ────╮ Chain selector to set config for - bool isOutgoingLane; // ───────────╯ If set to true, represents the outgoing message lane (OnRamp), and the incoming message lane otherwise (OffRamp) + bool isOutboundLane; // ───────────╯ If set to true, represents the outbound message lane (OnRamp), and the inbound message lane otherwise (OffRamp) RateLimiter.Config rateLimiterConfig; // Rate limiter config to set } /// @notice Struct to store rate limit token buckets for both lane directions struct RateLimiterBuckets { - RateLimiter.TokenBucket incomingLaneBucket; // Bucket for the incoming lane (remote -> local) - RateLimiter.TokenBucket outgoingLaneBucket; // Bucket for the outgoing lane (local -> remote) + RateLimiter.TokenBucket inboundLaneBucket; // Bucket for the inbound lane (remote -> local) + RateLimiter.TokenBucket outboundLaneBucket; // Bucket for the outbound lane (local -> remote) } /// @dev Tokens that should be included in Aggregate Rate Limiting (from local chain (this chain) -> remote), @@ -72,30 +62,20 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, OwnerIsCreator { mapping(uint64 remoteChainSelector => EnumerableMapAddresses.AddressToBytes32Map tokensLocalToRemote) internal s_rateLimitedTokensLocalToRemote; - /// @dev Set of callers that can call the validation functions (this is required since the validations modify state) - EnumerableSet.AddressSet internal s_authorizedCallers; - /// @notice The address of the PriceRegistry used to query token values for ratelimiting address internal s_priceRegistry; - /// @notice Rate limiter token bucket states per chain, with separate buckets for incoming and outgoing lanes. + /// @notice Rate limiter token bucket states per chain, with separate buckets for inbound and outbound lanes. mapping(uint64 remoteChainSelector => RateLimiterBuckets buckets) internal s_rateLimitersByChainSelector; /// @param priceRegistry the price registry to set /// @param authorizedCallers the authorized callers to set - constructor(address priceRegistry, address[] memory authorizedCallers) { + constructor(address priceRegistry, address[] memory authorizedCallers) AuthorizedCallers(authorizedCallers) { _setPriceRegistry(priceRegistry); - _applyAuthorizedCallerUpdates( - AuthorizedCallerArgs({addedCallers: authorizedCallers, removedCallers: new address[](0)}) - ); } /// @inheritdoc IMessageInterceptor - function onIncomingMessage(Client.Any2EVMMessage memory message) external { - if (!s_authorizedCallers.contains(msg.sender)) { - revert UnauthorizedCaller(msg.sender); - } - + function onInboundMessage(Client.Any2EVMMessage memory message) external onlyAuthorizedCallers { uint64 remoteChainSelector = message.sourceChainSelector; RateLimiter.TokenBucket storage tokenBucket = _getTokenBucket(remoteChainSelector, false); @@ -114,23 +94,23 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, OwnerIsCreator { } /// @inheritdoc IMessageInterceptor - function onOutgoingMessage(Client.EVM2AnyMessage memory message, uint64 destChainSelector) external { - // TODO: to be implemented (assuming the same rate limiter states are shared for incoming and outgoing messages) + function onOutboundMessage(Client.EVM2AnyMessage memory message, uint64 destChainSelector) external { + // TODO: to be implemented (assuming the same rate limiter states are shared for inbound and outbound messages) } /// @param remoteChainSelector chain selector to retrieve token bucket for - /// @param isOutgoingLane if set to true, fetches the bucket for the outgoing message lane (OnRamp). - /// Otherwise fetches for the incoming message lane (OffRamp). + /// @param isOutboundLane if set to true, fetches the bucket for the outbound message lane (OnRamp). + /// Otherwise fetches for the inbound message lane (OffRamp). /// @return bucket Storage pointer to the token bucket representing a specific lane function _getTokenBucket( uint64 remoteChainSelector, - bool isOutgoingLane + bool isOutboundLane ) internal view returns (RateLimiter.TokenBucket storage) { RateLimiterBuckets storage rateLimiterBuckets = s_rateLimitersByChainSelector[remoteChainSelector]; - if (isOutgoingLane) { - return rateLimiterBuckets.outgoingLaneBucket; + if (isOutboundLane) { + return rateLimiterBuckets.outboundLaneBucket; } else { - return rateLimiterBuckets.incomingLaneBucket; + return rateLimiterBuckets.inboundLaneBucket; } } @@ -146,15 +126,15 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, OwnerIsCreator { /// @notice Gets the token bucket with its values for the block it was requested at. /// @param remoteChainSelector chain selector to retrieve state for - /// @param isOutgoingLane if set to true, fetches the rate limit state for the outgoing message lane (OnRamp). - /// Otherwise fetches for the incoming message lane (OffRamp). - /// The outgoing and incoming message rate limit state is completely separated. + /// @param isOutboundLane if set to true, fetches the rate limit state for the outbound message lane (OnRamp). + /// Otherwise fetches for the inbound message lane (OffRamp). + /// The outbound and inbound message rate limit state is completely separated. /// @return The token bucket. function currentRateLimiterState( uint64 remoteChainSelector, - bool isOutgoingLane + bool isOutboundLane ) external view returns (RateLimiter.TokenBucket memory) { - return _getTokenBucket(remoteChainSelector, isOutgoingLane)._currentTokenBucketState(); + return _getTokenBucket(remoteChainSelector, isOutboundLane)._currentTokenBucketState(); } /// @notice Applies the provided rate limiter config updates. @@ -170,9 +150,9 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, OwnerIsCreator { revert ZeroChainSelectorNotAllowed(); } - bool isOutgoingLane = updateArgs.isOutgoingLane; + bool isOutboundLane = updateArgs.isOutboundLane; - RateLimiter.TokenBucket storage tokenBucket = _getTokenBucket(remoteChainSelector, isOutgoingLane); + RateLimiter.TokenBucket storage tokenBucket = _getTokenBucket(remoteChainSelector, isOutboundLane); if (tokenBucket.lastUpdated == 0) { // Token bucket needs to be newly added @@ -184,15 +164,15 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, OwnerIsCreator { isEnabled: configUpdate.isEnabled }); - if (isOutgoingLane) { - s_rateLimitersByChainSelector[remoteChainSelector].outgoingLaneBucket = newTokenBucket; + if (isOutboundLane) { + s_rateLimitersByChainSelector[remoteChainSelector].outboundLaneBucket = newTokenBucket; } else { - s_rateLimitersByChainSelector[remoteChainSelector].incomingLaneBucket = newTokenBucket; + s_rateLimitersByChainSelector[remoteChainSelector].inboundLaneBucket = newTokenBucket; } } else { tokenBucket._setTokenBucketConfig(configUpdate); } - emit RateLimiterConfigUpdated(remoteChainSelector, isOutgoingLane, configUpdate); + emit RateLimiterConfigUpdated(remoteChainSelector, isOutboundLane, configUpdate); } } @@ -276,44 +256,4 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, OwnerIsCreator { s_priceRegistry = newPriceRegistry; emit PriceRegistrySet(newPriceRegistry); } - - // ================================================================ - // │ Access │ - // ================================================================ - - /// @return authorizedCallers Returns all callers that are authorized to call the validation functions - function getAllAuthorizedCallers() external view returns (address[] memory) { - return s_authorizedCallers.values(); - } - - /// @notice Updates the callers that are authorized to call the message validation functions - /// @param authorizedCallerArgs Callers to add and remove - function applyAuthorizedCallerUpdates(AuthorizedCallerArgs memory authorizedCallerArgs) external onlyOwner { - _applyAuthorizedCallerUpdates(authorizedCallerArgs); - } - - /// @notice Updates the callers that are authorized to call the message validation functions - /// @param authorizedCallerArgs Callers to add and remove - function _applyAuthorizedCallerUpdates(AuthorizedCallerArgs memory authorizedCallerArgs) internal { - address[] memory removedCallers = authorizedCallerArgs.removedCallers; - for (uint256 i = 0; i < removedCallers.length; ++i) { - address caller = removedCallers[i]; - - if (s_authorizedCallers.remove(caller)) { - emit AuthorizedCallerRemoved(caller); - } - } - - address[] memory addedCallers = authorizedCallerArgs.addedCallers; - for (uint256 i = 0; i < addedCallers.length; ++i) { - address caller = addedCallers[i]; - - if (caller == address(0)) { - revert ZeroAddressNotAllowed(); - } - - s_authorizedCallers.add(caller); - emit AuthorizedCallerAdded(caller); - } - } } diff --git a/contracts/src/v0.8/ccip/NonceManager.sol b/contracts/src/v0.8/ccip/NonceManager.sol new file mode 100644 index 0000000000..96e5fd03e4 --- /dev/null +++ b/contracts/src/v0.8/ccip/NonceManager.sol @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IEVM2AnyOnRamp} from "./interfaces/IEVM2AnyOnRamp.sol"; +import {INonceManager} from "./interfaces/INonceManager.sol"; + +import {AuthorizedCallers} from "../shared/access/AuthorizedCallers.sol"; + +/// @title NonceManager +/// @notice NonceManager contract that manages sender nonces for the on/off ramps +contract NonceManager is INonceManager, AuthorizedCallers { + error PreviousRampAlreadySet(); + + event PreviousOnRampUpdated(uint64 indexed destChainSelector, address prevOnRamp); + + /// @dev Struct that contains the previous on/off ramp addresses + // TODO: add prevOffRamp + struct PreviousRamps { + address prevOnRamp; // Previous onRamp + } + + /// @dev Struct that contains the chain selector and the previous on/off ramps, same as PreviousRamps but with the chain selector + /// so that an array of these can be passed to the applyPreviousRampsUpdates function + struct PreviousRampsArgs { + uint64 remoteChainSelector; // Chain selector + PreviousRamps prevRamps; // Previous on/off ramps + } + + /// @dev previous ramps + mapping(uint64 chainSelector => PreviousRamps previousRamps) private s_previousRamps; + /// @dev The current outbound nonce per sender used on the onramp + mapping(uint64 destChainSelector => mapping(address sender => uint64 outboundNonce)) private s_outboundNonces; + + constructor(address[] memory authorizedCallers) AuthorizedCallers(authorizedCallers) {} + + /// @inheritdoc INonceManager + function getIncrementedOutboundNonce( + uint64 destChainSelector, + address sender + ) external onlyAuthorizedCallers returns (uint64) { + uint64 outboundNonce = _getOutboundNonce(destChainSelector, sender) + 1; + s_outboundNonces[destChainSelector][sender] = outboundNonce; + + return outboundNonce; + } + + /// TODO: add incrementInboundNonce + + /// @notice Returns the outbound nonce for the given sender on the given destination chain + /// @param destChainSelector The destination chain selector + /// @param sender The sender address + /// @return The outbound nonce + function getOutboundNonce(uint64 destChainSelector, address sender) external view returns (uint64) { + return _getOutboundNonce(destChainSelector, sender); + } + + function _getOutboundNonce(uint64 destChainSelector, address sender) private view returns (uint64) { + uint64 outboundNonce = s_outboundNonces[destChainSelector][sender]; + + if (outboundNonce == 0) { + address prevOnRamp = s_previousRamps[destChainSelector].prevOnRamp; + if (prevOnRamp != address(0)) { + return IEVM2AnyOnRamp(prevOnRamp).getSenderNonce(sender); + } + } + + return outboundNonce; + } + + /// TODO: add getInboundNonce + + /// @notice Updates the previous ramps addresses + /// @param previousRampsArgs The previous on/off ramps addresses + function applyPreviousRampsUpdates(PreviousRampsArgs[] calldata previousRampsArgs) external onlyOwner { + for (uint256 i = 0; i < previousRampsArgs.length; ++i) { + PreviousRampsArgs calldata previousRampsArg = previousRampsArgs[i]; + + PreviousRamps storage prevRamps = s_previousRamps[previousRampsArg.remoteChainSelector]; + + // If the previous onRamp is already set then it should not be updated + if (prevRamps.prevOnRamp != address(0)) { + revert PreviousRampAlreadySet(); + } + + prevRamps.prevOnRamp = previousRampsArg.prevRamps.prevOnRamp; + emit PreviousOnRampUpdated(previousRampsArg.remoteChainSelector, prevRamps.prevOnRamp); + } + } + + /// @notice Gets the previous onRamp address for the given chain selector + /// @param chainSelector The chain selector + /// @return The previous onRamp address + function getPreviousRamps(uint64 chainSelector) external view returns (PreviousRamps memory) { + return s_previousRamps[chainSelector]; + } +} diff --git a/contracts/src/v0.8/ccip/capability/CCIPCapabilityConfiguration.sol b/contracts/src/v0.8/ccip/capability/CCIPCapabilityConfiguration.sol new file mode 100644 index 0000000000..45ffe3da78 --- /dev/null +++ b/contracts/src/v0.8/ccip/capability/CCIPCapabilityConfiguration.sol @@ -0,0 +1,497 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ICapabilityConfiguration} from "../../keystone/interfaces/ICapabilityConfiguration.sol"; +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; +import {ICapabilityRegistry} from "./interfaces/ICapabilityRegistry.sol"; + +import {OwnerIsCreator} from "../../shared/access/OwnerIsCreator.sol"; + +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; + +/// @notice CCIPCapabilityConfiguration stores the configuration for the CCIP capability. +/// We have two classes of configuration: chain configuration and DON (in the CapabilityRegistry sense) configuration. +/// Each chain will have a single configuration which includes information like the router address. +/// Each CR DON will have up to four configurations: for each of (commit, exec), one blue and one green configuration. +/// This is done in order to achieve "blue-green" deployments. +contract CCIPCapabilityConfiguration is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator { + using EnumerableSet for EnumerableSet.UintSet; + + /// @notice Emitted when a chain's configuration is set. + /// @param chainSelector The chain selector. + /// @param chainConfig The chain configuration. + event ChainConfigSet(uint64 chainSelector, ChainConfig chainConfig); + + /// @notice Emitted when a chain's configuration is removed. + /// @param chainSelector The chain selector. + event ChainConfigRemoved(uint64 chainSelector); + + error ChainConfigNotSetForChain(uint64 chainSelector); + error NodeNotInRegistry(bytes32 p2pId); + error OnlyCapabilityRegistryCanCall(); + error ChainSelectorNotFound(uint64 chainSelector); + error ChainSelectorNotSet(); + error TooManyOCR3Configs(); + error TooManySigners(); + error TooManyTransmitters(); + error TooManyBootstrapP2PIds(); + error P2PIdsLengthNotMatching(uint256 p2pIdsLength, uint256 signersLength, uint256 transmittersLength); + error NotEnoughTransmitters(uint256 got, uint256 minimum); + error FMustBePositive(); + error FChainMustBePositive(); + error FTooHigh(); + error InvalidPluginType(); + error OfframpAddressCannotBeZero(); + error InvalidConfigLength(uint256 length); + error InvalidConfigStateTransition(ConfigState currentState, ConfigState proposedState); + error NonExistentConfigTransition(); + error WrongConfigCount(uint64 got, uint64 expected); + error WrongConfigDigest(bytes32 got, bytes32 expected); + error WrongConfigDigestBlueGreen(bytes32 got, bytes32 expected); + + /// @notice PluginType indicates the type of plugin that the configuration is for. + /// @param Commit The configuration is for the commit plugin. + /// @param Execution The configuration is for the execution plugin. + enum PluginType { + Commit, + Execution + } + + /// @notice ConfigState indicates the state of the configuration. + /// A DON's configuration always starts out in the "Init" state - this is the starting state. + /// The only valid transition from "Init" is to the "Running" state - this is the first ever configuration. + /// The only valid transition from "Running" is to the "Staging" state - this is a blue/green proposal. + /// The only valid transition from "Staging" is back to the "Running" state - this is a promotion. + /// TODO: explain rollbacks? + enum ConfigState { + Init, + Running, + Staging + } + + /// @notice Chain configuration. + /// Changes to chain configuration are detected out-of-band in plugins and decoded offchain. + struct ChainConfig { + bytes32[] readers; // The P2P IDs of the readers for the chain. These IDs must be registered in the capability registry. + uint8 fChain; // The fault tolerance parameter of the chain. + bytes config; // The chain configuration. This is kept intentionally opaque so as to add fields in the future if needed. + } + + /// @notice Chain configuration information struct used in applyChainConfigUpdates and getAllChainConfigs. + struct ChainConfigInfo { + uint64 chainSelector; + ChainConfig chainConfig; + } + + /// @notice OCR3 configuration. + struct OCR3Config { + PluginType pluginType; // ────────╮ The plugin that the configuration is for. + uint64 chainSelector; // | The (remote) chain that the configuration is for. + uint8 F; // | The "big F" parameter for the role DON. + uint64 offchainConfigVersion; // ─╯ The version of the offchain configuration. + bytes offrampAddress; // The remote chain offramp address. + bytes32[] bootstrapP2PIds; // The bootstrap P2P IDs of the oracles that are part of the role DON. + // len(p2pIds) == len(signers) == len(transmitters) == 3 * F + 1 + // NOTE: indexes matter here! The p2p ID at index i corresponds to the signer at index i and the transmitter at index i. + // This is crucial in order to build the oracle ID <-> peer ID mapping offchain. + bytes32[] p2pIds; // The P2P IDs of the oracles that are part of the role DON. + bytes[] signers; // The onchain signing keys of nodes in the don. + bytes[] transmitters; // The onchain transmitter keys of nodes in the don. + bytes offchainConfig; // The offchain configuration for the OCR3 protocol. Protobuf encoded. + } + + /// @notice OCR3 configuration with metadata, specifically the config count and the config digest. + struct OCR3ConfigWithMeta { + OCR3Config config; // The OCR3 configuration. + uint64 configCount; // The config count used to compute the config digest. + bytes32 configDigest; // The config digest of the OCR3 configuration. + } + + /// @notice Type and version override. + string public constant override typeAndVersion = "CCIPCapabilityConfiguration 1.6.0-dev"; + + /// @notice The canonical capability registry address. + address internal immutable i_capabilityRegistry; + + /// @notice chain configuration for each chain that CCIP is deployed on. + mapping(uint64 chainSelector => ChainConfig chainConfig) internal s_chainConfigurations; + + /// @notice All chains that are configured. + EnumerableSet.UintSet internal s_remoteChainSelectors; + + /// @notice OCR3 configurations for each DON. + /// Each CR DON will have a commit and execution configuration. + /// This means that a DON can have up to 4 configurations, since we are implementing blue/green deployments. + mapping(uint32 donId => mapping(PluginType pluginType => OCR3ConfigWithMeta[] ocr3Configs)) internal s_ocr3Configs; + + /// @notice The DONs that have been configured. + EnumerableSet.UintSet internal s_donIds; + + uint8 internal constant MAX_OCR3_CONFIGS_PER_PLUGIN = 2; + uint8 internal constant MAX_OCR3_CONFIGS_PER_DON = 4; + uint8 internal constant MAX_NUM_ORACLES = 31; + + /// @param capabilityRegistry the canonical capability registry address. + constructor(address capabilityRegistry) { + i_capabilityRegistry = capabilityRegistry; + } + + // ================================================================ + // │ Config Getters │ + // ================================================================ + + /// @notice Returns all the chain configurations. + /// @return The chain configurations. + // TODO: will this eventually hit the RPC max response size limit? + function getAllChainConfigs() external view returns (ChainConfigInfo[] memory) { + uint256[] memory chainSelectors = s_remoteChainSelectors.values(); + ChainConfigInfo[] memory chainConfigs = new ChainConfigInfo[](s_remoteChainSelectors.length()); + for (uint256 i = 0; i < chainSelectors.length; ++i) { + uint64 chainSelector = uint64(chainSelectors[i]); + chainConfigs[i] = + ChainConfigInfo({chainSelector: chainSelector, chainConfig: s_chainConfigurations[chainSelector]}); + } + return chainConfigs; + } + + /// @notice Returns the OCR configuration for the given don ID and plugin type. + /// @param donId The DON ID. + /// @param pluginType The plugin type. + /// @return The OCR3 configurations, up to 2 (blue and green). + function getOCRConfig(uint32 donId, PluginType pluginType) external view returns (OCR3ConfigWithMeta[] memory) { + return s_ocr3Configs[donId][pluginType]; + } + + // ================================================================ + // │ Capability Configuration │ + // ================================================================ + + /// @inheritdoc ICapabilityConfiguration + /// @dev The CCIP capability will fetch the configuration needed directly from this contract. + /// The offchain syncer will call this function, however, so its important that it doesn't revert. + function getCapabilityConfiguration(uint32 /* donId */ ) external pure override returns (bytes memory configuration) { + return bytes(""); + } + + /// @notice Called by the registry prior to the config being set for a particular DON. + function beforeCapabilityConfigSet( + bytes32[] calldata, /* nodes */ + bytes calldata config, + uint64, /* configCount */ + uint32 donId + ) external override { + if (msg.sender != i_capabilityRegistry) { + revert OnlyCapabilityRegistryCanCall(); + } + + OCR3Config[] memory ocr3Configs = abi.decode(config, (OCR3Config[])); + (OCR3Config[] memory commitConfigs, OCR3Config[] memory execConfigs) = _groupByPluginType(ocr3Configs); + if (commitConfigs.length > 0) { + _updatePluginConfig(donId, PluginType.Commit, commitConfigs); + } + if (execConfigs.length > 0) { + _updatePluginConfig(donId, PluginType.Execution, execConfigs); + } + } + + function _updatePluginConfig(uint32 donId, PluginType pluginType, OCR3Config[] memory newConfig) internal { + OCR3ConfigWithMeta[] memory currentConfig = s_ocr3Configs[donId][pluginType]; + + // Validate the state transition being proposed, which is implicitly defined by the combination + // of lengths of the current and new configurations. + ConfigState currentState = _stateFromConfigLength(currentConfig.length); + ConfigState proposedState = _stateFromConfigLength(newConfig.length); + _validateConfigStateTransition(currentState, proposedState); + + // Build the new configuration with metadata and validate that the transition is valid. + OCR3ConfigWithMeta[] memory newConfigWithMeta = + _computeNewConfigWithMeta(donId, currentConfig, newConfig, currentState, proposedState); + _validateConfigTransition(currentConfig, newConfigWithMeta); + + // Update contract state with new configuration if its valid. + // We won't run out of gas from this delete since the array is at most 2 elements long. + delete s_ocr3Configs[donId][pluginType]; + for (uint256 i = 0; i < newConfigWithMeta.length; ++i) { + s_ocr3Configs[donId][pluginType].push(newConfigWithMeta[i]); + } + } + + // ================================================================ + // │ Config State Machine │ + // ================================================================ + + /// @notice Determine the config state of the configuration from the length of the config. + /// @param configLen The length of the configuration. + /// @return The config state. + function _stateFromConfigLength(uint256 configLen) internal pure returns (ConfigState) { + if (configLen > 2) { + revert InvalidConfigLength(configLen); + } + return ConfigState(configLen); + } + + // the only valid state transitions are the following: + // init -> running (first ever config) + // running -> staging (blue/green proposal) + // staging -> running (promotion) + // everything else is invalid and should revert. + function _validateConfigStateTransition(ConfigState currentState, ConfigState newState) internal pure { + // TODO: may be able to save gas if we put this in the if condition. + bool initToRunning = currentState == ConfigState.Init && newState == ConfigState.Running; + bool runningToStaging = currentState == ConfigState.Running && newState == ConfigState.Staging; + bool stagingToRunning = currentState == ConfigState.Staging && newState == ConfigState.Running; + if (initToRunning || runningToStaging || stagingToRunning) { + return; + } + revert InvalidConfigStateTransition(currentState, newState); + } + + function _validateConfigTransition( + OCR3ConfigWithMeta[] memory currentConfig, + OCR3ConfigWithMeta[] memory newConfigWithMeta + ) internal pure { + uint256 currentConfigLen = currentConfig.length; + uint256 newConfigLen = newConfigWithMeta.length; + if (currentConfigLen == 0 && newConfigLen == 1) { + // Config counts always must start at 1 for the first ever config. + if (newConfigWithMeta[0].configCount != 1) { + revert WrongConfigCount(newConfigWithMeta[0].configCount, 1); + } + return; + } + + if (currentConfigLen == 1 && newConfigLen == 2) { + // On a blue/green proposal: + // * the config digest of the blue config must remain unchanged. + // * the green config count must be the blue config count + 1. + if (newConfigWithMeta[0].configDigest != currentConfig[0].configDigest) { + revert WrongConfigDigestBlueGreen(newConfigWithMeta[0].configDigest, currentConfig[0].configDigest); + } + if (newConfigWithMeta[1].configCount != currentConfig[0].configCount + 1) { + revert WrongConfigCount(newConfigWithMeta[1].configCount, currentConfig[0].configCount + 1); + } + return; + } + + if (currentConfigLen == 2 && newConfigLen == 1) { + // On a promotion, the green config digest must become the blue config digest. + if (newConfigWithMeta[0].configDigest != currentConfig[1].configDigest) { + revert WrongConfigDigest(newConfigWithMeta[0].configDigest, currentConfig[1].configDigest); + } + return; + } + + revert NonExistentConfigTransition(); + } + + /// @notice Computes a new configuration with metadata based on the current configuration and the new configuration. + /// @param donId The DON ID. + /// @param currentConfig The current configuration, including metadata. + /// @param newConfig The new configuration, without metadata. + /// @param currentState The current state of the configuration. + /// @param newState The new state of the configuration. + /// @return The new configuration with metadata. + function _computeNewConfigWithMeta( + uint32 donId, + OCR3ConfigWithMeta[] memory currentConfig, + OCR3Config[] memory newConfig, + ConfigState currentState, + ConfigState newState + ) internal view returns (OCR3ConfigWithMeta[] memory) { + uint64[] memory configCounts = new uint64[](newConfig.length); + + // Set config counts based on the only valid state transitions. + // Init -> Running (first ever config) + // Running -> Staging (blue/green proposal) + // Staging -> Running (promotion) + if (currentState == ConfigState.Init && newState == ConfigState.Running) { + // First ever config starts with config count == 1. + configCounts[0] = 1; + } else if (currentState == ConfigState.Running && newState == ConfigState.Staging) { + // On a blue/green proposal, the config count of the green config is the blue config count + 1. + configCounts[0] = currentConfig[0].configCount; + configCounts[1] = currentConfig[0].configCount + 1; + } else if (currentState == ConfigState.Staging && newState == ConfigState.Running) { + // On a promotion, the config count of the green config becomes the blue config count. + configCounts[0] = currentConfig[1].configCount; + } else { + revert InvalidConfigStateTransition(currentState, newState); + } + + OCR3ConfigWithMeta[] memory newConfigWithMeta = new OCR3ConfigWithMeta[](newConfig.length); + for (uint256 i = 0; i < configCounts.length; ++i) { + _validateConfig(newConfig[i]); + newConfigWithMeta[i] = OCR3ConfigWithMeta({ + config: newConfig[i], + configCount: configCounts[i], + configDigest: _computeConfigDigest(donId, configCounts[i], newConfig[i]) + }); + } + + return newConfigWithMeta; + } + + /// @notice Group the OCR3 configurations by plugin type for further processing. + /// @param ocr3Configs The OCR3 configurations to group. + function _groupByPluginType(OCR3Config[] memory ocr3Configs) + internal + pure + returns (OCR3Config[] memory commitConfigs, OCR3Config[] memory execConfigs) + { + if (ocr3Configs.length > MAX_OCR3_CONFIGS_PER_DON) { + revert TooManyOCR3Configs(); + } + + // Declare with size 2 since we have a maximum of two configs per plugin type (blue, green). + // If we have less we will adjust the length later using mstore. + // If the caller provides more than 2 configs per plugin type, we will revert due to out of bounds + // access in the for loop below. + commitConfigs = new OCR3Config[](MAX_OCR3_CONFIGS_PER_PLUGIN); + execConfigs = new OCR3Config[](MAX_OCR3_CONFIGS_PER_PLUGIN); + uint256 commitCount; + uint256 execCount; + for (uint256 i = 0; i < ocr3Configs.length; ++i) { + if (ocr3Configs[i].pluginType == PluginType.Commit) { + commitConfigs[commitCount] = ocr3Configs[i]; + ++commitCount; + } else { + execConfigs[execCount] = ocr3Configs[i]; + ++execCount; + } + } + + // Adjust the length of the arrays to the actual number of configs. + assembly { + mstore(commitConfigs, commitCount) + mstore(execConfigs, execCount) + } + + return (commitConfigs, execConfigs); + } + + function _validateConfig(OCR3Config memory cfg) internal view { + if (cfg.chainSelector == 0) revert ChainSelectorNotSet(); + if (cfg.pluginType != PluginType.Commit && cfg.pluginType != PluginType.Execution) revert InvalidPluginType(); + // TODO: can we do more sophisticated validation than this? + if (cfg.offrampAddress.length == 0) revert OfframpAddressCannotBeZero(); + if (!s_remoteChainSelectors.contains(cfg.chainSelector)) revert ChainSelectorNotFound(cfg.chainSelector); + + // Some of these checks below are done in OCR2/3Base config validation, so we do them again here. + // Role DON OCR configs will have all the Role DON signers but only a subset of transmitters. + if (cfg.signers.length > MAX_NUM_ORACLES) revert TooManySigners(); + if (cfg.transmitters.length > MAX_NUM_ORACLES) revert TooManyTransmitters(); + + // We check for chain config presence above, so fChain here must be non-zero. + uint256 minTransmittersLength = 3 * s_chainConfigurations[cfg.chainSelector].fChain + 1; + if (cfg.transmitters.length < minTransmittersLength) { + revert NotEnoughTransmitters(cfg.transmitters.length, minTransmittersLength); + } + if (cfg.F == 0) revert FMustBePositive(); + if (cfg.signers.length <= 3 * cfg.F) revert FTooHigh(); + + if (cfg.p2pIds.length != cfg.signers.length || cfg.p2pIds.length != cfg.transmitters.length) { + revert P2PIdsLengthNotMatching(cfg.p2pIds.length, cfg.signers.length, cfg.transmitters.length); + } + if (cfg.bootstrapP2PIds.length > cfg.p2pIds.length) revert TooManyBootstrapP2PIds(); + + // Check that the readers are in the capability registry. + // TODO: check for duplicate signers, duplicate p2p ids, etc. + // TODO: check that p2p ids in cfg.bootstrapP2PIds are included in cfg.p2pIds. + for (uint256 i = 0; i < cfg.signers.length; ++i) { + _ensureInRegistry(cfg.p2pIds[i]); + } + } + + /// @notice Computes the digest of the provided configuration. + /// @dev In traditional OCR config digest computation, block.chainid and address(this) are used + /// in order to further domain separate the digest. We can't do that here since the digest will + /// be used on remote chains; so we use the chain selector instead of block.chainid. The don ID + /// replaces the address(this) in the traditional computation. + /// @param donId The DON ID. + /// @param configCount The configuration count. + /// @param ocr3Config The OCR3 configuration. + /// @return The computed digest. + function _computeConfigDigest( + uint32 donId, + uint64 configCount, + OCR3Config memory ocr3Config + ) internal pure returns (bytes32) { + uint256 h = uint256( + keccak256( + abi.encode( + ocr3Config.chainSelector, + donId, + ocr3Config.pluginType, + ocr3Config.offrampAddress, + configCount, + ocr3Config.bootstrapP2PIds, + ocr3Config.p2pIds, + ocr3Config.signers, + ocr3Config.transmitters, + ocr3Config.F, + ocr3Config.offchainConfigVersion, + ocr3Config.offchainConfig + ) + ) + ); + uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 + uint256 prefix = 0x000a << (256 - 16); // 0x000a00..00 + return bytes32((prefix & prefixMask) | (h & ~prefixMask)); + } + + // ================================================================ + // │ Chain Configuration │ + // ================================================================ + + /// @notice Sets and/or removes chain configurations. + /// @param chainSelectorRemoves The chain configurations to remove. + /// @param chainConfigAdds The chain configurations to add. + function applyChainConfigUpdates( + uint64[] calldata chainSelectorRemoves, + ChainConfigInfo[] calldata chainConfigAdds + ) external onlyOwner { + // Process removals first. + for (uint256 i = 0; i < chainSelectorRemoves.length; ++i) { + // check if the chain selector is in s_remoteChainSelectors first. + if (!s_remoteChainSelectors.contains(chainSelectorRemoves[i])) { + revert ChainSelectorNotFound(chainSelectorRemoves[i]); + } + + delete s_chainConfigurations[chainSelectorRemoves[i]]; + s_remoteChainSelectors.remove(chainSelectorRemoves[i]); + + emit ChainConfigRemoved(chainSelectorRemoves[i]); + } + + // Process additions next. + for (uint256 i = 0; i < chainConfigAdds.length; ++i) { + ChainConfig memory chainConfig = chainConfigAdds[i].chainConfig; + bytes32[] memory readers = chainConfig.readers; + uint64 chainSelector = chainConfigAdds[i].chainSelector; + + // Verify that the provided readers are present in the capability registry. + for (uint256 j = 0; j < readers.length; j++) { + _ensureInRegistry(readers[j]); + } + + // Verify that fChain is positive. + if (chainConfig.fChain == 0) { + revert FChainMustBePositive(); + } + + s_chainConfigurations[chainSelector] = chainConfig; + s_remoteChainSelectors.add(chainSelector); + + emit ChainConfigSet(chainSelector, chainConfig); + } + } + + /// @notice Helper function to ensure that a node is in the capability registry. + /// @param p2pId The P2P ID of the node to check. + function _ensureInRegistry(bytes32 p2pId) internal view { + (ICapabilityRegistry.NodeInfo memory node,) = ICapabilityRegistry(i_capabilityRegistry).getNode(p2pId); + if (node.p2pId == bytes32("")) { + revert NodeNotInRegistry(p2pId); + } + } +} diff --git a/contracts/src/v0.8/ccip/capability/interfaces/ICapabilityRegistry.sol b/contracts/src/v0.8/ccip/capability/interfaces/ICapabilityRegistry.sol new file mode 100644 index 0000000000..85a98843c6 --- /dev/null +++ b/contracts/src/v0.8/ccip/capability/interfaces/ICapabilityRegistry.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +interface ICapabilityRegistry { + struct NodeInfo { + /// @notice The id of the node operator that manages this node + uint32 nodeOperatorId; + /// @notice The signer address for application-layer message verification. + bytes32 signer; + /// @notice This is an Ed25519 public key that is used to identify a node. + /// This key is guaranteed to be unique in the CapabilityRegistry. It is + /// used to identify a node in the the P2P network. + bytes32 p2pId; + /// @notice The list of hashed capability IDs supported by the node + bytes32[] hashedCapabilityIds; + } + + /// @notice Gets a node's data + /// @param p2pId The P2P ID of the node to query for + /// @return NodeInfo The node data + /// @return configCount The number of times the node has been configured + function getNode(bytes32 p2pId) external view returns (NodeInfo memory, uint32 configCount); +} diff --git a/contracts/src/v0.8/ccip/interfaces/IEVM2AnyMultiOnRamp.sol b/contracts/src/v0.8/ccip/interfaces/IEVM2AnyMultiOnRamp.sol deleted file mode 100644 index 3c76502d85..0000000000 --- a/contracts/src/v0.8/ccip/interfaces/IEVM2AnyMultiOnRamp.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {IEVM2AnyOnRampClient} from "./IEVM2AnyOnRampClient.sol"; - -interface IEVM2AnyMultiOnRamp is IEVM2AnyOnRampClient { - /// @notice Gets the next sequence number to be used in the onRamp - /// @param destChainSelector The destination chain selector - /// @return the next sequence number to be used - function getExpectedNextSequenceNumber(uint64 destChainSelector) external view returns (uint64); - - /// @notice Returns the current nonce for a sender - /// @param destChainSelector The destination chain selector - /// @param sender The sender address - /// @return The sender's nonce - function getSenderNonce(uint64 destChainSelector, address sender) external view returns (uint64); -} diff --git a/contracts/src/v0.8/ccip/interfaces/IMessageInterceptor.sol b/contracts/src/v0.8/ccip/interfaces/IMessageInterceptor.sol index cacc276fe0..f8b88265be 100644 --- a/contracts/src/v0.8/ccip/interfaces/IMessageInterceptor.sol +++ b/contracts/src/v0.8/ccip/interfaces/IMessageInterceptor.sol @@ -13,10 +13,10 @@ interface IMessageInterceptor { /// @notice Intercepts & validates the given OffRamp message. Reverts on validation failure /// @param message to validate - function onIncomingMessage(Client.Any2EVMMessage memory message) external; + function onInboundMessage(Client.Any2EVMMessage memory message) external; /// @notice Intercepts & validates the given OnRamp message. Reverts on validation failure /// @param message to validate /// @param destChainSelector remote destination chain selector where the message is being sent to - function onOutgoingMessage(Client.EVM2AnyMessage memory message, uint64 destChainSelector) external; + function onOutboundMessage(Client.EVM2AnyMessage memory message, uint64 destChainSelector) external; } diff --git a/contracts/src/v0.8/ccip/interfaces/INonceManager.sol b/contracts/src/v0.8/ccip/interfaces/INonceManager.sol new file mode 100644 index 0000000000..1e1b915ce0 --- /dev/null +++ b/contracts/src/v0.8/ccip/interfaces/INonceManager.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @notice Contract interface that allows managing sender nonces +interface INonceManager { + /// @notice Increments the outbound nonce for the given sender on the given destination chain + /// @param destChainSelector The destination chain selector + /// @param sender The sender address + /// @return The new outbound nonce + function getIncrementedOutboundNonce(uint64 destChainSelector, address sender) external returns (uint64); +} diff --git a/contracts/src/v0.8/ccip/ocr/MultiOCR3Base.sol b/contracts/src/v0.8/ccip/ocr/MultiOCR3Base.sol index e5a474241b..1872ae276c 100644 --- a/contracts/src/v0.8/ccip/ocr/MultiOCR3Base.sol +++ b/contracts/src/v0.8/ccip/ocr/MultiOCR3Base.sol @@ -4,7 +4,6 @@ pragma solidity ^0.8.0; import {OwnerIsCreator} from "../../shared/access/OwnerIsCreator.sol"; import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; -// TODO: consider splitting configs & verification logic off to auth library (if size is prohibitive) /// @notice Onchain verification of reports from the offchain reporting protocol /// with multiple OCR plugin support. abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { @@ -50,7 +49,6 @@ abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { bytes32 configDigest; uint8 F; // ──────────────────────────────╮ maximum number of faulty/dishonest oracles the system can tolerate uint8 n; // │ number of signers / transmitters - bool uniqueReports; // │ if true, the reports should be unique bool isSignatureVerificationEnabled; // ──╯ if true, requires signers and verifies signatures on transmission verification } @@ -85,7 +83,6 @@ abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { bytes32 configDigest; // Config digest to update to uint8 ocrPluginType; // ──────────────────╮ OCR plugin type to update config for uint8 F; // │ maximum number of faulty/dishonest oracles - bool uniqueReports; // │ if true, the reports should be unique bool isSignatureVerificationEnabled; // ──╯ if true, requires signers and verifies signatures on transmission verification address[] signers; // signing address of each oracle address[] transmitters; // transmission address of each oracle (i.e. the address the oracle actually sends transactions to the contract from) @@ -143,12 +140,8 @@ abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { // If F is 0, then the config is not yet set if (configInfo.F == 0) { - configInfo.uniqueReports = ocrConfigArgs.uniqueReports; configInfo.isSignatureVerificationEnabled = ocrConfigArgs.isSignatureVerificationEnabled; - } else if ( - configInfo.uniqueReports != ocrConfigArgs.uniqueReports - || configInfo.isSignatureVerificationEnabled != ocrConfigArgs.isSignatureVerificationEnabled - ) { + } else if (configInfo.isSignatureVerificationEnabled != ocrConfigArgs.isSignatureVerificationEnabled) { revert StaticConfigCannotBeChanged(ocrPluginType); } @@ -228,15 +221,13 @@ abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { // TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT need to be changed accordingly bytes32[3] calldata reportContext, bytes calldata report, - // TODO: revisit trade-off - converting this to calldata and using one CONSTANT_LENGTH_COMPONENT - // decreases contract size by ~220B, decreasees commit gas usage by ~400 gas, but increases exec gas usage by ~3600 gas bytes32[] memory rs, bytes32[] memory ss, bytes32 rawVs // signatures ) internal { // reportContext consists of: // reportContext[0]: ConfigDigest - // reportContext[1]: 27 byte padding, 4-byte epoch and 1-byte round + // reportContext[1]: 24 byte padding, 8 byte sequence number // reportContext[2]: ExtraHash ConfigInfo memory configInfo = s_ocrConfigs[ocrPluginType].configInfo; bytes32 configDigest = reportContext[0]; @@ -259,7 +250,7 @@ abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { // If the cached chainID at time of deployment doesn't match the current chainID, we reject all signed reports. // This avoids a (rare) scenario where chain A forks into chain A and A', A' still has configDigest // calculated from chain A and so OCR reports will be valid on both forks. - if (i_chainID != block.chainid) revert ForkedChain(i_chainID, block.chainid); + _whenChainNotForked(); // Scoping this reduces stack pressure and gas usage { @@ -278,13 +269,7 @@ abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { if (configInfo.isSignatureVerificationEnabled) { // Scoping to reduce stack pressure { - uint256 expectedNumSignatures; - if (configInfo.uniqueReports) { - expectedNumSignatures = (configInfo.n + configInfo.F) / 2 + 1; - } else { - expectedNumSignatures = configInfo.F + 1; - } - if (rs.length != expectedNumSignatures) revert WrongNumberOfSignatures(); + if (rs.length != configInfo.F + 1) revert WrongNumberOfSignatures(); if (rs.length != ss.length) revert SignaturesOutOfRegistration(); } @@ -292,7 +277,7 @@ abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { _verifySignatures(ocrPluginType, h, rs, ss, rawVs); } - emit Transmitted(ocrPluginType, configDigest, uint32(uint256(reportContext[1]) >> 8)); + emit Transmitted(ocrPluginType, configDigest, uint64(uint256(reportContext[1]))); } /// @notice verifies the signatures of a hashed report value for one OCR plugin type @@ -324,6 +309,11 @@ abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { } } + /// @notice Validates that the chain ID has not diverged after deployment. Reverts if the chain IDs do not match + function _whenChainNotForked() internal view { + if (i_chainID != block.chainid) revert ForkedChain(i_chainID, block.chainid); + } + /// @notice information about current offchain reporting protocol configuration /// @param ocrPluginType OCR plugin type to return config details for /// @return ocrConfig OCR config for the plugin type diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol index c76a26e567..a261c1fc65 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol @@ -36,14 +36,11 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 error AlreadyAttempted(uint64 sourceChainSelector, uint64 sequenceNumber); error AlreadyExecuted(uint64 sourceChainSelector, uint64 sequenceNumber); - error ZeroAddressNotAllowed(); error ZeroChainSelectorNotAllowed(); error ExecutionError(bytes32 messageId, bytes error); error SourceChainNotEnabled(uint64 sourceChainSelector); - error MessageTooLarge(bytes32 messageId, uint256 maxSize, uint256 actualSize); error TokenDataMismatch(uint64 sourceChainSelector, uint64 sequenceNumber); error UnexpectedTokenData(); - error UnsupportedNumberOfTokens(uint64 sourceChainSelector, uint64 sequenceNumber); error ManualExecutionNotYetEnabled(uint64 sourceChainSelector); error ManualExecutionGasLimitMismatch(); error InvalidManualExecutionGasLimit(uint64 sourceChainSelector, uint256 index, uint256 newLimit); @@ -62,10 +59,11 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 error InvalidStaticConfig(uint64 sourceChainSelector); error StaleCommitReport(); error InvalidInterval(uint64 sourceChainSelector, Interval interval); - error PausedError(); + error ZeroAddressNotAllowed(); /// @dev Atlas depends on this event, if changing, please notify Atlas. - event ConfigSet(StaticConfig staticConfig, DynamicConfig dynamicConfig); + event StaticConfigSet(StaticConfig staticConfig); + event DynamicConfigSet(DynamicConfig dynamicConfig); event SkippedIncorrectNonce(uint64 sourceChainSelector, uint64 nonce, address sender); event SkippedSenderWithPreviousRampMessageInflight(uint64 sourceChainSelector, uint64 nonce, address sender); /// @dev RMN depends on this event, if changing, please notify the RMN maintainers. @@ -79,12 +77,10 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 event SourceChainSelectorAdded(uint64 sourceChainSelector); event SourceChainConfigSet(uint64 indexed sourceChainSelector, SourceChainConfig sourceConfig); event SkippedAlreadyExecutedMessage(uint64 sourceChainSelector, uint64 sequenceNumber); - event Paused(address account); - event Unpaused(address account); /// @dev RMN depends on this event, if changing, please notify the RMN maintainers. event CommitReportAccepted(CommitReport report); event RootRemoved(bytes32 root); - event LatestPriceEpochAndRoundSet(uint40 oldEpochAndRound, uint40 newEpochAndRound); + event LatestPriceSequenceNumberSet(uint64 oldSequenceNumber, uint64 newSequenceNumber); /// @notice Static offRamp config /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. @@ -121,19 +117,10 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 uint32 permissionLessExecutionThresholdSeconds; // │ Waiting time before manual execution is enabled uint32 maxTokenTransferGas; // │ Maximum amount of gas passed on to token `transfer` call uint32 maxPoolReleaseOrMintGas; // ─────────────────╯ Maximum amount of gas passed on to token pool when calling releaseOrMint - uint16 maxNumberOfTokensPerMsg; // ──╮ Maximum number of ERC20 token transfers that can be included per message - uint32 maxDataBytes; // │ Maximum payload data size in bytes - address messageValidator; // ────────╯ Optional message validator to validate incoming messages (zero address = no validator) + address messageValidator; // Optional message validator to validate incoming messages (zero address = no validator) address priceRegistry; // Price registry address on the local chain } - /// @notice Struct that represents a message route (sender -> receiver and source chain) - struct Any2EVMMessageRoute { - bytes sender; // Message sender - uint64 sourceChainSelector; // ───╮ Source chain that the message originates from - address receiver; // ─────────────╯ Address that receives the message - } - /// @notice a sequenceNumber interval /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. struct Interval { @@ -175,7 +162,7 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 /// @notice SourceConfig per chain /// (forms lane configurations from sourceChainSelector => StaticConfig.chainSelector) - mapping(uint64 sourceChainSelector => SourceChainConfig) internal s_sourceChainConfigs; + mapping(uint64 sourceChainSelector => SourceChainConfig sourceChainConfig) internal s_sourceChainConfigs; // STATE /// @dev The expected nonce for a given sender per source chain. @@ -191,15 +178,14 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 // sourceChainSelector => merkleRoot => timestamp when received mapping(uint64 sourceChainSelector => mapping(bytes32 merkleRoot => uint256 timestamp)) internal s_roots; - /// @dev The epoch and round of the last report - uint40 private s_latestPriceEpochAndRound; - /// @dev Whether this OffRamp is paused or not - bool private s_paused = false; + /// @dev The sequence number of the last report + uint64 private s_latestPriceSequenceNumber; constructor(StaticConfig memory staticConfig, SourceChainConfigArgs[] memory sourceChainConfigs) MultiOCR3Base() { if (staticConfig.rmnProxy == address(0) || staticConfig.tokenAdminRegistry == address(0)) { revert ZeroAddressNotAllowed(); } + if (staticConfig.chainSelector == 0) { revert ZeroChainSelectorNotAllowed(); } @@ -207,6 +193,7 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 i_chainSelector = staticConfig.chainSelector; i_rmnProxy = staticConfig.rmnProxy; i_tokenAdminRegistry = staticConfig.tokenAdminRegistry; + emit StaticConfigSet(staticConfig); _applySourceChainConfigUpdates(sourceChainConfigs); } @@ -235,7 +222,7 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 ) public view returns (Internal.MessageExecutionState) { return Internal.MessageExecutionState( ( - s_executionStates[sourceChainSelector][sequenceNumber / 128] + _getSequenceNumberBitmap(sourceChainSelector, sequenceNumber) >> ((sequenceNumber % 128) * MESSAGE_EXECUTION_STATE_BIT_WIDTH) ) & MESSAGE_EXECUTION_STATE_MASK ); @@ -252,7 +239,7 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 Internal.MessageExecutionState newState ) internal { uint256 offset = (sequenceNumber % 128) * MESSAGE_EXECUTION_STATE_BIT_WIDTH; - uint256 bitmap = s_executionStates[sourceChainSelector][sequenceNumber / 128]; + uint256 bitmap = _getSequenceNumberBitmap(sourceChainSelector, sequenceNumber); // to unset any potential existing state we zero the bits of the section the state occupies, // then we do an AND operation to blank out any existing state for the section. bitmap &= ~(MESSAGE_EXECUTION_STATE_MASK << offset); @@ -262,6 +249,16 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 s_executionStates[sourceChainSelector][sequenceNumber / 128] = bitmap; } + /// @param sourceChainSelector remote source chain selector to get sequence number bitmap for + /// @param sequenceNumber sequence number to get bitmap for + /// @return bitmap Bitmap of the given sequence number for the provided source chain selector. One bitmap represents 128 sequence numbers + function _getSequenceNumberBitmap( + uint64 sourceChainSelector, + uint64 sequenceNumber + ) internal view returns (uint256 bitmap) { + return s_executionStates[sourceChainSelector][sequenceNumber / 128]; + } + /// @inheritdoc IAny2EVMMultiOffRamp function getSenderNonce(uint64 sourceChainSelector, address sender) external view returns (uint64) { (uint64 nonce,) = _getSenderNonce(sourceChainSelector, sender); @@ -304,8 +301,7 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 uint256[][] memory gasLimitOverrides ) external { // We do this here because the other _execute path is already covered by MultiOCR3Base. - // TODO: contract size golfing - split to internal function - if (i_chainID != block.chainid) revert MultiOCR3Base.ForkedChain(i_chainID, uint64(block.chainid)); + _whenChainNotForked(); uint256 numReports = reports.length; if (numReports != gasLimitOverrides.length) revert ManualExecutionGasLimitMismatch(); @@ -333,19 +329,12 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 /// and expects the exec plugin type to be configured with no signatures. /// @param report serialized execution report function execute(bytes32[3] calldata reportContext, bytes calldata report) external { - _reportExec(report); + _batchExecute(abi.decode(report, (Internal.ExecutionReportSingleChain[])), new uint256[][](0)); - // TODO: gas / contract size saving from CONSTANT? bytes32[] memory emptySigs = new bytes32[](0); _transmit(uint8(Internal.OCRPluginType.Execution), reportContext, report, emptySigs, emptySigs, bytes32("")); } - /// @notice Reporting function for the execution plugin - /// @param encodedReport encoded ExecutionReport - function _reportExec(bytes calldata encodedReport) internal { - _batchExecute(abi.decode(encodedReport, (Internal.ExecutionReportSingleChain[])), new uint256[][](0)); - } - /// @notice Batch executes a set of reports, each report matching one single source chain /// @param reports Set of execution reports (one per chain) containing the messages and proofs /// @param manualExecGasLimits An array of gas limits to use for manual execution @@ -378,18 +367,14 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 uint256[] memory manualExecGasLimits ) internal { uint64 sourceChainSelector = report.sourceChainSelector; - // TODO: re-use isCursed / isUnpaused check from _verify here - if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(sourceChainSelector)))) revert CursedByRMN(sourceChainSelector); + _whenNotCursed(sourceChainSelector); + + SourceChainConfig storage sourceChainConfig = _getEnabledSourceChainConfig(sourceChainSelector); uint256 numMsgs = report.messages.length; if (numMsgs == 0) revert EmptyReport(); if (numMsgs != report.offchainTokenData.length) revert UnexpectedTokenData(); - SourceChainConfig storage sourceChainConfig = s_sourceChainConfigs[sourceChainSelector]; - if (!sourceChainConfig.isEnabled) { - revert SourceChainNotEnabled(sourceChainSelector); - } - bytes32[] memory hashedLeaves = new bytes32[](numMsgs); for (uint256 i = 0; i < numMsgs; ++i) { @@ -483,16 +468,10 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 // Although we expect only valid messages will be committed, we check again // when executing as a defense in depth measure. - // TODO: GAS GOLF - evaluate caching sequenceNumber instead of offchainTokenData bytes[] memory offchainTokenData = report.offchainTokenData[i]; - _isWellFormed( - message.messageId, - sourceChainSelector, - message.sequenceNumber, - message.tokenAmounts.length, - message.data.length, - offchainTokenData.length - ); + if (message.tokenAmounts.length != offchainTokenData.length) { + revert TokenDataMismatch(sourceChainSelector, message.sequenceNumber); + } _setExecutionState(sourceChainSelector, message.sequenceNumber, Internal.MessageExecutionState.IN_PROGRESS); (Internal.MessageExecutionState newState, bytes memory returnData) = _trialExecute(message, offchainTokenData); @@ -529,30 +508,6 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 } } - /// @notice Does basic message validation. Should never fail. - /// @param sequenceNumber Sequence number of the message. - /// @param numberOfTokens Length of tokenAmounts array in the message. - /// @param dataLength Length of data field in the message. - /// @param offchainTokenDataLength Length of offchainTokenData array. - /// @dev reverts on validation failures. - function _isWellFormed( - bytes32 messageId, - uint64 sourceChainSelector, - uint64 sequenceNumber, - uint256 numberOfTokens, - uint256 dataLength, - uint256 offchainTokenDataLength - ) private view { - // TODO: move maxNumberOfTokens & data length validation offchain - if (numberOfTokens > uint256(s_dynamicConfig.maxNumberOfTokensPerMsg)) { - revert UnsupportedNumberOfTokens(sourceChainSelector, sequenceNumber); - } - if (numberOfTokens != offchainTokenDataLength) revert TokenDataMismatch(sourceChainSelector, sequenceNumber); - if (dataLength > uint256(s_dynamicConfig.maxDataBytes)) { - revert MessageTooLarge(messageId, uint256(s_dynamicConfig.maxDataBytes), dataLength); - } - } - /// @notice Try executing a message. /// @param message Internal.EVM2EVMMessage memory message. /// @param offchainTokenData Data provided by the DON for token transfers. @@ -597,11 +552,9 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 if (message.tokenAmounts.length > 0) { destTokenAmounts = _releaseOrMintTokens( message.tokenAmounts, - Any2EVMMessageRoute({ - sender: abi.encode(message.sender), - sourceChainSelector: message.sourceChainSelector, - receiver: message.receiver - }), + abi.encode(message.sender), + message.receiver, + message.sourceChainSelector, message.sourceTokenData, offchainTokenData ); @@ -611,7 +564,7 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 address messageValidator = s_dynamicConfig.messageValidator; if (messageValidator != address(0)) { - try IMessageInterceptor(messageValidator).onIncomingMessage(any2EvmMessage) {} + try IMessageInterceptor(messageValidator).onInboundMessage(any2EvmMessage) {} catch (bytes memory err) { revert IMessageInterceptor.MessageValidationError(err); } @@ -667,79 +620,71 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 bytes32[] calldata ss, bytes32 rawVs // signatures ) external { - _reportCommit(report, uint40(uint256(reportContext[1]))); - _transmit(uint8(Internal.OCRPluginType.Commit), reportContext, report, rs, ss, rawVs); - } - - /// @notice Reporting function for the commit plugin - /// @param encodedReport encoded CommitReport - /// @param epochAndRound Epoch and round of the report - function _reportCommit(bytes calldata encodedReport, uint40 epochAndRound) internal whenNotPaused { - CommitReport memory report = abi.decode(encodedReport, (CommitReport)); + CommitReport memory commitReport = abi.decode(report, (CommitReport)); // Check if the report contains price updates - if (report.priceUpdates.tokenPriceUpdates.length > 0 || report.priceUpdates.gasPriceUpdates.length > 0) { + if (commitReport.priceUpdates.tokenPriceUpdates.length > 0 || commitReport.priceUpdates.gasPriceUpdates.length > 0) + { + uint64 sequenceNumber = uint64(uint256(reportContext[1])); + // Check for price staleness based on the epoch and round - if (s_latestPriceEpochAndRound < epochAndRound) { + if (s_latestPriceSequenceNumber < sequenceNumber) { // If prices are not stale, update the latest epoch and round - s_latestPriceEpochAndRound = epochAndRound; + s_latestPriceSequenceNumber = sequenceNumber; // And update the prices in the price registry - IPriceRegistry(s_dynamicConfig.priceRegistry).updatePrices(report.priceUpdates); - - // If there is no root, the report only contained fee updated and - // we return to not revert on the empty root check below. - if (report.merkleRoots.length == 0) return; + IPriceRegistry(s_dynamicConfig.priceRegistry).updatePrices(commitReport.priceUpdates); } else { // If prices are stale and the report doesn't contain a root, this report // does not have any valid information and we revert. // If it does contain a merkle root, continue to the root checking section. - if (report.merkleRoots.length == 0) revert StaleCommitReport(); + if (commitReport.merkleRoots.length == 0) revert StaleCommitReport(); } } - for (uint256 i = 0; i < report.merkleRoots.length; ++i) { - MerkleRoot memory root = report.merkleRoots[i]; + for (uint256 i = 0; i < commitReport.merkleRoots.length; ++i) { + MerkleRoot memory root = commitReport.merkleRoots[i]; uint64 sourceChainSelector = root.sourceChainSelector; - if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(sourceChainSelector)))) revert CursedByRMN(sourceChainSelector); - - SourceChainConfig storage sourceChainConfig = s_sourceChainConfigs[sourceChainSelector]; + _whenNotCursed(sourceChainSelector); + SourceChainConfig storage sourceChainConfig = _getEnabledSourceChainConfig(sourceChainSelector); - if (!sourceChainConfig.isEnabled) revert SourceChainNotEnabled(sourceChainSelector); // If we reached this section, the report should contain a valid root if (sourceChainConfig.minSeqNr != root.interval.min || root.interval.min > root.interval.max) { revert InvalidInterval(root.sourceChainSelector, root.interval); } // TODO: confirm how RMN offchain blessing impacts commit report - if (root.merkleRoot == bytes32(0)) revert InvalidRoot(); + bytes32 merkleRoot = root.merkleRoot; + if (merkleRoot == bytes32(0)) revert InvalidRoot(); // Disallow duplicate roots as that would reset the timestamp and // delay potential manual execution. - if (s_roots[root.sourceChainSelector][root.merkleRoot] != 0) { - revert RootAlreadyCommitted(root.sourceChainSelector, root.merkleRoot); + if (s_roots[root.sourceChainSelector][merkleRoot] != 0) { + revert RootAlreadyCommitted(root.sourceChainSelector, merkleRoot); } sourceChainConfig.minSeqNr = root.interval.max + 1; - s_roots[root.sourceChainSelector][root.merkleRoot] = block.timestamp; + s_roots[root.sourceChainSelector][merkleRoot] = block.timestamp; } - emit CommitReportAccepted(report); + emit CommitReportAccepted(commitReport); + + _transmit(uint8(Internal.OCRPluginType.Commit), reportContext, report, rs, ss, rawVs); } - /// @notice Returns the epoch and round of the last price update. - /// @return the latest price epoch and round. - function getLatestPriceEpochAndRound() external view returns (uint64) { - return s_latestPriceEpochAndRound; + /// @notice Returns the sequence number of the last price update. + /// @return the latest price sequence number. + function getLatestPriceSequenceNumber() public view returns (uint64) { + return s_latestPriceSequenceNumber; } - /// @notice Sets the latest epoch and round for price update. - /// @param latestPriceEpochAndRound The new epoch and round for prices. - function setLatestPriceEpochAndRound(uint40 latestPriceEpochAndRound) external onlyOwner { - uint40 oldEpochAndRound = s_latestPriceEpochAndRound; + /// @notice Sets the latest sequence number for price update. + /// @param latestPriceSequenceNumber The new sequence number for prices + function setLatestPriceSequenceNumber(uint64 latestPriceSequenceNumber) external onlyOwner { + uint64 oldPriceSequenceNumber = s_latestPriceSequenceNumber; - s_latestPriceEpochAndRound = latestPriceEpochAndRound; + s_latestPriceSequenceNumber = latestPriceSequenceNumber; - emit LatestPriceEpochAndRoundSet(oldEpochAndRound, latestPriceEpochAndRound); + emit LatestPriceSequenceNumberSet(oldPriceSequenceNumber, latestPriceSequenceNumber); } /// @notice Returns the timestamp of a potentially previously committed merkle root. @@ -783,7 +728,7 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 bytes32[] memory hashedLeaves, bytes32[] memory proofs, uint256 proofFlagBits - ) internal view virtual whenNotPaused returns (uint256 timestamp) { + ) internal view virtual returns (uint256 timestamp) { bytes32 root = MerkleMultiProof.merkleRoot(hashedLeaves, proofs, proofFlagBits); // Only return non-zero if present and blessed. if (!isBlessed(root)) { @@ -799,7 +744,7 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 // since epoch and rounds are scoped per config digest. // Note that s_minSeqNr/roots do not need to be reset as the roots persist // across reconfigurations and are de-duplicated separately. - s_latestPriceEpochAndRound = 0; + s_latestPriceSequenceNumber = 0; } } @@ -874,25 +819,115 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 /// @notice Sets the dynamic config. function setDynamicConfig(DynamicConfig memory dynamicConfig) external onlyOwner { - if (dynamicConfig.priceRegistry == address(0)) revert ZeroAddressNotAllowed(); - if (dynamicConfig.router == address(0)) revert ZeroAddressNotAllowed(); + if (dynamicConfig.priceRegistry == address(0) || dynamicConfig.router == address(0)) { + revert ZeroAddressNotAllowed(); + } s_dynamicConfig = dynamicConfig; - // TODO: contract size golfing - is StaticConfig needed in the event? - emit ConfigSet( - StaticConfig({chainSelector: i_chainSelector, rmnProxy: i_rmnProxy, tokenAdminRegistry: i_tokenAdminRegistry}), - dynamicConfig - ); + emit DynamicConfigSet(dynamicConfig); + } + + /// @notice Returns a source chain config with a check that the config is enabled + /// @param sourceChainSelector Source chain selector to check for cursing + /// @return sourceChainConfig Source chain config + function _getEnabledSourceChainConfig(uint64 sourceChainSelector) internal view returns (SourceChainConfig storage) { + SourceChainConfig storage sourceChainConfig = s_sourceChainConfigs[sourceChainSelector]; + if (!sourceChainConfig.isEnabled) { + revert SourceChainNotEnabled(sourceChainSelector); + } + + return sourceChainConfig; } // ================================================================ // │ Tokens and pools │ // ================================================================ + /// @notice Uses a pool to release or mint a token to a receiver address in two steps. First, the pool is called + /// to release the tokens to the offRamp, then the offRamp calls the token contract to transfer the tokens to the + /// receiver. This is done to ensure the exact number of tokens, the pool claims to release are actually transferred. + /// @dev The local token address is validated through the TokenAdminRegistry. If, due to some misconfiguration, the + /// token is unknown to the registry, the offRamp will revert. The tx, and the tokens, can be retrieved by + /// registering the token on this chain, and re-trying the msg. + /// @param sourceAmount The amount of tokens to be released/minted. + /// @param originalSender The message sender on the source chain. + /// @param receiver The address that will receive the tokens. + /// @param sourceTokenData A struct containing the local token address, the source pool address and optional data + /// returned from the source pool. + /// @param offchainTokenData Data fetched offchain by the DON. + function _releaseOrMintSingleToken( + uint256 sourceAmount, + bytes memory originalSender, + address receiver, + uint64 sourceChainSelector, + Internal.SourceTokenData memory sourceTokenData, + bytes memory offchainTokenData + ) internal returns (Client.EVMTokenAmount memory destTokenAmount) { + // We need to safely decode the token address from the sourceTokenData, as it could be wrong, + // in which case it doesn't have to be a valid EVM address. + address localToken = Internal._validateEVMAddress(sourceTokenData.destTokenAddress); + // We check with the token admin registry if the token has a pool on this chain. + address localPoolAddress = ITokenAdminRegistry(i_tokenAdminRegistry).getPool(localToken); + // This will call the supportsInterface through the ERC165Checker, and not directly on the pool address. + // This is done to prevent a pool from reverting the entire transaction if it doesn't support the interface. + // The call gets a max or 30k gas per instance, of which there are three. This means gas estimations should + // account for 90k gas overhead due to the interface check. + if (localPoolAddress == address(0) || !localPoolAddress.supportsInterface(Pool.CCIP_POOL_V1)) { + revert NotACompatiblePool(localPoolAddress); + } + + // We determined that the pool address is a valid EVM address, but that does not mean the code at this + // address is a (compatible) pool contract. _callWithExactGasSafeReturnData will check if the location + // contains a contract. If it doesn't it reverts with a known error, which we catch gracefully. + // We call the pool with exact gas to increase resistance against malicious tokens or token pools. + // We protects against return data bombs by capping the return data size at MAX_RET_BYTES. + (bool success, bytes memory returnData,) = CallWithExactGas._callWithExactGasSafeReturnData( + abi.encodeWithSelector( + IPoolV1.releaseOrMint.selector, + Pool.ReleaseOrMintInV1({ + originalSender: originalSender, + receiver: receiver, + amount: sourceAmount, + localToken: localToken, + remoteChainSelector: sourceChainSelector, + sourcePoolAddress: sourceTokenData.sourcePoolAddress, + sourcePoolData: sourceTokenData.extraData, + offchainTokenData: offchainTokenData + }) + ), + localPoolAddress, + s_dynamicConfig.maxPoolReleaseOrMintGas, + Internal.GAS_FOR_CALL_EXACT_CHECK, + Internal.MAX_RET_BYTES + ); + + // wrap and rethrow the error so we can catch it lower in the stack + if (!success) revert TokenHandlingError(returnData); + + // If the call was successful, the returnData should be the local token address. + if (returnData.length != Pool.CCIP_POOL_V1_RET_BYTES) { + revert InvalidDataLength(Pool.CCIP_POOL_V1_RET_BYTES, returnData.length); + } + uint256 localAmount = abi.decode(returnData, (uint256)); + // Since token pools send the tokens to the msg.sender, which is this offRamp, we need to + // transfer them to the final receiver. We use the _callWithExactGasSafeReturnData function because + // the token contracts are not considered trusted. + (success, returnData,) = CallWithExactGas._callWithExactGasSafeReturnData( + abi.encodeWithSelector(IERC20.transfer.selector, receiver, localAmount), + localToken, + s_dynamicConfig.maxTokenTransferGas, + Internal.GAS_FOR_CALL_EXACT_CHECK, + Internal.MAX_RET_BYTES + ); + + if (!success) revert TokenHandlingError(returnData); + + return Client.EVMTokenAmount({token: localToken, amount: localAmount}); + } + /// @notice Uses pools to release or mint a number of different tokens to a receiver address. /// @param sourceTokenAmounts List of tokens and amount values to be released/minted. - /// @param messageRoute Message route details (original sender, receiver and source chain) /// @param encodedSourceTokenData Array of token data returned by token pools on the source chain. /// @param offchainTokenData Array of token data fetched offchain by the DON. /// @dev This function wrappes the token pool call in a try catch block to gracefully handle @@ -900,83 +935,30 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 /// we bubble it up. If we encounter a non-rate limiting error we wrap it in a TokenHandlingError. function _releaseOrMintTokens( Client.EVMTokenAmount[] memory sourceTokenAmounts, - Any2EVMMessageRoute memory messageRoute, + bytes memory originalSender, + address receiver, + uint64 sourceChainSelector, bytes[] memory encodedSourceTokenData, bytes[] memory offchainTokenData ) internal returns (Client.EVMTokenAmount[] memory destTokenAmounts) { // Creating a copy is more gas efficient than initializing a new array. destTokenAmounts = sourceTokenAmounts; for (uint256 i = 0; i < sourceTokenAmounts.length; ++i) { - // This should never revert as the onRamp creates the sourceTokenData. Only the inner components from - // this struct come from untrusted sources. - Internal.SourceTokenData memory sourceTokenData = - abi.decode(encodedSourceTokenData[i], (Internal.SourceTokenData)); - // We need to safely decode the pool address from the sourceTokenData, as it could be wrong, - // in which case it doesn't have to be a valid EVM address. - address localToken = Internal._validateEVMAddress(sourceTokenData.destTokenAddress); - // We check with the token admin registry if the token has a pool on this chain. - address localPoolAddress = ITokenAdminRegistry(i_tokenAdminRegistry).getPool(localToken); - // This will call the supportsInterface through the ERC165Checker, and not directly on the pool address. - // This is done to prevent a pool from reverting the entire transaction if it doesn't support the interface. - // The call gets a max or 30k gas per instance, of which there are three. This means gas estimations should - // account for 90k gas overhead due to the interface check. - if (localPoolAddress == address(0) || !localPoolAddress.supportsInterface(Pool.CCIP_POOL_V1)) { - revert NotACompatiblePool(localPoolAddress); - } - - // We determined that the pool address is a valid EVM address, but that does not mean the code at this - // address is a (compatible) pool contract. _callWithExactGasSafeReturnData will check if the location - // contains a contract. If it doesn't it reverts with a known error, which we catch gracefully. - // We call the pool with exact gas to increase resistance against malicious tokens or token pools. - // We protects against return data bombs by capping the return data size at MAX_RET_BYTES. - (bool success, bytes memory returnData,) = CallWithExactGas._callWithExactGasSafeReturnData( - abi.encodeWithSelector( - IPoolV1.releaseOrMint.selector, - Pool.ReleaseOrMintInV1({ - originalSender: messageRoute.sender, - receiver: messageRoute.receiver, - amount: sourceTokenAmounts[i].amount, - localToken: localToken, - remoteChainSelector: messageRoute.sourceChainSelector, - sourcePoolAddress: sourceTokenData.sourcePoolAddress, - sourcePoolData: sourceTokenData.extraData, - offchainTokenData: offchainTokenData[i] - }) - ), - localPoolAddress, - s_dynamicConfig.maxPoolReleaseOrMintGas, - Internal.GAS_FOR_CALL_EXACT_CHECK, - Internal.MAX_RET_BYTES - ); - - // wrap and rethrow the error so we can catch it lower in the stack - if (!success) revert TokenHandlingError(returnData); - - // If the call was successful, the returnData should be the local token address. - if (returnData.length != Pool.CCIP_POOL_V1_RET_BYTES) { - revert InvalidDataLength(Pool.CCIP_POOL_V1_RET_BYTES, returnData.length); - } - uint256 amount = abi.decode(returnData, (uint256)); - - (success, returnData,) = CallWithExactGas._callWithExactGasSafeReturnData( - abi.encodeWithSelector(IERC20.transfer.selector, messageRoute.receiver, amount), - localToken, - s_dynamicConfig.maxTokenTransferGas, - Internal.GAS_FOR_CALL_EXACT_CHECK, - Internal.MAX_RET_BYTES + destTokenAmounts[i] = _releaseOrMintSingleToken( + sourceTokenAmounts[i].amount, + originalSender, + receiver, + sourceChainSelector, + abi.decode(encodedSourceTokenData[i], (Internal.SourceTokenData)), + offchainTokenData[i] ); - - if (!success) revert TokenHandlingError(returnData); - - destTokenAmounts[i].token = localToken; - destTokenAmounts[i].amount = amount; } return destTokenAmounts; } // ================================================================ - // │ Access │ + // │ Access and RMN │ // ================================================================ /// @notice Reverts as this contract should not access CCIP messages @@ -985,34 +967,11 @@ contract EVM2EVMMultiOffRamp is IAny2EVMMultiOffRamp, ITypeAndVersion, MultiOCR3 revert(); } - /// @notice Single function to check the status of the commitStore. - function isUnpausedAndNotCursed(uint64 sourceChainSelector) external view returns (bool) { - return !IRMN(i_rmnProxy).isCursed(bytes16(uint128(sourceChainSelector))) && !s_paused; - } - - // TODO: global pausing can be removed delegated to the i_rmnProxy - /// @notice Modifier to make a function callable only when the contract is not paused. - modifier whenNotPaused() { - if (paused()) revert PausedError(); - _; - } - - /// @notice Returns true if the contract is paused, and false otherwise. - function paused() public view returns (bool) { - return s_paused; - } - - /// @notice Pause the contract - /// @dev only callable by the owner - function pause() external onlyOwner { - s_paused = true; - emit Paused(msg.sender); - } - - /// @notice Unpause the contract - /// @dev only callable by the owner - function unpause() external onlyOwner { - s_paused = false; - emit Unpaused(msg.sender); + /// @notice Validates that the source chain -> this chain lane, and reverts if it is cursed + /// @param sourceChainSelector Source chain selector to check for cursing + function _whenNotCursed(uint64 sourceChainSelector) internal view { + if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(sourceChainSelector)))) { + revert CursedByRMN(sourceChainSelector); + } } } diff --git a/contracts/src/v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol b/contracts/src/v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol index c6ce638585..aa88294be7 100644 --- a/contracts/src/v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol +++ b/contracts/src/v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol @@ -2,9 +2,8 @@ pragma solidity 0.8.24; import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; -import {IEVM2AnyMultiOnRamp} from "../interfaces/IEVM2AnyMultiOnRamp.sol"; -import {IEVM2AnyOnRamp} from "../interfaces/IEVM2AnyOnRamp.sol"; import {IEVM2AnyOnRampClient} from "../interfaces/IEVM2AnyOnRampClient.sol"; +import {INonceManager} from "../interfaces/INonceManager.sol"; import {IPoolV1} from "../interfaces/IPool.sol"; import {IPriceRegistry} from "../interfaces/IPriceRegistry.sol"; import {IRMN} from "../interfaces/IRMN.sol"; @@ -23,7 +22,7 @@ import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/tok /// @notice The EVM2EVMMultiOnRamp is a contract that handles lane-specific fee logic /// @dev The EVM2EVMMultiOnRamp, MultiCommitStore and EVM2EVMMultiOffRamp form an xchain upgradeable unit. Any change to one of them /// results an onchain upgrade of all 3. -contract EVM2EVMMultiOnRamp is IEVM2AnyMultiOnRamp, AggregateRateLimiter, ITypeAndVersion { +contract EVM2EVMMultiOnRamp is IEVM2AnyOnRampClient, AggregateRateLimiter, ITypeAndVersion { using SafeERC20 for IERC20; using USDPriceWith18Decimals for uint224; @@ -67,6 +66,7 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyMultiOnRamp, AggregateRateLimiter, ITypeA uint64 chainSelector; // ─────╯ Source chainSelector uint96 maxFeeJuelsPerMsg; // ─╮ Maximum fee that can be charged for a message address rmnProxy; // ─────────╯ Address of RMN proxy + address nonceManager; // Address of the nonce manager address tokenAdminRegistry; // Token admin registry address } @@ -173,6 +173,8 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyMultiOnRamp, AggregateRateLimiter, ITypeA uint64 internal immutable i_chainSelector; /// @dev The address of the rmn proxy address internal immutable i_rmnProxy; + /// @dev The address of the nonce manager + address internal immutable i_nonceManager; /// @dev The address of the token admin registry address internal immutable i_tokenAdminRegistry; /// @dev the maximum number of nops that can be configured at the same time. @@ -193,10 +195,6 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyMultiOnRamp, AggregateRateLimiter, ITypeA s_tokenTransferFeeConfig; // STATE - /// @dev The current nonce per sender. - /// The offramp has a corresponding s_senderNonce mapping to ensure messages - /// are executed in the same order they are sent. - mapping(uint64 destChainSelector => mapping(address sender => uint64 nonce)) internal s_senderNonce; /// @dev The amount of LINK available to pay NOPS uint96 internal s_nopFeesJuels; /// @dev The combined weight of all NOPs weights @@ -212,7 +210,7 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyMultiOnRamp, AggregateRateLimiter, ITypeA ) AggregateRateLimiter(rateLimiterConfig) { if ( staticConfig.linkToken == address(0) || staticConfig.chainSelector == 0 || staticConfig.rmnProxy == address(0) - || staticConfig.tokenAdminRegistry == address(0) + || staticConfig.nonceManager == address(0) || staticConfig.tokenAdminRegistry == address(0) ) { revert InvalidConfig(); } @@ -221,6 +219,7 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyMultiOnRamp, AggregateRateLimiter, ITypeA i_chainSelector = staticConfig.chainSelector; i_maxFeeJuelsPerMsg = staticConfig.maxFeeJuelsPerMsg; i_rmnProxy = staticConfig.rmnProxy; + i_nonceManager = staticConfig.nonceManager; i_tokenAdminRegistry = staticConfig.tokenAdminRegistry; _setDynamicConfig(dynamicConfig); @@ -233,26 +232,13 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyMultiOnRamp, AggregateRateLimiter, ITypeA // │ Messaging │ // ================================================================ - /// @inheritdoc IEVM2AnyMultiOnRamp + /// @notice Gets the next sequence number to be used in the onRamp + /// @param destChainSelector The destination chain selector + /// @return the next sequence number to be used function getExpectedNextSequenceNumber(uint64 destChainSelector) external view returns (uint64) { return s_destChainConfig[destChainSelector].sequenceNumber + 1; } - /// @inheritdoc IEVM2AnyMultiOnRamp - function getSenderNonce(uint64 destChainSelector, address sender) public view returns (uint64) { - uint64 senderNonce = s_senderNonce[destChainSelector][sender]; - - if (senderNonce == 0) { - address prevOnRamp = s_destChainConfig[destChainSelector].prevOnRamp; - if (prevOnRamp != address(0)) { - // If OnRamp was upgraded, check if sender has a nonce from the previous OnRamp. - return IEVM2AnyOnRamp(prevOnRamp).getSenderNonce(sender); - } - } - - return senderNonce; - } - /// @inheritdoc IEVM2AnyOnRampClient function forwardFromRouter( uint64 destChainSelector, @@ -371,9 +357,6 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyMultiOnRamp, AggregateRateLimiter, ITypeA if (msgFeeJuels > i_maxFeeJuelsPerMsg) revert MessageFeeTooHigh(msgFeeJuels, i_maxFeeJuelsPerMsg); - uint64 nonce = getSenderNonce(destChainSelector, originalSender) + 1; - s_senderNonce[destChainSelector][originalSender] = nonce; - // We need the next available sequence number so we increment before we use the value return Internal.EVM2EVMMessage({ sourceChainSelector: i_chainSelector, @@ -384,7 +367,7 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyMultiOnRamp, AggregateRateLimiter, ITypeA sequenceNumber: ++destChainConfig.sequenceNumber, gasLimit: gasLimit, strict: false, - nonce: nonce, + nonce: INonceManager(i_nonceManager).getIncrementedOutboundNonce(destChainSelector, originalSender), feeToken: message.feeToken, feeTokenAmount: feeTokenAmount, data: message.data, @@ -439,6 +422,7 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyMultiOnRamp, AggregateRateLimiter, ITypeA chainSelector: i_chainSelector, maxFeeJuelsPerMsg: i_maxFeeJuelsPerMsg, rmnProxy: i_rmnProxy, + nonceManager: i_nonceManager, tokenAdminRegistry: i_tokenAdminRegistry }); } @@ -468,6 +452,7 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyMultiOnRamp, AggregateRateLimiter, ITypeA chainSelector: i_chainSelector, maxFeeJuelsPerMsg: i_maxFeeJuelsPerMsg, rmnProxy: i_rmnProxy, + nonceManager: i_nonceManager, tokenAdminRegistry: i_tokenAdminRegistry }), dynamicConfig diff --git a/contracts/src/v0.8/ccip/test/NonceManager.t.sol b/contracts/src/v0.8/ccip/test/NonceManager.t.sol new file mode 100644 index 0000000000..7c59e82272 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/NonceManager.t.sol @@ -0,0 +1,227 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {NonceManager} from "../NonceManager.sol"; +import {Client} from "../libraries/Client.sol"; +import {Internal} from "../libraries/Internal.sol"; +import {Pool} from "../libraries/Pool.sol"; +import {RateLimiter} from "../libraries/RateLimiter.sol"; +import {EVM2EVMMultiOnRamp} from "../onRamp/EVM2EVMMultiOnRamp.sol"; +import {EVM2EVMOnRamp} from "../onRamp/EVM2EVMOnRamp.sol"; +import {EVM2EVMMultiOnRampHelper} from "./helpers/EVM2EVMMultiOnRampHelper.sol"; +import {EVM2EVMOnRampHelper} from "./helpers/EVM2EVMOnRampHelper.sol"; +import {EVM2EVMMultiOnRampSetup} from "./onRamp/EVM2EVMMultiOnRampSetup.t.sol"; + +contract NonceManagerTest_getIncrementedOutboundNonce is EVM2EVMMultiOnRampSetup { + function test_getIncrementedOutboundNonce_Success() public { + vm.startPrank(address(s_onRamp)); + address sender = address(this); + + assertEq(s_nonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, sender), 0); + + uint64 outboundNonce = s_nonceManager.getIncrementedOutboundNonce(DEST_CHAIN_SELECTOR, sender); + assertEq(outboundNonce, 1); + } +} + +contract NonceManager_applyPreviousRampsUpdates is EVM2EVMMultiOnRampSetup { + function test_SingleRampUpdate() public { + address prevOnRamp = vm.addr(1); + NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); + previousRamps[0] = NonceManager.PreviousRampsArgs(DEST_CHAIN_SELECTOR, NonceManager.PreviousRamps(prevOnRamp)); + + vm.expectEmit(); + emit NonceManager.PreviousOnRampUpdated(DEST_CHAIN_SELECTOR, prevOnRamp); + + s_nonceManager.applyPreviousRampsUpdates(previousRamps); + + _assertPreviousRampsEqual(s_nonceManager.getPreviousRamps(DEST_CHAIN_SELECTOR), previousRamps[0].prevRamps); + } + + function test_MultipleRampsUpdates() public { + address prevOnRamp1 = vm.addr(1); + address prevOnRamp2 = vm.addr(2); + NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](2); + previousRamps[0] = NonceManager.PreviousRampsArgs(DEST_CHAIN_SELECTOR, NonceManager.PreviousRamps(prevOnRamp1)); + previousRamps[1] = NonceManager.PreviousRampsArgs(DEST_CHAIN_SELECTOR + 1, NonceManager.PreviousRamps(prevOnRamp2)); + + vm.expectEmit(); + emit NonceManager.PreviousOnRampUpdated(DEST_CHAIN_SELECTOR, prevOnRamp1); + vm.expectEmit(); + emit NonceManager.PreviousOnRampUpdated(DEST_CHAIN_SELECTOR + 1, prevOnRamp2); + + s_nonceManager.applyPreviousRampsUpdates(previousRamps); + + _assertPreviousRampsEqual(s_nonceManager.getPreviousRamps(DEST_CHAIN_SELECTOR), previousRamps[0].prevRamps); + _assertPreviousRampsEqual(s_nonceManager.getPreviousRamps(DEST_CHAIN_SELECTOR + 1), previousRamps[1].prevRamps); + } + + function test_ZeroInput() public { + vm.recordLogs(); + s_nonceManager.applyPreviousRampsUpdates(new NonceManager.PreviousRampsArgs[](0)); + + assertEq(vm.getRecordedLogs().length, 0); + } + + function test_PreviousRampAlreadySetOnRamp_Revert() public { + NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); + previousRamps[0] = + NonceManager.PreviousRampsArgs(DEST_CHAIN_SELECTOR, NonceManager.PreviousRamps(address(vm.addr(1)))); + + s_nonceManager.applyPreviousRampsUpdates(previousRamps); + + previousRamps[0] = + NonceManager.PreviousRampsArgs(DEST_CHAIN_SELECTOR, NonceManager.PreviousRamps(address(vm.addr(2)))); + + vm.expectRevert(NonceManager.PreviousRampAlreadySet.selector); + s_nonceManager.applyPreviousRampsUpdates(previousRamps); + } + + function _assertPreviousRampsEqual( + NonceManager.PreviousRamps memory a, + NonceManager.PreviousRamps memory b + ) internal pure { + assertEq(a.prevOnRamp, b.prevOnRamp); + } +} + +contract NonceManager_onRampUpgrade is EVM2EVMMultiOnRampSetup { + uint256 internal constant FEE_AMOUNT = 1234567890; + EVM2EVMOnRampHelper internal s_prevOnRamp; + + function setUp() public virtual override { + EVM2EVMMultiOnRampSetup.setUp(); + + EVM2EVMOnRamp.FeeTokenConfigArgs[] memory feeTokenConfigArgs = new EVM2EVMOnRamp.FeeTokenConfigArgs[](1); + feeTokenConfigArgs[0] = EVM2EVMOnRamp.FeeTokenConfigArgs({ + token: s_sourceFeeToken, + networkFeeUSDCents: 1_00, // 1 USD + gasMultiplierWeiPerEth: 1e18, // 1x + premiumMultiplierWeiPerEth: 5e17, // 0.5x + enabled: true + }); + + EVM2EVMOnRamp.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfig = + new EVM2EVMOnRamp.TokenTransferFeeConfigArgs[](1); + + tokenTransferFeeConfig[0] = EVM2EVMOnRamp.TokenTransferFeeConfigArgs({ + token: s_sourceFeeToken, + minFeeUSDCents: 1_00, // 1 USD + maxFeeUSDCents: 1000_00, // 1,000 USD + deciBps: 2_5, // 2.5 bps, or 0.025% + destGasOverhead: 40_000, + destBytesOverhead: uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES), + aggregateRateLimitEnabled: true + }); + + s_prevOnRamp = new EVM2EVMOnRampHelper( + EVM2EVMOnRamp.StaticConfig({ + linkToken: s_sourceTokens[0], + chainSelector: SOURCE_CHAIN_SELECTOR, + destChainSelector: DEST_CHAIN_SELECTOR, + defaultTxGasLimit: GAS_LIMIT, + maxNopFeesJuels: MAX_NOP_FEES_JUELS, + prevOnRamp: address(0), + rmnProxy: address(s_mockRMN), + tokenAdminRegistry: address(s_tokenAdminRegistry) + }), + EVM2EVMOnRamp.DynamicConfig({ + router: address(s_sourceRouter), + maxNumberOfTokensPerMsg: MAX_TOKENS_LENGTH, + destGasOverhead: DEST_GAS_OVERHEAD, + destGasPerPayloadByte: DEST_GAS_PER_PAYLOAD_BYTE, + destDataAvailabilityOverheadGas: DEST_DATA_AVAILABILITY_OVERHEAD_GAS, + destGasPerDataAvailabilityByte: DEST_GAS_PER_DATA_AVAILABILITY_BYTE, + destDataAvailabilityMultiplierBps: DEST_GAS_DATA_AVAILABILITY_MULTIPLIER_BPS, + priceRegistry: address(s_priceRegistry), + maxDataBytes: MAX_DATA_SIZE, + maxPerMsgGasLimit: MAX_GAS_LIMIT, + defaultTokenFeeUSDCents: DEFAULT_TOKEN_FEE_USD_CENTS, + defaultTokenDestGasOverhead: DEFAULT_TOKEN_DEST_GAS_OVERHEAD, + defaultTokenDestBytesOverhead: DEFAULT_TOKEN_BYTES_OVERHEAD, + enforceOutOfOrder: false + }), + RateLimiter.Config({isEnabled: true, capacity: 100e28, rate: 1e15}), + feeTokenConfigArgs, + tokenTransferFeeConfig, + new EVM2EVMOnRamp.NopAndWeight[](0) + ); + + NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); + previousRamps[0] = + NonceManager.PreviousRampsArgs(DEST_CHAIN_SELECTOR, NonceManager.PreviousRamps(address(s_prevOnRamp))); + s_nonceManager.applyPreviousRampsUpdates(previousRamps); + + EVM2EVMMultiOnRamp.DestChainConfigArgs[] memory destChainConfigArgs = _generateDestChainConfigArgs(); + destChainConfigArgs[0].prevOnRamp = address(s_prevOnRamp); + + (s_onRamp, s_metadataHash) = _deployOnRamp( + SOURCE_CHAIN_SELECTOR, address(s_sourceRouter), address(s_nonceManager), address(s_tokenAdminRegistry) + ); + + vm.startPrank(address(s_sourceRouter)); + } + + function test_Upgrade_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, FEE_AMOUNT, OWNER)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); + } + + function test_UpgradeSenderNoncesReadsPreviousRamp_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + uint64 startNonce = s_nonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER); + + for (uint64 i = 1; i < 4; ++i) { + s_prevOnRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + + assertEq(startNonce + i, s_nonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER)); + } + } + + function test_UpgradeNonceStartsAtV1Nonce_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + uint64 startNonce = s_nonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER); + + // send 1 message from previous onramp + s_prevOnRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); + + assertEq(startNonce + 1, s_nonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER)); + + // new onramp nonce should start from 2, while sequence number start from 1 + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.CCIPSendRequested( + DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, startNonce + 2, FEE_AMOUNT, OWNER) + ); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); + + assertEq(startNonce + 2, s_nonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER)); + + // after another send, nonce should be 3, and sequence number be 2 + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.CCIPSendRequested( + DEST_CHAIN_SELECTOR, _messageToEvent(message, 2, startNonce + 3, FEE_AMOUNT, OWNER) + ); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); + + assertEq(startNonce + 3, s_nonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER)); + } + + function test_UpgradeNonceNewSenderStartsAtZero_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + // send 1 message from previous onramp from OWNER + s_prevOnRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); + + address newSender = address(1234567); + // new onramp nonce should start from 1 for new sender + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.CCIPSendRequested( + DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, FEE_AMOUNT, newSender) + ); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, newSender); + } +} diff --git a/contracts/src/v0.8/ccip/test/capability/CCIPCapabilityConfiguration.t.sol b/contracts/src/v0.8/ccip/test/capability/CCIPCapabilityConfiguration.t.sol new file mode 100644 index 0000000000..25e6d79c88 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/capability/CCIPCapabilityConfiguration.t.sol @@ -0,0 +1,1572 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.24; + +import {Test} from "forge-std/Test.sol"; + +import {CCIPCapabilityConfiguration} from "../../capability/CCIPCapabilityConfiguration.sol"; +import {ICapabilityRegistry} from "../../capability/interfaces/ICapabilityRegistry.sol"; +import {CCIPCapabilityConfigurationHelper} from "../helpers/CCIPCapabilityConfigurationHelper.sol"; + +contract CCIPCapabilityConfigurationSetup is Test { + address public constant OWNER = 0x82ae2B4F57CA5C1CBF8f744ADbD3697aD1a35AFe; + address public constant CAPABILITY_REGISTRY = 0x272aF4BF7FBFc4944Ed59F914Cd864DfD912D55e; + + CCIPCapabilityConfigurationHelper public s_ccipCC; + + function setUp() public { + changePrank(OWNER); + s_ccipCC = new CCIPCapabilityConfigurationHelper(CAPABILITY_REGISTRY); + } + + function _makeBytes32Array(uint256 length, uint256 seed) internal pure returns (bytes32[] memory arr) { + arr = new bytes32[](length); + for (uint256 i = 0; i < length; i++) { + arr[i] = keccak256(abi.encode(i, 1, seed)); + } + return arr; + } + + function _makeBytesArray(uint256 length, uint256 seed) internal pure returns (bytes[] memory arr) { + arr = new bytes[](length); + for (uint256 i = 0; i < length; i++) { + arr[i] = abi.encodePacked(keccak256(abi.encode(i, 1, seed))); + } + return arr; + } + + function _subset(bytes32[] memory arr, uint256 start, uint256 end) internal pure returns (bytes32[] memory) { + bytes32[] memory subset = new bytes32[](end - start); + for (uint256 i = start; i < end; i++) { + subset[i - start] = arr[i]; + } + return subset; + } + + function _addChainConfig(uint256 numNodes) + internal + returns (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) + { + p2pIds = _makeBytes32Array(numNodes, 0); + signers = _makeBytesArray(numNodes, 10); + transmitters = _makeBytesArray(numNodes, 20); + for (uint256 i = 0; i < numNodes; i++) { + vm.mockCall( + CAPABILITY_REGISTRY, + abi.encodeWithSelector(ICapabilityRegistry.getNode.selector, p2pIds[i]), + abi.encode( + ICapabilityRegistry.NodeInfo({ + nodeOperatorId: 1, + signer: bytes32(signers[i]), + p2pId: p2pIds[i], + hashedCapabilityIds: new bytes32[](0) + }), + uint32(1) + ) + ); + } + // Add chain selector for chain 1. + CCIPCapabilityConfiguration.ChainConfigInfo[] memory adds = new CCIPCapabilityConfiguration.ChainConfigInfo[](1); + adds[0] = CCIPCapabilityConfiguration.ChainConfigInfo({ + chainSelector: 1, + chainConfig: CCIPCapabilityConfiguration.ChainConfig({readers: p2pIds, fChain: 1, config: bytes("config1")}) + }); + + vm.expectEmit(); + emit CCIPCapabilityConfiguration.ChainConfigSet(1, adds[0].chainConfig); + s_ccipCC.applyChainConfigUpdates(new uint64[](0), adds); + + return (p2pIds, signers, transmitters); + } + + function test_getCapabilityConfiguration_Success() public { + bytes memory capConfig = s_ccipCC.getCapabilityConfiguration(42 /* doesn't matter, not used */ ); + assertEq(capConfig.length, 0, "capability config length must be 0"); + } +} + +contract CCIPCapabilityConfiguration_chainConfig is CCIPCapabilityConfigurationSetup { + // Successes. + + function test_applyChainConfigUpdates_addChainConfigs_Success() public { + bytes32[] memory chainReaders = new bytes32[](1); + chainReaders[0] = keccak256(abi.encode(1)); + CCIPCapabilityConfiguration.ChainConfigInfo[] memory adds = new CCIPCapabilityConfiguration.ChainConfigInfo[](2); + adds[0] = CCIPCapabilityConfiguration.ChainConfigInfo({ + chainSelector: 1, + chainConfig: CCIPCapabilityConfiguration.ChainConfig({readers: chainReaders, fChain: 1, config: bytes("config1")}) + }); + adds[1] = CCIPCapabilityConfiguration.ChainConfigInfo({ + chainSelector: 2, + chainConfig: CCIPCapabilityConfiguration.ChainConfig({readers: chainReaders, fChain: 1, config: bytes("config2")}) + }); + + vm.mockCall( + CAPABILITY_REGISTRY, + abi.encodeWithSelector(ICapabilityRegistry.getNode.selector, chainReaders[0]), + abi.encode( + ICapabilityRegistry.NodeInfo({ + nodeOperatorId: 1, + signer: bytes32(uint256(1)), + p2pId: chainReaders[0], + hashedCapabilityIds: new bytes32[](0) + }), + uint32(1) + ) + ); + + vm.expectEmit(); + emit CCIPCapabilityConfiguration.ChainConfigSet(1, adds[0].chainConfig); + vm.expectEmit(); + emit CCIPCapabilityConfiguration.ChainConfigSet(2, adds[1].chainConfig); + s_ccipCC.applyChainConfigUpdates(new uint64[](0), adds); + + CCIPCapabilityConfiguration.ChainConfigInfo[] memory configs = s_ccipCC.getAllChainConfigs(); + assertEq(configs.length, 2, "chain configs length must be 2"); + assertEq(configs[0].chainSelector, 1, "chain selector must match"); + assertEq(configs[1].chainSelector, 2, "chain selector must match"); + } + + function test_applyChainConfigUpdates_removeChainConfigs_Success() public { + bytes32[] memory chainReaders = new bytes32[](1); + chainReaders[0] = keccak256(abi.encode(1)); + CCIPCapabilityConfiguration.ChainConfigInfo[] memory adds = new CCIPCapabilityConfiguration.ChainConfigInfo[](2); + adds[0] = CCIPCapabilityConfiguration.ChainConfigInfo({ + chainSelector: 1, + chainConfig: CCIPCapabilityConfiguration.ChainConfig({readers: chainReaders, fChain: 1, config: bytes("config1")}) + }); + adds[1] = CCIPCapabilityConfiguration.ChainConfigInfo({ + chainSelector: 2, + chainConfig: CCIPCapabilityConfiguration.ChainConfig({readers: chainReaders, fChain: 1, config: bytes("config2")}) + }); + + vm.mockCall( + CAPABILITY_REGISTRY, + abi.encodeWithSelector(ICapabilityRegistry.getNode.selector, chainReaders[0]), + abi.encode( + ICapabilityRegistry.NodeInfo({ + nodeOperatorId: 1, + signer: bytes32(uint256(1)), + p2pId: chainReaders[0], + hashedCapabilityIds: new bytes32[](0) + }), + uint32(1) + ) + ); + + vm.expectEmit(); + emit CCIPCapabilityConfiguration.ChainConfigSet(1, adds[0].chainConfig); + vm.expectEmit(); + emit CCIPCapabilityConfiguration.ChainConfigSet(2, adds[1].chainConfig); + s_ccipCC.applyChainConfigUpdates(new uint64[](0), adds); + + uint64[] memory removes = new uint64[](1); + removes[0] = uint64(1); + + vm.expectEmit(); + emit CCIPCapabilityConfiguration.ChainConfigRemoved(1); + s_ccipCC.applyChainConfigUpdates(removes, new CCIPCapabilityConfiguration.ChainConfigInfo[](0)); + } + + // Reverts. + + function test_applyChainConfigUpdates_selectorNotFound_Reverts() public { + uint64[] memory removes = new uint64[](1); + removes[0] = uint64(1); + + vm.expectRevert(abi.encodeWithSelector(CCIPCapabilityConfiguration.ChainSelectorNotFound.selector, 1)); + s_ccipCC.applyChainConfigUpdates(removes, new CCIPCapabilityConfiguration.ChainConfigInfo[](0)); + } + + function test_applyChainConfigUpdates_nodeNotInRegistry_Reverts() public { + bytes32[] memory chainReaders = new bytes32[](1); + chainReaders[0] = keccak256(abi.encode(1)); + CCIPCapabilityConfiguration.ChainConfigInfo[] memory adds = new CCIPCapabilityConfiguration.ChainConfigInfo[](1); + adds[0] = CCIPCapabilityConfiguration.ChainConfigInfo({ + chainSelector: 1, + chainConfig: CCIPCapabilityConfiguration.ChainConfig({readers: chainReaders, fChain: 1, config: abi.encode(1, 2, 3)}) + }); + + vm.mockCall( + CAPABILITY_REGISTRY, + abi.encodeWithSelector(ICapabilityRegistry.getNode.selector, chainReaders[0]), + abi.encode( + ICapabilityRegistry.NodeInfo({ + nodeOperatorId: 0, + signer: bytes32(0), + p2pId: bytes32(uint256(0)), + hashedCapabilityIds: new bytes32[](0) + }), + uint32(1) + ) + ); + + vm.expectRevert(abi.encodeWithSelector(CCIPCapabilityConfiguration.NodeNotInRegistry.selector, chainReaders[0])); + s_ccipCC.applyChainConfigUpdates(new uint64[](0), adds); + } + + function test__applyChainConfigUpdates_FChainNotPositive_Reverts() public { + bytes32[] memory chainReaders = new bytes32[](1); + chainReaders[0] = keccak256(abi.encode(1)); + CCIPCapabilityConfiguration.ChainConfigInfo[] memory adds = new CCIPCapabilityConfiguration.ChainConfigInfo[](2); + adds[0] = CCIPCapabilityConfiguration.ChainConfigInfo({ + chainSelector: 1, + chainConfig: CCIPCapabilityConfiguration.ChainConfig({readers: chainReaders, fChain: 1, config: bytes("config1")}) + }); + adds[1] = CCIPCapabilityConfiguration.ChainConfigInfo({ + chainSelector: 2, + chainConfig: CCIPCapabilityConfiguration.ChainConfig({readers: chainReaders, fChain: 0, config: bytes("config2")}) // bad fChain + }); + + vm.mockCall( + CAPABILITY_REGISTRY, + abi.encodeWithSelector(ICapabilityRegistry.getNode.selector, chainReaders[0]), + abi.encode( + ICapabilityRegistry.NodeInfo({ + nodeOperatorId: 1, + signer: bytes32(uint256(1)), + p2pId: chainReaders[0], + hashedCapabilityIds: new bytes32[](0) + }), + uint32(1) + ) + ); + + vm.expectRevert(CCIPCapabilityConfiguration.FChainMustBePositive.selector); + s_ccipCC.applyChainConfigUpdates(new uint64[](0), adds); + } +} + +contract CCIPCapabilityConfiguration_validateConfig is CCIPCapabilityConfigurationSetup { + // Successes. + + function test__validateConfig_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + + // Config is for 4 nodes, so f == 1. + CCIPCapabilityConfiguration.OCR3Config memory config = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + s_ccipCC.validateConfig(config); + } + + // Reverts. + + function test__validateConfig_ChainSelectorNotSet_Reverts() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + + // Config is for 4 nodes, so f == 1. + CCIPCapabilityConfiguration.OCR3Config memory config = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 0, // invalid + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(CCIPCapabilityConfiguration.ChainSelectorNotSet.selector); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_OfframpAddressCannotBeZero_Reverts() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + + // Config is for 4 nodes, so f == 1. + CCIPCapabilityConfiguration.OCR3Config memory config = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: bytes(""), // invalid + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(CCIPCapabilityConfiguration.OfframpAddressCannotBeZero.selector); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_ChainSelectorNotFound_Reverts() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + + // Config is for 4 nodes, so f == 1. + CCIPCapabilityConfiguration.OCR3Config memory config = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 2, // not set + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(abi.encodeWithSelector(CCIPCapabilityConfiguration.ChainSelectorNotFound.selector, 2)); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_TooManySigners_Reverts() public { + // 32 > 31 (max num oracles) + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(32); + + CCIPCapabilityConfiguration.OCR3Config memory config = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(CCIPCapabilityConfiguration.TooManySigners.selector); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_TooManyTransmitters_Reverts() public { + // 32 > 31 (max num oracles) + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(32); + + // truncate signers but keep transmitters > 31 + assembly { + mstore(signers, 30) + } + + CCIPCapabilityConfiguration.OCR3Config memory config = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(CCIPCapabilityConfiguration.TooManyTransmitters.selector); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_NotEnoughTransmitters_Reverts() public { + // 32 > 31 (max num oracles) + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(31); + + // truncate transmitters to < 3 * fChain + 1 + // since fChain is 1 in this case, we need to truncate to 3 transmitters. + assembly { + mstore(transmitters, 3) + } + + CCIPCapabilityConfiguration.OCR3Config memory config = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(abi.encodeWithSelector(CCIPCapabilityConfiguration.NotEnoughTransmitters.selector, 3, 4)); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_FMustBePositive_Reverts() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + + // Config is for 4 nodes, so f == 1. + CCIPCapabilityConfiguration.OCR3Config memory config = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 0, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(CCIPCapabilityConfiguration.FMustBePositive.selector); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_FTooHigh_Reverts() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + + CCIPCapabilityConfiguration.OCR3Config memory config = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 2, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(CCIPCapabilityConfiguration.FTooHigh.selector); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_P2PIdsLengthNotMatching_Reverts() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + // truncate the p2pIds length + assembly { + mstore(p2pIds, 3) + } + + // Config is for 4 nodes, so f == 1. + CCIPCapabilityConfiguration.OCR3Config memory config = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert( + abi.encodeWithSelector( + CCIPCapabilityConfiguration.P2PIdsLengthNotMatching.selector, uint256(3), uint256(4), uint256(4) + ) + ); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_TooManyBootstrapP2PIds_Reverts() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + + // Config is for 4 nodes, so f == 1. + CCIPCapabilityConfiguration.OCR3Config memory config = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _makeBytes32Array(5, 0), // too many bootstrap p2pIds, 5 > 4 + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(CCIPCapabilityConfiguration.TooManyBootstrapP2PIds.selector); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_NodeNotInRegistry_Reverts() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + bytes32 nonExistentP2PId = keccak256("notInRegistry"); + p2pIds[0] = nonExistentP2PId; + + vm.mockCall( + CAPABILITY_REGISTRY, + abi.encodeWithSelector(ICapabilityRegistry.getNode.selector, nonExistentP2PId), + abi.encode( + ICapabilityRegistry.NodeInfo({ + nodeOperatorId: 0, + signer: bytes32(0), + p2pId: bytes32(uint256(0)), + hashedCapabilityIds: new bytes32[](0) + }), + uint32(1) + ) + ); + + // Config is for 4 nodes, so f == 1. + CCIPCapabilityConfiguration.OCR3Config memory config = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(abi.encodeWithSelector(CCIPCapabilityConfiguration.NodeNotInRegistry.selector, nonExistentP2PId)); + s_ccipCC.validateConfig(config); + } +} + +contract CCIPCapabilityConfiguration_ConfigStateMachine is CCIPCapabilityConfigurationSetup { + // Successful cases. + + function test__stateFromConfigLength_Success() public { + uint256 configLen = 0; + CCIPCapabilityConfiguration.ConfigState state = s_ccipCC.stateFromConfigLength(configLen); + assertEq(uint256(state), uint256(CCIPCapabilityConfiguration.ConfigState.Init)); + + configLen = 1; + state = s_ccipCC.stateFromConfigLength(configLen); + assertEq(uint256(state), uint256(CCIPCapabilityConfiguration.ConfigState.Running)); + + configLen = 2; + state = s_ccipCC.stateFromConfigLength(configLen); + assertEq(uint256(state), uint256(CCIPCapabilityConfiguration.ConfigState.Staging)); + } + + function test__validateConfigStateTransition_Success() public { + s_ccipCC.validateConfigStateTransition( + CCIPCapabilityConfiguration.ConfigState.Init, CCIPCapabilityConfiguration.ConfigState.Running + ); + + s_ccipCC.validateConfigStateTransition( + CCIPCapabilityConfiguration.ConfigState.Running, CCIPCapabilityConfiguration.ConfigState.Staging + ); + + s_ccipCC.validateConfigStateTransition( + CCIPCapabilityConfiguration.ConfigState.Staging, CCIPCapabilityConfiguration.ConfigState.Running + ); + } + + function test__computeConfigDigest_Success() public { + // config digest must change upon: + // - ocr config change (e.g plugin type, chain selector, etc.) + // - don id change + // - config count change + bytes32[] memory p2pIds = _makeBytes32Array(4, 0); + bytes[] memory signers = _makeBytesArray(2, 10); + bytes[] memory transmitters = _makeBytesArray(2, 20); + CCIPCapabilityConfiguration.OCR3Config memory config = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + uint32 donId = 1; + uint32 configCount = 1; + + bytes32 configDigest1 = s_ccipCC.computeConfigDigest(donId, configCount, config); + + donId = 2; + bytes32 configDigest2 = s_ccipCC.computeConfigDigest(donId, configCount, config); + + donId = 1; + configCount = 2; + bytes32 configDigest3 = s_ccipCC.computeConfigDigest(donId, configCount, config); + + configCount = 1; + config.pluginType = CCIPCapabilityConfiguration.PluginType.Execution; + bytes32 configDigest4 = s_ccipCC.computeConfigDigest(donId, configCount, config); + + assertNotEq(configDigest1, configDigest2, "config digests 1 and 2 must not match"); + assertNotEq(configDigest1, configDigest3, "config digests 1 and 3 must not match"); + assertNotEq(configDigest1, configDigest4, "config digests 1 and 4 must not match"); + + assertNotEq(configDigest2, configDigest3, "config digests 2 and 3 must not match"); + assertNotEq(configDigest2, configDigest4, "config digests 2 and 4 must not match"); + } + + function test_Fuzz__groupByPluginType_Success(uint256 numCommitCfgs, uint256 numExecCfgs) public { + vm.assume(numCommitCfgs >= 0 && numCommitCfgs < 3); + vm.assume(numExecCfgs >= 0 && numExecCfgs < 3); + + bytes32[] memory p2pIds = _makeBytes32Array(4, 0); + bytes[] memory signers = _makeBytesArray(4, 10); + bytes[] memory transmitters = _makeBytesArray(4, 20); + CCIPCapabilityConfiguration.OCR3Config[] memory cfgs = + new CCIPCapabilityConfiguration.OCR3Config[](numCommitCfgs + numExecCfgs); + for (uint256 i = 0; i < numCommitCfgs; i++) { + cfgs[i] = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: abi.encode("commit", i) + }); + } + for (uint256 i = 0; i < numExecCfgs; i++) { + cfgs[numCommitCfgs + i] = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Execution, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: abi.encode("exec", numCommitCfgs + i) + }); + } + ( + CCIPCapabilityConfiguration.OCR3Config[] memory commitCfgs, + CCIPCapabilityConfiguration.OCR3Config[] memory execCfgs + ) = s_ccipCC.groupByPluginType(cfgs); + + assertEq(commitCfgs.length, numCommitCfgs, "commitCfgs length must match"); + assertEq(execCfgs.length, numExecCfgs, "execCfgs length must match"); + for (uint256 i = 0; i < commitCfgs.length; i++) { + assertEq( + uint8(commitCfgs[i].pluginType), + uint8(CCIPCapabilityConfiguration.PluginType.Commit), + "plugin type must be commit" + ); + assertEq(commitCfgs[i].offchainConfig, abi.encode("commit", i), "offchain config must match"); + } + for (uint256 i = 0; i < execCfgs.length; i++) { + assertEq( + uint8(execCfgs[i].pluginType), + uint8(CCIPCapabilityConfiguration.PluginType.Execution), + "plugin type must be execution" + ); + assertEq(execCfgs[i].offchainConfig, abi.encode("exec", numCommitCfgs + i), "offchain config must match"); + } + } + + function test__computeNewConfigWithMeta_InitToRunning_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + uint32 donId = 1; + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory currentConfig = + new CCIPCapabilityConfiguration.OCR3ConfigWithMeta[](0); + CCIPCapabilityConfiguration.OCR3Config[] memory newConfig = new CCIPCapabilityConfiguration.OCR3Config[](1); + newConfig[0] = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPCapabilityConfiguration.ConfigState currentState = CCIPCapabilityConfiguration.ConfigState.Init; + CCIPCapabilityConfiguration.ConfigState newState = CCIPCapabilityConfiguration.ConfigState.Running; + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory newConfigWithMeta = + s_ccipCC.computeNewConfigWithMeta(donId, currentConfig, newConfig, currentState, newState); + assertEq(newConfigWithMeta.length, 1, "new config with meta length must be 1"); + assertEq(newConfigWithMeta[0].configCount, uint64(1), "config count must be 1"); + assertEq(uint8(newConfigWithMeta[0].config.pluginType), uint8(newConfig[0].pluginType), "plugin type must match"); + assertEq(newConfigWithMeta[0].config.offchainConfig, newConfig[0].offchainConfig, "offchain config must match"); + assertEq( + newConfigWithMeta[0].configDigest, + s_ccipCC.computeConfigDigest(donId, 1, newConfig[0]), + "config digest must match" + ); + + // This ensures that the test case is using correct inputs. + s_ccipCC.validateConfigTransition(currentConfig, newConfigWithMeta); + } + + function test__computeNewConfigWithMeta_RunningToStaging_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + uint32 donId = 1; + CCIPCapabilityConfiguration.OCR3Config memory blueConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPCapabilityConfiguration.OCR3Config memory greenConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit-new") + }); + + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory currentConfig = + new CCIPCapabilityConfiguration.OCR3ConfigWithMeta[](1); + currentConfig[0] = CCIPCapabilityConfiguration.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + + CCIPCapabilityConfiguration.OCR3Config[] memory newConfig = new CCIPCapabilityConfiguration.OCR3Config[](2); + // existing blue config first. + newConfig[0] = blueConfig; + // green config next. + newConfig[1] = greenConfig; + + CCIPCapabilityConfiguration.ConfigState currentState = CCIPCapabilityConfiguration.ConfigState.Running; + CCIPCapabilityConfiguration.ConfigState newState = CCIPCapabilityConfiguration.ConfigState.Staging; + + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory newConfigWithMeta = + s_ccipCC.computeNewConfigWithMeta(donId, currentConfig, newConfig, currentState, newState); + assertEq(newConfigWithMeta.length, 2, "new config with meta length must be 2"); + + assertEq(newConfigWithMeta[0].configCount, uint64(1), "config count of blue must be 1"); + assertEq( + uint8(newConfigWithMeta[0].config.pluginType), uint8(blueConfig.pluginType), "plugin type of blue must match" + ); + assertEq( + newConfigWithMeta[0].config.offchainConfig, blueConfig.offchainConfig, "offchain config of blue must match" + ); + assertEq( + newConfigWithMeta[0].configDigest, + s_ccipCC.computeConfigDigest(donId, 1, blueConfig), + "config digest of blue must match" + ); + + assertEq(newConfigWithMeta[1].configCount, uint64(2), "config count of green must be 2"); + assertEq( + uint8(newConfigWithMeta[1].config.pluginType), uint8(greenConfig.pluginType), "plugin type of green must match" + ); + assertEq( + newConfigWithMeta[1].config.offchainConfig, greenConfig.offchainConfig, "offchain config of green must match" + ); + assertEq( + newConfigWithMeta[1].configDigest, + s_ccipCC.computeConfigDigest(donId, 2, greenConfig), + "config digest of green must match" + ); + + // This ensures that the test case is using correct inputs. + s_ccipCC.validateConfigTransition(currentConfig, newConfigWithMeta); + } + + function test__computeNewConfigWithMeta_StagingToRunning_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + uint32 donId = 1; + CCIPCapabilityConfiguration.OCR3Config memory blueConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPCapabilityConfiguration.OCR3Config memory greenConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit-new") + }); + + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory currentConfig = + new CCIPCapabilityConfiguration.OCR3ConfigWithMeta[](2); + currentConfig[0] = CCIPCapabilityConfiguration.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + currentConfig[1] = CCIPCapabilityConfiguration.OCR3ConfigWithMeta({ + configCount: 2, + config: greenConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 2, greenConfig) + }); + CCIPCapabilityConfiguration.OCR3Config[] memory newConfig = new CCIPCapabilityConfiguration.OCR3Config[](1); + newConfig[0] = greenConfig; + + CCIPCapabilityConfiguration.ConfigState currentState = CCIPCapabilityConfiguration.ConfigState.Staging; + CCIPCapabilityConfiguration.ConfigState newState = CCIPCapabilityConfiguration.ConfigState.Running; + + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory newConfigWithMeta = + s_ccipCC.computeNewConfigWithMeta(donId, currentConfig, newConfig, currentState, newState); + + assertEq(newConfigWithMeta.length, 1, "new config with meta length must be 1"); + assertEq(newConfigWithMeta[0].configCount, uint64(2), "config count must be 2"); + assertEq(uint8(newConfigWithMeta[0].config.pluginType), uint8(greenConfig.pluginType), "plugin type must match"); + assertEq(newConfigWithMeta[0].config.offchainConfig, greenConfig.offchainConfig, "offchain config must match"); + assertEq( + newConfigWithMeta[0].configDigest, s_ccipCC.computeConfigDigest(donId, 2, greenConfig), "config digest must match" + ); + + // This ensures that the test case is using correct inputs. + s_ccipCC.validateConfigTransition(currentConfig, newConfigWithMeta); + } + + function test__validateConfigTransition_InitToRunning_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + uint32 donId = 1; + CCIPCapabilityConfiguration.OCR3Config memory blueConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory newConfig = + new CCIPCapabilityConfiguration.OCR3ConfigWithMeta[](1); + newConfig[0] = CCIPCapabilityConfiguration.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory currentConfig = + new CCIPCapabilityConfiguration.OCR3ConfigWithMeta[](0); + + s_ccipCC.validateConfigTransition(currentConfig, newConfig); + } + + function test__validateConfigTransition_RunningToStaging_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + uint32 donId = 1; + CCIPCapabilityConfiguration.OCR3Config memory blueConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPCapabilityConfiguration.OCR3Config memory greenConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit-new") + }); + + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory newConfig = + new CCIPCapabilityConfiguration.OCR3ConfigWithMeta[](2); + newConfig[0] = CCIPCapabilityConfiguration.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + newConfig[1] = CCIPCapabilityConfiguration.OCR3ConfigWithMeta({ + configCount: 2, + config: greenConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 2, greenConfig) + }); + + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory currentConfig = + new CCIPCapabilityConfiguration.OCR3ConfigWithMeta[](1); + currentConfig[0] = CCIPCapabilityConfiguration.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + + s_ccipCC.validateConfigTransition(currentConfig, newConfig); + } + + function test__validateConfigTransition_StagingToRunning_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + uint32 donId = 1; + CCIPCapabilityConfiguration.OCR3Config memory blueConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPCapabilityConfiguration.OCR3Config memory greenConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit-new") + }); + + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory currentConfig = + new CCIPCapabilityConfiguration.OCR3ConfigWithMeta[](2); + currentConfig[0] = CCIPCapabilityConfiguration.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + currentConfig[1] = CCIPCapabilityConfiguration.OCR3ConfigWithMeta({ + configCount: 2, + config: greenConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 2, greenConfig) + }); + + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory newConfig = + new CCIPCapabilityConfiguration.OCR3ConfigWithMeta[](1); + newConfig[0] = CCIPCapabilityConfiguration.OCR3ConfigWithMeta({ + configCount: 2, + config: greenConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 2, greenConfig) + }); + + s_ccipCC.validateConfigTransition(currentConfig, newConfig); + } + + // Reverts. + + function test_Fuzz__stateFromConfigLength_Reverts(uint256 configLen) public { + vm.assume(configLen > 2); + vm.expectRevert(abi.encodeWithSelector(CCIPCapabilityConfiguration.InvalidConfigLength.selector, configLen)); + s_ccipCC.stateFromConfigLength(configLen); + } + + function test__groupByPluginType_threeCommitConfigs_Reverts() public { + bytes32[] memory p2pIds = _makeBytes32Array(4, 0); + bytes[] memory signers = _makeBytesArray(4, 10); + bytes[] memory transmitters = _makeBytesArray(4, 20); + CCIPCapabilityConfiguration.OCR3Config[] memory cfgs = new CCIPCapabilityConfiguration.OCR3Config[](3); + for (uint256 i = 0; i < 3; i++) { + cfgs[i] = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: abi.encode("commit", i) + }); + } + vm.expectRevert(); + s_ccipCC.groupByPluginType(cfgs); + } + + function test__groupByPluginType_threeExecutionConfigs_Reverts() public { + bytes32[] memory p2pIds = _makeBytes32Array(4, 0); + bytes[] memory signers = _makeBytesArray(4, 10); + bytes[] memory transmitters = _makeBytesArray(4, 20); + CCIPCapabilityConfiguration.OCR3Config[] memory cfgs = new CCIPCapabilityConfiguration.OCR3Config[](3); + for (uint256 i = 0; i < 3; i++) { + cfgs[i] = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Execution, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: abi.encode("exec", i) + }); + } + vm.expectRevert(); + s_ccipCC.groupByPluginType(cfgs); + } + + function test__groupByPluginType_TooManyOCR3Configs_Reverts() public { + CCIPCapabilityConfiguration.OCR3Config[] memory cfgs = new CCIPCapabilityConfiguration.OCR3Config[](5); + vm.expectRevert(CCIPCapabilityConfiguration.TooManyOCR3Configs.selector); + s_ccipCC.groupByPluginType(cfgs); + } + + function test__validateConfigTransition_InitToRunning_WrongConfigCount_Reverts() public { + uint32 donId = 1; + CCIPCapabilityConfiguration.OCR3Config memory blueConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(_makeBytes32Array(4, 0), 0, 1), + p2pIds: _makeBytes32Array(4, 0), + signers: _makeBytesArray(4, 10), + transmitters: _makeBytesArray(4, 20), + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory newConfig = + new CCIPCapabilityConfiguration.OCR3ConfigWithMeta[](1); + newConfig[0] = CCIPCapabilityConfiguration.OCR3ConfigWithMeta({ + configCount: 0, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory currentConfig = + new CCIPCapabilityConfiguration.OCR3ConfigWithMeta[](0); + + vm.expectRevert(abi.encodeWithSelector(CCIPCapabilityConfiguration.WrongConfigCount.selector, 0, 1)); + s_ccipCC.validateConfigTransition(currentConfig, newConfig); + } + + function test__validateConfigTransition_RunningToStaging_WrongConfigDigestBlueGreen_Reverts() public { + uint32 donId = 1; + CCIPCapabilityConfiguration.OCR3Config memory blueConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(_makeBytes32Array(4, 0), 0, 1), + p2pIds: _makeBytes32Array(4, 0), + signers: _makeBytesArray(4, 10), + transmitters: _makeBytesArray(4, 20), + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPCapabilityConfiguration.OCR3Config memory greenConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(_makeBytes32Array(4, 0), 0, 1), + p2pIds: _makeBytes32Array(4, 0), + signers: _makeBytesArray(4, 10), + transmitters: _makeBytesArray(4, 20), + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit-new") + }); + + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory currentConfig = + new CCIPCapabilityConfiguration.OCR3ConfigWithMeta[](1); + currentConfig[0] = CCIPCapabilityConfiguration.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory newConfig = + new CCIPCapabilityConfiguration.OCR3ConfigWithMeta[](2); + newConfig[0] = CCIPCapabilityConfiguration.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 3, blueConfig) // wrong config digest (due to diff config count) + }); + newConfig[1] = CCIPCapabilityConfiguration.OCR3ConfigWithMeta({ + configCount: 2, + config: greenConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 2, greenConfig) + }); + + vm.expectRevert( + abi.encodeWithSelector( + CCIPCapabilityConfiguration.WrongConfigDigestBlueGreen.selector, + s_ccipCC.computeConfigDigest(donId, 3, blueConfig), + s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + ) + ); + s_ccipCC.validateConfigTransition(currentConfig, newConfig); + } + + function test__validateConfigTransition_RunningToStaging_WrongConfigCount_Reverts() public { + uint32 donId = 1; + CCIPCapabilityConfiguration.OCR3Config memory blueConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(_makeBytes32Array(4, 0), 0, 1), + p2pIds: _makeBytes32Array(4, 0), + signers: _makeBytesArray(4, 10), + transmitters: _makeBytesArray(4, 20), + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPCapabilityConfiguration.OCR3Config memory greenConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(_makeBytes32Array(4, 0), 0, 1), + p2pIds: _makeBytes32Array(4, 0), + signers: _makeBytesArray(4, 10), + transmitters: _makeBytesArray(4, 20), + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit-new") + }); + + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory currentConfig = + new CCIPCapabilityConfiguration.OCR3ConfigWithMeta[](1); + currentConfig[0] = CCIPCapabilityConfiguration.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory newConfig = + new CCIPCapabilityConfiguration.OCR3ConfigWithMeta[](2); + newConfig[0] = CCIPCapabilityConfiguration.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + newConfig[1] = CCIPCapabilityConfiguration.OCR3ConfigWithMeta({ + configCount: 3, // wrong config count + config: greenConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 3, greenConfig) + }); + + vm.expectRevert(abi.encodeWithSelector(CCIPCapabilityConfiguration.WrongConfigCount.selector, 3, 2)); + s_ccipCC.validateConfigTransition(currentConfig, newConfig); + } + + function test__validateConfigTransition_StagingToRunning_WrongConfigDigest_Reverts() public { + uint32 donId = 1; + CCIPCapabilityConfiguration.OCR3Config memory blueConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(_makeBytes32Array(4, 0), 0, 1), + p2pIds: _makeBytes32Array(4, 0), + signers: _makeBytesArray(4, 10), + transmitters: _makeBytesArray(4, 20), + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPCapabilityConfiguration.OCR3Config memory greenConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(_makeBytes32Array(4, 0), 0, 1), + p2pIds: _makeBytes32Array(4, 0), + signers: _makeBytesArray(4, 10), + transmitters: _makeBytesArray(4, 20), + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit-new") + }); + + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory currentConfig = + new CCIPCapabilityConfiguration.OCR3ConfigWithMeta[](2); + currentConfig[0] = CCIPCapabilityConfiguration.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + currentConfig[1] = CCIPCapabilityConfiguration.OCR3ConfigWithMeta({ + configCount: 2, + config: greenConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 2, greenConfig) + }); + + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory newConfig = + new CCIPCapabilityConfiguration.OCR3ConfigWithMeta[](1); + newConfig[0] = CCIPCapabilityConfiguration.OCR3ConfigWithMeta({ + configCount: 2, + config: greenConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 3, greenConfig) // wrong config digest + }); + + vm.expectRevert( + abi.encodeWithSelector( + CCIPCapabilityConfiguration.WrongConfigDigest.selector, + s_ccipCC.computeConfigDigest(donId, 3, greenConfig), + s_ccipCC.computeConfigDigest(donId, 2, greenConfig) + ) + ); + s_ccipCC.validateConfigTransition(currentConfig, newConfig); + } + + function test__validateConfigTransition_NonExistentConfigTransition_Reverts() public { + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory currentConfig = + new CCIPCapabilityConfiguration.OCR3ConfigWithMeta[](3); + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory newConfig = + new CCIPCapabilityConfiguration.OCR3ConfigWithMeta[](1); + vm.expectRevert(CCIPCapabilityConfiguration.NonExistentConfigTransition.selector); + s_ccipCC.validateConfigTransition(currentConfig, newConfig); + } +} + +contract CCIPCapabilityConfiguration__updatePluginConfig is CCIPCapabilityConfigurationSetup { + // Successes. + + function test__updatePluginConfig_InitToRunning_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + uint32 donId = 1; + CCIPCapabilityConfiguration.OCR3Config memory blueConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPCapabilityConfiguration.OCR3Config[] memory configs = new CCIPCapabilityConfiguration.OCR3Config[](1); + configs[0] = blueConfig; + + s_ccipCC.updatePluginConfig(donId, CCIPCapabilityConfiguration.PluginType.Commit, configs); + + // should see the updated config in the contract state. + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory storedConfig = + s_ccipCC.getOCRConfig(donId, CCIPCapabilityConfiguration.PluginType.Commit); + assertEq(storedConfig.length, 1, "don config length must be 1"); + assertEq(storedConfig[0].configCount, uint64(1), "config count must be 1"); + assertEq(uint256(storedConfig[0].config.pluginType), uint256(blueConfig.pluginType), "plugin type must match"); + } + + function test__updatePluginConfig_RunningToStaging_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + // add blue config. + uint32 donId = 1; + CCIPCapabilityConfiguration.PluginType pluginType = CCIPCapabilityConfiguration.PluginType.Commit; + CCIPCapabilityConfiguration.OCR3Config memory blueConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPCapabilityConfiguration.OCR3Config[] memory startConfigs = new CCIPCapabilityConfiguration.OCR3Config[](1); + startConfigs[0] = blueConfig; + + // add blue AND green config to indicate an update. + s_ccipCC.updatePluginConfig(donId, CCIPCapabilityConfiguration.PluginType.Commit, startConfigs); + CCIPCapabilityConfiguration.OCR3Config memory greenConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit-new") + }); + CCIPCapabilityConfiguration.OCR3Config[] memory blueAndGreen = new CCIPCapabilityConfiguration.OCR3Config[](2); + blueAndGreen[0] = blueConfig; + blueAndGreen[1] = greenConfig; + + s_ccipCC.updatePluginConfig(donId, CCIPCapabilityConfiguration.PluginType.Commit, blueAndGreen); + + // should see the updated config in the contract state. + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory storedConfig = + s_ccipCC.getOCRConfig(donId, CCIPCapabilityConfiguration.PluginType.Commit); + assertEq(storedConfig.length, 2, "don config length must be 2"); + // 0 index is blue config, 1 index is green config. + assertEq(storedConfig[1].configCount, uint64(2), "config count must be 2"); + assertEq( + uint256(storedConfig[0].config.pluginType), + uint256(CCIPCapabilityConfiguration.PluginType.Commit), + "plugin type must match" + ); + assertEq( + uint256(storedConfig[1].config.pluginType), + uint256(CCIPCapabilityConfiguration.PluginType.Commit), + "plugin type must match" + ); + assertEq(storedConfig[0].config.offchainConfig, bytes("commit"), "blue offchain config must match"); + assertEq(storedConfig[1].config.offchainConfig, bytes("commit-new"), "green offchain config must match"); + } + + function test__updatePluginConfig_StagingToRunning_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + // add blue config. + uint32 donId = 1; + CCIPCapabilityConfiguration.PluginType pluginType = CCIPCapabilityConfiguration.PluginType.Commit; + CCIPCapabilityConfiguration.OCR3Config memory blueConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPCapabilityConfiguration.OCR3Config[] memory startConfigs = new CCIPCapabilityConfiguration.OCR3Config[](1); + startConfigs[0] = blueConfig; + + // add blue AND green config to indicate an update. + s_ccipCC.updatePluginConfig(donId, CCIPCapabilityConfiguration.PluginType.Commit, startConfigs); + CCIPCapabilityConfiguration.OCR3Config memory greenConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit-new") + }); + CCIPCapabilityConfiguration.OCR3Config[] memory blueAndGreen = new CCIPCapabilityConfiguration.OCR3Config[](2); + blueAndGreen[0] = blueConfig; + blueAndGreen[1] = greenConfig; + + s_ccipCC.updatePluginConfig(donId, CCIPCapabilityConfiguration.PluginType.Commit, blueAndGreen); + + // should see the updated config in the contract state. + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory storedConfig = + s_ccipCC.getOCRConfig(donId, CCIPCapabilityConfiguration.PluginType.Commit); + assertEq(storedConfig.length, 2, "don config length must be 2"); + // 0 index is blue config, 1 index is green config. + assertEq(storedConfig[1].configCount, uint64(2), "config count must be 2"); + assertEq( + uint256(storedConfig[0].config.pluginType), + uint256(CCIPCapabilityConfiguration.PluginType.Commit), + "plugin type must match" + ); + assertEq( + uint256(storedConfig[1].config.pluginType), + uint256(CCIPCapabilityConfiguration.PluginType.Commit), + "plugin type must match" + ); + assertEq(storedConfig[0].config.offchainConfig, bytes("commit"), "blue offchain config must match"); + assertEq(storedConfig[1].config.offchainConfig, bytes("commit-new"), "green offchain config must match"); + + // promote green to blue. + CCIPCapabilityConfiguration.OCR3Config[] memory promote = new CCIPCapabilityConfiguration.OCR3Config[](1); + promote[0] = greenConfig; + + s_ccipCC.updatePluginConfig(donId, CCIPCapabilityConfiguration.PluginType.Commit, promote); + + // should see the updated config in the contract state. + storedConfig = s_ccipCC.getOCRConfig(donId, CCIPCapabilityConfiguration.PluginType.Commit); + assertEq(storedConfig.length, 1, "don config length must be 1"); + assertEq(storedConfig[0].configCount, uint64(2), "config count must be 2"); + assertEq( + uint256(storedConfig[0].config.pluginType), + uint256(CCIPCapabilityConfiguration.PluginType.Commit), + "plugin type must match" + ); + assertEq(storedConfig[0].config.offchainConfig, bytes("commit-new"), "green offchain config must match"); + } + + // Reverts. + function test__updatePluginConfig_InvalidConfigLength_Reverts() public { + uint32 donId = 1; + CCIPCapabilityConfiguration.OCR3Config[] memory newConfig = new CCIPCapabilityConfiguration.OCR3Config[](3); + vm.expectRevert(abi.encodeWithSelector(CCIPCapabilityConfiguration.InvalidConfigLength.selector, uint256(3))); + s_ccipCC.updatePluginConfig(donId, CCIPCapabilityConfiguration.PluginType.Commit, newConfig); + } + + function test__updatePluginConfig_InvalidConfigStateTransition_Reverts() public { + uint32 donId = 1; + CCIPCapabilityConfiguration.OCR3Config[] memory newConfig = new CCIPCapabilityConfiguration.OCR3Config[](2); + // 0 -> 2 is an invalid state transition. + vm.expectRevert(abi.encodeWithSelector(CCIPCapabilityConfiguration.InvalidConfigStateTransition.selector, 0, 2)); + s_ccipCC.updatePluginConfig(donId, CCIPCapabilityConfiguration.PluginType.Commit, newConfig); + } +} + +contract CCIPCapabilityConfiguration_beforeCapabilityConfigSet is CCIPCapabilityConfigurationSetup { + // Successes. + function test_beforeCapabilityConfigSet_ZeroLengthConfig_Success() public { + changePrank(CAPABILITY_REGISTRY); + + CCIPCapabilityConfiguration.OCR3Config[] memory configs = new CCIPCapabilityConfiguration.OCR3Config[](0); + bytes memory encodedConfigs = abi.encode(configs); + s_ccipCC.beforeCapabilityConfigSet(new bytes32[](0), encodedConfigs, 1, 1); + } + + function test_beforeCapabilityConfigSet_CommitConfigOnly_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + changePrank(CAPABILITY_REGISTRY); + + uint32 donId = 1; + CCIPCapabilityConfiguration.OCR3Config memory blueConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPCapabilityConfiguration.OCR3Config[] memory configs = new CCIPCapabilityConfiguration.OCR3Config[](1); + configs[0] = blueConfig; + + bytes memory encoded = abi.encode(configs); + s_ccipCC.beforeCapabilityConfigSet(new bytes32[](0), encoded, 1, donId); + + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory storedConfigs = + s_ccipCC.getOCRConfig(donId, CCIPCapabilityConfiguration.PluginType.Commit); + assertEq(storedConfigs.length, 1, "config length must be 1"); + assertEq(storedConfigs[0].configCount, uint64(1), "config count must be 1"); + assertEq( + uint256(storedConfigs[0].config.pluginType), + uint256(CCIPCapabilityConfiguration.PluginType.Commit), + "plugin type must be commit" + ); + } + + function test_beforeCapabilityConfigSet_ExecConfigOnly_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + changePrank(CAPABILITY_REGISTRY); + + uint32 donId = 1; + CCIPCapabilityConfiguration.OCR3Config memory blueConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Execution, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("exec") + }); + CCIPCapabilityConfiguration.OCR3Config[] memory configs = new CCIPCapabilityConfiguration.OCR3Config[](1); + configs[0] = blueConfig; + + bytes memory encoded = abi.encode(configs); + s_ccipCC.beforeCapabilityConfigSet(new bytes32[](0), encoded, 1, donId); + + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory storedConfigs = + s_ccipCC.getOCRConfig(donId, CCIPCapabilityConfiguration.PluginType.Execution); + assertEq(storedConfigs.length, 1, "config length must be 1"); + assertEq(storedConfigs[0].configCount, uint64(1), "config count must be 1"); + assertEq( + uint256(storedConfigs[0].config.pluginType), + uint256(CCIPCapabilityConfiguration.PluginType.Execution), + "plugin type must be execution" + ); + } + + function test_beforeCapabilityConfigSet_CommitAndExecConfig_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + changePrank(CAPABILITY_REGISTRY); + + uint32 donId = 1; + CCIPCapabilityConfiguration.OCR3Config memory blueCommitConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPCapabilityConfiguration.OCR3Config memory blueExecConfig = CCIPCapabilityConfiguration.OCR3Config({ + pluginType: CCIPCapabilityConfiguration.PluginType.Execution, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("exec") + }); + CCIPCapabilityConfiguration.OCR3Config[] memory configs = new CCIPCapabilityConfiguration.OCR3Config[](2); + configs[0] = blueExecConfig; + configs[1] = blueCommitConfig; + + bytes memory encoded = abi.encode(configs); + s_ccipCC.beforeCapabilityConfigSet(new bytes32[](0), encoded, 1, donId); + + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory storedExecConfigs = + s_ccipCC.getOCRConfig(donId, CCIPCapabilityConfiguration.PluginType.Execution); + assertEq(storedExecConfigs.length, 1, "config length must be 1"); + assertEq(storedExecConfigs[0].configCount, uint64(1), "config count must be 1"); + assertEq( + uint256(storedExecConfigs[0].config.pluginType), + uint256(CCIPCapabilityConfiguration.PluginType.Execution), + "plugin type must be execution" + ); + + CCIPCapabilityConfiguration.OCR3ConfigWithMeta[] memory storedCommitConfigs = + s_ccipCC.getOCRConfig(donId, CCIPCapabilityConfiguration.PluginType.Commit); + assertEq(storedCommitConfigs.length, 1, "config length must be 1"); + assertEq(storedCommitConfigs[0].configCount, uint64(1), "config count must be 1"); + assertEq( + uint256(storedCommitConfigs[0].config.pluginType), + uint256(CCIPCapabilityConfiguration.PluginType.Commit), + "plugin type must be commit" + ); + } + + // Reverts. + + function test_beforeCapabilityConfigSet_OnlyCapabilityRegistryCanCall_Reverts() public { + bytes32[] memory nodes = new bytes32[](0); + bytes memory config = bytes(""); + uint64 configCount = 1; + uint32 donId = 1; + vm.expectRevert(CCIPCapabilityConfiguration.OnlyCapabilityRegistryCanCall.selector); + s_ccipCC.beforeCapabilityConfigSet(nodes, config, configCount, donId); + } +} diff --git a/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol index 2db164eaf4..ad89b70f63 100644 --- a/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol +++ b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol @@ -1,6 +1,8 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; +import {AuthorizedCallers} from "../../../shared/access/AuthorizedCallers.sol"; +import {NonceManager} from "../../NonceManager.sol"; import {TokenAdminRegistry} from "../../tokenAdminRegistry/TokenAdminRegistry.sol"; import "../helpers/MerkleHelper.sol"; import "../offRamp/EVM2EVMMultiOffRampSetup.t.sol"; @@ -17,6 +19,7 @@ contract MultiRampsE2E is EVM2EVMMultiOnRampSetup, EVM2EVMMultiOffRampSetup { Router internal s_sourceRouter2; EVM2EVMMultiOnRampHelper internal s_onRamp2; TokenAdminRegistry internal s_tokenAdminRegistry2; + NonceManager internal s_nonceManager2; bytes32 internal s_metadataHash2; @@ -55,10 +58,22 @@ contract MultiRampsE2E is EVM2EVMMultiOnRampSetup, EVM2EVMMultiOffRampSetup { ); } - // Deploy the new source chain onramp - // Outsource to shared helper function with EVM2EVMMultiOnRampSetup - (s_onRamp2, s_metadataHash2) = - _deployOnRamp(SOURCE_CHAIN_SELECTOR + 1, address(s_sourceRouter2), address(s_tokenAdminRegistry2)); + s_nonceManager2 = new NonceManager(new address[](0)); + + ( + // Deploy the new source chain onramp + // Outsource to shared helper function with EVM2EVMMultiOnRampSetup + s_onRamp2, + s_metadataHash2 + ) = _deployOnRamp( + SOURCE_CHAIN_SELECTOR + 1, address(s_sourceRouter2), address(s_nonceManager2), address(s_tokenAdminRegistry2) + ); + + address[] memory authorizedCallers = new address[](1); + authorizedCallers[0] = address(s_onRamp2); + s_nonceManager2.applyAuthorizedCallerUpdates( + AuthorizedCallers.AuthorizedCallerArgs({addedCallers: authorizedCallers, removedCallers: new address[](0)}) + ); // Enable destination chain on new source chain router Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); @@ -138,10 +153,8 @@ contract MultiRampsE2E is EVM2EVMMultiOnRampSetup, EVM2EVMMultiOffRampSetup { EVM2EVMMultiOffRamp.CommitReport memory report = EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); - bytes memory commitReport = abi.encode(report); - vm.resumeGasMetering(); - s_offRamp.reportCommit(commitReport, ++s_latestEpochAndRound); + _commit(report, ++s_latestSequenceNumber); vm.pauseGasMetering(); bytes32[] memory proofs = new bytes32[](0); diff --git a/contracts/src/v0.8/ccip/test/helpers/CCIPCapabilityConfigurationHelper.sol b/contracts/src/v0.8/ccip/test/helpers/CCIPCapabilityConfigurationHelper.sol new file mode 100644 index 0000000000..7acc65f9bd --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/CCIPCapabilityConfigurationHelper.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.24; + +import {CCIPCapabilityConfiguration} from "../../capability/CCIPCapabilityConfiguration.sol"; + +contract CCIPCapabilityConfigurationHelper is CCIPCapabilityConfiguration { + constructor(address capabilityRegistry) CCIPCapabilityConfiguration(capabilityRegistry) {} + + function stateFromConfigLength(uint256 configLength) public pure returns (ConfigState) { + return _stateFromConfigLength(configLength); + } + + function validateConfigStateTransition(ConfigState currentState, ConfigState newState) public pure { + _validateConfigStateTransition(currentState, newState); + } + + function validateConfigTransition( + OCR3ConfigWithMeta[] memory currentConfig, + OCR3ConfigWithMeta[] memory newConfigWithMeta + ) public pure { + _validateConfigTransition(currentConfig, newConfigWithMeta); + } + + function computeNewConfigWithMeta( + uint32 donId, + OCR3ConfigWithMeta[] memory currentConfig, + OCR3Config[] memory newConfig, + ConfigState currentState, + ConfigState newState + ) public view returns (OCR3ConfigWithMeta[] memory) { + return _computeNewConfigWithMeta(donId, currentConfig, newConfig, currentState, newState); + } + + function groupByPluginType(OCR3Config[] memory ocr3Configs) + public + pure + returns (OCR3Config[] memory commitConfigs, OCR3Config[] memory execConfigs) + { + return _groupByPluginType(ocr3Configs); + } + + function computeConfigDigest( + uint32 donId, + uint64 configCount, + OCR3Config memory ocr3Config + ) public pure returns (bytes32) { + return _computeConfigDigest(donId, configCount, ocr3Config); + } + + function validateConfig(OCR3Config memory cfg) public view { + _validateConfig(cfg); + } + + function updatePluginConfig(uint32 donId, PluginType pluginType, OCR3Config[] memory newConfig) public { + _updatePluginConfig(donId, pluginType, newConfig); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOffRampHelper.sol b/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOffRampHelper.sol index 9d0c5d14f5..83b9569425 100644 --- a/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOffRampHelper.sol +++ b/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOffRampHelper.sol @@ -30,13 +30,30 @@ contract EVM2EVMMultiOffRampHelper is EVM2EVMMultiOffRamp, IgnoreContractSize { return _metadataHash(sourceChainSelector, onRamp, Internal.EVM_2_EVM_MESSAGE_HASH); } + function releaseOrMintSingleToken( + uint256 sourceTokenAmount, + bytes calldata originalSender, + address receiver, + uint64 sourceChainSelector, + Internal.SourceTokenData calldata sourceTokenData, + bytes calldata offchainTokenData + ) external returns (Client.EVMTokenAmount memory) { + return _releaseOrMintSingleToken( + sourceTokenAmount, originalSender, receiver, sourceChainSelector, sourceTokenData, offchainTokenData + ); + } + function releaseOrMintTokens( Client.EVMTokenAmount[] memory sourceTokenAmounts, - EVM2EVMMultiOffRamp.Any2EVMMessageRoute memory messageRoute, + bytes memory originalSender, + address receiver, + uint64 sourceChainSelector, bytes[] calldata sourceTokenData, bytes[] calldata offchainTokenData ) external returns (Client.EVMTokenAmount[] memory) { - return _releaseOrMintTokens(sourceTokenAmounts, messageRoute, sourceTokenData, offchainTokenData); + return _releaseOrMintTokens( + sourceTokenAmounts, originalSender, receiver, sourceChainSelector, sourceTokenData, offchainTokenData + ); } function trialExecute( @@ -46,14 +63,6 @@ contract EVM2EVMMultiOffRampHelper is EVM2EVMMultiOffRamp, IgnoreContractSize { return _trialExecute(message, offchainTokenData); } - function reportExec(bytes calldata executableReports) external { - _reportExec(executableReports); - } - - function reportCommit(bytes calldata commitReport, uint40 epochAndRound) external { - _reportCommit(commitReport, epochAndRound); - } - function executeSingleReport( Internal.ExecutionReportSingleChain memory rep, uint256[] memory manualExecGasLimits diff --git a/contracts/src/v0.8/ccip/test/helpers/MessageInterceptorHelper.sol b/contracts/src/v0.8/ccip/test/helpers/MessageInterceptorHelper.sol index ac7f8004ca..104c996857 100644 --- a/contracts/src/v0.8/ccip/test/helpers/MessageInterceptorHelper.sol +++ b/contracts/src/v0.8/ccip/test/helpers/MessageInterceptorHelper.sol @@ -16,14 +16,14 @@ contract MessageInterceptorHelper is IMessageInterceptor { } /// @inheritdoc IMessageInterceptor - function onIncomingMessage(Client.Any2EVMMessage memory message) external view { + function onInboundMessage(Client.Any2EVMMessage memory message) external view { if (s_invalidMessageIds[message.messageId]) { revert IncomingMessageValidationError(bytes("Invalid message")); } } /// @inheritdoc IMessageInterceptor - function onOutgoingMessage(Client.EVM2AnyMessage memory, uint64) external pure { + function onOutboundMessage(Client.EVM2AnyMessage memory, uint64) external pure { // TODO: to be implemented return; } diff --git a/contracts/src/v0.8/ccip/test/ocr/MultiOCR3Base.t.sol b/contracts/src/v0.8/ccip/test/ocr/MultiOCR3Base.t.sol index b937fb9ff5..5b784bf721 100644 --- a/contracts/src/v0.8/ccip/test/ocr/MultiOCR3Base.t.sol +++ b/contracts/src/v0.8/ccip/test/ocr/MultiOCR3Base.t.sol @@ -24,7 +24,6 @@ contract MultiOCR3Base_transmit is MultiOCR3BaseSetup { ocrPluginType: 0, configDigest: s_configDigest1, F: 1, - uniqueReports: false, isSignatureVerificationEnabled: true, signers: s_validSigners, transmitters: s_validTransmitters @@ -33,7 +32,6 @@ contract MultiOCR3Base_transmit is MultiOCR3BaseSetup { ocrPluginType: 1, configDigest: s_configDigest2, F: 2, - uniqueReports: true, isSignatureVerificationEnabled: true, signers: s_validSigners, transmitters: s_validTransmitters @@ -42,7 +40,6 @@ contract MultiOCR3Base_transmit is MultiOCR3BaseSetup { ocrPluginType: 2, configDigest: s_configDigest3, F: 1, - uniqueReports: false, isSignatureVerificationEnabled: false, signers: s_emptySigners, transmitters: s_validTransmitters @@ -51,42 +48,24 @@ contract MultiOCR3Base_transmit is MultiOCR3BaseSetup { s_multiOCR3.setOCR3Configs(ocrConfigs); } - function test_TransmitSignersNonUniqueReports_gas_Success() public { + function test_TransmitSigners_gas_Success() public { vm.pauseGasMetering(); bytes32[3] memory reportContext = [s_configDigest1, s_configDigest1, s_configDigest1]; // F = 2, need 2 signatures (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = - _getSignaturesForDigest(s_validSignerKeys, s_configDigest1, REPORT, 2); + _getSignaturesForDigest(s_validSignerKeys, REPORT, reportContext, 2); s_multiOCR3.setTransmitOcrPluginType(0); vm.expectEmit(); - emit MultiOCR3Base.Transmitted(0, s_configDigest1, uint32(uint256(s_configDigest1) >> 8)); + emit MultiOCR3Base.Transmitted(0, s_configDigest1, uint64(uint256(s_configDigest1))); vm.startPrank(s_validTransmitters[1]); vm.resumeGasMetering(); s_multiOCR3.transmitWithSignatures(reportContext, REPORT, rs, ss, rawVs); } - function test_TransmitUniqueReportSigners_gas_Success() public { - vm.pauseGasMetering(); - bytes32[3] memory reportContext = [s_configDigest2, s_configDigest2, s_configDigest2]; - - // F = 1, need 5 signatures - (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = - _getSignaturesForDigest(s_validSignerKeys, s_configDigest2, REPORT, 5); - - s_multiOCR3.setTransmitOcrPluginType(1); - - vm.expectEmit(); - emit MultiOCR3Base.Transmitted(1, s_configDigest2, uint32(uint256(s_configDigest2) >> 8)); - - vm.startPrank(s_validTransmitters[2]); - vm.resumeGasMetering(); - s_multiOCR3.transmitWithSignatures(reportContext, REPORT, rs, ss, rawVs); - } - function test_TransmitWithoutSignatureVerification_gas_Success() public { vm.pauseGasMetering(); bytes32[3] memory reportContext = [s_configDigest3, s_configDigest3, s_configDigest3]; @@ -94,18 +73,14 @@ contract MultiOCR3Base_transmit is MultiOCR3BaseSetup { s_multiOCR3.setTransmitOcrPluginType(2); vm.expectEmit(); - emit MultiOCR3Base.Transmitted(2, s_configDigest3, uint32(uint256(s_configDigest3) >> 8)); + emit MultiOCR3Base.Transmitted(2, s_configDigest3, uint64(uint256(s_configDigest3))); vm.startPrank(s_validTransmitters[0]); vm.resumeGasMetering(); s_multiOCR3.transmitWithoutSignatures(reportContext, REPORT); } - function test_Fuzz_TransmitSignersWithSignatures_Success( - uint8 F, - uint64 randomAddressOffset, - bool uniqueReports - ) public { + function test_Fuzz_TransmitSignersWithSignatures_Success(uint8 F, uint64 randomAddressOffset) public { vm.pauseGasMetering(); F = uint8(bound(F, 1, 3)); @@ -133,7 +108,6 @@ contract MultiOCR3Base_transmit is MultiOCR3BaseSetup { ocrPluginType: 3, configDigest: s_configDigest1, F: F, - uniqueReports: uniqueReports, isSignatureVerificationEnabled: true, signers: signers, transmitters: transmitters @@ -147,7 +121,7 @@ contract MultiOCR3Base_transmit is MultiOCR3BaseSetup { bytes32[3] memory reportContext = [s_configDigest1, s_configDigest1, s_configDigest1]; // condition: matches signature expectation for transmit - uint8 numSignatures = uniqueReports ? ((signersLength + F) / 2 + 1) : (F + 1); + uint8 numSignatures = F + 1; uint256[] memory pickedSignerKeys = new uint256[](numSignatures); // Randomise picked signers with random offset @@ -156,10 +130,10 @@ contract MultiOCR3Base_transmit is MultiOCR3BaseSetup { } (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = - _getSignaturesForDigest(pickedSignerKeys, s_configDigest1, REPORT, numSignatures); + _getSignaturesForDigest(pickedSignerKeys, REPORT, reportContext, numSignatures); vm.expectEmit(); - emit MultiOCR3Base.Transmitted(3, s_configDigest1, uint32(uint256(s_configDigest1) >> 8)); + emit MultiOCR3Base.Transmitted(3, s_configDigest1, uint64(uint256(s_configDigest1))); vm.resumeGasMetering(); s_multiOCR3.transmitWithSignatures(reportContext, REPORT, rs, ss, rawVs); @@ -170,7 +144,7 @@ contract MultiOCR3Base_transmit is MultiOCR3BaseSetup { bytes32[3] memory reportContext = [s_configDigest1, s_configDigest1, s_configDigest1]; (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = - _getSignaturesForDigest(s_validSignerKeys, s_configDigest1, REPORT, 2); + _getSignaturesForDigest(s_validSignerKeys, REPORT, reportContext, 2); s_multiOCR3.setTransmitOcrPluginType(0); @@ -198,7 +172,7 @@ contract MultiOCR3Base_transmit is MultiOCR3BaseSetup { // 1 signature too many (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = - _getSignaturesForDigest(s_validSignerKeys, s_configDigest2, REPORT, 6); + _getSignaturesForDigest(s_validSignerKeys, REPORT, reportContext, 6); s_multiOCR3.setTransmitOcrPluginType(1); @@ -212,7 +186,7 @@ contract MultiOCR3Base_transmit is MultiOCR3BaseSetup { // Missing 1 signature for unique report (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = - _getSignaturesForDigest(s_validSignerKeys, s_configDigest2, REPORT, 4); + _getSignaturesForDigest(s_validSignerKeys, REPORT, reportContext, 4); s_multiOCR3.setTransmitOcrPluginType(1); @@ -225,7 +199,7 @@ contract MultiOCR3Base_transmit is MultiOCR3BaseSetup { bytes32 configDigest; bytes32[3] memory reportContext = [configDigest, configDigest, configDigest]; - (,,, bytes32 rawVs) = _getSignaturesForDigest(s_validSignerKeys, s_configDigest1, REPORT, 2); + (,,, bytes32 rawVs) = _getSignaturesForDigest(s_validSignerKeys, REPORT, reportContext, 2); s_multiOCR3.setTransmitOcrPluginType(0); @@ -261,7 +235,7 @@ contract MultiOCR3Base_transmit is MultiOCR3BaseSetup { bytes32[3] memory reportContext = [s_configDigest1, s_configDigest1, s_configDigest1]; (bytes32[] memory rs, bytes32[] memory ss, uint8[] memory vs, bytes32 rawVs) = - _getSignaturesForDigest(s_validSignerKeys, s_configDigest1, REPORT, 2); + _getSignaturesForDigest(s_validSignerKeys, REPORT, reportContext, 2); rs[1] = rs[0]; ss[1] = ss[0]; @@ -279,7 +253,7 @@ contract MultiOCR3Base_transmit is MultiOCR3BaseSetup { bytes32[3] memory reportContext = [s_configDigest1, s_configDigest1, s_configDigest1]; (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = - _getSignaturesForDigest(s_validSignerKeys, s_configDigest1, REPORT, 2); + _getSignaturesForDigest(s_validSignerKeys, REPORT, reportContext, 2); rs[0] = s_configDigest1; ss = rs; @@ -367,7 +341,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { ocrPluginType: 0, configDigest: _getBasicConfigDigest(F, s_validSigners, s_validTransmitters), F: F, - uniqueReports: false, isSignatureVerificationEnabled: true, signers: s_validSigners, transmitters: s_validTransmitters @@ -392,7 +365,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { configDigest: ocrConfigs[0].configDigest, F: ocrConfigs[0].F, n: uint8(ocrConfigs[0].signers.length), - uniqueReports: ocrConfigs[0].uniqueReports, isSignatureVerificationEnabled: ocrConfigs[0].isSignatureVerificationEnabled }), signers: s_validSigners, @@ -412,7 +384,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { ocrPluginType: 0, configDigest: _getBasicConfigDigest(F, signers, s_validTransmitters), F: F, - uniqueReports: false, isSignatureVerificationEnabled: false, signers: signers, transmitters: s_validTransmitters @@ -437,7 +408,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { configDigest: ocrConfigs[0].configDigest, F: ocrConfigs[0].F, n: uint8(ocrConfigs[0].signers.length), - uniqueReports: ocrConfigs[0].uniqueReports, isSignatureVerificationEnabled: ocrConfigs[0].isSignatureVerificationEnabled }), signers: signers, @@ -456,7 +426,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { ocrPluginType: 0, configDigest: _getBasicConfigDigest(F, new address[](0), s_validTransmitters), F: F, - uniqueReports: false, isSignatureVerificationEnabled: false, signers: s_validSigners, transmitters: s_validTransmitters @@ -481,7 +450,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { configDigest: ocrConfigs[0].configDigest, F: ocrConfigs[0].F, n: 0, - uniqueReports: ocrConfigs[0].uniqueReports, isSignatureVerificationEnabled: ocrConfigs[0].isSignatureVerificationEnabled }), signers: s_emptySigners, @@ -506,7 +474,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { ocrPluginType: 0, configDigest: _getBasicConfigDigest(2, s_validSigners, s_validTransmitters), F: 2, - uniqueReports: false, isSignatureVerificationEnabled: true, signers: s_validSigners, transmitters: s_validTransmitters @@ -515,7 +482,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { ocrPluginType: 1, configDigest: _getBasicConfigDigest(1, s_validSigners, s_validTransmitters), F: 1, - uniqueReports: true, isSignatureVerificationEnabled: true, signers: s_validSigners, transmitters: s_validTransmitters @@ -524,7 +490,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { ocrPluginType: 2, configDigest: _getBasicConfigDigest(1, s_partialSigners, s_partialTransmitters), F: 1, - uniqueReports: true, isSignatureVerificationEnabled: true, signers: s_partialSigners, transmitters: s_partialTransmitters @@ -551,7 +516,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { configDigest: ocrConfigs[i].configDigest, F: ocrConfigs[i].F, n: uint8(ocrConfigs[i].signers.length), - uniqueReports: ocrConfigs[i].uniqueReports, isSignatureVerificationEnabled: ocrConfigs[i].isSignatureVerificationEnabled }), signers: ocrConfigs[i].signers, @@ -617,7 +581,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { configDigest: ocrConfig.configDigest, F: ocrConfig.F, n: ocrConfig.isSignatureVerificationEnabled ? uint8(ocrConfig.signers.length) : 0, - uniqueReports: ocrConfig.uniqueReports, isSignatureVerificationEnabled: ocrConfig.isSignatureVerificationEnabled }), signers: ocrConfig.signers, @@ -634,7 +597,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { ocrPluginType: 0, configDigest: _getBasicConfigDigest(1, s_emptySigners, s_validTransmitters), F: 1, - uniqueReports: false, isSignatureVerificationEnabled: false, signers: s_emptySigners, transmitters: s_validTransmitters @@ -665,7 +627,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { configDigest: ocrConfigs[0].configDigest, F: ocrConfigs[0].F, n: uint8(ocrConfigs[0].signers.length), - uniqueReports: ocrConfigs[0].uniqueReports, isSignatureVerificationEnabled: ocrConfigs[0].isSignatureVerificationEnabled }), signers: s_emptySigners, @@ -695,7 +656,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { ocrPluginType: 0, configDigest: _getBasicConfigDigest(2, s_validSigners, s_validTransmitters), F: 2, - uniqueReports: false, isSignatureVerificationEnabled: true, signers: s_validSigners, transmitters: s_validTransmitters @@ -728,7 +688,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { configDigest: ocrConfigs[0].configDigest, F: ocrConfigs[0].F, n: uint8(ocrConfigs[0].signers.length), - uniqueReports: ocrConfigs[0].uniqueReports, isSignatureVerificationEnabled: ocrConfigs[0].isSignatureVerificationEnabled }), signers: newSigners, @@ -769,7 +728,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { ocrPluginType: 0, configDigest: _getBasicConfigDigest(1, signers, transmitters), F: 1, - uniqueReports: false, isSignatureVerificationEnabled: true, signers: signers, transmitters: transmitters @@ -793,7 +751,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { ocrPluginType: 0, configDigest: _getBasicConfigDigest(1, signers, transmitters), F: 1, - uniqueReports: false, isSignatureVerificationEnabled: true, signers: signers, transmitters: transmitters @@ -823,7 +780,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { ocrPluginType: 0, configDigest: _getBasicConfigDigest(F, signers, transmitters), F: F, - uniqueReports: false, isSignatureVerificationEnabled: true, signers: signers, transmitters: transmitters @@ -849,7 +805,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { ocrPluginType: 0, configDigest: _getBasicConfigDigest(F, signers, transmitters), F: F, - uniqueReports: false, isSignatureVerificationEnabled: true, signers: signers, transmitters: transmitters @@ -869,7 +824,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { ocrPluginType: 0, configDigest: _getBasicConfigDigest(F, s_validSigners, s_validTransmitters), F: F, - uniqueReports: false, isSignatureVerificationEnabled: true, signers: s_validSigners, transmitters: s_validTransmitters @@ -877,13 +831,7 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { s_multiOCR3.setOCR3Configs(ocrConfigs); - // uniqueReports cannot change - ocrConfigs[0].uniqueReports = true; - vm.expectRevert(abi.encodeWithSelector(MultiOCR3Base.StaticConfigCannotBeChanged.selector, 0)); - s_multiOCR3.setOCR3Configs(ocrConfigs); - // signature verification cannot change - ocrConfigs[0].uniqueReports = false; ocrConfigs[0].isSignatureVerificationEnabled = false; vm.expectRevert(abi.encodeWithSelector(MultiOCR3Base.StaticConfigCannotBeChanged.selector, 0)); s_multiOCR3.setOCR3Configs(ocrConfigs); @@ -898,7 +846,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { ocrPluginType: 0, configDigest: _getBasicConfigDigest(1, signers, transmitters), F: 1, - uniqueReports: false, isSignatureVerificationEnabled: true, signers: signers, transmitters: transmitters @@ -916,7 +863,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { ocrPluginType: 0, configDigest: _getBasicConfigDigest(0, s_validSigners, s_validTransmitters), F: 0, - uniqueReports: false, isSignatureVerificationEnabled: true, signers: s_validSigners, transmitters: s_validTransmitters @@ -939,7 +885,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { ocrPluginType: 0, configDigest: _getBasicConfigDigest(10, signers, transmitters), F: 10, - uniqueReports: false, isSignatureVerificationEnabled: false, signers: signers, transmitters: transmitters @@ -961,7 +906,6 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { ocrPluginType: 0, configDigest: _getBasicConfigDigest(1, signers, s_validTransmitters), F: 1, - uniqueReports: false, isSignatureVerificationEnabled: true, signers: signers, transmitters: s_validTransmitters diff --git a/contracts/src/v0.8/ccip/test/ocr/MultiOCR3BaseSetup.t.sol b/contracts/src/v0.8/ccip/test/ocr/MultiOCR3BaseSetup.t.sol index 3fb2b4a9fc..6f6219bc9b 100644 --- a/contracts/src/v0.8/ccip/test/ocr/MultiOCR3BaseSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/ocr/MultiOCR3BaseSetup.t.sol @@ -71,13 +71,6 @@ contract MultiOCR3BaseSetup is BaseTest { return bytes32((prefix & prefixMask) | (h & ~prefixMask)); } - /// @dev returns a hash value in the same format as the h value on which the signature verified - /// in the _transmit function - function _getReportDigest(bytes32 configDigest, bytes memory report) internal pure returns (bytes32) { - bytes32[3] memory reportContext = [configDigest, configDigest, configDigest]; - return keccak256(abi.encodePacked(keccak256(report), reportContext)); - } - function _assertOCRConfigEquality( MultiOCR3Base.OCRConfig memory configA, MultiOCR3Base.OCRConfig memory configB @@ -85,7 +78,6 @@ contract MultiOCR3BaseSetup is BaseTest { vm.assertEq(configA.configInfo.configDigest, configB.configInfo.configDigest); vm.assertEq(configA.configInfo.F, configB.configInfo.F); vm.assertEq(configA.configInfo.n, configB.configInfo.n); - vm.assertEq(configA.configInfo.uniqueReports, configB.configInfo.uniqueReports); vm.assertEq(configA.configInfo.isSignatureVerificationEnabled, configB.configInfo.isSignatureVerificationEnabled); vm.assertEq(configA.signers, configB.signers); @@ -100,17 +92,19 @@ contract MultiOCR3BaseSetup is BaseTest { function _getSignaturesForDigest( uint256[] memory signerPrivateKeys, - bytes32 configDigest, bytes memory report, + bytes32[3] memory reportContext, uint8 signatureCount ) internal pure returns (bytes32[] memory rs, bytes32[] memory ss, uint8[] memory vs, bytes32 rawVs) { rs = new bytes32[](signatureCount); ss = new bytes32[](signatureCount); vs = new uint8[](signatureCount); + bytes32 reportDigest = keccak256(abi.encodePacked(keccak256(report), reportContext)); + // Calculate signatures for (uint256 i; i < signatureCount; ++i) { - (vs[i], rs[i], ss[i]) = vm.sign(signerPrivateKeys[i], _getReportDigest(configDigest, report)); + (vs[i], rs[i], ss[i]) = vm.sign(signerPrivateKeys[i], reportDigest); rawVs = rawVs | (bytes32(bytes1(vs[i] - 27)) >> (8 * i)); } diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol index 345d6af494..39dc2b61df 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol @@ -3,9 +3,9 @@ pragma solidity 0.8.24; import {ICommitStore} from "../../interfaces/ICommitStore.sol"; -import {IPoolV1} from "../../interfaces/IPool.sol"; import {IPriceRegistry} from "../../interfaces/IPriceRegistry.sol"; import {IRMN} from "../../interfaces/IRMN.sol"; +import {ITokenAdminRegistry} from "../../interfaces/ITokenAdminRegistry.sol"; import {CallWithExactGas} from "../../../shared/call/CallWithExactGas.sol"; import {PriceRegistry} from "../../PriceRegistry.sol"; @@ -76,6 +76,9 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { metadataHash: s_offRamp.metadataHash(SOURCE_CHAIN_SELECTOR_1 + 1, sourceChainConfigs[1].onRamp) }); + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.StaticConfigSet(staticConfig); + vm.expectEmit(); emit EVM2EVMMultiOffRamp.SourceChainSelectorAdded(SOURCE_CHAIN_SELECTOR_1); @@ -95,7 +98,6 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { ocrPluginType: uint8(Internal.OCRPluginType.Execution), configDigest: s_configDigestExec, F: s_F, - uniqueReports: false, isSignatureVerificationEnabled: false, signers: s_emptySigners, transmitters: s_validTransmitters @@ -120,7 +122,6 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { configDigest: ocrConfigs[0].configDigest, F: ocrConfigs[0].F, n: 0, - uniqueReports: ocrConfigs[0].uniqueReports, isSignatureVerificationEnabled: ocrConfigs[0].isSignatureVerificationEnabled }), signers: s_emptySigners, @@ -139,9 +140,7 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { // OffRamp initial values assertEq("EVM2EVMMultiOffRamp 1.6.0-dev", s_offRamp.typeAndVersion()); assertEq(OWNER, s_offRamp.owner()); - assertEq(0, s_offRamp.getLatestPriceEpochAndRound()); - assertTrue(s_offRamp.isUnpausedAndNotCursed(sourceChainConfigs[0].sourceChainSelector)); - assertTrue(s_offRamp.isUnpausedAndNotCursed(sourceChainConfigs[1].sourceChainSelector)); + assertEq(0, s_offRamp.getLatestPriceSequenceNumber()); } // Revert @@ -255,12 +254,11 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { contract EVM2EVMMultiOffRamp_setDynamicConfig is EVM2EVMMultiOffRampSetup { function test_SetDynamicConfig_Success() public { - EVM2EVMMultiOffRamp.StaticConfig memory staticConfig = s_offRamp.getStaticConfig(); EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = _generateDynamicMultiOffRampConfig(USER_3, address(s_priceRegistry)); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ConfigSet(staticConfig, dynamicConfig); + emit EVM2EVMMultiOffRamp.DynamicConfigSet(dynamicConfig); s_offRamp.setDynamicConfig(dynamicConfig); @@ -269,13 +267,12 @@ contract EVM2EVMMultiOffRamp_setDynamicConfig is EVM2EVMMultiOffRampSetup { } function test_SetDynamicConfigWithValidator_Success() public { - EVM2EVMMultiOffRamp.StaticConfig memory staticConfig = s_offRamp.getStaticConfig(); EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = _generateDynamicMultiOffRampConfig(USER_3, address(s_priceRegistry)); dynamicConfig.messageValidator = address(s_messageValidator); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ConfigSet(staticConfig, dynamicConfig); + emit EVM2EVMMultiOffRamp.DynamicConfigSet(dynamicConfig); s_offRamp.setDynamicConfig(dynamicConfig); @@ -830,22 +827,6 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_2, messages), new uint256[](0)); } - function test_UnsupportedNumberOfTokens_Revert() public { - Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); - Client.EVMTokenAmount[] memory newTokens = new Client.EVMTokenAmount[](MAX_TOKENS_LENGTH + 1); - messages[0].tokenAmounts = newTokens; - messages[0].messageId = - Internal._hash(messages[0], s_offRamp.metadataHash(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1)); - Internal.ExecutionReportSingleChain memory report = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); - - vm.expectRevert( - abi.encodeWithSelector( - EVM2EVMMultiOffRamp.UnsupportedNumberOfTokens.selector, SOURCE_CHAIN_SELECTOR_1, messages[0].sequenceNumber - ) - ); - s_offRamp.executeSingleReport(report, new uint256[](0)); - } - function test_TokenDataMismatch_Revert() public { Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); Internal.ExecutionReportSingleChain memory report = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); @@ -860,22 +841,6 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { s_offRamp.executeSingleReport(report, new uint256[](0)); } - function test_MessageTooLarge_Revert() public { - Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); - messages[0].data = new bytes(MAX_DATA_SIZE + 1); - messages[0].messageId = - Internal._hash(messages[0], s_offRamp.metadataHash(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1)); - - Internal.ExecutionReportSingleChain memory executionReport = - _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); - vm.expectRevert( - abi.encodeWithSelector( - EVM2EVMMultiOffRamp.MessageTooLarge.selector, messages[0].messageId, MAX_DATA_SIZE, messages[0].data.length - ) - ); - s_offRamp.executeSingleReport(executionReport, new uint256[](0)); - } - function test_RouterYULCall_Revert() public { Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); @@ -1972,7 +1937,7 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { } } -contract EVM2EVMMultiOffRamp_reportExec is EVM2EVMMultiOffRampSetup { +contract EVM2EVMMultiOffRamp_execute is EVM2EVMMultiOffRampSetup { function setUp() public virtual override { super.setUp(); _setupMultipleOffRamps(); @@ -1993,7 +1958,13 @@ contract EVM2EVMMultiOffRamp_reportExec is EVM2EVMMultiOffRampSetup { Internal.MessageExecutionState.SUCCESS, "" ); - s_offRamp.reportExec(abi.encode(reports)); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted( + uint8(Internal.OCRPluginType.Execution), s_configDigestExec, uint64(uint256(s_configDigestExec)) + ); + + _execute(reports); } function test_MultipleReports_Success() public { @@ -2035,7 +2006,12 @@ contract EVM2EVMMultiOffRamp_reportExec is EVM2EVMMultiOffRampSetup { "" ); - s_offRamp.reportExec(abi.encode(reports)); + vm.expectEmit(); + emit MultiOCR3Base.Transmitted( + uint8(Internal.OCRPluginType.Execution), s_configDigestExec, uint64(uint256(s_configDigestExec)) + ); + + _execute(reports); } function test_LargeBatch_Success() public { @@ -2062,7 +2038,12 @@ contract EVM2EVMMultiOffRamp_reportExec is EVM2EVMMultiOffRampSetup { } } - s_offRamp.reportExec(abi.encode(reports)); + vm.expectEmit(); + emit MultiOCR3Base.Transmitted( + uint8(Internal.OCRPluginType.Execution), s_configDigestExec, uint64(uint256(s_configDigestExec)) + ); + + _execute(reports); } function test_MultipleReportsWithPartialValidationFailures_Success() public { @@ -2119,66 +2100,12 @@ contract EVM2EVMMultiOffRamp_reportExec is EVM2EVMMultiOffRampSetup { ) ); - s_offRamp.reportExec(abi.encode(reports)); - } - - // Reverts - - function test_ZeroReports_Revert() public { - Internal.ExecutionReportSingleChain[] memory reports = new Internal.ExecutionReportSingleChain[](0); - - vm.expectRevert(EVM2EVMMultiOffRamp.EmptyReport.selector); - s_offRamp.reportExec(abi.encode(reports)); - } - - function test_IncorrectArrayType_Revert() public { - uint256[] memory wrongData = new uint256[](1); - wrongData[0] = 1; - - vm.expectRevert(); - s_offRamp.reportExec(abi.encode(wrongData)); - } - - function test_NonArray_Revert() public { - Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); - Internal.ExecutionReportSingleChain memory report = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); - - vm.expectRevert(); - s_offRamp.reportExec(abi.encode(report)); - } -} - -contract EVM2EVMMultiOffRamp_execute is EVM2EVMMultiOffRampSetup { - function setUp() public virtual override { - super.setUp(); - _setupMultipleOffRamps(); - s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_1, 1); - } - - // Asserts that execute completes - function test_SingleReport_Success() public { - bytes32[3] memory reportContext = [s_configDigestExec, s_configDigestExec, s_configDigestExec]; - - Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); - Internal.ExecutionReportSingleChain[] memory reports = - _generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); - - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( - SOURCE_CHAIN_SELECTOR_1, - messages[0].sequenceNumber, - messages[0].messageId, - Internal.MessageExecutionState.SUCCESS, - "" - ); - vm.expectEmit(); emit MultiOCR3Base.Transmitted( - uint8(Internal.OCRPluginType.Execution), s_configDigestExec, uint32(uint256(s_configDigestExec) >> 8) + uint8(Internal.OCRPluginType.Execution), s_configDigestExec, uint64(uint256(s_configDigestExec)) ); - vm.startPrank(s_validTransmitters[0]); - s_offRamp.execute(reportContext, abi.encode(reports)); + _execute(reports); } // Reverts @@ -2198,12 +2125,12 @@ contract EVM2EVMMultiOffRamp_execute is EVM2EVMMultiOffRampSetup { _redeployOffRampWithNoOCRConfigs(); s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_1, 1); - bytes32[3] memory reportContext = [bytes32(""), s_configDigestExec, s_configDigestExec]; - Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); Internal.ExecutionReportSingleChain[] memory reports = _generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + bytes32[3] memory reportContext = [bytes32(""), s_configDigestExec, s_configDigestExec]; + vm.startPrank(s_validTransmitters[0]); vm.expectRevert(MultiOCR3Base.UnauthorizedTransmitter.selector); s_offRamp.execute(reportContext, abi.encode(reports)); @@ -2218,19 +2145,18 @@ contract EVM2EVMMultiOffRamp_execute is EVM2EVMMultiOffRampSetup { ocrPluginType: uint8(Internal.OCRPluginType.Commit), configDigest: s_configDigestCommit, F: s_F, - uniqueReports: false, isSignatureVerificationEnabled: false, signers: s_emptySigners, transmitters: s_validTransmitters }); s_offRamp.setOCR3Configs(ocrConfigs); - bytes32[3] memory reportContext = [bytes32(""), s_configDigestExec, s_configDigestExec]; - Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); Internal.ExecutionReportSingleChain[] memory reports = _generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + bytes32[3] memory reportContext = [bytes32(""), s_configDigestExec, s_configDigestExec]; + vm.startPrank(s_validTransmitters[0]); vm.expectRevert(MultiOCR3Base.UnauthorizedTransmitter.selector); s_offRamp.execute(reportContext, abi.encode(reports)); @@ -2247,22 +2173,47 @@ contract EVM2EVMMultiOffRamp_execute is EVM2EVMMultiOffRampSetup { ocrPluginType: uint8(Internal.OCRPluginType.Execution), configDigest: s_configDigestExec, F: s_F, - uniqueReports: false, isSignatureVerificationEnabled: true, signers: s_validSigners, transmitters: s_validTransmitters }); s_offRamp.setOCR3Configs(ocrConfigs); - bytes32[3] memory reportContext = [s_configDigestExec, s_configDigestExec, s_configDigestExec]; - Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); Internal.ExecutionReportSingleChain[] memory reports = _generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + vm.expectRevert(); + _execute(reports); + } + + function test_ZeroReports_Revert() public { + Internal.ExecutionReportSingleChain[] memory reports = new Internal.ExecutionReportSingleChain[](0); + + vm.expectRevert(EVM2EVMMultiOffRamp.EmptyReport.selector); + _execute(reports); + } + + function test_IncorrectArrayType_Revert() public { + bytes32[3] memory reportContext = [s_configDigestExec, s_configDigestExec, s_configDigestExec]; + + uint256[] memory wrongData = new uint256[](1); + wrongData[0] = 1; + vm.startPrank(s_validTransmitters[0]); vm.expectRevert(); - s_offRamp.execute(reportContext, abi.encode(reports)); + s_offRamp.execute(reportContext, abi.encode(wrongData)); + } + + function test_NonArray_Revert() public { + bytes32[3] memory reportContext = [s_configDigestExec, s_configDigestExec, s_configDigestExec]; + + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + Internal.ExecutionReportSingleChain memory report = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + + vm.startPrank(s_validTransmitters[0]); + vm.expectRevert(); + s_offRamp.execute(reportContext, abi.encode(report)); } } @@ -2544,18 +2495,125 @@ contract EVM2EVMMultiOffRamp_trialExecute is EVM2EVMMultiOffRampSetup { } } -contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { - EVM2EVMMultiOffRamp.Any2EVMMessageRoute internal MESSAGE_ROUTE; - +contract EVM2EVMMultiOffRamp__releaseOrMintSingleToken is EVM2EVMMultiOffRampSetup { function setUp() public virtual override { super.setUp(); _setupMultipleOffRamps(); + } - MESSAGE_ROUTE = EVM2EVMMultiOffRamp.Any2EVMMessageRoute({ - sender: abi.encode(OWNER), - sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, - receiver: OWNER + function test__releaseOrMintSingleToken_Success() public { + uint256 amount = 123123; + address token = s_sourceTokens[0]; + bytes memory originalSender = abi.encode(OWNER); + bytes memory offchainTokenData = abi.encode(keccak256("offchainTokenData")); + + IERC20 dstToken1 = IERC20(s_destTokenBySourceToken[token]); + uint256 startingBalance = dstToken1.balanceOf(OWNER); + + Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), + destTokenAddress: abi.encode(s_destTokenBySourceToken[token]), + extraData: "" }); + + vm.expectCall( + s_destPoolBySourceToken[token], + abi.encodeWithSelector( + LockReleaseTokenPool.releaseOrMint.selector, + Pool.ReleaseOrMintInV1({ + originalSender: originalSender, + receiver: OWNER, + amount: amount, + localToken: s_destTokenBySourceToken[token], + remoteChainSelector: SOURCE_CHAIN_SELECTOR_1, + sourcePoolAddress: sourceTokenData.sourcePoolAddress, + sourcePoolData: sourceTokenData.extraData, + offchainTokenData: offchainTokenData + }) + ) + ); + + s_offRamp.releaseOrMintSingleToken( + amount, originalSender, OWNER, SOURCE_CHAIN_SELECTOR_1, sourceTokenData, offchainTokenData + ); + + assertEq(startingBalance + amount, dstToken1.balanceOf(OWNER)); + } + + function test__releaseOrMintSingleToken_NotACompatiblePool_Revert() public { + uint256 amount = 123123; + address token = s_sourceTokens[0]; + address destToken = s_destTokenBySourceToken[token]; + vm.label(destToken, "destToken"); + bytes memory originalSender = abi.encode(OWNER); + bytes memory offchainTokenData = abi.encode(keccak256("offchainTokenData")); + + Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), + destTokenAddress: abi.encode(destToken), + extraData: "" + }); + + // Address(0) should always revert + address returnedPool = address(0); + + vm.mockCall( + address(s_tokenAdminRegistry), + abi.encodeWithSelector(ITokenAdminRegistry.getPool.selector, destToken), + abi.encode(returnedPool) + ); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.NotACompatiblePool.selector, returnedPool)); + + s_offRamp.releaseOrMintSingleToken( + amount, originalSender, OWNER, SOURCE_CHAIN_SELECTOR_1, sourceTokenData, offchainTokenData + ); + + // A contract that doesn't support the interface should also revert + returnedPool = address(s_offRamp); + + vm.mockCall( + address(s_tokenAdminRegistry), + abi.encodeWithSelector(ITokenAdminRegistry.getPool.selector, destToken), + abi.encode(returnedPool) + ); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.NotACompatiblePool.selector, returnedPool)); + + s_offRamp.releaseOrMintSingleToken( + amount, originalSender, OWNER, SOURCE_CHAIN_SELECTOR_1, sourceTokenData, offchainTokenData + ); + } + + function test__releaseOrMintSingleToken_TokenHandlingError_revert_Revert() public { + address receiver = makeAddr("receiver"); + uint256 amount = 123123; + address token = s_sourceTokens[0]; + address destToken = s_destTokenBySourceToken[token]; + bytes memory originalSender = abi.encode(OWNER); + bytes memory offchainTokenData = abi.encode(keccak256("offchainTokenData")); + + Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), + destTokenAddress: abi.encode(destToken), + extraData: "" + }); + + bytes memory revertData = "call reverted :o"; + + vm.mockCallRevert(destToken, abi.encodeWithSelector(IERC20.transfer.selector, receiver, amount), revertData); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.TokenHandlingError.selector, revertData)); + s_offRamp.releaseOrMintSingleToken( + amount, originalSender, receiver, SOURCE_CHAIN_SELECTOR_1, sourceTokenData, offchainTokenData + ); + } +} + +contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { + function setUp() public virtual override { + super.setUp(); + _setupMultipleOffRamps(); } function test_releaseOrMintTokens_Success() public { @@ -2576,11 +2634,11 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { abi.encodeWithSelector( LockReleaseTokenPool.releaseOrMint.selector, Pool.ReleaseOrMintInV1({ - originalSender: MESSAGE_ROUTE.sender, - receiver: MESSAGE_ROUTE.receiver, + originalSender: abi.encode(OWNER), + receiver: OWNER, amount: srcTokenAmounts[0].amount, localToken: s_destTokenBySourceToken[srcTokenAmounts[0].token], - remoteChainSelector: MESSAGE_ROUTE.sourceChainSelector, + remoteChainSelector: SOURCE_CHAIN_SELECTOR_1, sourcePoolAddress: sourceTokenData.sourcePoolAddress, sourcePoolData: sourceTokenData.extraData, offchainTokenData: offchainTokenData[0] @@ -2588,7 +2646,9 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { ) ); - s_offRamp.releaseOrMintTokens(srcTokenAmounts, MESSAGE_ROUTE, encodedSourceTokenData, offchainTokenData); + s_offRamp.releaseOrMintTokens( + srcTokenAmounts, abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR_1, encodedSourceTokenData, offchainTokenData + ); assertEq(startingBalance + amount1, dstToken1.balanceOf(OWNER)); } @@ -2612,11 +2672,11 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { abi.encodeWithSelector( LockReleaseTokenPool.releaseOrMint.selector, Pool.ReleaseOrMintInV1({ - originalSender: MESSAGE_ROUTE.sender, - receiver: MESSAGE_ROUTE.receiver, + originalSender: abi.encode(OWNER), + receiver: OWNER, amount: amount, localToken: s_destTokenBySourceToken[srcTokenAmounts[0].token], - remoteChainSelector: MESSAGE_ROUTE.sourceChainSelector, + remoteChainSelector: SOURCE_CHAIN_SELECTOR_1, sourcePoolAddress: sourceTokenData.sourcePoolAddress, sourcePoolData: sourceTokenData.extraData, offchainTokenData: offchainTokenData[0] @@ -2625,8 +2685,9 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { abi.encode(amount * destinationDenominationMultiplier) ); - Client.EVMTokenAmount[] memory destTokenAmounts = - s_offRamp.releaseOrMintTokens(srcTokenAmounts, MESSAGE_ROUTE, encodedSourceTokenData, offchainTokenData); + Client.EVMTokenAmount[] memory destTokenAmounts = s_offRamp.releaseOrMintTokens( + srcTokenAmounts, abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR_1, encodedSourceTokenData, offchainTokenData + ); assertEq(destTokenAmounts[0].amount, amount * destinationDenominationMultiplier); assertEq(destTokenAmounts[0].token, destToken); @@ -2643,7 +2704,12 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.TokenHandlingError.selector, unknownError)); s_offRamp.releaseOrMintTokens( - srcTokenAmounts, MESSAGE_ROUTE, _getDefaultSourceTokenData(srcTokenAmounts), new bytes[](srcTokenAmounts.length) + srcTokenAmounts, + abi.encode(OWNER), + OWNER, + SOURCE_CHAIN_SELECTOR_1, + _getDefaultSourceTokenData(srcTokenAmounts), + new bytes[](srcTokenAmounts.length) ); } @@ -2661,11 +2727,11 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { abi.encodeWithSelector( LockReleaseTokenPool.releaseOrMint.selector, Pool.ReleaseOrMintInV1({ - originalSender: MESSAGE_ROUTE.sender, - receiver: MESSAGE_ROUTE.receiver, + originalSender: abi.encode(OWNER), + receiver: OWNER, amount: amount, localToken: s_destTokenBySourceToken[srcTokenAmounts[0].token], - remoteChainSelector: MESSAGE_ROUTE.sourceChainSelector, + remoteChainSelector: SOURCE_CHAIN_SELECTOR_1, sourcePoolAddress: sourceTokenData.sourcePoolAddress, sourcePoolData: sourceTokenData.extraData, offchainTokenData: offchainTokenData[0] @@ -2679,7 +2745,9 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { abi.encodeWithSelector(EVM2EVMMultiOffRamp.InvalidDataLength.selector, Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES, 64) ); - s_offRamp.releaseOrMintTokens(srcTokenAmounts, MESSAGE_ROUTE, encodedSourceTokenData, offchainTokenData); + s_offRamp.releaseOrMintTokens( + srcTokenAmounts, abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR_1, encodedSourceTokenData, offchainTokenData + ); } function test_releaseOrMintTokens_InvalidEVMAddress_Revert() public { @@ -2699,40 +2767,11 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { vm.expectRevert(abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, wrongAddress)); - s_offRamp.releaseOrMintTokens(srcTokenAmounts, MESSAGE_ROUTE, sourceTokenData, offchainTokenData); + s_offRamp.releaseOrMintTokens( + srcTokenAmounts, abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR_1, sourceTokenData, offchainTokenData + ); } - // TODO: re-add after ARL changes - // function test_RateLimitErrors_Reverts() public { - // Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); - - // bytes[] memory rateLimitErrors = new bytes[](5); - // rateLimitErrors[0] = abi.encodeWithSelector(RateLimiter.BucketOverfilled.selector); - // rateLimitErrors[1] = - // abi.encodeWithSelector(RateLimiter.AggregateValueMaxCapacityExceeded.selector, uint256(100), uint256(1000)); - // rateLimitErrors[2] = - // abi.encodeWithSelector(RateLimiter.AggregateValueRateLimitReached.selector, uint256(42), 1, s_sourceTokens[0]); - // rateLimitErrors[3] = abi.encodeWithSelector( - // RateLimiter.TokenMaxCapacityExceeded.selector, uint256(100), uint256(1000), s_sourceTokens[0] - // ); - // rateLimitErrors[4] = - // abi.encodeWithSelector(RateLimiter.TokenRateLimitReached.selector, uint256(42), 1, s_sourceTokens[0]); - - // for (uint256 i = 0; i < rateLimitErrors.length; ++i) { - // s_maybeRevertingPool.setShouldRevert(rateLimitErrors[i]); - - // vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.TokenHandlingError.selector, rateLimitErrors[i])); - - // s_offRamp.releaseOrMintTokens( - // srcTokenAmounts, - // abi.encode(OWNER), - // OWNER, - // _getDefaultSourceTokenData(srcTokenAmounts), - // new bytes[](srcTokenAmounts.length) - // ); - // } - // } - function test__releaseOrMintTokens_PoolIsNotAPool_Reverts() public { // The offRamp is a contract, but not a pool address fakePoolAddress = address(s_offRamp); @@ -2747,7 +2786,9 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { ); vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.NotACompatiblePool.selector, address(0))); - s_offRamp.releaseOrMintTokens(new Client.EVMTokenAmount[](1), MESSAGE_ROUTE, sourceTokenData, new bytes[](1)); + s_offRamp.releaseOrMintTokens( + new Client.EVMTokenAmount[](1), abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR_1, sourceTokenData, new bytes[](1) + ); } function test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() public { @@ -2761,22 +2802,16 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { bytes[] memory encodedSourceTokenData = _getDefaultSourceTokenData(srcTokenAmounts); Internal.SourceTokenData memory sourceTokenData = abi.decode(encodedSourceTokenData[0], (Internal.SourceTokenData)); - EVM2EVMMultiOffRamp.Any2EVMMessageRoute memory messageRouteChain3 = EVM2EVMMultiOffRamp.Any2EVMMessageRoute({ - sender: abi.encode(OWNER), - sourceChainSelector: SOURCE_CHAIN_SELECTOR_3, - receiver: OWNER - }); - vm.expectCall( s_destPoolBySourceToken[srcTokenAmounts[0].token], abi.encodeWithSelector( LockReleaseTokenPool.releaseOrMint.selector, Pool.ReleaseOrMintInV1({ - originalSender: messageRouteChain3.sender, - receiver: messageRouteChain3.receiver, + originalSender: abi.encode(OWNER), + receiver: OWNER, amount: srcTokenAmounts[0].amount, localToken: s_destTokenBySourceToken[srcTokenAmounts[0].token], - remoteChainSelector: messageRouteChain3.sourceChainSelector, + remoteChainSelector: SOURCE_CHAIN_SELECTOR_3, sourcePoolAddress: sourceTokenData.sourcePoolAddress, sourcePoolData: sourceTokenData.extraData, offchainTokenData: offchainTokenData[0] @@ -2784,7 +2819,9 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { ) ); vm.expectRevert(); - s_offRamp.releaseOrMintTokens(srcTokenAmounts, messageRouteChain3, encodedSourceTokenData, offchainTokenData); + s_offRamp.releaseOrMintTokens( + srcTokenAmounts, abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR_3, encodedSourceTokenData, offchainTokenData + ); } /// forge-config: default.fuzz.runs = 32 @@ -2804,8 +2841,9 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { }) ); - try s_offRamp.releaseOrMintTokens(new Client.EVMTokenAmount[](1), MESSAGE_ROUTE, sourceTokenData, new bytes[](1)) {} - catch (bytes memory reason) { + try s_offRamp.releaseOrMintTokens( + new Client.EVMTokenAmount[](1), abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR_1, sourceTokenData, new bytes[](1) + ) {} catch (bytes memory reason) { // Any revert should be a TokenHandlingError, InvalidEVMAddress, InvalidDataLength or NoContract as those are caught by the offramp assertTrue( bytes4(reason) == EVM2EVMMultiOffRamp.TokenHandlingError.selector @@ -3095,55 +3133,30 @@ contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRam } } -contract EVM2EVMMultiOffRamp_isUnpausedAndRMNHealthy is EVM2EVMMultiOffRampSetup { - function test_RMN_Success() public { - // Test pausing - assertFalse(s_offRamp.paused()); - assertTrue(s_offRamp.isUnpausedAndNotCursed(SOURCE_CHAIN_SELECTOR)); - s_offRamp.pause(); - assertTrue(s_offRamp.paused()); - assertFalse(s_offRamp.isUnpausedAndNotCursed(SOURCE_CHAIN_SELECTOR)); - s_offRamp.unpause(); - assertFalse(s_offRamp.paused()); - assertTrue(s_offRamp.isUnpausedAndNotCursed(SOURCE_CHAIN_SELECTOR)); - // Test rmn - s_mockRMN.voteToCurse(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); - assertFalse(s_offRamp.isUnpausedAndNotCursed(SOURCE_CHAIN_SELECTOR)); - RMN.UnvoteToCurseRecord[] memory records = new RMN.UnvoteToCurseRecord[](1); - records[0] = RMN.UnvoteToCurseRecord({curseVoteAddr: OWNER, cursesHash: bytes32(uint256(0)), forceUnvote: true}); - s_mockRMN.ownerUnvoteToCurse(records); - assertTrue(s_offRamp.isUnpausedAndNotCursed(SOURCE_CHAIN_SELECTOR)); - s_mockRMN.voteToCurse(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); - s_offRamp.pause(); - assertFalse(s_offRamp.isUnpausedAndNotCursed(SOURCE_CHAIN_SELECTOR)); - } -} - -contract EVM2EVMMultiOffRamp_setLatestPriceEpochAndRound is EVM2EVMMultiOffRampSetup { - function test_SetLatestPriceEpochAndRound_Success() public { - uint40 latestRoundAndEpoch = 1782155; +contract EVM2EVMMultiOffRamp_setLatestPriceSequenceNumber is EVM2EVMMultiOffRampSetup { + function test_setLatestPriceSequenceNumber_Success() public { + uint64 latestSequenceNumber = 1782155; vm.expectEmit(); - emit EVM2EVMMultiOffRamp.LatestPriceEpochAndRoundSet( - uint40(s_offRamp.getLatestPriceEpochAndRound()), latestRoundAndEpoch + emit EVM2EVMMultiOffRamp.LatestPriceSequenceNumberSet( + s_offRamp.getLatestPriceSequenceNumber(), latestSequenceNumber ); - s_offRamp.setLatestPriceEpochAndRound(latestRoundAndEpoch); - assertEq(s_offRamp.getLatestPriceEpochAndRound(), latestRoundAndEpoch); + s_offRamp.setLatestPriceSequenceNumber(latestSequenceNumber); + assertEq(s_offRamp.getLatestPriceSequenceNumber(), latestSequenceNumber); } function test_PriceEpochCleared_Success() public { // Set latest price epoch and round to non-zero. - uint40 latestEpochAndRound = 1782155; - s_offRamp.setLatestPriceEpochAndRound(latestEpochAndRound); - assertEq(latestEpochAndRound, s_offRamp.getLatestPriceEpochAndRound()); + uint64 latestSequenceNumber = 1782155; + s_offRamp.setLatestPriceSequenceNumber(latestSequenceNumber); + assertEq(latestSequenceNumber, s_offRamp.getLatestPriceSequenceNumber()); MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ ocrPluginType: uint8(Internal.OCRPluginType.Execution), configDigest: s_configDigestExec, F: s_F, - uniqueReports: false, isSignatureVerificationEnabled: false, signers: s_emptySigners, transmitters: s_validTransmitters @@ -3151,14 +3164,13 @@ contract EVM2EVMMultiOffRamp_setLatestPriceEpochAndRound is EVM2EVMMultiOffRampS s_offRamp.setOCR3Configs(ocrConfigs); // Execution plugin OCR config should not clear latest epoch and round - assertEq(latestEpochAndRound, s_offRamp.getLatestPriceEpochAndRound()); + assertEq(latestSequenceNumber, s_offRamp.getLatestPriceSequenceNumber()); // Commit plugin config should clear latest epoch & round ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ ocrPluginType: uint8(Internal.OCRPluginType.Commit), configDigest: s_configDigestCommit, F: s_F, - uniqueReports: false, isSignatureVerificationEnabled: true, signers: s_validSigners, transmitters: s_validTransmitters @@ -3166,7 +3178,7 @@ contract EVM2EVMMultiOffRamp_setLatestPriceEpochAndRound is EVM2EVMMultiOffRampS s_offRamp.setOCR3Configs(ocrConfigs); // Assert cleared. - assertEq(0, s_offRamp.getLatestPriceEpochAndRound()); + assertEq(0, s_offRamp.getLatestPriceSequenceNumber()); } // Reverts @@ -3174,67 +3186,60 @@ contract EVM2EVMMultiOffRamp_setLatestPriceEpochAndRound is EVM2EVMMultiOffRampS function test_OnlyOwner_Revert() public { vm.stopPrank(); vm.expectRevert("Only callable by owner"); - s_offRamp.setLatestPriceEpochAndRound(6723); + s_offRamp.setLatestPriceSequenceNumber(6723); } } -contract EVM2EVMMultiOffRamp_reportCommit is EVM2EVMMultiOffRampSetup { +contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { + uint64 internal s_maxInterval = 12; + function setUp() public virtual override { super.setUp(); _setupMultipleOffRamps(); - } - function test_ReportOnlyRootSuccess_gas() public { - vm.pauseGasMetering(); - uint64 max1 = 931; - bytes32 root = "Only a single root"; - - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); - roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ - sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, - interval: EVM2EVMMultiOffRamp.Interval(1, max1), - merkleRoot: root - }); + s_latestSequenceNumber = uint64(uint256(s_configDigestCommit)); + } - EVM2EVMMultiOffRamp.CommitReport memory report = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + function test_ReportAndPriceUpdate_Success() public { + EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport(); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.CommitReportAccepted(report); + emit EVM2EVMMultiOffRamp.CommitReportAccepted(commitReport); - bytes memory encodedReport = abi.encode(report); + vm.expectEmit(); + emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); - vm.resumeGasMetering(); - s_offRamp.reportCommit(encodedReport, ++s_latestEpochAndRound); - vm.pauseGasMetering(); + _commit(commitReport, s_latestSequenceNumber); - assertEq(max1 + 1, s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR).minSeqNr); - assertEq(block.timestamp, s_offRamp.getMerkleRoot(SOURCE_CHAIN_SELECTOR_1, root)); - vm.resumeGasMetering(); + assertEq(s_maxInterval + 1, s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR).minSeqNr); + assertEq(s_latestSequenceNumber, s_offRamp.getLatestPriceSequenceNumber()); } - function test_ReportAndPriceUpdate_Success() public { - uint64 max1 = 12; + function test_ReportOnlyRootSuccess_gas() public { + uint64 max1 = 931; + bytes32 root = "Only a single root"; EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, interval: EVM2EVMMultiOffRamp.Interval(1, max1), - merkleRoot: "test #2" + merkleRoot: root }); - EVM2EVMMultiOffRamp.CommitReport memory report = EVM2EVMMultiOffRamp.CommitReport({ - priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), - merkleRoots: roots - }); + EVM2EVMMultiOffRamp.CommitReport memory commitReport = + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.CommitReportAccepted(report); + emit EVM2EVMMultiOffRamp.CommitReportAccepted(commitReport); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); - s_offRamp.reportCommit(abi.encode(report), ++s_latestEpochAndRound); + _commit(commitReport, s_latestSequenceNumber); assertEq(max1 + 1, s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR).minSeqNr); - assertEq(s_latestEpochAndRound, s_offRamp.getLatestPriceEpochAndRound()); + assertEq(0, s_offRamp.getLatestPriceSequenceNumber()); + assertEq(block.timestamp, s_offRamp.getMerkleRoot(SOURCE_CHAIN_SELECTOR_1, root)); } function test_StaleReportWithRoot_Success() public { @@ -3248,22 +3253,33 @@ contract EVM2EVMMultiOffRamp_reportCommit is EVM2EVMMultiOffRampSetup { interval: EVM2EVMMultiOffRamp.Interval(1, maxSeq), merkleRoot: "stale report 1" }); - EVM2EVMMultiOffRamp.CommitReport memory report = + EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.CommitReportAccepted(report); - s_offRamp.reportCommit(abi.encode(report), s_latestEpochAndRound); + emit EVM2EVMMultiOffRamp.CommitReportAccepted(commitReport); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); + + _commit(commitReport, s_latestSequenceNumber); + assertEq(maxSeq + 1, s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR).minSeqNr); - assertEq(s_latestEpochAndRound, s_offRamp.getLatestPriceEpochAndRound()); + assertEq(0, s_offRamp.getLatestPriceSequenceNumber()); + + commitReport.merkleRoots[0].interval = EVM2EVMMultiOffRamp.Interval(maxSeq + 1, maxSeq * 2); + commitReport.merkleRoots[0].merkleRoot = "stale report 2"; - report.merkleRoots[0].interval = EVM2EVMMultiOffRamp.Interval(maxSeq + 1, maxSeq * 2); - report.merkleRoots[0].merkleRoot = "stale report 2"; vm.expectEmit(); - emit EVM2EVMMultiOffRamp.CommitReportAccepted(report); - s_offRamp.reportCommit(abi.encode(report), s_latestEpochAndRound); + emit EVM2EVMMultiOffRamp.CommitReportAccepted(commitReport); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); + + _commit(commitReport, s_latestSequenceNumber); + assertEq(maxSeq * 2 + 1, s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR).minSeqNr); - assertEq(s_latestEpochAndRound, s_offRamp.getLatestPriceEpochAndRound()); + assertEq(0, s_offRamp.getLatestPriceSequenceNumber()); assertEq( tokenStartPrice, IPriceRegistry(s_offRamp.getDynamicConfig().priceRegistry).getTokenPrice(s_sourceFeeToken).value ); @@ -3271,26 +3287,37 @@ contract EVM2EVMMultiOffRamp_reportCommit is EVM2EVMMultiOffRampSetup { function test_OnlyTokenPriceUpdates_Success() public { EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); - EVM2EVMMultiOffRamp.CommitReport memory report = EVM2EVMMultiOffRamp.CommitReport({ + EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots }); + vm.expectEmit(); emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); - s_offRamp.reportCommit(abi.encode(report), ++s_latestEpochAndRound); - assertEq(s_latestEpochAndRound, s_offRamp.getLatestPriceEpochAndRound()); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); + + _commit(commitReport, s_latestSequenceNumber); + + assertEq(s_latestSequenceNumber, s_offRamp.getLatestPriceSequenceNumber()); } function test_OnlyGasPriceUpdates_Success() public { EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); - EVM2EVMMultiOffRamp.CommitReport memory report = EVM2EVMMultiOffRamp.CommitReport({ + EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots }); + vm.expectEmit(); emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); - s_offRamp.reportCommit(abi.encode(report), ++s_latestEpochAndRound); - assertEq(s_latestEpochAndRound, s_offRamp.getLatestPriceEpochAndRound()); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); + + _commit(commitReport, s_latestSequenceNumber); + assertEq(s_latestSequenceNumber, s_offRamp.getLatestPriceSequenceNumber()); } function test_ValidPriceUpdateThenStaleReportWithRoot_Success() public { @@ -3298,14 +3325,19 @@ contract EVM2EVMMultiOffRamp_reportCommit is EVM2EVMMultiOffRampSetup { uint224 tokenPrice1 = 4e18; uint224 tokenPrice2 = 5e18; EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); - EVM2EVMMultiOffRamp.CommitReport memory report = EVM2EVMMultiOffRamp.CommitReport({ + EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice1), merkleRoots: roots }); + vm.expectEmit(); emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, tokenPrice1, block.timestamp); - s_offRamp.reportCommit(abi.encode(report), ++s_latestEpochAndRound); - assertEq(s_latestEpochAndRound, s_offRamp.getLatestPriceEpochAndRound()); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); + + _commit(commitReport, s_latestSequenceNumber); + assertEq(s_latestSequenceNumber, s_offRamp.getLatestPriceSequenceNumber()); roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ @@ -3313,25 +3345,96 @@ contract EVM2EVMMultiOffRamp_reportCommit is EVM2EVMMultiOffRampSetup { interval: EVM2EVMMultiOffRamp.Interval(1, maxSeq), merkleRoot: "stale report" }); - report.priceUpdates = getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice2); - report.merkleRoots = roots; + commitReport.priceUpdates = getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice2); + commitReport.merkleRoots = roots; vm.expectEmit(); - emit EVM2EVMMultiOffRamp.CommitReportAccepted(report); - s_offRamp.reportCommit(abi.encode(report), s_latestEpochAndRound); + emit EVM2EVMMultiOffRamp.CommitReportAccepted(commitReport); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); + + _commit(commitReport, s_latestSequenceNumber); + assertEq(maxSeq + 1, s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR).minSeqNr); assertEq( tokenPrice1, IPriceRegistry(s_offRamp.getDynamicConfig().priceRegistry).getTokenPrice(s_sourceFeeToken).value ); - assertEq(s_latestEpochAndRound, s_offRamp.getLatestPriceEpochAndRound()); + assertEq(s_latestSequenceNumber, s_offRamp.getLatestPriceSequenceNumber()); } + // Reverts - function test_Paused_Revert() public { - s_offRamp.pause(); - bytes memory report; - vm.expectRevert(EVM2EVMMultiOffRamp.PausedError.selector); - s_offRamp.reportCommit(report, ++s_latestEpochAndRound); + function test_UnauthorizedTransmitter_Revert() public { + EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport(); + + bytes32[3] memory reportContext = + [s_configDigestCommit, bytes32(uint256(s_latestSequenceNumber)), s_configDigestCommit]; + + (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = + _getSignaturesForDigest(s_validSignerKeys, abi.encode(commitReport), reportContext, s_F + 1); + + vm.expectRevert(MultiOCR3Base.UnauthorizedTransmitter.selector); + s_offRamp.commit(reportContext, abi.encode(commitReport), rs, ss, rawVs); + } + + function test_NoConfig_Revert() public { + _redeployOffRampWithNoOCRConfigs(); + + EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport(); + + bytes32[3] memory reportContext = [bytes32(""), s_configDigestCommit, s_configDigestCommit]; + (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = + _getSignaturesForDigest(s_validSignerKeys, abi.encode(commitReport), reportContext, s_F + 1); + + vm.startPrank(s_validTransmitters[0]); + vm.expectRevert(); + s_offRamp.commit(reportContext, abi.encode(commitReport), rs, ss, rawVs); + } + + function test_NoConfigWithOtherConfigPresent_Revert() public { + _redeployOffRampWithNoOCRConfigs(); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: uint8(Internal.OCRPluginType.Execution), + configDigest: s_configDigestExec, + F: s_F, + isSignatureVerificationEnabled: false, + signers: s_emptySigners, + transmitters: s_validTransmitters + }); + s_offRamp.setOCR3Configs(ocrConfigs); + + EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport(); + + bytes32[3] memory reportContext = [bytes32(""), s_configDigestCommit, s_configDigestCommit]; + (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = + _getSignaturesForDigest(s_validSignerKeys, abi.encode(commitReport), reportContext, s_F + 1); + + vm.startPrank(s_validTransmitters[0]); + vm.expectRevert(); + s_offRamp.commit(reportContext, abi.encode(commitReport), rs, ss, rawVs); + } + + function test_WrongConfigWithoutSigners_Revert() public { + _redeployOffRampWithNoOCRConfigs(); + + EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport(); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: uint8(Internal.OCRPluginType.Commit), + configDigest: s_configDigestCommit, + F: s_F, + isSignatureVerificationEnabled: false, + signers: s_emptySigners, + transmitters: s_validTransmitters + }); + s_offRamp.setOCR3Configs(ocrConfigs); + + vm.expectRevert(); + _commit(commitReport, s_latestSequenceNumber); } function test_Unhealthy_Revert() public { @@ -3343,10 +3446,11 @@ contract EVM2EVMMultiOffRamp_reportCommit is EVM2EVMMultiOffRampSetup { merkleRoot: "Only a single root" }); - EVM2EVMMultiOffRamp.CommitReport memory report = + EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.CursedByRMN.selector, roots[0].sourceChainSelector)); - s_offRamp.reportCommit(abi.encode(report), ++s_latestEpochAndRound); + _commit(commitReport, s_latestSequenceNumber); } function test_InvalidRootRevert() public { @@ -3356,10 +3460,11 @@ contract EVM2EVMMultiOffRamp_reportCommit is EVM2EVMMultiOffRampSetup { interval: EVM2EVMMultiOffRamp.Interval(1, 4), merkleRoot: bytes32(0) }); - EVM2EVMMultiOffRamp.CommitReport memory report = + EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + vm.expectRevert(EVM2EVMMultiOffRamp.InvalidRoot.selector); - s_offRamp.reportCommit(abi.encode(report), ++s_latestEpochAndRound); + _commit(commitReport, s_latestSequenceNumber); } function test_InvalidInterval_Revert() public { @@ -3370,12 +3475,13 @@ contract EVM2EVMMultiOffRamp_reportCommit is EVM2EVMMultiOffRampSetup { interval: interval, merkleRoot: bytes32(0) }); - EVM2EVMMultiOffRamp.CommitReport memory report = + EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + vm.expectRevert( abi.encodeWithSelector(EVM2EVMMultiOffRamp.InvalidInterval.selector, roots[0].sourceChainSelector, interval) ); - s_offRamp.reportCommit(abi.encode(report), ++s_latestEpochAndRound); + _commit(commitReport, s_latestSequenceNumber); } function test_InvalidIntervalMinLargerThanMax_Revert() public { @@ -3387,35 +3493,39 @@ contract EVM2EVMMultiOffRamp_reportCommit is EVM2EVMMultiOffRampSetup { interval: interval, merkleRoot: bytes32(0) }); - EVM2EVMMultiOffRamp.CommitReport memory report = + EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + vm.expectRevert( abi.encodeWithSelector(EVM2EVMMultiOffRamp.InvalidInterval.selector, roots[0].sourceChainSelector, interval) ); - s_offRamp.reportCommit(abi.encode(report), ++s_latestEpochAndRound); + _commit(commitReport, s_latestSequenceNumber); } function test_ZeroEpochAndRound_Revert() public { EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); - EVM2EVMMultiOffRamp.CommitReport memory report = EVM2EVMMultiOffRamp.CommitReport({ + EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots }); + vm.expectRevert(EVM2EVMMultiOffRamp.StaleCommitReport.selector); - s_offRamp.reportCommit(abi.encode(report), 0); + _commit(commitReport, 0); } function test_OnlyPriceUpdateStaleReport_Revert() public { EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); - EVM2EVMMultiOffRamp.CommitReport memory report = EVM2EVMMultiOffRamp.CommitReport({ + EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots }); + vm.expectEmit(); emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); - s_offRamp.reportCommit(abi.encode(report), ++s_latestEpochAndRound); + _commit(commitReport, s_latestSequenceNumber); + vm.expectRevert(EVM2EVMMultiOffRamp.StaleCommitReport.selector); - s_offRamp.reportCommit(abi.encode(report), s_latestEpochAndRound); + _commit(commitReport, s_latestSequenceNumber); } function test_SourceChainNotEnabled_Revert() public { @@ -3426,11 +3536,11 @@ contract EVM2EVMMultiOffRamp_reportCommit is EVM2EVMMultiOffRampSetup { merkleRoot: "Only a single root" }); - EVM2EVMMultiOffRamp.CommitReport memory report = + EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.SourceChainNotEnabled.selector, 0)); - s_offRamp.reportCommit(abi.encode(report), ++s_latestEpochAndRound); + _commit(commitReport, s_latestSequenceNumber); } function test_RootAlreadyCommitted_Revert() public { @@ -3440,129 +3550,18 @@ contract EVM2EVMMultiOffRamp_reportCommit is EVM2EVMMultiOffRampSetup { interval: EVM2EVMMultiOffRamp.Interval(1, 2), merkleRoot: "Only a single root" }); - EVM2EVMMultiOffRamp.CommitReport memory report = + EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); - s_offRamp.reportCommit(abi.encode(report), ++s_latestEpochAndRound); - report.merkleRoots[0].interval = EVM2EVMMultiOffRamp.Interval(3, 3); + + _commit(commitReport, s_latestSequenceNumber); + commitReport.merkleRoots[0].interval = EVM2EVMMultiOffRamp.Interval(3, 3); + vm.expectRevert( abi.encodeWithSelector( EVM2EVMMultiOffRamp.RootAlreadyCommitted.selector, roots[0].sourceChainSelector, roots[0].merkleRoot ) ); - s_offRamp.reportCommit(abi.encode(report), ++s_latestEpochAndRound); - } -} - -contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { - uint64 internal s_maxInterval = 12; - - function setUp() public virtual override { - super.setUp(); - _setupMultipleOffRamps(); - } - - function test_SingleReport_Success() public { - EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport(); - bytes32[3] memory reportContext = [s_configDigestCommit, s_configDigestCommit, s_configDigestCommit]; - - // F = 1, need 2 signatures - (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = - _getSignaturesForDigest(s_validSignerKeys, s_configDigestCommit, abi.encode(commitReport), 2); - - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.CommitReportAccepted(commitReport); - - vm.expectEmit(); - emit MultiOCR3Base.Transmitted( - uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, uint32(uint256(s_configDigestCommit) >> 8) - ); - - vm.startPrank(s_validTransmitters[0]); - s_offRamp.commit(reportContext, abi.encode(commitReport), rs, ss, rawVs); - - assertEq(s_maxInterval + 1, s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR).minSeqNr); - assertEq(uint40(uint256(reportContext[1])), s_offRamp.getLatestPriceEpochAndRound()); - } - - // Reverts - - function test_UnauthorizedTransmitter_Revert() public { - EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport(); - bytes32[3] memory reportContext = [s_configDigestCommit, s_configDigestCommit, s_configDigestCommit]; - - (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = - _getSignaturesForDigest(s_validSignerKeys, s_configDigestCommit, abi.encode(commitReport), 2); - - vm.expectRevert(MultiOCR3Base.UnauthorizedTransmitter.selector); - s_offRamp.commit(reportContext, abi.encode(commitReport), rs, ss, rawVs); - } - - function test_NoConfig_Revert() public { - _redeployOffRampWithNoOCRConfigs(); - - EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport(); - bytes32[3] memory reportContext = [bytes32(""), s_configDigestCommit, s_configDigestCommit]; - - (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = - _getSignaturesForDigest(s_validSignerKeys, s_configDigestCommit, abi.encode(commitReport), 2); - - vm.startPrank(s_validTransmitters[0]); - vm.expectRevert(); - s_offRamp.commit(reportContext, abi.encode(commitReport), rs, ss, rawVs); - } - - function test_NoConfigWithOtherConfigPresent_Revert() public { - _redeployOffRampWithNoOCRConfigs(); - - MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); - ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ - ocrPluginType: uint8(Internal.OCRPluginType.Execution), - configDigest: s_configDigestExec, - F: s_F, - uniqueReports: false, - isSignatureVerificationEnabled: false, - signers: s_emptySigners, - transmitters: s_validTransmitters - }); - s_offRamp.setOCR3Configs(ocrConfigs); - - EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport(); - bytes32[3] memory reportContext = [bytes32(""), s_configDigestCommit, s_configDigestCommit]; - - (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = - _getSignaturesForDigest(s_validSignerKeys, s_configDigestCommit, abi.encode(commitReport), 2); - - vm.startPrank(s_validTransmitters[0]); - vm.expectRevert(); - s_offRamp.commit(reportContext, abi.encode(commitReport), rs, ss, rawVs); - } - - function test_WrongConfigWithoutSigners_Revert() public { - _redeployOffRampWithNoOCRConfigs(); - - EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport(); - s_configDigestCommit = _getBasicConfigDigest(1, s_validSigners, s_validTransmitters); - - MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); - ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ - ocrPluginType: uint8(Internal.OCRPluginType.Commit), - configDigest: s_configDigestCommit, - F: s_F, - uniqueReports: false, - isSignatureVerificationEnabled: false, - signers: s_emptySigners, - transmitters: s_validTransmitters - }); - s_offRamp.setOCR3Configs(ocrConfigs); - - bytes32[3] memory reportContext = [s_configDigestCommit, s_configDigestCommit, s_configDigestCommit]; - - (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = - _getSignaturesForDigest(s_validSignerKeys, s_configDigestCommit, abi.encode(commitReport), 2); - - vm.startPrank(s_validTransmitters[0]); - vm.expectRevert(); - s_offRamp.commit(reportContext, abi.encode(commitReport), rs, ss, rawVs); + _commit(commitReport, ++s_latestSequenceNumber); } function _constructCommitReport() internal view returns (EVM2EVMMultiOffRamp.CommitReport memory) { @@ -3614,7 +3613,7 @@ contract EVM2EVMMultiOffRamp_resetUnblessedRoots is EVM2EVMMultiOffRampSetup { EVM2EVMMultiOffRamp.CommitReport memory report = EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); - s_offRamp.reportCommit(abi.encode(report), ++s_latestEpochAndRound); + _commit(report, ++s_latestSequenceNumber); IRMN.TaggedRoot[] memory blessedTaggedRoots = new IRMN.TaggedRoot[](1); blessedTaggedRoots[0] = IRMN.TaggedRoot({commitStore: address(s_offRamp), root: rootsToReset[1].merkleRoot}); @@ -3666,7 +3665,7 @@ contract EVM2EVMMultiOffRamp_verify is EVM2EVMMultiOffRampSetup { }); EVM2EVMMultiOffRamp.CommitReport memory report = EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); - s_offRamp.reportCommit(abi.encode(report), ++s_latestEpochAndRound); + _commit(report, ++s_latestSequenceNumber); bytes32[] memory proofs = new bytes32[](0); // We have not blessed this root, should return 0. uint256 timestamp = s_offRamp.verify(SOURCE_CHAIN_SELECTOR, leaves, proofs, 0); @@ -3684,7 +3683,7 @@ contract EVM2EVMMultiOffRamp_verify is EVM2EVMMultiOffRampSetup { }); EVM2EVMMultiOffRamp.CommitReport memory report = EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); - s_offRamp.reportCommit(abi.encode(report), ++s_latestEpochAndRound); + _commit(report, ++s_latestSequenceNumber); // Bless that root. IRMN.TaggedRoot[] memory taggedRoots = new IRMN.TaggedRoot[](1); taggedRoots[0] = IRMN.TaggedRoot({commitStore: address(s_offRamp), root: leaves[0]}); @@ -3707,7 +3706,7 @@ contract EVM2EVMMultiOffRamp_verify is EVM2EVMMultiOffRampSetup { EVM2EVMMultiOffRamp.CommitReport memory report = EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); - s_offRamp.reportCommit(abi.encode(report), ++s_latestEpochAndRound); + _commit(report, ++s_latestSequenceNumber); // Bless that root. IRMN.TaggedRoot[] memory taggedRoots = new IRMN.TaggedRoot[](1); @@ -3722,15 +3721,6 @@ contract EVM2EVMMultiOffRamp_verify is EVM2EVMMultiOffRampSetup { // Reverts - function test_Paused_Revert() public { - s_offRamp.pause(); - bytes32[] memory hashedLeaves = new bytes32[](0); - bytes32[] memory proofs = new bytes32[](0); - uint256 proofFlagBits = 0; - vm.expectRevert(EVM2EVMMultiOffRamp.PausedError.selector); - s_offRamp.verify(SOURCE_CHAIN_SELECTOR, hashedLeaves, proofs, proofFlagBits); - } - function test_TooManyLeaves_Revert() public { bytes32[] memory leaves = new bytes32[](258); bytes32[] memory proofs = new bytes32[](0); diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol index b8217808de..003671c6b1 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol @@ -57,7 +57,7 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba uint64 internal constant s_offchainConfigVersion = 3; uint8 internal constant s_F = 1; - uint40 internal s_latestEpochAndRound; + uint64 internal s_latestSequenceNumber; function setUp() public virtual override(TokenSetup, PriceRegistrySetup, MultiOCR3BaseSetup) { TokenSetup.setUp(); @@ -95,7 +95,6 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba ocrPluginType: uint8(Internal.OCRPluginType.Execution), configDigest: s_configDigestExec, F: s_F, - uniqueReports: false, isSignatureVerificationEnabled: false, signers: s_emptySigners, transmitters: s_validTransmitters @@ -104,7 +103,6 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba ocrPluginType: uint8(Internal.OCRPluginType.Commit), configDigest: s_configDigestCommit, F: s_F, - uniqueReports: false, isSignatureVerificationEnabled: true, signers: s_validSigners, transmitters: s_validTransmitters @@ -229,8 +227,6 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba permissionLessExecutionThresholdSeconds: PERMISSION_LESS_EXECUTION_THRESHOLD_SECONDS, router: router, priceRegistry: priceRegistry, - maxNumberOfTokensPerMsg: MAX_TOKENS_LENGTH, - maxDataBytes: MAX_DATA_SIZE, messageValidator: address(0), maxPoolReleaseOrMintGas: MAX_TOKEN_POOL_RELEASE_OR_MINT_GAS, maxTokenTransferGas: MAX_TOKEN_POOL_TRANSFER_GAS @@ -411,8 +407,6 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba ) public pure { assertEq(a.permissionLessExecutionThresholdSeconds, b.permissionLessExecutionThresholdSeconds); assertEq(a.router, b.router); - assertEq(a.maxNumberOfTokensPerMsg, b.maxNumberOfTokensPerMsg); - assertEq(a.maxDataBytes, b.maxDataBytes); assertEq(a.maxPoolReleaseOrMintGas, b.maxPoolReleaseOrMintGas); assertEq(a.maxTokenTransferGas, b.maxTokenTransferGas); assertEq(a.messageValidator, b.messageValidator); @@ -484,4 +478,21 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba // Overwrite base mock rmn with real. s_realRMN = new RMN(RMN.Config({voters: voters, blessWeightThreshold: 1, curseWeightThreshold: 1})); } + + function _commit(EVM2EVMMultiOffRamp.CommitReport memory commitReport, uint64 sequenceNumber) internal { + bytes32[3] memory reportContext = [s_configDigestCommit, bytes32(uint256(sequenceNumber)), s_configDigestCommit]; + + (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = + _getSignaturesForDigest(s_validSignerKeys, abi.encode(commitReport), reportContext, s_F + 1); + + vm.startPrank(s_validTransmitters[0]); + s_offRamp.commit(reportContext, abi.encode(commitReport), rs, ss, rawVs); + } + + function _execute(Internal.ExecutionReportSingleChain[] memory reports) internal { + bytes32[3] memory reportContext = [s_configDigestExec, s_configDigestExec, s_configDigestExec]; + + vm.startPrank(s_validTransmitters[0]); + s_offRamp.execute(reportContext, abi.encode(reports)); + } } diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol index defe7a62d3..18013636bf 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol @@ -6,6 +6,8 @@ import {IPoolV1} from "../../interfaces/IPool.sol"; import {ITokenAdminRegistry} from "../../interfaces/ITokenAdminRegistry.sol"; import {CallWithExactGas} from "../../../shared/call/CallWithExactGas.sol"; + +import {GenericReceiver} from "../../../shared/test/testhelpers/GenericReceiver.sol"; import {AggregateRateLimiter} from "../../AggregateRateLimiter.sol"; import {RMN} from "../../RMN.sol"; import {Router} from "../../Router.sol"; @@ -188,6 +190,125 @@ contract EVM2EVMOffRamp_ccipReceive is EVM2EVMOffRampSetup { contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { error PausedError(); + function _generateMsgWithoutTokens( + uint256 gasLimit, + bytes memory messageData + ) internal view returns (Internal.EVM2EVMMessage memory) { + Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageNoTokens(1); + message.gasLimit = gasLimit; + message.data = messageData; + message.messageId = Internal._hash( + message, + keccak256( + abi.encode(Internal.EVM_2_EVM_MESSAGE_HASH, SOURCE_CHAIN_SELECTOR, DEST_CHAIN_SELECTOR, ON_RAMP_ADDRESS) + ) + ); + return message; + } + + function test_Fuzz_trialExecuteWithoutTokens_Success(bytes4 funcSelector, bytes memory messageData) public { + vm.assume( + funcSelector != GenericReceiver.setRevert.selector && funcSelector != GenericReceiver.setErr.selector + && funcSelector != 0x5100fc21 && funcSelector != 0x00000000 // s_toRevert(), which is public and therefore has a function selector + ); + + // Convert bytes4 into bytes memory to use in the message + Internal.EVM2EVMMessage memory message = _generateMsgWithoutTokens(GAS_LIMIT, messageData); + + // Convert an Internal.EVM2EVMMessage into a Client.Any2EVMMessage digestable by the client + Client.Any2EVMMessage memory receivedMessage = _convertToGeneralMessage(message); + bytes memory expectedCallData = + abi.encodeWithSelector(MaybeRevertMessageReceiver.ccipReceive.selector, receivedMessage); + + vm.expectCall(address(s_receiver), expectedCallData); + (Internal.MessageExecutionState newState, bytes memory err) = + s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + assertEq(uint256(Internal.MessageExecutionState.SUCCESS), uint256(newState)); + assertEq("", err); + } + + function test_Fuzz_trialExecuteWithTokens_Success(uint16 tokenAmount, bytes calldata messageData) public { + vm.assume(tokenAmount != 0); + + uint256[] memory amounts = new uint256[](2); + amounts[0] = uint256(tokenAmount); + amounts[1] = uint256(tokenAmount); + + Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageWithTokens(1, amounts); + // console.log(message.length); + message.data = messageData; + + IERC20 dstToken0 = IERC20(s_destTokens[0]); + uint256 startingBalance = dstToken0.balanceOf(message.receiver); + + vm.expectCall(s_destTokens[0], abi.encodeWithSelector(IERC20.transfer.selector, address(s_receiver), amounts[0])); + + (Internal.MessageExecutionState newState, bytes memory err) = + s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + assertEq(uint256(Internal.MessageExecutionState.SUCCESS), uint256(newState)); + assertEq("", err); + + // Check that the tokens were transferred + assertEq(startingBalance + amounts[0], dstToken0.balanceOf(message.receiver)); + } + + function test_Fuzz_getSenderNonce(uint8 trialExecutions) public { + vm.assume(trialExecutions > 1); + + Internal.EVM2EVMMessage[] memory messages; + + if (trialExecutions == 1) { + messages = new Internal.EVM2EVMMessage[](1); + messages[0] = _generateAny2EVMMessageNoTokens(0); + } else { + messages = _generateSingleBasicMessage(); + } + + // Fuzz the number of calls from the sender to ensure that getSenderNonce works + for (uint256 i = 1; i < trialExecutions; ++i) { + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + + messages[0].nonce++; + messages[0].sequenceNumber++; + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + } + + messages[0].nonce = 0; + messages[0].sequenceNumber = 0; + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + + uint64 nonceBefore = s_offRamp.getSenderNonce(messages[0].sender); + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + assertEq(s_offRamp.getSenderNonce(messages[0].sender), nonceBefore, "sender nonce is not as expected"); + } + + function test_Fuzz_getSenderNonceWithPrevOffRamp_Success(uint8 trialExecutions) public { + vm.assume(trialExecutions > 1); + // Fuzz a random nonce for getSenderNonce + test_Fuzz_getSenderNonce(trialExecutions); + + address prevOffRamp = address(s_offRamp); + deployOffRamp(s_mockCommitStore, s_destRouter, prevOffRamp); + + // Make sure the off-ramp address has changed by querying the static config + assertNotEq(address(s_offRamp), prevOffRamp); + EVM2EVMOffRamp.StaticConfig memory staticConfig = s_offRamp.getStaticConfig(); + assertEq(staticConfig.prevOffRamp, prevOffRamp, "Previous offRamp does not match expected address"); + + // Since i_prevOffRamp != address(0) and senderNonce == 0, there should be a call to the previous offRamp + vm.expectCall(prevOffRamp, abi.encodeWithSelector(s_offRamp.getSenderNonce.selector, OWNER)); + uint256 currentSenderNonce = s_offRamp.getSenderNonce(OWNER); + assertNotEq(currentSenderNonce, 0, "Sender nonce should not be zero"); + assertEq(currentSenderNonce, trialExecutions - 1, "Sender Nonce does not match expected trial executions"); + + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + + currentSenderNonce = s_offRamp.getSenderNonce(OWNER); + assertEq(currentSenderNonce, trialExecutions - 1, "Sender Nonce on new offramp does not match expected executions"); + } + function test_SingleMessageNoTokens_Success() public { Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); vm.expectEmit(); @@ -1797,6 +1918,62 @@ contract EVM2EVMOffRamp_updateRateLimitTokens is EVM2EVMOffRampSetup { assertEq(adds[1].destToken, destTokens[0]); } + function test_Fuzz_UpdateRateLimitTokens(uint8 numTokens) public { + // Needs to be more than 1 so that the division doesn't round down and the even makes the comparisons simpler + vm.assume(numTokens > 1 && numTokens % 2 == 0); + + // Clear the Rate limit tokens array so the test can start from a baseline + (address[] memory sourceTokens, address[] memory destTokens) = s_offRamp.getAllRateLimitTokens(); + EVM2EVMOffRamp.RateLimitToken[] memory removes = new EVM2EVMOffRamp.RateLimitToken[](sourceTokens.length); + for (uint256 x = 0; x < removes.length; x++) { + removes[x] = EVM2EVMOffRamp.RateLimitToken({sourceToken: sourceTokens[x], destToken: destTokens[x]}); + } + s_offRamp.updateRateLimitTokens(removes, new EVM2EVMOffRamp.RateLimitToken[](0)); + + // Sanity check that the rateLimitTokens were successfully cleared + (sourceTokens, destTokens) = s_offRamp.getAllRateLimitTokens(); + assertEq(sourceTokens.length, 0, "sourceTokenLength should be zero"); + + EVM2EVMOffRamp.RateLimitToken[] memory adds = new EVM2EVMOffRamp.RateLimitToken[](numTokens); + + for (uint256 x = 0; x < numTokens; x++) { + address tokenAddr = vm.addr(x + 1); + + // Create an array of several fake tokens to add which are deployed on the same address on both chains for simplicity + adds[x] = EVM2EVMOffRamp.RateLimitToken({sourceToken: tokenAddr, destToken: tokenAddr}); + } + + // Attempt to add the tokens to the RateLimitToken Array + s_offRamp.updateRateLimitTokens(new EVM2EVMOffRamp.RateLimitToken[](0), adds); + + // Retrieve them from storage and make sure that they all match the expected adds + (sourceTokens, destTokens) = s_offRamp.getAllRateLimitTokens(); + + for (uint256 x = 0; x < sourceTokens.length; x++) { + // Check that the tokens match the ones we generated earlier + assertEq(sourceTokens[x], adds[x].sourceToken, "Source token doesn't match add"); + assertEq(destTokens[x], adds[x].sourceToken, "dest Token doesn't match add"); + } + + // Attempt to remove half of the numTokens by removing the second half of the list and copying it to a removes array + removes = new EVM2EVMOffRamp.RateLimitToken[](adds.length / 2); + + for (uint256 x = 0; x < adds.length / 2; x++) { + removes[x] = adds[x + (adds.length / 2)]; + } + + // Attempt to update again, this time adding nothing and removing the second half of the tokens + s_offRamp.updateRateLimitTokens(removes, new EVM2EVMOffRamp.RateLimitToken[](0)); + + (sourceTokens, destTokens) = s_offRamp.getAllRateLimitTokens(); + assertEq(sourceTokens.length, adds.length / 2, "Current Rate limit token length is not half of the original adds"); + for (uint256 x = 0; x < sourceTokens.length; x++) { + // Check that the tokens match the ones we generated earlier and didn't remove in the previous step + assertEq(sourceTokens[x], adds[x].sourceToken, "Source token doesn't match add after removes"); + assertEq(destTokens[x], adds[x].destToken, "dest Token doesn't match add after removes"); + } + } + // Reverts function test_updateRateLimitTokens_NonOwner_Revert() public { diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol index 5e29e945d4..5b8a1aa346 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol @@ -1,21 +1,17 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; -import {ITokenAdminRegistry} from "../../interfaces/ITokenAdminRegistry.sol"; - import {BurnMintERC677} from "../../../shared/token/ERC677/BurnMintERC677.sol"; import {AggregateRateLimiter} from "../../AggregateRateLimiter.sol"; +import {ITokenAdminRegistry} from "../../interfaces/ITokenAdminRegistry.sol"; import {Pool} from "../../libraries/Pool.sol"; import {RateLimiter} from "../../libraries/RateLimiter.sol"; import {USDPriceWith18Decimals} from "../../libraries/USDPriceWith18Decimals.sol"; import {EVM2EVMMultiOnRamp} from "../../onRamp/EVM2EVMMultiOnRamp.sol"; import {EVM2EVMMultiOnRamp} from "../../onRamp/EVM2EVMMultiOnRamp.sol"; -import {EVM2EVMOnRamp} from "../../onRamp/EVM2EVMOnRamp.sol"; import {TokenAdminRegistry} from "../../tokenAdminRegistry/TokenAdminRegistry.sol"; -import {EVM2EVMOnRampHelper} from "../helpers/EVM2EVMOnRampHelper.sol"; import {MaybeRevertingBurnMintTokenPool} from "../helpers/MaybeRevertingBurnMintTokenPool.sol"; import "./EVM2EVMMultiOnRampSetup.t.sol"; -import {Vm} from "forge-std/Vm.sol"; contract EVM2EVMMultiOnRamp_constructor is EVM2EVMMultiOnRampSetup { function test_Constructor_Success() public { @@ -24,6 +20,7 @@ contract EVM2EVMMultiOnRamp_constructor is EVM2EVMMultiOnRampSetup { chainSelector: SOURCE_CHAIN_SELECTOR, maxFeeJuelsPerMsg: MAX_MSG_FEES_JUELS, rmnProxy: address(s_mockRMN), + nonceManager: address(s_nonceManager), tokenAdminRegistry: address(s_tokenAdminRegistry) }); EVM2EVMMultiOnRamp.DynamicConfig memory dynamicConfig = @@ -54,7 +51,9 @@ contract EVM2EVMMultiOnRamp_constructor is EVM2EVMMultiOnRampSetup { s_premiumMultiplierWeiPerEthArgs[1].token, s_premiumMultiplierWeiPerEthArgs[1].premiumMultiplierWeiPerEth ); - _deployOnRamp(SOURCE_CHAIN_SELECTOR, address(s_sourceRouter), address(s_tokenAdminRegistry)); + _deployOnRamp( + SOURCE_CHAIN_SELECTOR, address(s_sourceRouter), address(s_nonceManager), address(s_tokenAdminRegistry) + ); EVM2EVMMultiOnRamp.DestChainConfig memory expectedDestChainConfig = EVM2EVMMultiOnRamp.DestChainConfig({ dynamicConfig: destChainConfigArg.dynamicConfig, @@ -96,6 +95,7 @@ contract EVM2EVMMultiOnRamp_constructor is EVM2EVMMultiOnRampSetup { chainSelector: SOURCE_CHAIN_SELECTOR, maxFeeJuelsPerMsg: MAX_NOP_FEES_JUELS, rmnProxy: address(s_mockRMN), + nonceManager: address(s_nonceManager), tokenAdminRegistry: address(s_tokenAdminRegistry) }), _generateDynamicMultiOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)), @@ -114,6 +114,7 @@ contract EVM2EVMMultiOnRamp_constructor is EVM2EVMMultiOnRampSetup { chainSelector: 0, maxFeeJuelsPerMsg: MAX_NOP_FEES_JUELS, rmnProxy: address(s_mockRMN), + nonceManager: address(s_nonceManager), tokenAdminRegistry: address(s_tokenAdminRegistry) }), _generateDynamicMultiOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)), @@ -126,12 +127,13 @@ contract EVM2EVMMultiOnRamp_constructor is EVM2EVMMultiOnRampSetup { function test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() public { vm.expectRevert(EVM2EVMMultiOnRamp.InvalidConfig.selector); - new EVM2EVMMultiOnRampHelper( + s_onRamp = new EVM2EVMMultiOnRampHelper( EVM2EVMMultiOnRamp.StaticConfig({ linkToken: s_sourceTokens[0], chainSelector: SOURCE_CHAIN_SELECTOR, maxFeeJuelsPerMsg: MAX_NOP_FEES_JUELS, rmnProxy: address(0), + nonceManager: address(s_nonceManager), tokenAdminRegistry: address(s_tokenAdminRegistry) }), _generateDynamicMultiOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)), @@ -141,6 +143,44 @@ contract EVM2EVMMultiOnRamp_constructor is EVM2EVMMultiOnRampSetup { s_tokenTransferFeeConfigArgs ); } + + function test_Constructor_InvalidConfigNonceManagerEqAddressZero_Revert() public { + vm.expectRevert(EVM2EVMMultiOnRamp.InvalidConfig.selector); + new EVM2EVMMultiOnRampHelper( + EVM2EVMMultiOnRamp.StaticConfig({ + linkToken: s_sourceTokens[0], + chainSelector: SOURCE_CHAIN_SELECTOR, + maxFeeJuelsPerMsg: MAX_NOP_FEES_JUELS, + rmnProxy: address(s_mockRMN), + nonceManager: address(0), + tokenAdminRegistry: address(s_tokenAdminRegistry) + }), + _generateDynamicMultiOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)), + _generateDestChainConfigArgs(), + getOutboundRateLimiterConfig(), + s_premiumMultiplierWeiPerEthArgs, + s_tokenTransferFeeConfigArgs + ); + } + + function test_Constructor_InvalidConfigTokenAdminRegistryEqAddressZero_Revert() public { + vm.expectRevert(EVM2EVMMultiOnRamp.InvalidConfig.selector); + new EVM2EVMMultiOnRampHelper( + EVM2EVMMultiOnRamp.StaticConfig({ + linkToken: s_sourceTokens[0], + chainSelector: SOURCE_CHAIN_SELECTOR, + maxFeeJuelsPerMsg: MAX_NOP_FEES_JUELS, + rmnProxy: address(s_mockRMN), + nonceManager: address(s_nonceManager), + tokenAdminRegistry: address(0) + }), + _generateDynamicMultiOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)), + _generateDestChainConfigArgs(), + getOutboundRateLimiterConfig(), + s_premiumMultiplierWeiPerEthArgs, + s_tokenTransferFeeConfigArgs + ); + } } contract EVM2EVMMultiOnRamp_applyDestChainConfigUpdates is EVM2EVMMultiOnRampSetup { @@ -384,14 +424,14 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { Client.EVM2AnyMessage memory message = _generateEmptyMessage(); for (uint64 i = 1; i < 4; ++i) { - uint64 nonceBefore = s_onRamp.getSenderNonce(DEST_CHAIN_SELECTOR, OWNER); + uint64 nonceBefore = s_nonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER); vm.expectEmit(); emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, i, i, 0, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); - uint64 nonceAfter = s_onRamp.getSenderNonce(DEST_CHAIN_SELECTOR, OWNER); + uint64 nonceAfter = s_nonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER); assertEq(nonceAfter, nonceBefore + 1); } } @@ -778,157 +818,6 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { } } -contract EVM2EVMMultiOnRamp_forwardFromRouter_upgrade is EVM2EVMMultiOnRampSetup { - uint256 internal constant FEE_AMOUNT = 1234567890; - EVM2EVMOnRampHelper internal s_prevOnRamp; - - function setUp() public virtual override { - EVM2EVMMultiOnRampSetup.setUp(); - - EVM2EVMOnRamp.FeeTokenConfigArgs[] memory feeTokenConfigArgs = new EVM2EVMOnRamp.FeeTokenConfigArgs[](1); - feeTokenConfigArgs[0] = EVM2EVMOnRamp.FeeTokenConfigArgs({ - token: s_sourceFeeToken, - networkFeeUSDCents: 1_00, // 1 USD - gasMultiplierWeiPerEth: 1e18, // 1x - premiumMultiplierWeiPerEth: 5e17, // 0.5x - enabled: true - }); - - EVM2EVMOnRamp.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfig = - new EVM2EVMOnRamp.TokenTransferFeeConfigArgs[](1); - - tokenTransferFeeConfig[0] = EVM2EVMOnRamp.TokenTransferFeeConfigArgs({ - token: s_sourceFeeToken, - minFeeUSDCents: 1_00, // 1 USD - maxFeeUSDCents: 1000_00, // 1,000 USD - deciBps: 2_5, // 2.5 bps, or 0.025% - destGasOverhead: 40_000, - destBytesOverhead: uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES), - aggregateRateLimitEnabled: true - }); - - s_prevOnRamp = new EVM2EVMOnRampHelper( - EVM2EVMOnRamp.StaticConfig({ - linkToken: s_sourceTokens[0], - chainSelector: SOURCE_CHAIN_SELECTOR, - destChainSelector: DEST_CHAIN_SELECTOR, - defaultTxGasLimit: GAS_LIMIT, - maxNopFeesJuels: MAX_NOP_FEES_JUELS, - prevOnRamp: address(0), - rmnProxy: address(s_mockRMN), - tokenAdminRegistry: address(s_tokenAdminRegistry) - }), - EVM2EVMOnRamp.DynamicConfig({ - router: address(s_sourceRouter), - maxNumberOfTokensPerMsg: MAX_TOKENS_LENGTH, - destGasOverhead: DEST_GAS_OVERHEAD, - destGasPerPayloadByte: DEST_GAS_PER_PAYLOAD_BYTE, - destDataAvailabilityOverheadGas: DEST_DATA_AVAILABILITY_OVERHEAD_GAS, - destGasPerDataAvailabilityByte: DEST_GAS_PER_DATA_AVAILABILITY_BYTE, - destDataAvailabilityMultiplierBps: DEST_GAS_DATA_AVAILABILITY_MULTIPLIER_BPS, - priceRegistry: address(s_priceRegistry), - maxDataBytes: MAX_DATA_SIZE, - maxPerMsgGasLimit: MAX_GAS_LIMIT, - defaultTokenFeeUSDCents: DEFAULT_TOKEN_FEE_USD_CENTS, - defaultTokenDestGasOverhead: DEFAULT_TOKEN_DEST_GAS_OVERHEAD, - defaultTokenDestBytesOverhead: DEFAULT_TOKEN_BYTES_OVERHEAD, - enforceOutOfOrder: false - }), - RateLimiter.Config({isEnabled: true, capacity: 100e28, rate: 1e15}), - feeTokenConfigArgs, - tokenTransferFeeConfig, - new EVM2EVMOnRamp.NopAndWeight[](0) - ); - - EVM2EVMMultiOnRamp.DestChainConfigArgs[] memory destChainConfigArgs = _generateDestChainConfigArgs(); - destChainConfigArgs[0].prevOnRamp = address(s_prevOnRamp); - - s_onRamp = new EVM2EVMMultiOnRampHelper( - EVM2EVMMultiOnRamp.StaticConfig({ - linkToken: s_sourceTokens[0], - chainSelector: SOURCE_CHAIN_SELECTOR, - maxFeeJuelsPerMsg: MAX_NOP_FEES_JUELS, - rmnProxy: address(s_mockRMN), - tokenAdminRegistry: address(s_tokenAdminRegistry) - }), - _generateDynamicMultiOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)), - destChainConfigArgs, - getOutboundRateLimiterConfig(), - s_premiumMultiplierWeiPerEthArgs, - s_tokenTransferFeeConfigArgs - ); - - s_metadataHash = keccak256( - abi.encode(Internal.EVM_2_EVM_MESSAGE_HASH, SOURCE_CHAIN_SELECTOR, DEST_CHAIN_SELECTOR, address(s_onRamp)) - ); - - vm.startPrank(address(s_sourceRouter)); - } - - function test_Upgrade_Success() public { - Client.EVM2AnyMessage memory message = _generateEmptyMessage(); - - vm.expectEmit(); - emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, FEE_AMOUNT, OWNER)); - s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); - } - - function test_UpgradeSenderNoncesReadsPreviousRamp_Success() public { - Client.EVM2AnyMessage memory message = _generateEmptyMessage(); - uint64 startNonce = s_onRamp.getSenderNonce(DEST_CHAIN_SELECTOR, OWNER); - - for (uint64 i = 1; i < 4; ++i) { - s_prevOnRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); - - assertEq(startNonce + i, s_onRamp.getSenderNonce(DEST_CHAIN_SELECTOR, OWNER)); - } - } - - function test_UpgradeNonceStartsAtV1Nonce_Success() public { - Client.EVM2AnyMessage memory message = _generateEmptyMessage(); - - uint64 startNonce = s_onRamp.getSenderNonce(DEST_CHAIN_SELECTOR, OWNER); - - // send 1 message from previous onramp - s_prevOnRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); - - assertEq(startNonce + 1, s_onRamp.getSenderNonce(DEST_CHAIN_SELECTOR, OWNER)); - - // new onramp nonce should start from 2, while sequence number start from 1 - vm.expectEmit(); - emit EVM2EVMMultiOnRamp.CCIPSendRequested( - DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, startNonce + 2, FEE_AMOUNT, OWNER) - ); - s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); - - assertEq(startNonce + 2, s_onRamp.getSenderNonce(DEST_CHAIN_SELECTOR, OWNER)); - - // after another send, nonce should be 3, and sequence number be 2 - vm.expectEmit(); - emit EVM2EVMMultiOnRamp.CCIPSendRequested( - DEST_CHAIN_SELECTOR, _messageToEvent(message, 2, startNonce + 3, FEE_AMOUNT, OWNER) - ); - s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); - - assertEq(startNonce + 3, s_onRamp.getSenderNonce(DEST_CHAIN_SELECTOR, OWNER)); - } - - function test_UpgradeNonceNewSenderStartsAtZero_Success() public { - Client.EVM2AnyMessage memory message = _generateEmptyMessage(); - - // send 1 message from previous onramp from OWNER - s_prevOnRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); - - address newSender = address(1234567); - // new onramp nonce should start from 1 for new sender - vm.expectEmit(); - emit EVM2EVMMultiOnRamp.CCIPSendRequested( - DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, FEE_AMOUNT, newSender) - ); - s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, newSender); - } -} - contract EVM2EVMMultiOnRamp_getFeeSetup is EVM2EVMMultiOnRampSetup { uint224 internal s_feeTokenPrice; uint224 internal s_wrappedTokenPrice; diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRampSetup.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRampSetup.t.sol index 3175afdee3..e8373cb120 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRampSetup.t.sol @@ -3,6 +3,8 @@ pragma solidity 0.8.24; import {IPoolV1} from "../../interfaces/IPool.sol"; +import {AuthorizedCallers} from "../../../shared/access/AuthorizedCallers.sol"; +import {NonceManager} from "../../NonceManager.sol"; import {PriceRegistry} from "../../PriceRegistry.sol"; import {Router} from "../../Router.sol"; import {Client} from "../../libraries/Client.sol"; @@ -31,7 +33,7 @@ contract EVM2EVMMultiOnRampSetup is TokenSetup, PriceRegistrySetup { EVM2EVMMultiOnRampHelper internal s_onRamp; address[] internal s_offRamps; - + NonceManager internal s_nonceManager; address internal s_destTokenPool = makeAddr("destTokenPool"); address internal s_destToken = makeAddr("destToken"); @@ -102,8 +104,10 @@ contract EVM2EVMMultiOnRampSetup is TokenSetup, PriceRegistrySetup { }) ); - (s_onRamp, s_metadataHash) = - _deployOnRamp(SOURCE_CHAIN_SELECTOR, address(s_sourceRouter), address(s_tokenAdminRegistry)); + s_nonceManager = new NonceManager(new address[](0)); + (s_onRamp, s_metadataHash) = _deployOnRamp( + SOURCE_CHAIN_SELECTOR, address(s_sourceRouter), address(s_nonceManager), address(s_tokenAdminRegistry) + ); s_offRamps = new address[](2); s_offRamps[0] = address(10); @@ -280,6 +284,7 @@ contract EVM2EVMMultiOnRampSetup is TokenSetup, PriceRegistrySetup { function _deployOnRamp( uint64 sourceChainSelector, address sourceRouter, + address nonceManager, address tokenAdminRegistry ) internal returns (EVM2EVMMultiOnRampHelper, bytes32 metadataHash) { EVM2EVMMultiOnRampHelper onRamp = new EVM2EVMMultiOnRampHelper( @@ -288,6 +293,7 @@ contract EVM2EVMMultiOnRampSetup is TokenSetup, PriceRegistrySetup { chainSelector: sourceChainSelector, maxFeeJuelsPerMsg: MAX_MSG_FEES_JUELS, rmnProxy: address(s_mockRMN), + nonceManager: nonceManager, tokenAdminRegistry: tokenAdminRegistry }), _generateDynamicMultiOnRampConfig(sourceRouter, address(s_priceRegistry)), @@ -298,6 +304,13 @@ contract EVM2EVMMultiOnRampSetup is TokenSetup, PriceRegistrySetup { ); onRamp.setAdmin(ADMIN); + address[] memory authorizedCallers = new address[](1); + authorizedCallers[0] = address(onRamp); + + NonceManager(nonceManager).applyAuthorizedCallerUpdates( + AuthorizedCallers.AuthorizedCallerArgs({addedCallers: authorizedCallers, removedCallers: new address[](0)}) + ); + return ( onRamp, keccak256(abi.encode(Internal.EVM_2_EVM_MESSAGE_HASH, sourceChainSelector, DEST_CHAIN_SELECTOR, address(onRamp))) diff --git a/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol b/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol index 9b8cf93a33..941d03d6cb 100644 --- a/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol +++ b/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.24; import {Vm} from "forge-std/Vm.sol"; +import {AuthorizedCallers} from "../../../shared/access/AuthorizedCallers.sol"; import {MultiAggregateRateLimiter} from "../../MultiAggregateRateLimiter.sol"; import {Client} from "../../libraries/Client.sol"; import {Internal} from "../../libraries/Internal.sol"; @@ -41,17 +42,17 @@ contract MultiAggregateRateLimiterSetup is BaseTest, PriceRegistrySetup { new MultiAggregateRateLimiter.RateLimiterConfigArgs[](3); configUpdates[0] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ remoteChainSelector: CHAIN_SELECTOR_1, - isOutgoingLane: false, + isOutboundLane: false, rateLimiterConfig: RATE_LIMITER_CONFIG_1 }); configUpdates[1] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ remoteChainSelector: CHAIN_SELECTOR_2, - isOutgoingLane: false, + isOutboundLane: false, rateLimiterConfig: RATE_LIMITER_CONFIG_2 }); configUpdates[2] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ remoteChainSelector: CHAIN_SELECTOR_1, - isOutgoingLane: true, + isOutboundLane: true, rateLimiterConfig: RATE_LIMITER_CONFIG_2 }); @@ -107,12 +108,6 @@ contract MultiAggregateRateLimiter_constructor is MultiAggregateRateLimiterSetup vm.expectEmit(); emit MultiAggregateRateLimiter.PriceRegistrySet(address(s_priceRegistry)); - vm.expectEmit(); - emit MultiAggregateRateLimiter.AuthorizedCallerAdded(MOCK_OFFRAMP); - - vm.expectEmit(); - emit MultiAggregateRateLimiter.AuthorizedCallerAdded(MOCK_ONRAMP); - s_rateLimiter = new MultiAggregateRateLimiterHelper(address(s_priceRegistry), authorizedCallers); assertEq(OWNER, s_rateLimiter.owner()); @@ -141,171 +136,20 @@ contract MultiAggregateRateLimiter_setPriceRegistry is MultiAggregateRateLimiter } function test_ZeroAddress_Revert() public { - vm.expectRevert(MultiAggregateRateLimiter.ZeroAddressNotAllowed.selector); + vm.expectRevert(AuthorizedCallers.ZeroAddressNotAllowed.selector); s_rateLimiter.setPriceRegistry(address(0)); } } -contract MultiAggregateRateLimiter_setAuthorizedCallers is MultiAggregateRateLimiterSetup { - function test_OnlyAdd_Success() public { - address[] memory addedCallers = new address[](2); - addedCallers[0] = address(42); - addedCallers[1] = address(43); - - address[] memory removedCallers = new address[](0); - - assertEq(s_rateLimiter.getAllAuthorizedCallers(), s_authorizedCallers); - - vm.expectEmit(); - emit MultiAggregateRateLimiter.AuthorizedCallerAdded(addedCallers[0]); - vm.expectEmit(); - emit MultiAggregateRateLimiter.AuthorizedCallerAdded(addedCallers[1]); - - s_rateLimiter.applyAuthorizedCallerUpdates( - MultiAggregateRateLimiter.AuthorizedCallerArgs({addedCallers: addedCallers, removedCallers: removedCallers}) - ); - - address[] memory expectedCallers = new address[](4); - expectedCallers[0] = s_authorizedCallers[0]; - expectedCallers[1] = s_authorizedCallers[1]; - expectedCallers[2] = addedCallers[0]; - expectedCallers[3] = addedCallers[1]; - - assertEq(s_rateLimiter.getAllAuthorizedCallers(), expectedCallers); - } - - function test_OnlyRemove_Success() public { - address[] memory addedCallers = new address[](0); - - address[] memory removedCallers = new address[](1); - removedCallers[0] = s_authorizedCallers[0]; - - assertEq(s_rateLimiter.getAllAuthorizedCallers(), s_authorizedCallers); - - vm.expectEmit(); - emit MultiAggregateRateLimiter.AuthorizedCallerRemoved(removedCallers[0]); - - s_rateLimiter.applyAuthorizedCallerUpdates( - MultiAggregateRateLimiter.AuthorizedCallerArgs({addedCallers: addedCallers, removedCallers: removedCallers}) - ); - - address[] memory expectedCallers = new address[](1); - expectedCallers[0] = s_authorizedCallers[1]; - - assertEq(s_rateLimiter.getAllAuthorizedCallers(), expectedCallers); - } - - function test_AddAndRemove_Success() public { - address[] memory addedCallers = new address[](2); - addedCallers[0] = address(42); - addedCallers[1] = address(43); - - address[] memory removedCallers = new address[](1); - removedCallers[0] = s_authorizedCallers[0]; - - assertEq(s_rateLimiter.getAllAuthorizedCallers(), s_authorizedCallers); - - vm.expectEmit(); - emit MultiAggregateRateLimiter.AuthorizedCallerRemoved(removedCallers[0]); - vm.expectEmit(); - emit MultiAggregateRateLimiter.AuthorizedCallerAdded(addedCallers[0]); - vm.expectEmit(); - emit MultiAggregateRateLimiter.AuthorizedCallerAdded(addedCallers[1]); - - s_rateLimiter.applyAuthorizedCallerUpdates( - MultiAggregateRateLimiter.AuthorizedCallerArgs({addedCallers: addedCallers, removedCallers: removedCallers}) - ); - - // Order of the set changes on removal - address[] memory expectedCallers = new address[](3); - expectedCallers[0] = s_authorizedCallers[1]; - expectedCallers[1] = addedCallers[0]; - expectedCallers[2] = addedCallers[1]; - - assertEq(s_rateLimiter.getAllAuthorizedCallers(), expectedCallers); - } - - function test_RemoveThenAdd_Success() public { - address[] memory addedCallers = new address[](1); - addedCallers[0] = s_authorizedCallers[0]; - - address[] memory removedCallers = new address[](1); - removedCallers[0] = s_authorizedCallers[0]; - - assertEq(s_rateLimiter.getAllAuthorizedCallers(), s_authorizedCallers); - - vm.expectEmit(); - emit MultiAggregateRateLimiter.AuthorizedCallerRemoved(removedCallers[0]); - - vm.expectEmit(); - emit MultiAggregateRateLimiter.AuthorizedCallerAdded(addedCallers[0]); - - s_rateLimiter.applyAuthorizedCallerUpdates( - MultiAggregateRateLimiter.AuthorizedCallerArgs({addedCallers: addedCallers, removedCallers: removedCallers}) - ); - - address[] memory expectedCallers = new address[](2); - expectedCallers[0] = s_authorizedCallers[1]; - expectedCallers[1] = s_authorizedCallers[0]; - - assertEq(s_rateLimiter.getAllAuthorizedCallers(), expectedCallers); - } - - function test_SkipRemove_Success() public { - address[] memory addedCallers = new address[](0); - - address[] memory removedCallers = new address[](1); - removedCallers[0] = address(42); - - vm.recordLogs(); - s_rateLimiter.applyAuthorizedCallerUpdates( - MultiAggregateRateLimiter.AuthorizedCallerArgs({addedCallers: addedCallers, removedCallers: removedCallers}) - ); - - assertEq(s_rateLimiter.getAllAuthorizedCallers(), s_authorizedCallers); - - Vm.Log[] memory logEntries = vm.getRecordedLogs(); - assertEq(logEntries.length, 0); - } - - // Reverts - - function test_OnlyOwner_Revert() public { - vm.startPrank(STRANGER); - vm.expectRevert(bytes("Only callable by owner")); - - address[] memory addedCallers = new address[](2); - addedCallers[0] = address(42); - addedCallers[1] = address(43); - - address[] memory removedCallers = new address[](0); - - s_rateLimiter.applyAuthorizedCallerUpdates( - MultiAggregateRateLimiter.AuthorizedCallerArgs({addedCallers: addedCallers, removedCallers: removedCallers}) - ); - } - - function test_ZeroAddressAdd_Revert() public { - address[] memory addedCallers = new address[](1); - addedCallers[0] = address(0); - address[] memory removedCallers = new address[](0); - - vm.expectRevert(MultiAggregateRateLimiter.ZeroAddressNotAllowed.selector); - s_rateLimiter.applyAuthorizedCallerUpdates( - MultiAggregateRateLimiter.AuthorizedCallerArgs({addedCallers: addedCallers, removedCallers: removedCallers}) - ); - } -} - contract MultiAggregateRateLimiter_getTokenBucket is MultiAggregateRateLimiterSetup { function test_GetTokenBucket_Success() public view { - RateLimiter.TokenBucket memory bucketIncoming = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, false); - _assertConfigWithTokenBucketEquality(RATE_LIMITER_CONFIG_1, bucketIncoming); - assertEq(BLOCK_TIME, bucketIncoming.lastUpdated); + RateLimiter.TokenBucket memory bucketInbound = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, false); + _assertConfigWithTokenBucketEquality(RATE_LIMITER_CONFIG_1, bucketInbound); + assertEq(BLOCK_TIME, bucketInbound.lastUpdated); - RateLimiter.TokenBucket memory bucketOutgoing = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, true); - _assertConfigWithTokenBucketEquality(RATE_LIMITER_CONFIG_2, bucketOutgoing); - assertEq(BLOCK_TIME, bucketOutgoing.lastUpdated); + RateLimiter.TokenBucket memory bucketOutbound = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, true); + _assertConfigWithTokenBucketEquality(RATE_LIMITER_CONFIG_2, bucketOutbound); + assertEq(BLOCK_TIME, bucketOutbound.lastUpdated); } function test_Refill_Success() public { @@ -315,7 +159,7 @@ contract MultiAggregateRateLimiter_getTokenBucket is MultiAggregateRateLimiterSe new MultiAggregateRateLimiter.RateLimiterConfigArgs[](1); configUpdates[0] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ remoteChainSelector: CHAIN_SELECTOR_1, - isOutgoingLane: false, + isOutboundLane: false, rateLimiterConfig: RATE_LIMITER_CONFIG_1 }); @@ -372,7 +216,7 @@ contract MultiAggregateRateLimiter_applyRateLimiterConfigUpdates is MultiAggrega new MultiAggregateRateLimiter.RateLimiterConfigArgs[](1); configUpdates[0] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ remoteChainSelector: CHAIN_SELECTOR_1 + 1, - isOutgoingLane: false, + isOutboundLane: false, rateLimiterConfig: RATE_LIMITER_CONFIG_1 }); @@ -393,12 +237,12 @@ contract MultiAggregateRateLimiter_applyRateLimiterConfigUpdates is MultiAggrega assertEq(BLOCK_TIME, bucket1.lastUpdated); } - function test_SingleConfigOutgoing_Success() public { + function test_SingleConfigOutbound_Success() public { MultiAggregateRateLimiter.RateLimiterConfigArgs[] memory configUpdates = new MultiAggregateRateLimiter.RateLimiterConfigArgs[](1); configUpdates[0] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ remoteChainSelector: CHAIN_SELECTOR_1 + 1, - isOutgoingLane: true, + isOutboundLane: true, rateLimiterConfig: RATE_LIMITER_CONFIG_2 }); @@ -426,13 +270,13 @@ contract MultiAggregateRateLimiter_applyRateLimiterConfigUpdates is MultiAggrega for (uint64 i; i < configUpdates.length; ++i) { configUpdates[i] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ remoteChainSelector: CHAIN_SELECTOR_1 + i + 1, - isOutgoingLane: i % 2 == 0 ? false : true, + isOutboundLane: i % 2 == 0 ? false : true, rateLimiterConfig: RateLimiter.Config({isEnabled: true, rate: 5 + i, capacity: 100 + i}) }); vm.expectEmit(); emit MultiAggregateRateLimiter.RateLimiterConfigUpdated( - configUpdates[i].remoteChainSelector, configUpdates[i].isOutgoingLane, configUpdates[i].rateLimiterConfig + configUpdates[i].remoteChainSelector, configUpdates[i].isOutboundLane, configUpdates[i].rateLimiterConfig ); } @@ -444,7 +288,7 @@ contract MultiAggregateRateLimiter_applyRateLimiterConfigUpdates is MultiAggrega for (uint256 i; i < configUpdates.length; ++i) { RateLimiter.TokenBucket memory bucket = - s_rateLimiter.currentRateLimiterState(configUpdates[i].remoteChainSelector, configUpdates[i].isOutgoingLane); + s_rateLimiter.currentRateLimiterState(configUpdates[i].remoteChainSelector, configUpdates[i].isOutboundLane); _assertConfigWithTokenBucketEquality(configUpdates[i].rateLimiterConfig, bucket); assertEq(BLOCK_TIME, bucket.lastUpdated); } @@ -457,13 +301,13 @@ contract MultiAggregateRateLimiter_applyRateLimiterConfigUpdates is MultiAggrega for (uint64 i; i < configUpdates.length; ++i) { configUpdates[i] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ remoteChainSelector: CHAIN_SELECTOR_1 + 1, - isOutgoingLane: i % 2 == 0 ? false : true, + isOutboundLane: i % 2 == 0 ? false : true, rateLimiterConfig: RateLimiter.Config({isEnabled: true, rate: 5 + i, capacity: 100 + i}) }); vm.expectEmit(); emit MultiAggregateRateLimiter.RateLimiterConfigUpdated( - configUpdates[i].remoteChainSelector, configUpdates[i].isOutgoingLane, configUpdates[i].rateLimiterConfig + configUpdates[i].remoteChainSelector, configUpdates[i].isOutboundLane, configUpdates[i].rateLimiterConfig ); } @@ -475,7 +319,7 @@ contract MultiAggregateRateLimiter_applyRateLimiterConfigUpdates is MultiAggrega for (uint256 i; i < configUpdates.length; ++i) { RateLimiter.TokenBucket memory bucket = - s_rateLimiter.currentRateLimiterState(configUpdates[i].remoteChainSelector, configUpdates[i].isOutgoingLane); + s_rateLimiter.currentRateLimiterState(configUpdates[i].remoteChainSelector, configUpdates[i].isOutboundLane); _assertConfigWithTokenBucketEquality(configUpdates[i].rateLimiterConfig, bucket); assertEq(BLOCK_TIME, bucket.lastUpdated); } @@ -486,7 +330,7 @@ contract MultiAggregateRateLimiter_applyRateLimiterConfigUpdates is MultiAggrega new MultiAggregateRateLimiter.RateLimiterConfigArgs[](1); configUpdates[0] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ remoteChainSelector: CHAIN_SELECTOR_1, - isOutgoingLane: false, + isOutboundLane: false, rateLimiterConfig: RATE_LIMITER_CONFIG_2 }); @@ -511,7 +355,7 @@ contract MultiAggregateRateLimiter_applyRateLimiterConfigUpdates is MultiAggrega // Tokens < capacity since capacity doubled assertTrue(bucket1.capacity != bucket1.tokens); - // Outgoing lane config remains unchanged + // Outbound lane config remains unchanged _assertConfigWithTokenBucketEquality( RATE_LIMITER_CONFIG_2, s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, true) ); @@ -522,7 +366,7 @@ contract MultiAggregateRateLimiter_applyRateLimiterConfigUpdates is MultiAggrega new MultiAggregateRateLimiter.RateLimiterConfigArgs[](1); configUpdates[0] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ remoteChainSelector: CHAIN_SELECTOR_1, - isOutgoingLane: false, + isOutboundLane: false, rateLimiterConfig: RATE_LIMITER_CONFIG_1 }); @@ -550,7 +394,7 @@ contract MultiAggregateRateLimiter_applyRateLimiterConfigUpdates is MultiAggrega new MultiAggregateRateLimiter.RateLimiterConfigArgs[](1); configUpdates[0] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ remoteChainSelector: 0, - isOutgoingLane: false, + isOutboundLane: false, rateLimiterConfig: RATE_LIMITER_CONFIG_1 }); @@ -563,7 +407,7 @@ contract MultiAggregateRateLimiter_applyRateLimiterConfigUpdates is MultiAggrega new MultiAggregateRateLimiter.RateLimiterConfigArgs[](1); configUpdates[0] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ remoteChainSelector: CHAIN_SELECTOR_1 + 1, - isOutgoingLane: false, + isOutboundLane: false, rateLimiterConfig: RATE_LIMITER_CONFIG_1 }); vm.startPrank(STRANGER); @@ -771,7 +615,7 @@ contract MultiAggregateRateLimiter_updateRateLimitTokens is MultiAggregateRateLi remoteToken: bytes32(bytes20(address(0))) }); - vm.expectRevert(MultiAggregateRateLimiter.ZeroAddressNotAllowed.selector); + vm.expectRevert(AuthorizedCallers.ZeroAddressNotAllowed.selector); s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), adds); } @@ -785,7 +629,7 @@ contract MultiAggregateRateLimiter_updateRateLimitTokens is MultiAggregateRateLi remoteToken: bytes32(bytes20(s_destTokens[0])) }); - vm.expectRevert(MultiAggregateRateLimiter.ZeroAddressNotAllowed.selector); + vm.expectRevert(AuthorizedCallers.ZeroAddressNotAllowed.selector); s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), adds); } @@ -799,7 +643,7 @@ contract MultiAggregateRateLimiter_updateRateLimitTokens is MultiAggregateRateLi } } -contract MultiAggregateRateLimiter_onIncomingMessage is MultiAggregateRateLimiterSetup { +contract MultiAggregateRateLimiter_onInboundMessage is MultiAggregateRateLimiterSetup { address internal immutable MOCK_RECEIVER = address(1113); function setUp() public virtual override { @@ -827,7 +671,7 @@ contract MultiAggregateRateLimiter_onIncomingMessage is MultiAggregateRateLimite vm.startPrank(MOCK_OFFRAMP); vm.recordLogs(); - s_rateLimiter.onIncomingMessage(_generateAny2EVMMessageNoTokens(CHAIN_SELECTOR_1)); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessageNoTokens(CHAIN_SELECTOR_1)); // No consumed rate limit events Vm.Log[] memory logEntries = vm.getRecordedLogs(); @@ -845,7 +689,7 @@ contract MultiAggregateRateLimiter_onIncomingMessage is MultiAggregateRateLimite vm.expectEmit(); emit RateLimiter.TokensConsumed((5 * TOKEN_PRICE) / 1e18); - s_rateLimiter.onIncomingMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); } function test_ValidateMessageWithDisabledRateLimitToken_Success() public { @@ -866,7 +710,7 @@ contract MultiAggregateRateLimiter_onIncomingMessage is MultiAggregateRateLimite vm.expectEmit(); emit RateLimiter.TokensConsumed((5 * TOKEN_PRICE) / 1e18); - s_rateLimiter.onIncomingMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); } function test_ValidateMessageWithRateLimitDisabled_Success() public { @@ -874,7 +718,7 @@ contract MultiAggregateRateLimiter_onIncomingMessage is MultiAggregateRateLimite new MultiAggregateRateLimiter.RateLimiterConfigArgs[](1); configUpdates[0] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ remoteChainSelector: CHAIN_SELECTOR_1, - isOutgoingLane: false, + isOutboundLane: false, rateLimiterConfig: RATE_LIMITER_CONFIG_1 }); configUpdates[0].rateLimiterConfig.isEnabled = false; @@ -886,7 +730,7 @@ contract MultiAggregateRateLimiter_onIncomingMessage is MultiAggregateRateLimite tokenAmounts[1] = Client.EVMTokenAmount({token: s_destTokens[1], amount: 50}); vm.startPrank(MOCK_OFFRAMP); - s_rateLimiter.onIncomingMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); // No consumed rate limit events Vm.Log[] memory logEntries = vm.getRecordedLogs(); @@ -917,7 +761,7 @@ contract MultiAggregateRateLimiter_onIncomingMessage is MultiAggregateRateLimite // 2 tokens * (TOKEN_PRICE) + 1 token * (2 * TOKEN_PRICE) uint256 totalValue = (4 * TOKEN_PRICE) / 1e18; - s_rateLimiter.onIncomingMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); // Chain 1 changed RateLimiter.TokenBucket memory bucketChain1 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, false); @@ -930,7 +774,7 @@ contract MultiAggregateRateLimiter_onIncomingMessage is MultiAggregateRateLimite vm.expectEmit(); emit RateLimiter.TokensConsumed(totalValue); - s_rateLimiter.onIncomingMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_2, tokenAmounts)); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_2, tokenAmounts)); // Chain 1 unchanged bucketChain1 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, false); @@ -965,7 +809,7 @@ contract MultiAggregateRateLimiter_onIncomingMessage is MultiAggregateRateLimite // 3 tokens * (TOKEN_PRICE) + 1 token * (2 * TOKEN_PRICE) uint256 totalValue = (5 * TOKEN_PRICE) / 1e18; - s_rateLimiter.onIncomingMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); // Chain 1 changed RateLimiter.TokenBucket memory bucketChain1 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, false); @@ -981,7 +825,7 @@ contract MultiAggregateRateLimiter_onIncomingMessage is MultiAggregateRateLimite vm.expectEmit(); emit RateLimiter.TokensConsumed(totalValue2); - s_rateLimiter.onIncomingMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_2, tokenAmounts)); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_2, tokenAmounts)); // Chain 1 unchanged bucketChain1 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, false); @@ -999,20 +843,20 @@ contract MultiAggregateRateLimiter_onIncomingMessage is MultiAggregateRateLimite tokenAmounts[0] = Client.EVMTokenAmount({token: s_destTokens[0], amount: 20}); // Remaining capacity: 100 -> 20 - s_rateLimiter.onIncomingMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); // Cannot fit 80 rate limit value (need to wait at least 12 blocks, current capacity is 20) vm.expectRevert(abi.encodeWithSelector(RateLimiter.AggregateValueRateLimitReached.selector, 12, 20)); - s_rateLimiter.onIncomingMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); // Remaining capacity: 20 -> 35 (need to wait 9 more blocks) vm.warp(BLOCK_TIME + 3); vm.expectRevert(abi.encodeWithSelector(RateLimiter.AggregateValueRateLimitReached.selector, 9, 35)); - s_rateLimiter.onIncomingMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); // Remaining capacity: 35 -> 80 (can fit exactly 80) vm.warp(BLOCK_TIME + 12); - s_rateLimiter.onIncomingMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); } // Reverts @@ -1026,17 +870,17 @@ contract MultiAggregateRateLimiter_onIncomingMessage is MultiAggregateRateLimite uint256 totalValue = (80 * TOKEN_PRICE + 2 * (30 * TOKEN_PRICE)) / 1e18; vm.expectRevert(abi.encodeWithSelector(RateLimiter.AggregateValueMaxCapacityExceeded.selector, 100, totalValue)); - s_rateLimiter.onIncomingMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); } function test_ValidateMessageFromUnauthorizedCaller_Revert() public { vm.startPrank(STRANGER); - vm.expectRevert(abi.encodeWithSelector(MultiAggregateRateLimiter.UnauthorizedCaller.selector, STRANGER)); - s_rateLimiter.onIncomingMessage(_generateAny2EVMMessageNoTokens(CHAIN_SELECTOR_1)); + vm.expectRevert(abi.encodeWithSelector(AuthorizedCallers.UnauthorizedCaller.selector, STRANGER)); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessageNoTokens(CHAIN_SELECTOR_1)); } - // TODO: add a test case similar to this one to verify that onIncomingMessage / onOutgoingMessage rate limits + // TODO: add a test case similar to this one to verify that onInboundMessage / onOutgoingMessage rate limits // are applied to 2 different buckets // function test_RateLimitValueDifferentLanes_Success() public { // vm.pauseGasMetering(); diff --git a/contracts/src/v0.8/shared/access/AuthorizedCallers.sol b/contracts/src/v0.8/shared/access/AuthorizedCallers.sol new file mode 100644 index 0000000000..93102d1a97 --- /dev/null +++ b/contracts/src/v0.8/shared/access/AuthorizedCallers.sol @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {OwnerIsCreator} from "./OwnerIsCreator.sol"; +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; + +/// @title The AuthorizedCallers contract +/// @notice A contract that manages multiple authorized callers. Enables restricting access to certain functions to a set of addresses. +contract AuthorizedCallers is OwnerIsCreator { + using EnumerableSet for EnumerableSet.AddressSet; + + event AuthorizedCallerAdded(address caller); + event AuthorizedCallerRemoved(address caller); + + error UnauthorizedCaller(address caller); + error ZeroAddressNotAllowed(); + + /// @notice Update args for changing the authorized callers + struct AuthorizedCallerArgs { + address[] addedCallers; + address[] removedCallers; + } + + /// @dev Set of authorized callers + EnumerableSet.AddressSet internal s_authorizedCallers; + + /// @param authorizedCallers the authorized callers to set + constructor(address[] memory authorizedCallers) { + _applyAuthorizedCallerUpdates( + AuthorizedCallerArgs({addedCallers: authorizedCallers, removedCallers: new address[](0)}) + ); + } + + /// @return authorizedCallers Returns all authorized callers + function getAllAuthorizedCallers() external view returns (address[] memory) { + return s_authorizedCallers.values(); + } + + /// @notice Updates the list of authorized callers + /// @param authorizedCallerArgs Callers to add and remove. Removals are performed first. + function applyAuthorizedCallerUpdates(AuthorizedCallerArgs memory authorizedCallerArgs) external onlyOwner { + _applyAuthorizedCallerUpdates(authorizedCallerArgs); + } + + /// @notice Updates the list of authorized callers + /// @param authorizedCallerArgs Callers to add and remove. Removals are performed first. + function _applyAuthorizedCallerUpdates(AuthorizedCallerArgs memory authorizedCallerArgs) internal { + address[] memory removedCallers = authorizedCallerArgs.removedCallers; + for (uint256 i = 0; i < removedCallers.length; ++i) { + address caller = removedCallers[i]; + + if (s_authorizedCallers.remove(caller)) { + emit AuthorizedCallerRemoved(caller); + } + } + + address[] memory addedCallers = authorizedCallerArgs.addedCallers; + for (uint256 i = 0; i < addedCallers.length; ++i) { + address caller = addedCallers[i]; + + if (caller == address(0)) { + revert ZeroAddressNotAllowed(); + } + + s_authorizedCallers.add(caller); + emit AuthorizedCallerAdded(caller); + } + } + + /// @notice Checks the sender and reverts if it is anyone other than a listed authorized caller. + function _validateCaller() internal view { + if (!s_authorizedCallers.contains(msg.sender)) { + revert UnauthorizedCaller(msg.sender); + } + } + + /// @notice Checks the sender and reverts if it is anyone other than a listed authorized caller. + modifier onlyAuthorizedCallers() { + _validateCaller(); + _; + } +} diff --git a/contracts/src/v0.8/shared/test/access/AuthorizedCallers.t.sol b/contracts/src/v0.8/shared/test/access/AuthorizedCallers.t.sol new file mode 100644 index 0000000000..34ae6848a4 --- /dev/null +++ b/contracts/src/v0.8/shared/test/access/AuthorizedCallers.t.sol @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {AuthorizedCallers} from "../../access/AuthorizedCallers.sol"; +import {BaseTest} from "../BaseTest.t.sol"; + +contract AuthorizedCallers_setup is BaseTest { + address[] s_callers; + + AuthorizedCallers s_authorizedCallers; + + function setUp() public override { + super.setUp(); + s_callers.push(makeAddr("caller1")); + s_callers.push(makeAddr("caller2")); + + s_authorizedCallers = new AuthorizedCallers(s_callers); + } +} + +contract AuthorizedCallers_constructor is AuthorizedCallers_setup { + event AuthorizedCallerAdded(address caller); + + function test_constructor_Success() public { + for (uint256 i = 0; i < s_callers.length; ++i) { + vm.expectEmit(); + emit AuthorizedCallerAdded(s_callers[i]); + } + + s_authorizedCallers = new AuthorizedCallers(s_callers); + + assertEq(s_callers, s_authorizedCallers.getAllAuthorizedCallers()); + } + + function test_ZeroAddressNotAllowed_Revert() public { + s_callers[0] = address(0); + + vm.expectRevert(AuthorizedCallers.ZeroAddressNotAllowed.selector); + + new AuthorizedCallers(s_callers); + } +} + +contract AuthorizedCallers_applyAuthorizedCallerUpdates is AuthorizedCallers_setup { + event AuthorizedCallerAdded(address caller); + event AuthorizedCallerRemoved(address caller); + + function test_OnlyAdd_Success() public { + address[] memory addedCallers = new address[](2); + addedCallers[0] = vm.addr(3); + addedCallers[1] = vm.addr(4); + + address[] memory removedCallers = new address[](0); + + assertEq(s_authorizedCallers.getAllAuthorizedCallers(), s_callers); + + vm.expectEmit(); + emit AuthorizedCallerAdded(addedCallers[0]); + vm.expectEmit(); + emit AuthorizedCallerAdded(addedCallers[1]); + + s_authorizedCallers.applyAuthorizedCallerUpdates( + AuthorizedCallers.AuthorizedCallerArgs({addedCallers: addedCallers, removedCallers: removedCallers}) + ); + + address[] memory expectedCallers = new address[](4); + expectedCallers[0] = s_callers[0]; + expectedCallers[1] = s_callers[1]; + expectedCallers[2] = addedCallers[0]; + expectedCallers[3] = addedCallers[1]; + + assertEq(s_authorizedCallers.getAllAuthorizedCallers(), expectedCallers); + } + + function test_OnlyRemove_Success() public { + address[] memory addedCallers = new address[](0); + address[] memory removedCallers = new address[](1); + removedCallers[0] = s_callers[0]; + + assertEq(s_authorizedCallers.getAllAuthorizedCallers(), s_callers); + + vm.expectEmit(); + emit AuthorizedCallerRemoved(removedCallers[0]); + + s_authorizedCallers.applyAuthorizedCallerUpdates( + AuthorizedCallers.AuthorizedCallerArgs({addedCallers: addedCallers, removedCallers: removedCallers}) + ); + + address[] memory expectedCallers = new address[](1); + expectedCallers[0] = s_callers[1]; + + assertEq(s_authorizedCallers.getAllAuthorizedCallers(), expectedCallers); + } + + function test_AddAndRemove_Success() public { + address[] memory addedCallers = new address[](2); + addedCallers[0] = address(42); + addedCallers[1] = address(43); + + address[] memory removedCallers = new address[](1); + removedCallers[0] = s_callers[0]; + + assertEq(s_authorizedCallers.getAllAuthorizedCallers(), s_callers); + + vm.expectEmit(); + emit AuthorizedCallerRemoved(removedCallers[0]); + vm.expectEmit(); + emit AuthorizedCallerAdded(addedCallers[0]); + vm.expectEmit(); + emit AuthorizedCallerAdded(addedCallers[1]); + + s_authorizedCallers.applyAuthorizedCallerUpdates( + AuthorizedCallers.AuthorizedCallerArgs({addedCallers: addedCallers, removedCallers: removedCallers}) + ); + + // Order of the set changes on removal + address[] memory expectedCallers = new address[](3); + expectedCallers[0] = s_callers[1]; + expectedCallers[1] = addedCallers[0]; + expectedCallers[2] = addedCallers[1]; + + assertEq(s_authorizedCallers.getAllAuthorizedCallers(), expectedCallers); + } + + function test_RemoveThenAdd_Success() public { + address[] memory addedCallers = new address[](1); + addedCallers[0] = s_callers[0]; + + address[] memory removedCallers = new address[](1); + removedCallers[0] = s_callers[0]; + + assertEq(s_authorizedCallers.getAllAuthorizedCallers(), s_callers); + + vm.expectEmit(); + emit AuthorizedCallerRemoved(removedCallers[0]); + + vm.expectEmit(); + emit AuthorizedCallerAdded(addedCallers[0]); + + s_authorizedCallers.applyAuthorizedCallerUpdates( + AuthorizedCallers.AuthorizedCallerArgs({addedCallers: addedCallers, removedCallers: removedCallers}) + ); + + address[] memory expectedCallers = new address[](2); + expectedCallers[0] = s_callers[1]; + expectedCallers[1] = s_callers[0]; + + assertEq(s_authorizedCallers.getAllAuthorizedCallers(), expectedCallers); + } + + function test_SkipRemove_Success() public { + address[] memory addedCallers = new address[](0); + + address[] memory removedCallers = new address[](1); + removedCallers[0] = address(42); + + vm.recordLogs(); + s_authorizedCallers.applyAuthorizedCallerUpdates( + AuthorizedCallers.AuthorizedCallerArgs({addedCallers: addedCallers, removedCallers: removedCallers}) + ); + + assertEq(s_authorizedCallers.getAllAuthorizedCallers(), s_callers); + assertEq(vm.getRecordedLogs().length, 0); + } + + function test_OnlyCallableByOwner_Revert() public { + vm.stopPrank(); + + AuthorizedCallers.AuthorizedCallerArgs memory authorizedCallerArgs = AuthorizedCallers.AuthorizedCallerArgs({ + addedCallers: new address[](0), + removedCallers: new address[](0) + }); + + vm.expectRevert("Only callable by owner"); + + s_authorizedCallers.applyAuthorizedCallerUpdates(authorizedCallerArgs); + } + + function test_ZeroAddressNotAllowed_Revert() public { + s_callers[0] = address(0); + + vm.expectRevert(AuthorizedCallers.ZeroAddressNotAllowed.selector); + + new AuthorizedCallers(s_callers); + } +} diff --git a/core/gethwrappers/ccip/generated/ccip_capability_configuration/ccip_capability_configuration.go b/core/gethwrappers/ccip/generated/ccip_capability_configuration/ccip_capability_configuration.go new file mode 100644 index 0000000000..88e100fd7b --- /dev/null +++ b/core/gethwrappers/ccip/generated/ccip_capability_configuration/ccip_capability_configuration.go @@ -0,0 +1,1079 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package ccip_capability_configuration + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type CCIPCapabilityConfigurationChainConfig struct { + Readers [][32]byte + FChain uint8 + Config []byte +} + +type CCIPCapabilityConfigurationChainConfigInfo struct { + ChainSelector uint64 + ChainConfig CCIPCapabilityConfigurationChainConfig +} + +type CCIPCapabilityConfigurationOCR3Config struct { + PluginType uint8 + ChainSelector uint64 + F uint8 + OffchainConfigVersion uint64 + OfframpAddress []byte + BootstrapP2PIds [][32]byte + P2pIds [][32]byte + Signers [][]byte + Transmitters [][]byte + OffchainConfig []byte +} + +type CCIPCapabilityConfigurationOCR3ConfigWithMeta struct { + Config CCIPCapabilityConfigurationOCR3Config + ConfigCount uint64 + ConfigDigest [32]byte +} + +var CCIPCapabilityConfigurationMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"capabilityRegistry\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainConfigNotSetForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainSelectorNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ChainSelectorNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FChainMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"InvalidConfigLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumCCIPCapabilityConfiguration.ConfigState\",\"name\":\"currentState\",\"type\":\"uint8\"},{\"internalType\":\"enumCCIPCapabilityConfiguration.ConfigState\",\"name\":\"proposedState\",\"type\":\"uint8\"}],\"name\":\"InvalidConfigStateTransition\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPluginType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"NodeNotInRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonExistentConfigTransition\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimum\",\"type\":\"uint256\"}],\"name\":\"NotEnoughTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OfframpAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCapabilityRegistryCanCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"p2pIdsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"signersLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"transmittersLength\",\"type\":\"uint256\"}],\"name\":\"P2PIdsLengthNotMatching\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyBootstrapP2PIds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOCR3Configs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManySigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyTransmitters\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"}],\"name\":\"WrongConfigCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"got\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"WrongConfigDigest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"got\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"WrongConfigDigestBlueGreen\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"CapabilityConfigurationSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainConfigRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structCCIPCapabilityConfiguration.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"chainSelectorRemoves\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPCapabilityConfiguration.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPCapabilityConfiguration.ChainConfigInfo[]\",\"name\":\"chainConfigAdds\",\"type\":\"tuple[]\"}],\"name\":\"applyChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"beforeCapabilityConfigSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllChainConfigs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPCapabilityConfiguration.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPCapabilityConfiguration.ChainConfigInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"getCapabilityConfiguration\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"configuration\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumCCIPCapabilityConfiguration.PluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getOCRConfig\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"enumCCIPCapabilityConfiguration.PluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"bootstrapP2PIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"p2pIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes[]\",\"name\":\"signers\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes[]\",\"name\":\"transmitters\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPCapabilityConfiguration.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"internalType\":\"structCCIPCapabilityConfiguration.OCR3ConfigWithMeta[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b50604051620040563803806200405683398101604081905262000034916200017e565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d3565b5050506001600160a01b0316608052620001b0565b336001600160a01b038216036200012d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019157600080fd5b81516001600160a01b0381168114620001a957600080fd5b9392505050565b608051613e83620001d360003960008181610d640152610ff90152613e836000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80638da5cb5b11610076578063f2fde38b1161005b578063f2fde38b1461014e578063f442c89a14610161578063fba64a7c1461017457600080fd5b80638da5cb5b14610111578063ddc042a81461013957600080fd5b8063181f5a77146100a85780634bd0473f146100c657806379ba5097146100e65780638318ed5d146100f0575b600080fd5b6100b0610187565b6040516100bd9190612d12565b60405180910390f35b6100d96100d4366004612d56565b6101a3565b6040516100bd9190612e82565b6100ee610674565b005b6100b06100fe36600461305f565b5060408051602081019091526000815290565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100bd565b610141610776565b6040516100bd91906130c0565b6100ee61015c366004613150565b610968565b6100ee61016f3660046131d2565b61097c565b6100ee610182366004613256565b610d4c565b604051806060016040528060258152602001613e526025913981565b63ffffffff821660009081526005602052604081206060918360018111156101cd576101cd612d8b565b60018111156101de576101de612d8b565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561066757600084815260209020604080516101a08101909152600984029091018054829060608201908390829060ff16600181111561025157610251612d8b565b600181111561026257610262612d8b565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a01000000000000000000009091041660608201526001820180546080909201916102ba90613313565b80601f01602080910402602001604051908101604052809291908181526020018280546102e690613313565b80156103335780601f1061030857610100808354040283529160200191610333565b820191906000526020600020905b81548152906001019060200180831161031657829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561038b57602002820191906000526020600020905b815481526020019060010190808311610377575b50505050508152602001600382018054806020026020016040519081016040528092919081815260200182805480156103e357602002820191906000526020600020905b8154815260200190600101908083116103cf575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b828210156104bd57838290600052602060002001805461043090613313565b80601f016020809104026020016040519081016040528092919081815260200182805461045c90613313565b80156104a95780601f1061047e576101008083540402835291602001916104a9565b820191906000526020600020905b81548152906001019060200180831161048c57829003601f168201915b505050505081526020019060010190610411565b50505050815260200160058201805480602002602001604051908101604052809291908181526020016000905b8282101561059657838290600052602060002001805461050990613313565b80601f016020809104026020016040519081016040528092919081815260200182805461053590613313565b80156105825780601f1061055757610100808354040283529160200191610582565b820191906000526020600020905b81548152906001019060200180831161056557829003601f168201915b5050505050815260200190600101906104ea565b5050505081526020016006820180546105ae90613313565b80601f01602080910402602001604051908101604052809291908181526020018280546105da90613313565b80156106275780601f106105fc57610100808354040283529160200191610627565b820191906000526020600020905b81548152906001019060200180831161060a57829003601f168201915b505050919092525050508152600782015467ffffffffffffffff16602080830191909152600890920154604090910152908252600192909201910161020c565b5050505090505b92915050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146106fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b606060006107846003610e0d565b905060006107926003610e21565b67ffffffffffffffff8111156107aa576107aa613366565b6040519080825280602002602001820160405280156107e357816020015b6107d0612a3f565b8152602001906001900390816107c85790505b50905060005b825181101561096157600083828151811061080657610806613395565b60209081029190910181015160408051808201825267ffffffffffffffff83168082526000908152600285528290208251815460808188028301810190955260608201818152959750929586019490939192849284919084018282801561088c57602002820191906000526020600020905b815481526020019060010190808311610878575b5050509183525050600182015460ff1660208201526002820180546040909201916108b690613313565b80601f01602080910402602001604051908101604052809291908181526020018280546108e290613313565b801561092f5780601f106109045761010080835404028352916020019161092f565b820191906000526020600020905b81548152906001019060200180831161091257829003601f168201915b50505050508152505081525083838151811061094d5761094d613395565b6020908102919091010152506001016107e9565b5092915050565b610970610e2b565b61097981610eae565b50565b610984610e2b565b60005b83811015610b6a576109cb8585838181106109a4576109a4613395565b90506020020160208101906109b991906133c4565b60039067ffffffffffffffff16610fa3565b610a35578484828181106109e1576109e1613395565b90506020020160208101906109f691906133c4565b6040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016106f1565b60026000868684818110610a4b57610a4b613395565b9050602002016020810190610a6091906133c4565b67ffffffffffffffff1681526020810191909152604001600090812090610a878282612a87565b6001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610abf600283016000612aa5565b5050610afd858583818110610ad657610ad6613395565b9050602002016020810190610aeb91906133c4565b60039067ffffffffffffffff16610fbb565b507f2a680691fef3b2d105196805935232c661ce703e92d464ef0b94a7bc62d714f0858583818110610b3157610b31613395565b9050602002016020810190610b4691906133c4565b60405167ffffffffffffffff909116815260200160405180910390a1600101610987565b5060005b81811015610d45576000838383818110610b8a57610b8a613395565b9050602002810190610b9c91906133df565b610baa90602081019061341d565b610bb39061361f565b80519091506000858585818110610bcc57610bcc613395565b9050602002810190610bde91906133df565b610bec9060208101906133c4565b905060005b8251811015610c2457610c1c838281518110610c0f57610c0f613395565b6020026020010151610fc7565b600101610bf1565b50826020015160ff16600003610c66576040517fa9b3766e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600260209081526040909120845180518693610c96928492910190612adf565b5060208201516001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff90921691909117905560408201516002820190610ce39082613706565b50610cfd91506003905067ffffffffffffffff83166110e1565b507f05dd57854af2c291a94ea52e7c43d80bc3be7fa73022f98b735dea86642fa5e08184604051610d2f929190613820565b60405180910390a1505050806001019050610b6e565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610dbb576040517f7b2485a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610dc9848601866138cb565b9050600080610dd7836110ed565b8151919350915015610def57610def84600084611346565b805115610e0257610e0284600183611346565b505050505050505050565b60606000610e1a83611b27565b9392505050565b600061066e825490565b60005473ffffffffffffffffffffffffffffffffffffffff163314610eac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016106f1565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610f2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106f1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120541515610e1a565b6000610e1a8383611b83565b6040517f50c946fe000000000000000000000000000000000000000000000000000000008152600481018290526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906350c946fe90602401600060405180830381865afa158015611055573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261109b9190810190613add565b5060408101519091506110dd576040517f8907a4fa000000000000000000000000000000000000000000000000000000008152600481018390526024016106f1565b5050565b6000610e1a8383611c76565b606080600460ff168351111561112f576040517f8854586400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160028082526060820190925290816020015b6111b36040805161014081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff1681526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b81526020019060019003908161114557505060408051600280825260608201909252919350602082015b61124b6040805161014081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff1681526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b8152602001906001900390816111dd57905050905060008060005b855181101561133957600086828151811061128357611283613395565b60200260200101516000015160018111156112a0576112a0612d8b565b036112ed578581815181106112b7576112b7613395565b60200260200101518584815181106112d1576112d1613395565b6020026020010181905250826112e690613c0b565b9250611331565b8581815181106112ff576112ff613395565b602002602001015184838151811061131957611319613395565b60200260200101819052508161132e90613c0b565b91505b600101611266565b5090835281529092909150565b63ffffffff831660009081526005602052604081208184600181111561136e5761136e612d8b565b600181111561137f5761137f612d8b565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561180857600084815260209020604080516101a08101909152600984029091018054829060608201908390829060ff1660018111156113f2576113f2612d8b565b600181111561140357611403612d8b565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a010000000000000000000090910416606082015260018201805460809092019161145b90613313565b80601f016020809104026020016040519081016040528092919081815260200182805461148790613313565b80156114d45780601f106114a9576101008083540402835291602001916114d4565b820191906000526020600020905b8154815290600101906020018083116114b757829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561152c57602002820191906000526020600020905b815481526020019060010190808311611518575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561158457602002820191906000526020600020905b815481526020019060010190808311611570575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b8282101561165e5783829060005260206000200180546115d190613313565b80601f01602080910402602001604051908101604052809291908181526020018280546115fd90613313565b801561164a5780601f1061161f5761010080835404028352916020019161164a565b820191906000526020600020905b81548152906001019060200180831161162d57829003601f168201915b5050505050815260200190600101906115b2565b50505050815260200160058201805480602002602001604051908101604052809291908181526020016000905b828210156117375783829060005260206000200180546116aa90613313565b80601f01602080910402602001604051908101604052809291908181526020018280546116d690613313565b80156117235780601f106116f857610100808354040283529160200191611723565b820191906000526020600020905b81548152906001019060200180831161170657829003601f168201915b50505050508152602001906001019061168b565b50505050815260200160068201805461174f90613313565b80601f016020809104026020016040519081016040528092919081815260200182805461177b90613313565b80156117c85780601f1061179d576101008083540402835291602001916117c8565b820191906000526020600020905b8154815290600101906020018083116117ab57829003601f168201915b505050919092525050508152600782015467ffffffffffffffff1660208083019190915260089092015460409091015290825260019290920191016113ad565b505050509050600061181a8251611cc5565b905060006118288451611cc5565b90506118348282611d17565b60006118438785878686611e0b565b905061184f84826121f7565b63ffffffff871660009081526005602052604081209087600181111561187757611877612d8b565b600181111561188857611888612d8b565b815260200190815260200160002060006118a29190612b2a565b60005b8151811015611b1d5763ffffffff88166000908152600560205260408120908860018111156118d6576118d6612d8b565b60018111156118e7576118e7612d8b565b815260200190815260200160002082828151811061190757611907613395565b6020908102919091018101518254600181810185556000948552929093208151805160099095029091018054929490939192849283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690838181111561197157611971612d8b565b021790555060208201518154604084015160608501517fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90921661010067ffffffffffffffff948516027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff1617690100000000000000000060ff90921691909102177fffffffffffffffffffffffffffff0000000000000000ffffffffffffffffffff166a0100000000000000000000929091169190910217815560808201516001820190611a409082613706565b5060a08201518051611a5c916002840191602090910190612adf565b5060c08201518051611a78916003840191602090910190612adf565b5060e08201518051611a94916004840191602090910190612b4b565b506101008201518051611ab1916005840191602090910190612b4b565b506101208201516006820190611ac79082613706565b50505060208201516007820180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff9092169190911790556040909101516008909101556001016118a5565b5050505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611b7757602002820191906000526020600020905b815481526020019060010190808311611b63575b50505050509050919050565b60008181526001830160205260408120548015611c6c576000611ba7600183613c43565b8554909150600090611bbb90600190613c43565b9050818114611c20576000866000018281548110611bdb57611bdb613395565b9060005260206000200154905080876000018481548110611bfe57611bfe613395565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611c3157611c31613c56565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061066e565b600091505061066e565b6000818152600183016020526040812054611cbd5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561066e565b50600061066e565b60006002821115611d05576040517f3e478526000000000000000000000000000000000000000000000000000000008152600481018390526024016106f1565b81600281111561066e5761066e612d8b565b600080836002811115611d2c57611d2c612d8b565b148015611d4a57506001826002811115611d4857611d48612d8b565b145b905060006001846002811115611d6257611d62612d8b565b148015611d8057506002836002811115611d7e57611d7e612d8b565b145b905060006002856002811115611d9857611d98612d8b565b148015611db657506001846002811115611db457611db4612d8b565b145b90508280611dc15750815b80611dc95750805b15611dd5575050505050565b84846040517f0a6b675b0000000000000000000000000000000000000000000000000000000081526004016106f1929190613c95565b60606000845167ffffffffffffffff811115611e2957611e29613366565b604051908082528060200260200182016040528015611e52578160200160208202803683370190505b5090506000846002811115611e6957611e69612d8b565b148015611e8757506001836002811115611e8557611e85612d8b565b145b15611ec857600181600081518110611ea157611ea1613395565b602002602001019067ffffffffffffffff16908167ffffffffffffffff1681525050612030565b6001846002811115611edc57611edc612d8b565b148015611efa57506002836002811115611ef857611ef8612d8b565b145b15611f915785600081518110611f1257611f12613395565b60200260200101516020015181600081518110611f3157611f31613395565b602002602001019067ffffffffffffffff16908167ffffffffffffffff168152505085600081518110611f6657611f66613395565b6020026020010151602001516001611f7e9190613cb0565b81600181518110611ea157611ea1613395565b6002846002811115611fa557611fa5612d8b565b148015611fc357506001836002811115611fc157611fc1612d8b565b145b15611ffa5785600181518110611fdb57611fdb613395565b60200260200101516020015181600081518110611ea157611ea1613395565b83836040517f0a6b675b0000000000000000000000000000000000000000000000000000000081526004016106f1929190613c95565b6000855167ffffffffffffffff81111561204c5761204c613366565b60405190808252806020026020018201604052801561210257816020015b604080516101a081018252600060608083018281526080840183905260a0840183905260c0840183905260e084018290526101008401829052610120840182905261014084018290526101608401829052610180840191909152825260208083018290529282015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161206a5790505b50905060005b82518110156121eb5761213387828151811061212657612126613395565b6020026020010151612576565b604051806060016040528088838151811061215057612150613395565b6020026020010151815260200184838151811061216f5761216f613395565b602002602001015167ffffffffffffffff1681526020016121c38b86858151811061219c5761219c613395565b60200260200101518b86815181106121b6576121b6613395565b602002602001015161296a565b8152508282815181106121d8576121d8613395565b6020908102919091010152600101612108565b50979650505050505050565b81518151811580156122095750806001145b156122ab578260008151811061222157612221613395565b60200260200101516020015167ffffffffffffffff166001146122a5578260008151811061225157612251613395565b60209081029190910181015101516040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152600160248201526044016106f1565b50505050565b8160011480156122bb5750806002145b1561247157836000815181106122d3576122d3613395565b602002602001015160400151836000815181106122f2576122f2613395565b6020026020010151604001511461237e578260008151811061231657612316613395565b6020026020010151604001518460008151811061233557612335613395565b6020026020010151604001516040517fc7ccdd7f0000000000000000000000000000000000000000000000000000000081526004016106f1929190918252602082015260400190565b8360008151811061239157612391613395565b60200260200101516020015160016123a99190613cb0565b67ffffffffffffffff16836001815181106123c6576123c6613395565b60200260200101516020015167ffffffffffffffff16146122a557826001815181106123f4576123f4613395565b6020026020010151602001518460008151811061241357612413613395565b602002602001015160200151600161242b9190613cb0565b6040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9283166004820152911660248201526044016106f1565b8160021480156124815750806001145b15612544578360018151811061249957612499613395565b602002602001015160400151836000815181106124b8576124b8613395565b602002602001015160400151146122a557826000815181106124dc576124dc613395565b602002602001015160400151846001815181106124fb576124fb613395565b6020026020010151604001516040517f9e9756700000000000000000000000000000000000000000000000000000000081526004016106f1929190918252602082015260400190565b6040517f1f1b2bb600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806020015167ffffffffffffffff166000036125be576040517f698cf8e000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815160018111156125d3576125d3612d8b565b141580156125f457506001815160018111156125f1576125f1612d8b565b14155b1561262b576040517f3302dbd700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80608001515160000361266a576040517f358c192700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101516126859060039067ffffffffffffffff16610fa3565b6126cd5760208101516040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016106f1565b60e081015151601f101561270d576040517f1b925da600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010081015151601f101561274e576040517f645960ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208082015167ffffffffffffffff1660009081526002909152604081206001015461277e9060ff166003613cd1565b612789906001613ced565b60ff169050808261010001515110156127e057610100820151516040517f548dd21f0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016106f1565b816040015160ff16600003612821576040517f39d1a4d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040820151612831906003613cd1565b60ff168260e001515111612871576040517f4856694e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160e00151518260c00151511415806128955750816101000151518260c001515114155b156128f05760c08201515160e083015151610100840151516040517fba900f6d0000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915260448201526064016106f1565b8160c00151518260a00151511115612934576040517f8473d80700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8260e00151518110156129655761295d8360c001518281518110610c0f57610c0f613395565b600101612937565b505050565b60008082602001518584600001518560800151878760a001518860c001518960e001518a61010001518b604001518c606001518d61012001516040516020016129be9c9b9a99989796959493929190613d71565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0a000000000000000000000000000000000000000000000000000000000000179150509392505050565b6040518060400160405280600067ffffffffffffffff168152602001612a82604051806060016040528060608152602001600060ff168152602001606081525090565b905290565b50805460008255906000526020600020908101906109799190612b9d565b508054612ab190613313565b6000825580601f10612ac1575050565b601f0160209004906000526020600020908101906109799190612b9d565b828054828255906000526020600020908101928215612b1a579160200282015b82811115612b1a578251825591602001919060010190612aff565b50612b26929150612b9d565b5090565b50805460008255600902906000526020600020908101906109799190612bb2565b828054828255906000526020600020908101928215612b91579160200282015b82811115612b915782518290612b819082613706565b5091602001919060010190612b6b565b50612b26929150612c73565b5b80821115612b265760008155600101612b9e565b80821115612b265780547fffffffffffffffffffffffffffff00000000000000000000000000000000000016815560008181612bf16001830182612aa5565b612bff600283016000612a87565b612c0d600383016000612a87565b612c1b600483016000612c90565b612c29600583016000612c90565b612c37600683016000612aa5565b5050506007810180547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016905560006008820155600901612bb2565b80821115612b26576000612c878282612aa5565b50600101612c73565b50805460008255906000526020600020908101906109799190612c73565b6000815180845260005b81811015612cd457602081850181015186830182015201612cb8565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610e1a6020830184612cae565b63ffffffff8116811461097957600080fd5b8035612d4281612d25565b919050565b803560028110612d4257600080fd5b60008060408385031215612d6957600080fd5b8235612d7481612d25565b9150612d8260208401612d47565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60028110612dca57612dca612d8b565b9052565b60008151808452602080850194506020840160005b83811015612dff57815187529582019590820190600101612de3565b509495945050505050565b60008282518085526020808601955060208260051b8401016020860160005b84811015612e75577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868403018952612e63838351612cae565b98840198925090830190600101612e29565b5090979650505050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b83811015613051577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0898403018552815160608151818652612ef08287018251612dba565b898101516080612f0b8189018367ffffffffffffffff169052565b8a830151915060a0612f21818a018460ff169052565b938301519360c09250612f3f8984018667ffffffffffffffff169052565b818401519450610140915060e082818b0152612f5f6101a08b0187612cae565b95508185015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0610100818c890301818d0152612f9e8885612dce565b97508587015195506101209350818c890301848d0152612fbe8887612dce565b9750828701519550818c890301858d0152612fd98887612e0a565b975080870151955050808b8803016101608c0152612ff78786612e0a565b9650828601519550808b8803016101808c015250505050506130198282612cae565b915050888201516130358a87018267ffffffffffffffff169052565b5090870151938701939093529386019390860190600101612eab565b509098975050505050505050565b60006020828403121561307157600080fd5b8135610e1a81612d25565b60008151606084526130916060850182612dce565b905060ff6020840151166020850152604083015184820360408601526130b78282612cae565b95945050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b83811015613051578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805167ffffffffffffffff16845287015187840187905261313d8785018261307c565b95880195935050908601906001016130e9565b60006020828403121561316257600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610e1a57600080fd5b60008083601f84011261319857600080fd5b50813567ffffffffffffffff8111156131b057600080fd5b6020830191508360208260051b85010111156131cb57600080fd5b9250929050565b600080600080604085870312156131e857600080fd5b843567ffffffffffffffff8082111561320057600080fd5b61320c88838901613186565b9096509450602087013591508082111561322557600080fd5b5061323287828801613186565b95989497509550505050565b803567ffffffffffffffff81168114612d4257600080fd5b6000806000806000806080878903121561326f57600080fd5b863567ffffffffffffffff8082111561328757600080fd5b6132938a838b01613186565b909850965060208901359150808211156132ac57600080fd5b818901915089601f8301126132c057600080fd5b8135818111156132cf57600080fd5b8a60208285010111156132e157600080fd5b6020830196508095505050506132f96040880161323e565b915061330760608801612d37565b90509295509295509295565b600181811c9082168061332757607f821691505b602082108103613360577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156133d657600080fd5b610e1a8261323e565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261341357600080fd5b9190910192915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa183360301811261341357600080fd5b604051610140810167ffffffffffffffff8111828210171561347557613475613366565b60405290565b6040516080810167ffffffffffffffff8111828210171561347557613475613366565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156134e5576134e5613366565b604052919050565b600067ffffffffffffffff82111561350757613507613366565b5060051b60200190565b600082601f83011261352257600080fd5b81356020613537613532836134ed565b61349e565b8083825260208201915060208460051b87010193508684111561355957600080fd5b602086015b84811015613575578035835291830191830161355e565b509695505050505050565b803560ff81168114612d4257600080fd5b600082601f8301126135a257600080fd5b813567ffffffffffffffff8111156135bc576135bc613366565b6135ed60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161349e565b81815284602083860101111561360257600080fd5b816020850160208301376000918101602001919091529392505050565b60006060823603121561363157600080fd5b6040516060810167ffffffffffffffff828210818311171561365557613655613366565b81604052843591508082111561366a57600080fd5b61367636838701613511565b835261368460208601613580565b6020840152604085013591508082111561369d57600080fd5b506136aa36828601613591565b60408301525092915050565b601f821115612965576000816000526020600020601f850160051c810160208610156136df5750805b601f850160051c820191505b818110156136fe578281556001016136eb565b505050505050565b815167ffffffffffffffff81111561372057613720613366565b6137348161372e8454613313565b846136b6565b602080601f83116001811461378757600084156137515750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556136fe565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156137d4578886015182559484019460019091019084016137b5565b508582101561381057878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b67ffffffffffffffff83168152604060208201526000613843604083018461307c565b949350505050565b600082601f83011261385c57600080fd5b8135602061386c613532836134ed565b82815260059290921b8401810191818101908684111561388b57600080fd5b8286015b8481101561357557803567ffffffffffffffff8111156138af5760008081fd5b6138bd8986838b0101613591565b84525091830191830161388f565b600060208083850312156138de57600080fd5b823567ffffffffffffffff808211156138f657600080fd5b818501915085601f83011261390a57600080fd5b8135613918613532826134ed565b81815260059190911b8301840190848101908883111561393757600080fd5b8585015b83811015613ac55780358581111561395257600080fd5b8601610140818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001121561398757600080fd5b61398f613451565b61399a898301612d47565b81526139a86040830161323e565b898201526139b860608301613580565b60408201526139c96080830161323e565b606082015260a0820135878111156139e057600080fd5b6139ee8d8b83860101613591565b60808301525060c082013587811115613a0657600080fd5b613a148d8b83860101613511565b60a08301525060e082013587811115613a2c57600080fd5b613a3a8d8b83860101613511565b60c0830152506101008083013588811115613a5457600080fd5b613a628e8c8387010161384b565b60e0840152506101208084013589811115613a7c57600080fd5b613a8a8f8d8388010161384b565b8385015250610140840135915088821115613aa457600080fd5b613ab28e8c84870101613591565b908301525084525091860191860161393b565b5098975050505050505050565b8051612d4281612d25565b60008060408385031215613af057600080fd5b825167ffffffffffffffff80821115613b0857600080fd5b9084019060808287031215613b1c57600080fd5b613b2461347b565b8251613b2f81612d25565b81526020838101518183015260408085015190830152606084015183811115613b5757600080fd5b80850194505087601f850112613b6c57600080fd5b83519250613b7c613532846134ed565b83815260059390931b84018101928181019089851115613b9b57600080fd5b948201945b84861015613bb957855182529482019490820190613ba0565b8060608501525050819550613bcf818801613ad2565b9450505050509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613c3c57613c3c613bdc565b5060010190565b8181038181111561066e5761066e613bdc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60038110612dca57612dca612d8b565b60408101613ca38285613c85565b610e1a6020830184613c85565b67ffffffffffffffff81811683821601908082111561096157610961613bdc565b60ff818116838216029081169081811461096157610961613bdc565b60ff818116838216019081111561066e5761066e613bdc565b60008282518085526020808601955060208260051b8401016020860160005b84811015612e75577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868403018952613d5f838351612cae565b98840198925090830190600101613d25565b67ffffffffffffffff8d16815263ffffffff8c166020820152613d97604082018c612dba565b61018060608201526000613daf61018083018c612cae565b67ffffffffffffffff8b16608084015282810360a0840152613dd1818b612dce565b905082810360c0840152613de5818a612dce565b905082810360e0840152613df98189613d06565b9050828103610100840152613e0e8188613d06565b60ff8716610120850152905067ffffffffffffffff8516610140840152828103610160840152613e3e8185612cae565b9f9e50505050505050505050505050505056fe434349504361706162696c697479436f6e66696775726174696f6e20312e362e302d646576a164736f6c6343000818000a", +} + +var CCIPCapabilityConfigurationABI = CCIPCapabilityConfigurationMetaData.ABI + +var CCIPCapabilityConfigurationBin = CCIPCapabilityConfigurationMetaData.Bin + +func DeployCCIPCapabilityConfiguration(auth *bind.TransactOpts, backend bind.ContractBackend, capabilityRegistry common.Address) (common.Address, *types.Transaction, *CCIPCapabilityConfiguration, error) { + parsed, err := CCIPCapabilityConfigurationMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(CCIPCapabilityConfigurationBin), backend, capabilityRegistry) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &CCIPCapabilityConfiguration{address: address, abi: *parsed, CCIPCapabilityConfigurationCaller: CCIPCapabilityConfigurationCaller{contract: contract}, CCIPCapabilityConfigurationTransactor: CCIPCapabilityConfigurationTransactor{contract: contract}, CCIPCapabilityConfigurationFilterer: CCIPCapabilityConfigurationFilterer{contract: contract}}, nil +} + +type CCIPCapabilityConfiguration struct { + address common.Address + abi abi.ABI + CCIPCapabilityConfigurationCaller + CCIPCapabilityConfigurationTransactor + CCIPCapabilityConfigurationFilterer +} + +type CCIPCapabilityConfigurationCaller struct { + contract *bind.BoundContract +} + +type CCIPCapabilityConfigurationTransactor struct { + contract *bind.BoundContract +} + +type CCIPCapabilityConfigurationFilterer struct { + contract *bind.BoundContract +} + +type CCIPCapabilityConfigurationSession struct { + Contract *CCIPCapabilityConfiguration + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type CCIPCapabilityConfigurationCallerSession struct { + Contract *CCIPCapabilityConfigurationCaller + CallOpts bind.CallOpts +} + +type CCIPCapabilityConfigurationTransactorSession struct { + Contract *CCIPCapabilityConfigurationTransactor + TransactOpts bind.TransactOpts +} + +type CCIPCapabilityConfigurationRaw struct { + Contract *CCIPCapabilityConfiguration +} + +type CCIPCapabilityConfigurationCallerRaw struct { + Contract *CCIPCapabilityConfigurationCaller +} + +type CCIPCapabilityConfigurationTransactorRaw struct { + Contract *CCIPCapabilityConfigurationTransactor +} + +func NewCCIPCapabilityConfiguration(address common.Address, backend bind.ContractBackend) (*CCIPCapabilityConfiguration, error) { + abi, err := abi.JSON(strings.NewReader(CCIPCapabilityConfigurationABI)) + if err != nil { + return nil, err + } + contract, err := bindCCIPCapabilityConfiguration(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &CCIPCapabilityConfiguration{address: address, abi: abi, CCIPCapabilityConfigurationCaller: CCIPCapabilityConfigurationCaller{contract: contract}, CCIPCapabilityConfigurationTransactor: CCIPCapabilityConfigurationTransactor{contract: contract}, CCIPCapabilityConfigurationFilterer: CCIPCapabilityConfigurationFilterer{contract: contract}}, nil +} + +func NewCCIPCapabilityConfigurationCaller(address common.Address, caller bind.ContractCaller) (*CCIPCapabilityConfigurationCaller, error) { + contract, err := bindCCIPCapabilityConfiguration(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &CCIPCapabilityConfigurationCaller{contract: contract}, nil +} + +func NewCCIPCapabilityConfigurationTransactor(address common.Address, transactor bind.ContractTransactor) (*CCIPCapabilityConfigurationTransactor, error) { + contract, err := bindCCIPCapabilityConfiguration(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &CCIPCapabilityConfigurationTransactor{contract: contract}, nil +} + +func NewCCIPCapabilityConfigurationFilterer(address common.Address, filterer bind.ContractFilterer) (*CCIPCapabilityConfigurationFilterer, error) { + contract, err := bindCCIPCapabilityConfiguration(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &CCIPCapabilityConfigurationFilterer{contract: contract}, nil +} + +func bindCCIPCapabilityConfiguration(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := CCIPCapabilityConfigurationMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CCIPCapabilityConfiguration.Contract.CCIPCapabilityConfigurationCaller.contract.Call(opts, result, method, params...) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CCIPCapabilityConfiguration.Contract.CCIPCapabilityConfigurationTransactor.contract.Transfer(opts) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CCIPCapabilityConfiguration.Contract.CCIPCapabilityConfigurationTransactor.contract.Transact(opts, method, params...) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CCIPCapabilityConfiguration.Contract.contract.Call(opts, result, method, params...) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CCIPCapabilityConfiguration.Contract.contract.Transfer(opts) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CCIPCapabilityConfiguration.Contract.contract.Transact(opts, method, params...) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationCaller) GetAllChainConfigs(opts *bind.CallOpts) ([]CCIPCapabilityConfigurationChainConfigInfo, error) { + var out []interface{} + err := _CCIPCapabilityConfiguration.contract.Call(opts, &out, "getAllChainConfigs") + + if err != nil { + return *new([]CCIPCapabilityConfigurationChainConfigInfo), err + } + + out0 := *abi.ConvertType(out[0], new([]CCIPCapabilityConfigurationChainConfigInfo)).(*[]CCIPCapabilityConfigurationChainConfigInfo) + + return out0, err + +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationSession) GetAllChainConfigs() ([]CCIPCapabilityConfigurationChainConfigInfo, error) { + return _CCIPCapabilityConfiguration.Contract.GetAllChainConfigs(&_CCIPCapabilityConfiguration.CallOpts) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationCallerSession) GetAllChainConfigs() ([]CCIPCapabilityConfigurationChainConfigInfo, error) { + return _CCIPCapabilityConfiguration.Contract.GetAllChainConfigs(&_CCIPCapabilityConfiguration.CallOpts) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationCaller) GetCapabilityConfiguration(opts *bind.CallOpts, arg0 uint32) ([]byte, error) { + var out []interface{} + err := _CCIPCapabilityConfiguration.contract.Call(opts, &out, "getCapabilityConfiguration", arg0) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationSession) GetCapabilityConfiguration(arg0 uint32) ([]byte, error) { + return _CCIPCapabilityConfiguration.Contract.GetCapabilityConfiguration(&_CCIPCapabilityConfiguration.CallOpts, arg0) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationCallerSession) GetCapabilityConfiguration(arg0 uint32) ([]byte, error) { + return _CCIPCapabilityConfiguration.Contract.GetCapabilityConfiguration(&_CCIPCapabilityConfiguration.CallOpts, arg0) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationCaller) GetOCRConfig(opts *bind.CallOpts, donId uint32, pluginType uint8) ([]CCIPCapabilityConfigurationOCR3ConfigWithMeta, error) { + var out []interface{} + err := _CCIPCapabilityConfiguration.contract.Call(opts, &out, "getOCRConfig", donId, pluginType) + + if err != nil { + return *new([]CCIPCapabilityConfigurationOCR3ConfigWithMeta), err + } + + out0 := *abi.ConvertType(out[0], new([]CCIPCapabilityConfigurationOCR3ConfigWithMeta)).(*[]CCIPCapabilityConfigurationOCR3ConfigWithMeta) + + return out0, err + +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationSession) GetOCRConfig(donId uint32, pluginType uint8) ([]CCIPCapabilityConfigurationOCR3ConfigWithMeta, error) { + return _CCIPCapabilityConfiguration.Contract.GetOCRConfig(&_CCIPCapabilityConfiguration.CallOpts, donId, pluginType) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationCallerSession) GetOCRConfig(donId uint32, pluginType uint8) ([]CCIPCapabilityConfigurationOCR3ConfigWithMeta, error) { + return _CCIPCapabilityConfiguration.Contract.GetOCRConfig(&_CCIPCapabilityConfiguration.CallOpts, donId, pluginType) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _CCIPCapabilityConfiguration.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationSession) Owner() (common.Address, error) { + return _CCIPCapabilityConfiguration.Contract.Owner(&_CCIPCapabilityConfiguration.CallOpts) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationCallerSession) Owner() (common.Address, error) { + return _CCIPCapabilityConfiguration.Contract.Owner(&_CCIPCapabilityConfiguration.CallOpts) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _CCIPCapabilityConfiguration.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationSession) TypeAndVersion() (string, error) { + return _CCIPCapabilityConfiguration.Contract.TypeAndVersion(&_CCIPCapabilityConfiguration.CallOpts) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationCallerSession) TypeAndVersion() (string, error) { + return _CCIPCapabilityConfiguration.Contract.TypeAndVersion(&_CCIPCapabilityConfiguration.CallOpts) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CCIPCapabilityConfiguration.contract.Transact(opts, "acceptOwnership") +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationSession) AcceptOwnership() (*types.Transaction, error) { + return _CCIPCapabilityConfiguration.Contract.AcceptOwnership(&_CCIPCapabilityConfiguration.TransactOpts) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _CCIPCapabilityConfiguration.Contract.AcceptOwnership(&_CCIPCapabilityConfiguration.TransactOpts) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationTransactor) ApplyChainConfigUpdates(opts *bind.TransactOpts, chainSelectorRemoves []uint64, chainConfigAdds []CCIPCapabilityConfigurationChainConfigInfo) (*types.Transaction, error) { + return _CCIPCapabilityConfiguration.contract.Transact(opts, "applyChainConfigUpdates", chainSelectorRemoves, chainConfigAdds) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationSession) ApplyChainConfigUpdates(chainSelectorRemoves []uint64, chainConfigAdds []CCIPCapabilityConfigurationChainConfigInfo) (*types.Transaction, error) { + return _CCIPCapabilityConfiguration.Contract.ApplyChainConfigUpdates(&_CCIPCapabilityConfiguration.TransactOpts, chainSelectorRemoves, chainConfigAdds) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationTransactorSession) ApplyChainConfigUpdates(chainSelectorRemoves []uint64, chainConfigAdds []CCIPCapabilityConfigurationChainConfigInfo) (*types.Transaction, error) { + return _CCIPCapabilityConfiguration.Contract.ApplyChainConfigUpdates(&_CCIPCapabilityConfiguration.TransactOpts, chainSelectorRemoves, chainConfigAdds) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationTransactor) BeforeCapabilityConfigSet(opts *bind.TransactOpts, arg0 [][32]byte, config []byte, arg2 uint64, donId uint32) (*types.Transaction, error) { + return _CCIPCapabilityConfiguration.contract.Transact(opts, "beforeCapabilityConfigSet", arg0, config, arg2, donId) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationSession) BeforeCapabilityConfigSet(arg0 [][32]byte, config []byte, arg2 uint64, donId uint32) (*types.Transaction, error) { + return _CCIPCapabilityConfiguration.Contract.BeforeCapabilityConfigSet(&_CCIPCapabilityConfiguration.TransactOpts, arg0, config, arg2, donId) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationTransactorSession) BeforeCapabilityConfigSet(arg0 [][32]byte, config []byte, arg2 uint64, donId uint32) (*types.Transaction, error) { + return _CCIPCapabilityConfiguration.Contract.BeforeCapabilityConfigSet(&_CCIPCapabilityConfiguration.TransactOpts, arg0, config, arg2, donId) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _CCIPCapabilityConfiguration.contract.Transact(opts, "transferOwnership", to) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _CCIPCapabilityConfiguration.Contract.TransferOwnership(&_CCIPCapabilityConfiguration.TransactOpts, to) +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _CCIPCapabilityConfiguration.Contract.TransferOwnership(&_CCIPCapabilityConfiguration.TransactOpts, to) +} + +type CCIPCapabilityConfigurationCapabilityConfigurationSetIterator struct { + Event *CCIPCapabilityConfigurationCapabilityConfigurationSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CCIPCapabilityConfigurationCapabilityConfigurationSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CCIPCapabilityConfigurationCapabilityConfigurationSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CCIPCapabilityConfigurationCapabilityConfigurationSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CCIPCapabilityConfigurationCapabilityConfigurationSetIterator) Error() error { + return it.fail +} + +func (it *CCIPCapabilityConfigurationCapabilityConfigurationSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CCIPCapabilityConfigurationCapabilityConfigurationSet struct { + Raw types.Log +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationFilterer) FilterCapabilityConfigurationSet(opts *bind.FilterOpts) (*CCIPCapabilityConfigurationCapabilityConfigurationSetIterator, error) { + + logs, sub, err := _CCIPCapabilityConfiguration.contract.FilterLogs(opts, "CapabilityConfigurationSet") + if err != nil { + return nil, err + } + return &CCIPCapabilityConfigurationCapabilityConfigurationSetIterator{contract: _CCIPCapabilityConfiguration.contract, event: "CapabilityConfigurationSet", logs: logs, sub: sub}, nil +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationFilterer) WatchCapabilityConfigurationSet(opts *bind.WatchOpts, sink chan<- *CCIPCapabilityConfigurationCapabilityConfigurationSet) (event.Subscription, error) { + + logs, sub, err := _CCIPCapabilityConfiguration.contract.WatchLogs(opts, "CapabilityConfigurationSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CCIPCapabilityConfigurationCapabilityConfigurationSet) + if err := _CCIPCapabilityConfiguration.contract.UnpackLog(event, "CapabilityConfigurationSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationFilterer) ParseCapabilityConfigurationSet(log types.Log) (*CCIPCapabilityConfigurationCapabilityConfigurationSet, error) { + event := new(CCIPCapabilityConfigurationCapabilityConfigurationSet) + if err := _CCIPCapabilityConfiguration.contract.UnpackLog(event, "CapabilityConfigurationSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CCIPCapabilityConfigurationChainConfigRemovedIterator struct { + Event *CCIPCapabilityConfigurationChainConfigRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CCIPCapabilityConfigurationChainConfigRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CCIPCapabilityConfigurationChainConfigRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CCIPCapabilityConfigurationChainConfigRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CCIPCapabilityConfigurationChainConfigRemovedIterator) Error() error { + return it.fail +} + +func (it *CCIPCapabilityConfigurationChainConfigRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CCIPCapabilityConfigurationChainConfigRemoved struct { + ChainSelector uint64 + Raw types.Log +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationFilterer) FilterChainConfigRemoved(opts *bind.FilterOpts) (*CCIPCapabilityConfigurationChainConfigRemovedIterator, error) { + + logs, sub, err := _CCIPCapabilityConfiguration.contract.FilterLogs(opts, "ChainConfigRemoved") + if err != nil { + return nil, err + } + return &CCIPCapabilityConfigurationChainConfigRemovedIterator{contract: _CCIPCapabilityConfiguration.contract, event: "ChainConfigRemoved", logs: logs, sub: sub}, nil +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationFilterer) WatchChainConfigRemoved(opts *bind.WatchOpts, sink chan<- *CCIPCapabilityConfigurationChainConfigRemoved) (event.Subscription, error) { + + logs, sub, err := _CCIPCapabilityConfiguration.contract.WatchLogs(opts, "ChainConfigRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CCIPCapabilityConfigurationChainConfigRemoved) + if err := _CCIPCapabilityConfiguration.contract.UnpackLog(event, "ChainConfigRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationFilterer) ParseChainConfigRemoved(log types.Log) (*CCIPCapabilityConfigurationChainConfigRemoved, error) { + event := new(CCIPCapabilityConfigurationChainConfigRemoved) + if err := _CCIPCapabilityConfiguration.contract.UnpackLog(event, "ChainConfigRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CCIPCapabilityConfigurationChainConfigSetIterator struct { + Event *CCIPCapabilityConfigurationChainConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CCIPCapabilityConfigurationChainConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CCIPCapabilityConfigurationChainConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CCIPCapabilityConfigurationChainConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CCIPCapabilityConfigurationChainConfigSetIterator) Error() error { + return it.fail +} + +func (it *CCIPCapabilityConfigurationChainConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CCIPCapabilityConfigurationChainConfigSet struct { + ChainSelector uint64 + ChainConfig CCIPCapabilityConfigurationChainConfig + Raw types.Log +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationFilterer) FilterChainConfigSet(opts *bind.FilterOpts) (*CCIPCapabilityConfigurationChainConfigSetIterator, error) { + + logs, sub, err := _CCIPCapabilityConfiguration.contract.FilterLogs(opts, "ChainConfigSet") + if err != nil { + return nil, err + } + return &CCIPCapabilityConfigurationChainConfigSetIterator{contract: _CCIPCapabilityConfiguration.contract, event: "ChainConfigSet", logs: logs, sub: sub}, nil +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationFilterer) WatchChainConfigSet(opts *bind.WatchOpts, sink chan<- *CCIPCapabilityConfigurationChainConfigSet) (event.Subscription, error) { + + logs, sub, err := _CCIPCapabilityConfiguration.contract.WatchLogs(opts, "ChainConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CCIPCapabilityConfigurationChainConfigSet) + if err := _CCIPCapabilityConfiguration.contract.UnpackLog(event, "ChainConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationFilterer) ParseChainConfigSet(log types.Log) (*CCIPCapabilityConfigurationChainConfigSet, error) { + event := new(CCIPCapabilityConfigurationChainConfigSet) + if err := _CCIPCapabilityConfiguration.contract.UnpackLog(event, "ChainConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CCIPCapabilityConfigurationOwnershipTransferRequestedIterator struct { + Event *CCIPCapabilityConfigurationOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CCIPCapabilityConfigurationOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CCIPCapabilityConfigurationOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CCIPCapabilityConfigurationOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CCIPCapabilityConfigurationOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *CCIPCapabilityConfigurationOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CCIPCapabilityConfigurationOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CCIPCapabilityConfigurationOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CCIPCapabilityConfiguration.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &CCIPCapabilityConfigurationOwnershipTransferRequestedIterator{contract: _CCIPCapabilityConfiguration.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CCIPCapabilityConfigurationOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CCIPCapabilityConfiguration.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CCIPCapabilityConfigurationOwnershipTransferRequested) + if err := _CCIPCapabilityConfiguration.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationFilterer) ParseOwnershipTransferRequested(log types.Log) (*CCIPCapabilityConfigurationOwnershipTransferRequested, error) { + event := new(CCIPCapabilityConfigurationOwnershipTransferRequested) + if err := _CCIPCapabilityConfiguration.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CCIPCapabilityConfigurationOwnershipTransferredIterator struct { + Event *CCIPCapabilityConfigurationOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CCIPCapabilityConfigurationOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CCIPCapabilityConfigurationOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CCIPCapabilityConfigurationOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CCIPCapabilityConfigurationOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *CCIPCapabilityConfigurationOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CCIPCapabilityConfigurationOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CCIPCapabilityConfigurationOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CCIPCapabilityConfiguration.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &CCIPCapabilityConfigurationOwnershipTransferredIterator{contract: _CCIPCapabilityConfiguration.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CCIPCapabilityConfigurationOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CCIPCapabilityConfiguration.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CCIPCapabilityConfigurationOwnershipTransferred) + if err := _CCIPCapabilityConfiguration.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfigurationFilterer) ParseOwnershipTransferred(log types.Log) (*CCIPCapabilityConfigurationOwnershipTransferred, error) { + event := new(CCIPCapabilityConfigurationOwnershipTransferred) + if err := _CCIPCapabilityConfiguration.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfiguration) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _CCIPCapabilityConfiguration.abi.Events["CapabilityConfigurationSet"].ID: + return _CCIPCapabilityConfiguration.ParseCapabilityConfigurationSet(log) + case _CCIPCapabilityConfiguration.abi.Events["ChainConfigRemoved"].ID: + return _CCIPCapabilityConfiguration.ParseChainConfigRemoved(log) + case _CCIPCapabilityConfiguration.abi.Events["ChainConfigSet"].ID: + return _CCIPCapabilityConfiguration.ParseChainConfigSet(log) + case _CCIPCapabilityConfiguration.abi.Events["OwnershipTransferRequested"].ID: + return _CCIPCapabilityConfiguration.ParseOwnershipTransferRequested(log) + case _CCIPCapabilityConfiguration.abi.Events["OwnershipTransferred"].ID: + return _CCIPCapabilityConfiguration.ParseOwnershipTransferred(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (CCIPCapabilityConfigurationCapabilityConfigurationSet) Topic() common.Hash { + return common.HexToHash("0x84ad7751b744c9e2ee77da1d902b428aec7f0a343d67a24bbe2142e6f58a8d0f") +} + +func (CCIPCapabilityConfigurationChainConfigRemoved) Topic() common.Hash { + return common.HexToHash("0x2a680691fef3b2d105196805935232c661ce703e92d464ef0b94a7bc62d714f0") +} + +func (CCIPCapabilityConfigurationChainConfigSet) Topic() common.Hash { + return common.HexToHash("0x05dd57854af2c291a94ea52e7c43d80bc3be7fa73022f98b735dea86642fa5e0") +} + +func (CCIPCapabilityConfigurationOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (CCIPCapabilityConfigurationOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (_CCIPCapabilityConfiguration *CCIPCapabilityConfiguration) Address() common.Address { + return _CCIPCapabilityConfiguration.address +} + +type CCIPCapabilityConfigurationInterface interface { + GetAllChainConfigs(opts *bind.CallOpts) ([]CCIPCapabilityConfigurationChainConfigInfo, error) + + GetCapabilityConfiguration(opts *bind.CallOpts, arg0 uint32) ([]byte, error) + + GetOCRConfig(opts *bind.CallOpts, donId uint32, pluginType uint8) ([]CCIPCapabilityConfigurationOCR3ConfigWithMeta, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyChainConfigUpdates(opts *bind.TransactOpts, chainSelectorRemoves []uint64, chainConfigAdds []CCIPCapabilityConfigurationChainConfigInfo) (*types.Transaction, error) + + BeforeCapabilityConfigSet(opts *bind.TransactOpts, arg0 [][32]byte, config []byte, arg2 uint64, donId uint32) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterCapabilityConfigurationSet(opts *bind.FilterOpts) (*CCIPCapabilityConfigurationCapabilityConfigurationSetIterator, error) + + WatchCapabilityConfigurationSet(opts *bind.WatchOpts, sink chan<- *CCIPCapabilityConfigurationCapabilityConfigurationSet) (event.Subscription, error) + + ParseCapabilityConfigurationSet(log types.Log) (*CCIPCapabilityConfigurationCapabilityConfigurationSet, error) + + FilterChainConfigRemoved(opts *bind.FilterOpts) (*CCIPCapabilityConfigurationChainConfigRemovedIterator, error) + + WatchChainConfigRemoved(opts *bind.WatchOpts, sink chan<- *CCIPCapabilityConfigurationChainConfigRemoved) (event.Subscription, error) + + ParseChainConfigRemoved(log types.Log) (*CCIPCapabilityConfigurationChainConfigRemoved, error) + + FilterChainConfigSet(opts *bind.FilterOpts) (*CCIPCapabilityConfigurationChainConfigSetIterator, error) + + WatchChainConfigSet(opts *bind.WatchOpts, sink chan<- *CCIPCapabilityConfigurationChainConfigSet) (event.Subscription, error) + + ParseChainConfigSet(log types.Log) (*CCIPCapabilityConfigurationChainConfigSet, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CCIPCapabilityConfigurationOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CCIPCapabilityConfigurationOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*CCIPCapabilityConfigurationOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CCIPCapabilityConfigurationOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CCIPCapabilityConfigurationOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*CCIPCapabilityConfigurationOwnershipTransferred, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go index 8c21d71aa0..1cdde293da 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go @@ -53,8 +53,6 @@ type EVM2EVMMultiOffRampDynamicConfig struct { PermissionLessExecutionThresholdSeconds uint32 MaxTokenTransferGas uint32 MaxPoolReleaseOrMintGas uint32 - MaxNumberOfTokensPerMsg uint16 - MaxDataBytes uint32 MessageValidator common.Address PriceRegistry common.Address } @@ -139,7 +137,6 @@ type MultiOCR3BaseConfigInfo struct { ConfigDigest [32]byte F uint8 N uint8 - UniqueReports bool IsSignatureVerificationEnabled bool } @@ -153,15 +150,14 @@ type MultiOCR3BaseOCRConfigArgs struct { ConfigDigest [32]byte OcrPluginType uint8 F uint8 - UniqueReports bool IsSignatureVerificationEnabled bool Signers []common.Address Transmitters []common.Address } var EVM2EVMMultiOffRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"name\":\"InvalidMessageId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint40\",\"name\":\"oldEpochAndRound\",\"type\":\"uint40\"},{\"indexed\":false,\"internalType\":\"uint40\",\"name\":\"newEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"LatestPriceEpochAndRoundSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedSenderWithPreviousRampMessageInflight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"metadataHash\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceEpochAndRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"metadataHash\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"isUnpausedAndNotCursed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"uniqueReports\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"latestPriceEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"setLatestPriceEpochAndRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"uniqueReports\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x610100604052600b805460ff60281b191690553480156200001f57600080fd5b5060405162007b1738038062007b17833981016040819052620000429162000608565b3380600081620000995760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000cc57620000cc8162000181565b5050466080525060208201516001600160a01b03161580620000f9575060408201516001600160a01b0316155b1562000118576040516342bcdf7f60e11b815260040160405180910390fd5b81516001600160401b0316600003620001445760405163c656089560e01b815260040160405180910390fd5b81516001600160401b031660a05260208201516001600160a01b0390811660c05260408301511660e05262000179816200022c565b505062000790565b336001600160a01b03821603620001db5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000090565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b8151811015620004dc5760008282815181106200025057620002506200077a565b60200260200101519050600081600001519050806001600160401b03166000036200028e5760405163c656089560e01b815260040160405180910390fd5b60608201516001600160a01b0316620002ba576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b038116600090815260076020526040902060018101546001600160a01b0316620003c0576200031c8284606001517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b3620004e060201b60201c565b600282015560608301516001820180546001600160a01b039283166001600160a01b03199091161790556040808501518354610100600160481b03199190931669010000000000000000000216610100600160e81b031990921691909117610100178255516001600160401b03831681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a16200042f565b606083015160018201546001600160a01b03908116911614158062000404575060408301518154690100000000000000000090046001600160a01b03908116911614155b156200042f5760405163c39a620560e01b81526001600160401b038316600482015260240162000090565b6020830151815490151560ff199091161781556040516001600160401b038316907fa73c588738263db34ef8c1942db8f99559bc6696f6a812d42e76bafb4c0e8d3090620004c5908490815460ff811615158252600881901c6001600160401b0316602083015260481c6001600160a01b0390811660408301526001830154166060820152600290910154608082015260a00190565b60405180910390a25050508060010190506200022f565b5050565b60a0805160408051602081018590526001600160401b0380881692820192909252911660608201526001600160a01b0384166080820152600091016040516020818303038152906040528051906020012090509392505050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156200057557620005756200053a565b60405290565b604051608081016001600160401b03811182821017156200057557620005756200053a565b604051601f8201601f191681016001600160401b0381118282101715620005cb57620005cb6200053a565b604052919050565b80516001600160401b0381168114620005eb57600080fd5b919050565b80516001600160a01b0381168114620005eb57600080fd5b6000808284036080808212156200061e57600080fd5b6060808312156200062e57600080fd5b6200063862000550565b92506200064586620005d3565b8352602062000656818801620005f0565b8185015260406200066a60408901620005f0565b604086015260608801519496506001600160401b03808611156200068d57600080fd5b858901955089601f870112620006a257600080fd5b855181811115620006b757620006b76200053a565b620006c7848260051b01620005a0565b818152848101925060079190911b87018401908b821115620006e857600080fd5b968401965b81881015620007685786888d031215620007075760008081fd5b620007116200057b565b6200071c89620005d3565b8152858901518015158114620007325760008081fd5b8187015262000743898601620005f0565b8582015262000754878a01620005f0565b8188015283529686019691840191620006ed565b80985050505050505050509250929050565b634e487b7160e01b600052603260045260246000fd5b60805160a05160c05160e0516172f96200081e6000396000818161026c01528181610a0b0152612df2015260008181610230015281816109e4015281816110c30152818161180401528181611b2201526135d6015260008181610200015281816109c00152613fa6015260008181610c1201528181610c5e01528181611f5d0152611fa901526172f96000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c80637f63b711116100f9578063ccd37ba311610097578063e9d68a8e11610071578063e9d68a8e146105f0578063f2fde38b14610718578063f52121a51461072b578063ff888fb11461073e57600080fd5b8063ccd37ba314610585578063d2a15d35146105ca578063d783efe7146105dd57600080fd5b80638b364334116100d35780638b364334146105175780638da5cb5b1461052a57806396c62bcc14610552578063c673e5841461056557600080fd5b80637f63b711146104ee5780638456cb591461050157806385572ffb1461050957600080fd5b8063311cd513116101665780635c975abb116101405780635c975abb146103805780635e36480c146103a05780637437ff9f146103c057806379ba5097146104e657600080fd5b8063311cd513146103525780633f4ba83a14610365578063542625af1461036d57600080fd5b8063181f5a7711610197578063181f5a77146102e357806329b980e41461032c5780632d04ab761461033f57600080fd5b806305a754ec146101be57806306285c69146101d357806310c374ed146102bf575b600080fd5b6101d16101cc3660046152db565b610751565b005b6102a9604080516060810182526000808252602082018190529181019190915260405180606001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102b691906153a5565b60405180910390f35b600b5464ffffffffff165b60405167ffffffffffffffff90911681526020016102b6565b61031f6040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b6040516102b6919061543d565b6101d161033a366004615450565b610a6a565b6101d161034d36600461550f565b610ae9565b6101d16103603660046155c2565b610b76565b6101d1610ba9565b6101d161037b366004615bbf565b610c0f565b600b5465010000000000900460ff165b60405190151581526020016102b6565b6103b36103ae366004615cea565b610e3c565b6040516102b69190615d66565b6104d96040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915250604080516101008101825260045473ffffffffffffffffffffffffffffffffffffffff808216835263ffffffff74010000000000000000000000000000000000000000830481166020850152780100000000000000000000000000000000000000000000000083048116948401949094527c01000000000000000000000000000000000000000000000000000000009091048316606083015260055461ffff8116608084015262010000810490931660a08301526601000000000000909204821660c082015260065490911660e082015290565b6040516102b69190615e23565b6101d1610ed0565b6101d16104fc366004615e32565b610fcd565b6101d1610fe1565b6101d16101b9366004615f16565b6102ca610525366004615f51565b611049565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102b6565b610390610560366004615f7f565b61105f565b610578610573366004615fad565b61114c565b6040516102b6919061601a565b6105bc61059336600461609c565b67ffffffffffffffff919091166000908152600a60209081526040808320938352929052205490565b6040519081526020016102b6565b6101d16105d83660046160c8565b6112dd565b6101d16105eb3660046161a5565b611397565b6106ae6105fe366004615f7f565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091525067ffffffffffffffff908116600090815260076020908152604091829020825160a081018452815460ff81161515825261010081049095169281019290925273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009094048416928201929092526001820154909216606083015260020154608082015290565b6040516102b69190600060a08201905082511515825267ffffffffffffffff6020840151166020830152604083015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606086015116606085015250506080830151608083015292915050565b6101d1610726366004616305565b6113d9565b6101d1610739366004616322565b6113ea565b61039061074c366004616386565b6117a1565b61075961186f565b60e081015173ffffffffffffffffffffffffffffffffffffffff166107aa576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805173ffffffffffffffffffffffffffffffffffffffff166107f8576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516004805460208085015160408087015160608089015163ffffffff9081167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9382167801000000000000000000000000000000000000000000000000029390931677ffffffffffffffffffffffffffffffffffffffffffffffff95821674010000000000000000000000000000000000000000027fffffffffffffffff00000000000000000000000000000000000000000000000090981673ffffffffffffffffffffffffffffffffffffffff9a8b16179790971794909416959095171790945560808601516005805460a089015160c08a015189166601000000000000027fffffffffffff0000000000000000000000000000000000000000ffffffffffff9190951662010000027fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000090921661ffff90941693909317179190911691909117905560e0850151600680549186167fffffffffffffffffffffffff0000000000000000000000000000000000000000929092169190911790558251918201835267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001682527f00000000000000000000000000000000000000000000000000000000000000008416908201527f000000000000000000000000000000000000000000000000000000000000000090921682820152517ff778ca28f5b9f37b5d23ffa5357592348ea60ec4e42b1dce5c857a5a65b276f791610a5f91849061639f565b60405180910390a150565b610a7261186f565b600b805464ffffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000083168117909355604080519190921680825260208201939093527ff0d557bfce33e354b41885eb9264448726cfe51f486ffa69809d2bf565456444910160405180910390a15050565b610af8878760208b01356118f2565b610b6c600089898989898080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808d0282810182019093528c82529093508c92508b9182918501908490808284376000920191909152508a9250611e19915050565b5050505050505050565b610b80828261226b565b604080516000808252602082019092529050610ba3600185858585866000611e19565b50505050565b610bb161186f565b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b467f000000000000000000000000000000000000000000000000000000000000000014610c9f576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015267ffffffffffffffff461660248201526044015b60405180910390fd5b815181518114610cdb576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610e2c576000848281518110610cfa57610cfa6163f5565b60200260200101519050600081602001515190506000858481518110610d2257610d226163f5565b6020026020010151905080518214610d66576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610e1d576000828281518110610d8557610d856163f5565b6020026020010151905080600014158015610dc0575084602001518281518110610db157610db16163f5565b60200260200101516080015181105b15610e145784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024810183905260448101829052606401610c96565b50600101610d69565b50505050806001019050610cde565b50610e3783836122a7565b505050565b6000610e4a60016004616453565b6002610e57608085616495565b67ffffffffffffffff16610e6b91906164bc565b67ffffffffffffffff8516600090815260096020526040812090610e906080876164d3565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c166003811115610ec757610ec7615d23565b90505b92915050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610f51576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610c96565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610fd561186f565b610fde81612357565b50565b610fe961186f565b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff16650100000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610c05565b60008061105684846126f5565b50949350505050565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608083901b16600482015260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa15801561110a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112e91906164fa565b158015610eca5750600b5465010000000000900460ff161592915050565b6111976040805161010081019091526000606082018181526080830182905260a0830182905260c0830182905260e08301919091528190815260200160608152602001606081525090565b60ff8083166000908152600260208181526040928390208351610100808201865282546060830190815260018401548089166080850152918204881660a08401526201000082048816151560c08401526301000000909104909616151560e08201529485529182018054845181840281018401909552808552929385830193909283018282801561125e57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611233575b50505050508152602001600382018054806020026020016040519081016040528092919081815260200182805480156112cd57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116112a2575b5050505050815250509050919050565b6112e561186f565b60005b81811015610e37576000838383818110611304576113046163f5565b90506040020180360381019061131a9190616517565b905061132981602001516117a1565b61138e57805167ffffffffffffffff166000908152600a602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b506001016112e8565b61139f61186f565b60005b81518110156113d5576113cd8282815181106113c0576113c06163f5565b602002602001015161282d565b6001016113a2565b5050565b6113e161186f565b610fde81612c65565b333014611423576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611460565b60408051808201909152600080825260208201528152602001906001900390816114395790505b5061014084015151909150156114fb576101408301516040805160608101909152602085015173ffffffffffffffffffffffffffffffffffffffff1660808201526114f891908060a0810160408051601f19818403018152918152908252875167ffffffffffffffff1660208301528781015173ffffffffffffffffffffffffffffffffffffffff1691015261016086015185612d5a565b90505b600061150784836132a2565b6005549091506601000000000000900473ffffffffffffffffffffffffffffffffffffffff168015611618576040517fa219f6e500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063a219f6e59061158590859060040161660c565b600060405180830381600087803b15801561159f57600080fd5b505af19250505080156115b0575060015b611618573d8080156115de576040519150601f19603f3d011682016040523d82523d6000602084013e6115e3565b606091505b50806040517f09c25325000000000000000000000000000000000000000000000000000000008152600401610c96919061543d565b6101208501515115801561162e57506080850151155b806116525750604085015173ffffffffffffffffffffffffffffffffffffffff163b155b8061169f5750604085015161169d9073ffffffffffffffffffffffffffffffffffffffff167f85572ffb00000000000000000000000000000000000000000000000000000000613352565b155b156116ab575050505050565b60048054608087015160408089015190517f3cf97983000000000000000000000000000000000000000000000000000000008152600094859473ffffffffffffffffffffffffffffffffffffffff1693633cf9798393611713938a936113889392910161661f565b6000604051808303816000875af1158015611732573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261175a91908101906166ad565b50915091508161179857806040517f0a8d6e8c000000000000000000000000000000000000000000000000000000008152600401610c96919061543d565b50505050505050565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa15801561184b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eca91906164fa565b60005473ffffffffffffffffffffffffffffffffffffffff1633146118f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610c96565b565b600b5465010000000000900460ff1615611938576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061194683850185616894565b8051515190915015158061195f57508051602001515115155b15611a8857600b5464ffffffffff80841691161015611a4957600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000001664ffffffffff841617905560065481516040517f3937306f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691633937306f916119ff91600401616af3565b600060405180830381600087803b158015611a1957600080fd5b505af1158015611a2d573d6000803e3d6000fd5b50505050806020015151600003611a445750505050565b611a88565b806020015151600003611a88576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b816020015151811015611ddb57600082602001518281518110611ab057611ab06163f5565b602090810291909101015180516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608083901b1660048201529192509073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa158015611b69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b8d91906164fa565b15611bd0576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610c96565b67ffffffffffffffff81166000908152600760205260409020805460ff16611c30576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff83166004820152602401610c96565b6020830151518154610100900467ffffffffffffffff9081169116141580611c6f575060208084015190810151905167ffffffffffffffff9182169116115b15611caf57825160208401516040517feefb0cac000000000000000000000000000000000000000000000000000000008152610c96929190600401616b06565b6040830151611cea576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b825167ffffffffffffffff166000908152600a6020908152604080832081870151845290915290205415611d6357825160408085015190517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90921660048301526024820152604401610c96565b6020808401510151611d76906001616b3b565b81547fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff1661010067ffffffffffffffff92831602179091558251166000908152600a602090815260408083209481015183529390529190912042905550600101611a8b565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d81604051611e0b9190616b63565b60405180910390a150505050565b60ff8781166000908152600260209081526040808320815160a08101835281548152600190910154808616938201939093526101008304851691810191909152620100008204841615156060820152630100000090910490921615156080830152873590611e888760a4616c00565b9050826080015115611ed0578451611ea19060206164bc565b8651611eae9060206164bc565b611eb99060a0616c00565b611ec39190616c00565b611ecd9082616c00565b90505b368114611f12576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610c96565b5081518114611f5a5781516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401610c96565b467f000000000000000000000000000000000000000000000000000000000000000014611fdb576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610c96565b60ff808a166000908152600360209081526040808320338452825280832081518083019092528054808616835293949193909284019161010090910416600281111561202957612029615d23565b600281111561203a5761203a615d23565b905250905060028160200151600281111561205757612057615d23565b1480156120b85750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110612093576120936163f5565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b6120ee576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5081608001511561221657600082606001511561213a5760028360200151846040015161211b9190616c13565b6121259190616c2c565b612130906001616c13565b60ff169050612150565b602083015161214a906001616c13565b60ff1690505b8086511461218a576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84518651146121c5576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600087876040516121d8929190616c4e565b6040519081900381206121ef918b90602001616c5e565b6040516020818303038152906040528051906020012090506122148a8288888861336e565b505b6040805182815260208a81013560081c63ffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b6113d561227a82840184616c72565b60408051600080825260208201909252906122a5565b60608152602001906001900390816122905790505b505b81516000036122e1576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b845181101561235057612348858281518110612316576123166163f5565b60200260200101518461234257858381518110612335576123356163f5565b6020026020010151613588565b83613588565b6001016122f8565b5050505050565b60005b81518110156113d5576000828281518110612377576123776163f5565b602002602001015190506000816000015190508067ffffffffffffffff166000036123ce576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606082015173ffffffffffffffffffffffffffffffffffffffff1661241f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600760205260409020600181015473ffffffffffffffffffffffffffffffffffffffff1661257d576124868284606001517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b3613fa0565b6002820155606083015160018201805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617905560408085015183547fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff91909316690100000000000000000002167fffffff00000000000000000000000000000000000000000000000000000000ff909216919091176101001782555167ffffffffffffffff831681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a161261d565b6060830151600182015473ffffffffffffffffffffffffffffffffffffffff90811691161415806125da5750604083015181546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff908116911614155b1561261d576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff83166004820152602401610c96565b602083015181549015157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617815560405167ffffffffffffffff8316907fa73c588738263db34ef8c1942db8f99559bc6696f6a812d42e76bafb4c0e8d30906126df908490815460ff811615158252600881901c67ffffffffffffffff16602083015260481c73ffffffffffffffffffffffffffffffffffffffff90811660408301526001830154166060820152600290910154608082015260a00190565b60405180910390a250505080600101905061235a565b67ffffffffffffffff808316600090815260086020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168452909152812054909182911680820361281f5767ffffffffffffffff85166000908152600760205260409020546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16801561281d576040517f856c824700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015282169063856c824790602401602060405180830381865afa1580156127ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128109190616ca7565b6001935093505050612826565b505b9150600090505b9250929050565b806040015160ff166000036128715760006040517f367f56a2000000000000000000000000000000000000000000000000000000008152600401610c969190616cc4565b60208082015160ff80821660009081526002909352604083206001810154929390928392169003612911576060840151600182018054608087015115156301000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff9315156201000002939093167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffff9091161791909117905561298b565b6060840151600182015460ff6201000090910416151590151514158061294f57506080840151600182015460ff630100000090910416151590151514155b1561298b576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff84166004820152602401610c96565b60c08401518051601f60ff821611156129d35760016040517f367f56a2000000000000000000000000000000000000000000000000000000008152600401610c969190616cc4565b612a468585600301805480602002602001604051908101604052809291908181526020018280548015612a3c57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612a11575b5050505050614030565b856080015115612bb457612ac18585600201805480602002602001604051908101604052809291908181526020018280548015612a3c5760200282019190600052602060002090815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612a11575050505050614030565b60a08601518051612adb9060028701906020840190615090565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f1015612b545760026040517f367f56a2000000000000000000000000000000000000000000000000000000008152600401610c969190616cc4565b6040880151612b64906003616cde565b60ff168160ff1611612ba55760036040517f367f56a2000000000000000000000000000000000000000000000000000000008152600401610c969190616cc4565b612bb1878360016140c3565b50505b612bc0858360026140c3565b8151612bd59060038601906020850190615090565b506040868101516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff8316179055875180865560c089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f54793612c4c938a939260028b01929190616cfa565b60405180910390a1612c5d856142be565b505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603612ce4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610c96565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b8360005b8551811015611056576000848281518110612d7b57612d7b6163f5565b6020026020010151806020019051810190612d969190616dc6565b90506000612da782602001516142f1565b6040517fbbe4f6db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612e39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e5d9190616e7b565b905073ffffffffffffffffffffffffffffffffffffffff81161580612ebf5750612ebd73ffffffffffffffffffffffffffffffffffffffff82167faff2afbf00000000000000000000000000000000000000000000000000000000613352565b155b15612f0e576040517fae9b4ce900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610c96565b60008061307b633907753760e01b6040518061010001604052808d6000015181526020018d6020015167ffffffffffffffff1681526020018d6040015173ffffffffffffffffffffffffffffffffffffffff1681526020018e8a81518110612f7857612f786163f5565b60200260200101516020015181526020018773ffffffffffffffffffffffffffffffffffffffff16815260200188600001518152602001886040015181526020018b8a81518110612fcb57612fcb6163f5565b6020026020010151815250604051602401612fe69190616e98565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152600454859063ffffffff7c010000000000000000000000000000000000000000000000000000000090910416611388608461434c565b5091509150816130b957806040517fe1cd5509000000000000000000000000000000000000000000000000000000008152600401610c96919061543d565b80516020146131015780516040517f78ef8024000000000000000000000000000000000000000000000000000000008152602060048201526024810191909152604401610c96565b6000818060200190518101906131179190616f7f565b60408c810151815173ffffffffffffffffffffffffffffffffffffffff909116602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526004549192506131d69187907801000000000000000000000000000000000000000000000000900463ffffffff16611388608461434c565b5090935091508261321557816040517fe1cd5509000000000000000000000000000000000000000000000000000000008152600401610c96919061543d565b84888881518110613228576132286163f5565b60200260200101516000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080888881518110613279576132796163f5565b60200260200101516020018181525050505050505050806001019050612d5e565b949350505050565b6040805160a08101825260008082526020820152606091810182905281810182905260808101919091526040518060a001604052808461018001518152602001846000015167ffffffffffffffff1681526020018460200151604051602001613327919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6040516020818303038152906040528152602001846101200151815260200183815250905092915050565b600061335d83614472565b8015610ec75750610ec783836144d6565b613376615116565b835160005b81811015610b6c57600060018886846020811061339a5761339a6163f5565b6133a791901a601b616c13565b8985815181106133b9576133b96163f5565b60200260200101518986815181106133d3576133d36163f5565b602002602001015160405160008152602001604052604051613411949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015613433573d6000803e3d6000fd5b505060408051601f1981015160ff808e1660009081526003602090815285822073ffffffffffffffffffffffffffffffffffffffff8516835281528582208587019096528554808416865293975090955092939284019161010090041660028111156134a1576134a1615d23565b60028111156134b2576134b2615d23565b90525090506001816020015160028111156134cf576134cf615d23565b14613506576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061351d5761351d6163f5565b602002015115613559576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f8110613574576135746163f5565b91151560209092020152505060010161337b565b81516040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015613632573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061365691906164fa565b15613699576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610c96565b60208301515160008190036136d9576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8360400151518114613717576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff82166000908152600760205260409020805460ff16613777576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610c96565b60008267ffffffffffffffff8111156137925761379261514a565b6040519080825280602002602001820160405280156137bb578160200160208202803683370190505b50905060005b83811015613880576000876020015182815181106137e1576137e16163f5565b602002602001015190506137f98185600201546145a5565b83838151811061380b5761380b6163f5565b60200260200101818152505080610180015183838151811061382f5761382f6163f5565b602002602001015114613877578061018001516040517f345039be000000000000000000000000000000000000000000000000000000008152600401610c9691815260200190565b506001016137c1565b506000613897858389606001518a6080015161470e565b9050806000036138df576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610c96565b8551151560005b85811015613f9557600089602001518281518110613906576139066163f5565b602002602001015190506000613920898360600151610e3c565b9050600281600381111561393657613936615d23565b0361398c5760608201516040805167ffffffffffffffff808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c910160405180910390a15050613f8d565b60008160038111156139a0576139a0615d23565b14806139bd575060038160038111156139bb576139bb615d23565b145b613a0d5760608201516040517f25507e7f00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808c1660048301529091166024820152604401610c96565b8315613aee5760045460009074010000000000000000000000000000000000000000900463ffffffff16613a418742616453565b1190508080613a6157506003826003811115613a5f57613a5f615d23565b145b613aa3576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8b166004820152602401610c96565b8a8481518110613ab557613ab56163f5565b6020026020010151600014613ae8578a8481518110613ad657613ad66163f5565b60200260200101518360800181815250505b50613b53565b6000816003811115613b0257613b02615d23565b14613b535760608201516040517f3ef2a99c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808c1660048301529091166024820152604401610c96565b600080613b648b85602001516126f5565b915091508015613c845760c084015167ffffffffffffffff16613b88836001616b3b565b67ffffffffffffffff1614613c185760c084015160208501516040517f5444a3301c7c42dd164cbf6ba4b72bf02504f86c049b06a27fc2b662e334bdbd92613c07928f9267ffffffffffffffff938416815291909216602082015273ffffffffffffffffffffffffffffffffffffffff91909116604082015260600190565b60405180910390a150505050613f8d565b67ffffffffffffffff8b811660009081526008602090815260408083208883015173ffffffffffffffffffffffffffffffffffffffff168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000169184169190911790555b6000836003811115613c9857613c98615d23565b03613d365760c084015167ffffffffffffffff16613cb7836001616b3b565b67ffffffffffffffff1614613d365760c084015160208501516040517f852dc8e405695593e311bd83991cf39b14a328f304935eac6d3d55617f911d8992613c07928f9267ffffffffffffffff938416815291909216602082015273ffffffffffffffffffffffffffffffffffffffff91909116604082015260600190565b60008d604001518681518110613d4e57613d4e6163f5565b60200260200101519050613d7c8561018001518d8760600151886101400151518961012001515186516147ab565b613d8c8c866060015160016148b3565b600080613d998784614991565b91509150613dac8e8860600151846148b3565b888015613dca57506003826003811115613dc857613dc8615d23565b145b8015613de857506000866003811115613de557613de5615d23565b14155b15613e2857866101800151816040517f2b11b8d9000000000000000000000000000000000000000000000000000000008152600401610c96929190616f98565b6003826003811115613e3c57613e3c615d23565b14158015613e5c57506002826003811115613e5957613e59615d23565b14155b15613e9d578d8760600151836040517f926c5a3e000000000000000000000000000000000000000000000000000000008152600401610c9693929190616fb1565b6000866003811115613eb157613eb1615d23565b03613f2c5767ffffffffffffffff808f1660009081526008602090815260408083208b83015173ffffffffffffffffffffffffffffffffffffffff168452909152812080549092169190613f0483616fd7565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b866101800151876060015167ffffffffffffffff168f67ffffffffffffffff167f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df28585604051613f7d929190616ffe565b60405180910390a4505050505050505b6001016138e6565b505050505050505050565b600081847f000000000000000000000000000000000000000000000000000000000000000085604051602001614010949392919093845267ffffffffffffffff92831660208501529116604083015273ffffffffffffffffffffffffffffffffffffffff16606082015260800190565b6040516020818303038152906040528051906020012090505b9392505050565b60005b8151811015610e375760ff831660009081526003602052604081208351909190849084908110614065576140656163f5565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055600101614033565b60005b82518160ff161015610ba3576000838260ff16815181106140e9576140e96163f5565b602002602001015190506000600281111561410657614106615d23565b60ff808716600090815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900416600281111561415257614152615d23565b1461418c5760046040517f367f56a2000000000000000000000000000000000000000000000000000000008152600401610c969190616cc4565b73ffffffffffffffffffffffffffffffffffffffff81166141d9576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156141ff576141ff615d23565b905260ff808716600090815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845282529091208351815493167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00841681178255918401519092909183917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016176101008360028111156142a4576142a4615d23565b021790555090505050806142b79061701e565b90506140c6565b60ff8116610fde57600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000016905550565b6000815160201461433057816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610c96919061543d565b610eca828060200190518101906143479190616f7f565b614cb5565b6000606060008361ffff1667ffffffffffffffff81111561436f5761436f61514a565b6040519080825280601f01601f191660200182016040528015614399576020820181803683370190505b509150863b6143cc577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a858110156143ff577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710614438577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d8481111561445b5750835b808352806000602085013e50955095509592505050565b600061449e827f01ffc9a7000000000000000000000000000000000000000000000000000000006144d6565b8015610eca57506144cf827fffffffff000000000000000000000000000000000000000000000000000000006144d6565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561458e575060208210155b801561459a5750600081115b979650505050505050565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b610100015160405160200161464898979695949392919073ffffffffffffffffffffffffffffffffffffffff9889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001614681919061703d565b604051602081830303815290604052805190602001208761016001516040516020016146ad91906170ff565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e0015b60405160208183030381529060405280519060200120905092915050565b600b5460009065010000000000900460ff1615614757576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000614764858585614d2f565b905061476f816117a1565b61477d57600091505061329a565b67ffffffffffffffff86166000908152600a6020908152604080832093835292905220549050949350505050565b60055461ffff168311156147ff576040517fa1e5205a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808716600483015285166024820152604401610c96565b80831461484c576040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808716600483015285166024820152604401610c96565b60055462010000900463ffffffff16821115612c5d576005546040517f1fd8fd04000000000000000000000000000000000000000000000000000000008152600481018890526201000090910463ffffffff16602482015260448101839052606401610c96565b600060026148c2608085616495565b67ffffffffffffffff166148d691906164bc565b67ffffffffffffffff8516600090815260096020526040812091925090816148ff6080876164d3565b67ffffffffffffffff16815260208101919091526040016000205490508161492960016004616453565b901b19168183600381111561494057614940615d23565b67ffffffffffffffff871660009081526009602052604081209190921b9290921791829161496f6080886164d3565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517ff52121a5000000000000000000000000000000000000000000000000000000008152600090606090309063f52121a5906149d59087908790600401617112565b600060405180830381600087803b1580156149ef57600080fd5b505af1925050508015614a00575060015b614c9a573d808015614a2e576040519150601f19603f3d011682016040523d82523d6000602084013e614a33565b606091505b506000614a3f8261729c565b90507f0a8d6e8c000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000082161480614ad257507fe1cd5509000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216145b80614b1e57507f8d666f60000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216145b80614b6a57507f78ef8024000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216145b80614bb657507f0c3b563c000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216145b80614c0257507fae9b4ce9000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216145b80614c4e57507f09c25325000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216145b15614c5f5750600392509050612826565b856101800151826040517f2b11b8d9000000000000000000000000000000000000000000000000000000008152600401610c96929190616f98565b50506040805160208101909152600081526002909250929050565b600073ffffffffffffffffffffffffffffffffffffffff821180614cda575061040082105b15614d2b5760408051602081018490520160408051601f19818403018152908290527f8d666f60000000000000000000000000000000000000000000000000000000008252610c969160040161543d565b5090565b8251825160009190818303614d70576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590614d8457506101018111155b614dba576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82820101610100811115614e1b576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003614e485786600081518110614e3657614e366163f5565b60200260200101519350505050614029565b60008167ffffffffffffffff811115614e6357614e6361514a565b604051908082528060200260200182016040528015614e8c578160200160208202803683370190505b50905060008080805b85811015614fcf5760006001821b8b811603614ef05788851015614ed9578c5160018601958e918110614eca57614eca6163f5565b60200260200101519050614f12565b8551600185019487918110614eca57614eca6163f5565b8b5160018401938d918110614f0757614f076163f5565b602002602001015190505b600089861015614f42578d5160018701968f918110614f3357614f336163f5565b60200260200101519050614f64565b8651600186019588918110614f5957614f596163f5565b602002602001015190505b82851115614f9e576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b614fa8828261504f565b878481518110614fba57614fba6163f5565b60209081029190910101525050600101614e95565b506001850382148015614fe157508683145b8015614fec57508581145b615022576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836001860381518110615037576150376163f5565b60200260200101519750505050505050509392505050565b600081831061506757615062828461506d565b610ec7565b610ec783835b6040805160016020820152908101839052606081018290526000906080016146f0565b82805482825590600052602060002090810192821561510a579160200282015b8281111561510a57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906150b0565b50614d2b929150615135565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115614d2b5760008155600101615136565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561519c5761519c61514a565b60405290565b6040516101a0810167ffffffffffffffff8111828210171561519c5761519c61514a565b60405160a0810167ffffffffffffffff8111828210171561519c5761519c61514a565b6040516080810167ffffffffffffffff8111828210171561519c5761519c61514a565b60405160e0810167ffffffffffffffff8111828210171561519c5761519c61514a565b6040516060810167ffffffffffffffff8111828210171561519c5761519c61514a565b604051601f8201601f1916810167ffffffffffffffff8111828210171561527b5761527b61514a565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610fde57600080fd5b80356152b081615283565b919050565b803563ffffffff811681146152b057600080fd5b803561ffff811681146152b057600080fd5b60006101008083850312156152ef57600080fd5b6040519081019067ffffffffffffffff821181831017156153125761531261514a565b816040528335915061532382615283565b818152615332602085016152b5565b6020820152615343604085016152b5565b6040820152615354606085016152b5565b6060820152615365608085016152c9565b608082015261537660a085016152b5565b60a082015261538760c085016152a5565b60c082015261539860e085016152a5565b60e0820152949350505050565b60608101610eca8284805167ffffffffffffffff16825260208082015173ffffffffffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60005b838110156154085781810151838201526020016153f0565b50506000910152565b600081518084526154298160208601602086016153ed565b601f01601f19169290920160200192915050565b602081526000610ec76020830184615411565b60006020828403121561546257600080fd5b813564ffffffffff8116811461402957600080fd5b8060608101831015610eca57600080fd5b60008083601f84011261549a57600080fd5b50813567ffffffffffffffff8111156154b257600080fd5b60208301915083602082850101111561282657600080fd5b60008083601f8401126154dc57600080fd5b50813567ffffffffffffffff8111156154f457600080fd5b6020830191508360208260051b850101111561282657600080fd5b60008060008060008060008060e0898b03121561552b57600080fd5b6155358a8a615477565b9750606089013567ffffffffffffffff8082111561555257600080fd5b61555e8c838d01615488565b909950975060808b013591508082111561557757600080fd5b6155838c838d016154ca565b909750955060a08b013591508082111561559c57600080fd5b506155a98b828c016154ca565b999c989b50969995989497949560c00135949350505050565b6000806000608084860312156155d757600080fd5b6155e18585615477565b9250606084013567ffffffffffffffff8111156155fd57600080fd5b61560986828701615488565b9497909650939450505050565b600067ffffffffffffffff8211156156305761563061514a565b5060051b60200190565b67ffffffffffffffff81168114610fde57600080fd5b80356152b08161563a565b8015158114610fde57600080fd5b80356152b08161565b565b600067ffffffffffffffff82111561568e5761568e61514a565b50601f01601f191660200190565b600082601f8301126156ad57600080fd5b81356156c06156bb82615674565b615252565b8181528460208386010111156156d557600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261570357600080fd5b813560206157136156bb83615616565b82815260069290921b8401810191818101908684111561573257600080fd5b8286015b8481101561577a576040818903121561574f5760008081fd5b615757615179565b813561576281615283565b81528185013585820152835291830191604001615736565b509695505050505050565b600082601f83011261579657600080fd5b813560206157a66156bb83615616565b82815260059290921b840181019181810190868411156157c557600080fd5b8286015b8481101561577a57803567ffffffffffffffff8111156157e95760008081fd5b6157f78986838b010161569c565b8452509183019183016157c9565b60006101a0828403121561581857600080fd5b6158206151a2565b905061582b82615650565b8152615839602083016152a5565b602082015261584a604083016152a5565b604082015261585b60608301615650565b60608201526080820135608082015261587660a08301615669565b60a082015261588760c08301615650565b60c082015261589860e083016152a5565b60e082015261010082810135908201526101208083013567ffffffffffffffff808211156158c557600080fd5b6158d18683870161569c565b838501526101409250828501359150808211156158ed57600080fd5b6158f9868387016156f2565b8385015261016092508285013591508082111561591557600080fd5b5061592285828601615785565b82840152505061018080830135818301525092915050565b600082601f83011261594b57600080fd5b8135602061595b6156bb83615616565b82815260059290921b8401810191818101908684111561597a57600080fd5b8286015b8481101561577a57803567ffffffffffffffff81111561599e5760008081fd5b6159ac8986838b0101615805565b84525091830191830161597e565b600082601f8301126159cb57600080fd5b813560206159db6156bb83615616565b82815260059290921b840181019181810190868411156159fa57600080fd5b8286015b8481101561577a57803567ffffffffffffffff811115615a1e5760008081fd5b615a2c8986838b0101615785565b8452509183019183016159fe565b600082601f830112615a4b57600080fd5b81356020615a5b6156bb83615616565b8083825260208201915060208460051b870101935086841115615a7d57600080fd5b602086015b8481101561577a5780358352918301918301615a82565b600082601f830112615aaa57600080fd5b81356020615aba6156bb83615616565b82815260059290921b84018101918181019086841115615ad957600080fd5b8286015b8481101561577a57803567ffffffffffffffff80821115615afe5760008081fd5b818901915060a080601f19848d03011215615b195760008081fd5b615b216151c6565b615b2c888501615650565b815260408085013584811115615b425760008081fd5b615b508e8b8389010161593a565b8a8401525060608086013585811115615b695760008081fd5b615b778f8c838a01016159ba565b8385015250608091508186013585811115615b925760008081fd5b615ba08f8c838a0101615a3a565b9184019190915250919093013590830152508352918301918301615add565b6000806040808486031215615bd357600080fd5b833567ffffffffffffffff80821115615beb57600080fd5b615bf787838801615a99565b9450602091508186013581811115615c0e57600080fd5b8601601f81018813615c1f57600080fd5b8035615c2d6156bb82615616565b81815260059190911b8201840190848101908a831115615c4c57600080fd5b8584015b83811015615cd857803586811115615c685760008081fd5b8501603f81018d13615c7a5760008081fd5b87810135615c8a6156bb82615616565b81815260059190911b82018a0190898101908f831115615caa5760008081fd5b928b01925b82841015615cc85783358252928a0192908a0190615caf565b8652505050918601918601615c50565b50809750505050505050509250929050565b60008060408385031215615cfd57600080fd5b8235615d088161563a565b91506020830135615d188161563a565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110615d6257615d62615d23565b9052565b60208101610eca8284615d52565b73ffffffffffffffffffffffffffffffffffffffff8151168252602081015163ffffffff808216602085015280604084015116604085015280606084015116606085015261ffff60808401511660808501528060a08401511660a0850152505060c0810151615dfb60c084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060e0810151610e3760e084018273ffffffffffffffffffffffffffffffffffffffff169052565b6101008101610eca8284615d74565b60006020808385031215615e4557600080fd5b823567ffffffffffffffff811115615e5c57600080fd5b8301601f81018513615e6d57600080fd5b8035615e7b6156bb82615616565b81815260079190911b82018301908381019087831115615e9a57600080fd5b928401925b8284101561459a5760808489031215615eb85760008081fd5b615ec06151e9565b8435615ecb8161563a565b815284860135615eda8161565b565b81870152604085810135615eed81615283565b90820152606085810135615f0081615283565b9082015282526080939093019290840190615e9f565b600060208284031215615f2857600080fd5b813567ffffffffffffffff811115615f3f57600080fd5b820160a0818503121561402957600080fd5b60008060408385031215615f6457600080fd5b8235615f6f8161563a565b91506020830135615d1881615283565b600060208284031215615f9157600080fd5b81356140298161563a565b803560ff811681146152b057600080fd5b600060208284031215615fbf57600080fd5b610ec782615f9c565b60008151808452602080850194506020840160005b8381101561600f57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101615fdd565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff60408201511660608401526060810151151560808401526080810151151560a084015250602083015160e060c0840152616076610100840182615fc8565b90506040840151601f198483030160e08501526160938282615fc8565b95945050505050565b600080604083850312156160af57600080fd5b82356160ba8161563a565b946020939093013593505050565b600080602083850312156160db57600080fd5b823567ffffffffffffffff808211156160f357600080fd5b818501915085601f83011261610757600080fd5b81358181111561611657600080fd5b8660208260061b850101111561612b57600080fd5b60209290920196919550909350505050565b600082601f83011261614e57600080fd5b8135602061615e6156bb83615616565b8083825260208201915060208460051b87010193508684111561618057600080fd5b602086015b8481101561577a57803561619881615283565b8352918301918301616185565b600060208083850312156161b857600080fd5b823567ffffffffffffffff808211156161d057600080fd5b818501915085601f8301126161e457600080fd5b81356161f26156bb82615616565b81815260059190911b8301840190848101908883111561621157600080fd5b8585015b838110156162f85780358581111561622c57600080fd5b860160e0818c03601f190112156162435760008081fd5b61624b61520c565b888201358152604061625e818401615f9c565b8a830152606061626f818501615f9c565b8284015260809150616282828501615669565b9083015260a0616293848201615669565b8284015260c0915081840135898111156162ad5760008081fd5b6162bb8f8d8388010161613d565b82850152505060e0830135888111156162d45760008081fd5b6162e28e8c8387010161613d565b9183019190915250845250918601918601616215565b5098975050505050505050565b60006020828403121561631757600080fd5b813561402981615283565b6000806040838503121561633557600080fd5b823567ffffffffffffffff8082111561634d57600080fd5b61635986838701615805565b9350602085013591508082111561636f57600080fd5b5061637c85828601615785565b9150509250929050565b60006020828403121561639857600080fd5b5035919050565b61016081016163e88285805167ffffffffffffffff16825260208082015173ffffffffffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6140296060830184615d74565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610eca57610eca616424565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff808416806164b0576164b0616466565b92169190910692915050565b8082028115828204841417610eca57610eca616424565b600067ffffffffffffffff808416806164ee576164ee616466565b92169190910492915050565b60006020828403121561650c57600080fd5b81516140298161565b565b60006040828403121561652957600080fd5b616531615179565b823561653c8161563a565b81526020928301359281019290925250919050565b60008151808452602080850194506020840160005b8381101561600f578151805173ffffffffffffffffffffffffffffffffffffffff1688526020908101519088015260408701965090820190600101616566565b8051825267ffffffffffffffff60208201511660208301526000604082015160a060408501526165d960a0850182615411565b9050606083015184820360608601526165f28282615411565b915050608083015184820360808601526160938282616551565b602081526000610ec760208301846165a6565b60808152600061663260808301876165a6565b61ffff95909516602083015250604081019290925273ffffffffffffffffffffffffffffffffffffffff16606090910152919050565b600082601f83011261667957600080fd5b81516166876156bb82615674565b81815284602083860101111561669c57600080fd5b61329a8260208301602087016153ed565b6000806000606084860312156166c257600080fd5b83516166cd8161565b565b602085015190935067ffffffffffffffff8111156166ea57600080fd5b6166f686828701616668565b925050604084015190509250925092565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146152b057600080fd5b600082601f83011261674457600080fd5b813560206167546156bb83615616565b82815260069290921b8401810191818101908684111561677357600080fd5b8286015b8481101561577a57604081890312156167905760008081fd5b616798615179565b81356167a38161563a565b81526167b0828601616707565b81860152835291830191604001616777565b600082601f8301126167d357600080fd5b813560206167e36156bb83615616565b82815260079290921b8401810191818101908684111561680257600080fd5b8286015b8481101561577a5780880360808112156168205760008081fd5b61682861522f565b82356168338161563a565b81526040601f1983018113156168495760008081fd5b616851615179565b9250868401356168608161563a565b83528381013561686f8161563a565b8388015281870192909252606083013591810191909152835291830191608001616806565b600060208083850312156168a757600080fd5b823567ffffffffffffffff808211156168bf57600080fd5b818501915060408083880312156168d557600080fd5b6168dd615179565b8335838111156168ec57600080fd5b84016040818a0312156168fe57600080fd5b616906615179565b81358581111561691557600080fd5b8201601f81018b1361692657600080fd5b80356169346156bb82615616565b81815260069190911b8201890190898101908d83111561695357600080fd5b928a01925b828410156169a35787848f0312156169705760008081fd5b616978615179565b843561698381615283565b8152616990858d01616707565b818d0152825292870192908a0190616958565b8452505050818701359350848411156169bb57600080fd5b6169c78a858401616733565b81880152825250838501359150828211156169e157600080fd5b6169ed888386016167c2565b85820152809550505050505092915050565b805160408084528151848201819052600092602091908201906060870190855b81811015616a78578351805173ffffffffffffffffffffffffffffffffffffffff1684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16858401529284019291850191600101616a1f565b50508583015187820388850152805180835290840192506000918401905b80831015616ae7578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685830152928401926001929092019190850190616a96565b50979650505050505050565b602081526000610ec760208301846169ff565b67ffffffffffffffff83168152606081016140296020830184805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff818116838216019080821115616b5c57616b5c616424565b5092915050565b600060208083526060845160408084870152616b8260608701836169ff565b87850151878203601f19016040890152805180835290860193506000918601905b808310156162f857845167ffffffffffffffff815116835287810151616be289850182805167ffffffffffffffff908116835260209182015116910152565b50840151828701529386019360019290920191608090910190616ba3565b80820180821115610eca57610eca616424565b60ff8181168382160190811115610eca57610eca616424565b600060ff831680616c3f57616c3f616466565b8060ff84160491505092915050565b8183823760009101908152919050565b828152606082602083013760800192915050565b600060208284031215616c8457600080fd5b813567ffffffffffffffff811115616c9b57600080fd5b61329a84828501615a99565b600060208284031215616cb957600080fd5b81516140298161563a565b6020810160058310616cd857616cd8615d23565b91905290565b60ff8181168382160290811690818114616b5c57616b5c616424565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015616d5f57845473ffffffffffffffffffffffffffffffffffffffff1683526001948501949284019201616d2d565b50508481036060860152865180825290820192508187019060005b81811015616dac57825173ffffffffffffffffffffffffffffffffffffffff1685529383019391830191600101616d7a565b50505060ff851660808501525090505b9695505050505050565b600060208284031215616dd857600080fd5b815167ffffffffffffffff80821115616df057600080fd5b9083019060608286031215616e0457600080fd5b616e0c61522f565b825182811115616e1b57600080fd5b616e2787828601616668565b825250602083015182811115616e3c57600080fd5b616e4887828601616668565b602083015250604083015182811115616e6057600080fd5b616e6c87828601616668565b60408301525095945050505050565b600060208284031215616e8d57600080fd5b815161402981615283565b6020815260008251610100806020850152616eb7610120850183615411565b91506020850151616ed4604086018267ffffffffffffffff169052565b50604085015173ffffffffffffffffffffffffffffffffffffffff8116606086015250606085015160808501526080850151616f2860a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a0850151601f19808685030160c0870152616f458483615411565b935060c08701519150808685030160e0870152616f628483615411565b935060e0870151915080868503018387015250616dbc8382615411565b600060208284031215616f9157600080fd5b5051919050565b82815260406020820152600061329a6040830184615411565b67ffffffffffffffff8481168252831660208201526060810161329a6040830184615d52565b600067ffffffffffffffff808316818103616ff457616ff4616424565b6001019392505050565b6170088184615d52565b60406020820152600061329a6040830184615411565b600060ff821660ff810361703457617034616424565b60010192915050565b6020808252825182820181905260009190848201906040850190845b81811015617099578351805173ffffffffffffffffffffffffffffffffffffffff1684526020908101519084015260408301938501939250600101617059565b50909695505050505050565b60008282518085526020808601955060208260051b8401016020860160005b848110156170f257601f198684030189526170e0838351615411565b988401989250908301906001016170c4565b5090979650505050505050565b602081526000610ec760208301846170a5565b6040815261712d60408201845167ffffffffffffffff169052565b60006020840151617156606084018273ffffffffffffffffffffffffffffffffffffffff169052565b50604084015173ffffffffffffffffffffffffffffffffffffffff8116608084015250606084015167ffffffffffffffff811660a084015250608084015160c083015260a084015180151560e08401525060c08401516101006171c48185018367ffffffffffffffff169052565b60e086015191506101206171ef8186018473ffffffffffffffffffffffffffffffffffffffff169052565b81870151925061014091508282860152808701519250506101a0610160818187015261721f6101e0870185615411565b93508288015192507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc061018081888703018189015261725e8686616551565b9550828a0151945081888703018489015261727986866170a5565b9550808a01516101c08901525050505050828103602084015261609381856170a5565b6000815160208301517fffffffff00000000000000000000000000000000000000000000000000000000808216935060048310156172e45780818460040360031b1b83161693505b50505091905056fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"name\":\"InvalidMessageId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"oldSequenceNumber\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"newSequenceNumber\",\"type\":\"uint64\"}],\"name\":\"LatestPriceSequenceNumberSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedSenderWithPreviousRampMessageInflight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"metadataHash\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"metadataHash\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"latestPriceSequenceNumber\",\"type\":\"uint64\"}],\"name\":\"setLatestPriceSequenceNumber\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b50604051620067e1380380620067e1833981016040819052620000359162000648565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001c1565b5050466080525060208201516001600160a01b03161580620000ec575060408201516001600160a01b0316155b156200010b576040516342bcdf7f60e11b815260040160405180910390fd5b81516001600160401b0316600003620001375760405163c656089560e01b815260040160405180910390fd5b81516001600160401b0390811660a052602080840180516001600160a01b0390811660c05260408087018051831660e052815188519096168652925182169385019390935290511682820152517f2f56698ec552a5d53d27d6f4b3dd8b6989f6426b6151a36aff61160c1d07efdf9181900360600190a1620001b9816200026c565b5050620007d0565b336001600160a01b038216036200021b5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b81518110156200051c576000828281518110620002905762000290620007ba565b60200260200101519050600081600001519050806001600160401b0316600003620002ce5760405163c656089560e01b815260040160405180910390fd5b60608201516001600160a01b0316620002fa576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b038116600090815260076020526040902060018101546001600160a01b031662000400576200035c8284606001517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b36200052060201b60201c565b600282015560608301516001820180546001600160a01b039283166001600160a01b03199091161790556040808501518354610100600160481b03199190931669010000000000000000000216610100600160e81b031990921691909117610100178255516001600160401b03831681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a16200046f565b606083015160018201546001600160a01b03908116911614158062000444575060408301518154690100000000000000000090046001600160a01b03908116911614155b156200046f5760405163c39a620560e01b81526001600160401b038316600482015260240162000083565b6020830151815490151560ff199091161781556040516001600160401b038316907fa73c588738263db34ef8c1942db8f99559bc6696f6a812d42e76bafb4c0e8d309062000505908490815460ff811615158252600881901c6001600160401b0316602083015260481c6001600160a01b0390811660408301526001830154166060820152600290910154608082015260a00190565b60405180910390a25050508060010190506200026f565b5050565b60a0805160408051602081018590526001600160401b0380881692820192909252911660608201526001600160a01b0384166080820152600091016040516020818303038152906040528051906020012090509392505050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b0381118282101715620005b557620005b56200057a565b60405290565b604051608081016001600160401b0381118282101715620005b557620005b56200057a565b604051601f8201601f191681016001600160401b03811182821017156200060b576200060b6200057a565b604052919050565b80516001600160401b03811681146200062b57600080fd5b919050565b80516001600160a01b03811681146200062b57600080fd5b6000808284036080808212156200065e57600080fd5b6060808312156200066e57600080fd5b6200067862000590565b9250620006858662000613565b835260206200069681880162000630565b818501526040620006aa6040890162000630565b604086015260608801519496506001600160401b0380861115620006cd57600080fd5b858901955089601f870112620006e257600080fd5b855181811115620006f757620006f76200057a565b62000707848260051b01620005e0565b818152848101925060079190911b87018401908b8211156200072857600080fd5b968401965b81881015620007a85786888d031215620007475760008081fd5b62000751620005bb565b6200075c8962000613565b8152858901518015158114620007725760008081fd5b818701526200078389860162000630565b8582015262000794878a0162000630565b81880152835296860196918401916200072d565b80985050505050505050509250929050565b634e487b7160e01b600052603260045260246000fd5b60805160a05160c05160e051615fb46200082d6000396000818161021e01526131fe0152600081816101ef015281816115fc01526116b30152600081816101bf0152613120015260008181611c4f0152611c9b0152615fb46000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c80637f63b711116100e3578063d2a15d351161008c578063f52121a511610066578063f52121a514610686578063f716f99f14610699578063ff888fb1146106ac57600080fd5b8063d2a15d3514610552578063e9d68a8e14610565578063f2fde38b1461067357600080fd5b80638da5cb5b116100bd5780638da5cb5b146104d2578063c673e584146104ed578063ccd37ba31461050d57600080fd5b80637f63b7111461049e57806385572ffb146104b15780638b364334146104bf57600080fd5b8063403b2d631161014557806369600bca1161011f57806369600bca1461036e5780637437ff9f1461038157806379ba50971461049657600080fd5b8063403b2d6314610328578063542625af1461033b5780635e36480c1461034e57600080fd5b80632d04ab76116101765780632d04ab76146102d9578063311cd513146102ee5780633f4b04aa1461030157600080fd5b806306285c6914610192578063181f5a7714610290575b600080fd5b61024e604080516060810182526000808252602082018190529181019190915260405180606001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b60408051825167ffffffffffffffff1681526020808401516001600160a01b039081169183019190915292820151909216908201526060015b60405180910390f35b6102cc6040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b604051610287919061423a565b6102ec6102e73660046142e5565b6106cf565b005b6102ec6102fc366004614398565b610a95565b600b5467ffffffffffffffff165b60405167ffffffffffffffff9091168152602001610287565b6102ec610336366004614545565b610afe565b6102ec610349366004614b69565b610cbb565b61036161035c366004614c94565b610e60565b6040516102879190614cf7565b6102ec61037c366004614d05565b610eb6565b61042d6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c0810182526004546001600160a01b03808216835263ffffffff74010000000000000000000000000000000000000000830481166020850152600160c01b8304811694840194909452600160e01b90910490921660608201526005548216608082015260065490911660a082015290565b6040516102879190600060c0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401528060a08501511660a08401525092915050565b6102ec610f21565b6102ec6104ac366004614d22565b610fdf565b6102ec61018d366004614e06565b61030f6104cd366004614e41565b610ff3565b6000546040516001600160a01b039091168152602001610287565b6105006104fb366004614e80565b611009565b6040516102879190614ee0565b61054461051b366004614f55565b67ffffffffffffffff919091166000908152600a60209081526040808320938352929052205490565b604051908152602001610287565b6102ec610560366004614f81565b611167565b610616610573366004614d05565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091525067ffffffffffffffff908116600090815260076020908152604091829020825160a081018452815460ff8116151582526101008104909516928101929092526001600160a01b0369010000000000000000009094048416928201929092526001820154909216606083015260020154608082015290565b6040516102879190600060a08201905082511515825267ffffffffffffffff602084015116602083015260408301516001600160a01b03808216604085015280606086015116606085015250506080830151608083015292915050565b6102ec610681366004614ff6565b611221565b6102ec610694366004615013565b611232565b6102ec6106a73660046150df565b611564565b6106bf6106ba36600461522a565b6115a6565b6040519015158152602001610287565b60006106dd878901896153bb565b805151519091501515806106f657508051602001515115155b156107f657600b5460208a01359067ffffffffffffffff808316911610156107b557600b805467ffffffffffffffff191667ffffffffffffffff831617905560065482516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921691633937306f9161077e916004016155f9565b600060405180830381600087803b15801561079857600080fd5b505af11580156107ac573d6000803e3d6000fd5b505050506107f4565b8160200151516000036107f4576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b8160200151518110156109de5760008260200151828151811061081e5761081e615526565b6020026020010151905060008160000151905061083a81611667565b600061084582611769565b602084015151815491925067ffffffffffffffff90811661010090920416141580610887575060208084015190810151905167ffffffffffffffff9182169116115b156108d057825160208401516040517feefb0cac0000000000000000000000000000000000000000000000000000000081526108c792919060040161560c565b60405180910390fd5b60408301518061090c576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff166000908152600a602090815260408083208484529091529020541561097f5783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602481018290526044016108c7565b6020808501510151610992906001615657565b825468ffffffffffffffff00191661010067ffffffffffffffff92831602179092559251166000908152600a6020908152604080832094835293905291909120429055506001016107f9565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d81604051610a0e919061567f565b60405180910390a1610a8a60008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b92506117c9915050565b505050505050505050565b610ad5610aa48284018461571c565b6040805160008082526020820190925290610acf565b6060815260200190600190039081610aba5790505b50611b40565b604080516000808252602082019092529050610af86001858585858660006117c9565b50505050565b610b06611bf0565b60a08101516001600160a01b03161580610b28575080516001600160a01b0316155b15610b5f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a177401000000000000000000000000000000000000000063ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff19908116928e1692909217905560a0808e01805160068054909416908f161790925586519a8b5297518716988a0198909852925185169388019390935251909216958501959095525185169383019390935251909216908201527f0da37fd00459f4f5f0b8210d31525e4910ae674b8bab34b561d146bb45773a4c9060c00160405180910390a150565b610cc3611c4c565b815181518114610cff576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610e50576000848281518110610d1e57610d1e615526565b60200260200101519050600081602001515190506000858481518110610d4657610d46615526565b6020026020010151905080518214610d8a576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610e41576000828281518110610da957610da9615526565b6020026020010151905080600014158015610de4575084602001518281518110610dd557610dd5615526565b60200260200101516080015181105b15610e385784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101839052604481018290526064016108c7565b50600101610d8d565b50505050806001019050610d02565b50610e5b8383611b40565b505050565b6000610e6e60016004615751565b6002610e7b60808561577a565b67ffffffffffffffff16610e8f91906157a1565b610e998585611ccd565b901c166003811115610ead57610ead614ccd565b90505b92915050565b610ebe611bf0565b600b805467ffffffffffffffff83811667ffffffffffffffff1983168117909355604080519190921680825260208201939093527f88ad9c61d6caf19a2af116a871802a03a31e680115a2dd20e8c08801d7c82f83910160405180910390a15050565b6001546001600160a01b03163314610f7b5760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108c7565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610fe7611bf0565b610ff081611d14565b50565b6000806110008484612025565b50949350505050565b61104c6040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c0820152948552918201805484518184028101840190955280855292938583019390928301828280156110f557602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116110d7575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561115757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611139575b5050505050815250509050919050565b61116f611bf0565b60005b81811015610e5b57600083838381811061118e5761118e615526565b9050604002018036038101906111a491906157b8565b90506111b381602001516115a6565b61121857805167ffffffffffffffff166000908152600a602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101611172565b611229611bf0565b610ff081612136565b33301461126b576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051600080825260208201909252816112a8565b60408051808201909152600080825260208201528152602001906001900390816112815790505b5061014084015151909150156113095761130683610140015184602001516040516020016112e591906001600160a01b0391909116815260200190565b60408051601f198184030181529181528601518651610160880151876121ec565b90505b60006113158483612299565b6005549091506001600160a01b03168015611402576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a19061136f9085906004016158a0565b600060405180830381600087803b15801561138957600080fd5b505af192505050801561139a575060015b611402573d8080156113c8576040519150601f19603f3d011682016040523d82523d6000602084013e6113cd565b606091505b50806040517f09c253250000000000000000000000000000000000000000000000000000000081526004016108c7919061423a565b6101208501515115801561141857506080850151155b8061142f575060408501516001600160a01b03163b155b8061146f5750604085015161146d906001600160a01b03167f85572ffb0000000000000000000000000000000000000000000000000000000061233c565b155b1561147b575050505050565b60048054608087015160408089015190517f3cf9798300000000000000000000000000000000000000000000000000000000815260009485946001600160a01b031693633cf97983936114d6938a93611388939291016158b3565b6000604051808303816000875af11580156114f5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261151d9190810190615934565b50915091508161155b57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016108c7919061423a565b50505050505050565b61156c611bf0565b60005b81518110156115a25761159a82828151811061158d5761158d615526565b6020026020010151612358565b60010161156f565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611643573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb0919061598e565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015611702573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611726919061598e565b15610ff0576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108c7565b67ffffffffffffffff81166000908152600760205260408120805460ff16610eb0576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108c7565b60ff878116600090815260026020908152604080832081516080810183528154815260019091015480861693820193909352610100830485169181019190915262010000909104909216151560608301528735906118288760a46159ab565b90508260600151156118705784516118419060206157a1565b865161184e9060206157a1565b6118599060a06159ab565b61186391906159ab565b61186d90826159ab565b90505b3681146118b2576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016108c7565b50815181146118fa5781516040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016108c7565b611902611c4c565b60ff808a166000908152600360209081526040808320338452825280832081518083019092528054808616835293949193909284019161010090910416600281111561195057611950614ccd565b600281111561196157611961614ccd565b905250905060028160200151600281111561197e5761197e614ccd565b1480156119d25750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff16815481106119ba576119ba615526565b6000918252602090912001546001600160a01b031633145b611a08576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611aea576020820151611a239060016159be565b60ff16855114611a5f576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611a9a576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611aac9291906159d7565b604051908190038120611ac3918b906020016159e7565b604051602081830303815290604052805190602001209050611ae88a82888888612663565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611b7a576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611be957611be1858281518110611baf57611baf615526565b602002602001015184611bdb57858381518110611bce57611bce615526565b602002602001015161287a565b8361287a565b600101611b91565b5050505050565b6000546001600160a01b03163314611c4a5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108c7565b565b467f000000000000000000000000000000000000000000000000000000000000000014611c4a576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016108c7565b67ffffffffffffffff8216600090815260096020526040812081611cf26080856159fb565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b60005b81518110156115a2576000828281518110611d3457611d34615526565b602002602001015190506000816000015190508067ffffffffffffffff16600003611d8b576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608201516001600160a01b0316611dcf576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8116600090815260076020526040902060018101546001600160a01b0316611ef257611e298284606001517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b361311a565b600282015560608301516001820180546001600160a01b0392831673ffffffffffffffffffffffffffffffffffffffff19909116179055604080850151835468ffffffffffffffff001991909316690100000000000000000002167fffffff00000000000000000000000000000000000000000000000000000000ff909216919091176101001782555167ffffffffffffffff831681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611f78565b606083015160018201546001600160a01b039081169116141580611f35575060408301518154690100000000000000000090046001600160a01b03908116911614155b15611f78576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff831660048201526024016108c7565b6020830151815490151560ff1990911617815560405167ffffffffffffffff8316907fa73c588738263db34ef8c1942db8f99559bc6696f6a812d42e76bafb4c0e8d309061200f908490815460ff811615158252600881901c67ffffffffffffffff16602083015260481c6001600160a01b0390811660408301526001830154166060820152600290910154608082015260a00190565b60405180910390a2505050806001019050611d17565b67ffffffffffffffff80831660009081526008602090815260408083206001600160a01b038616845290915281205490918291168082036121285767ffffffffffffffff8516600090815260076020526040902054690100000000000000000090046001600160a01b03168015612126576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b03868116600483015282169063856c824790602401602060405180830381865afa1580156120f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121199190615a22565b600193509350505061212f565b505b9150600090505b9250929050565b336001600160a01b0382160361218e5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108c7565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b8560005b875181101561228e5761226988828151811061220e5761220e615526565b60200260200101516020015188888888868151811061222f5761222f615526565b602002602001015180602001905181019061224a9190615a3f565b88878151811061225c5761225c615526565b602002602001015161319d565b82828151811061227b5761227b615526565b60209081029190910101526001016121f0565b509695505050505050565b6040805160a08101825260008082526020820152606091810182905281810182905260808101919091526040518060a001604052808461018001518152602001846000015167ffffffffffffffff168152602001846020015160405160200161231191906001600160a01b0391909116815260200190565b6040516020818303038152906040528152602001846101200151815260200183815250905092915050565b600061234783613516565b8015610ead5750610ead8383613562565b806040015160ff16600003612383576000604051631b3fab5160e11b81526004016108c79190615af4565b60208082015160ff808216600090815260029093526040832060018101549293909283921690036123d4576060840151600182018054911515620100000262ff000019909216919091179055612429565b6060840151600182015460ff6201000090910416151590151514612429576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff841660048201526024016108c7565b60a08401518051601f60ff82161115612458576001604051631b3fab5160e11b81526004016108c79190615af4565b6124be85856003018054806020026020016040519081016040528092919081815260200182805480156124b457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612496575b5050505050613604565b8560600151156125d05761252c85856002018054806020026020016040519081016040528092919081815260200182805480156124b4576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311612496575050505050613604565b608086015180516125469060028701906020840190614148565b50805160018501805461ff00191661010060ff841690810291909117909155601f1015612589576002604051631b3fab5160e11b81526004016108c79190615af4565b6040880151612599906003615b0e565b60ff168160ff16116125c1576003604051631b3fab5160e11b81526004016108c79190615af4565b6125cd8783600161366d565b50505b6125dc8583600261366d565b81516125f19060038601906020850190614148565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f5479361264a938a939260028b01929190615b2a565b60405180910390a161265b856137ed565b505050505050565b61266b6141b6565b835160005b8181101561287057600060018886846020811061268f5761268f615526565b61269c91901a601b6159be565b8985815181106126ae576126ae615526565b60200260200101518986815181106126c8576126c8615526565b602002602001015160405160008152602001604052604051612706949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612728573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b0385168352815285822085870190965285548084168652939750909550929392840191610100900416600281111561278957612789614ccd565b600281111561279a5761279a614ccd565b90525090506001816020015160028111156127b7576127b7614ccd565b146127ee576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061280557612805615526565b602002015115612841576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061285c5761285c615526565b911515602090920201525050600101612670565b5050505050505050565b815161288581611667565b600061289082611769565b60208501515190915060008190036128d3576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460400151518114612911576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561292c5761292c6143ec565b604051908082528060200260200182016040528015612955578160200160208202803683370190505b50905060005b82811015612a1a5760008760200151828151811061297b5761297b615526565b60200260200101519050612993818660020154613809565b8383815181106129a5576129a5615526565b6020026020010181815250508061018001518383815181106129c9576129c9615526565b602002602001015114612a11578061018001516040517f345039be0000000000000000000000000000000000000000000000000000000081526004016108c791815260200190565b5060010161295b565b506000612a31858389606001518a60800151613965565b905080600003612a79576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016108c7565b8551151560005b84811015610a8a57600089602001518281518110612aa057612aa0615526565b602002602001015190506000612aba898360600151610e60565b90506002816003811115612ad057612ad0614ccd565b03612b265760608201516040805167ffffffffffffffff808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c910160405180910390a15050613112565b6000816003811115612b3a57612b3a614ccd565b1480612b5757506003816003811115612b5557612b55614ccd565b145b612ba75760608201516040517f25507e7f00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808c16600483015290911660248201526044016108c7565b8315612c885760045460009074010000000000000000000000000000000000000000900463ffffffff16612bdb8742615751565b1190508080612bfb57506003826003811115612bf957612bf9614ccd565b145b612c3d576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8b1660048201526024016108c7565b8a8481518110612c4f57612c4f615526565b6020026020010151600014612c82578a8481518110612c7057612c70615526565b60200260200101518360800181815250505b50612ced565b6000816003811115612c9c57612c9c614ccd565b14612ced5760608201516040517f3ef2a99c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808c16600483015290911660248201526044016108c7565b600080612cfe8b8560200151612025565b915091508015612ded5760c084015167ffffffffffffffff16612d22836001615657565b67ffffffffffffffff1614612da55760c084015160208501516040517f5444a3301c7c42dd164cbf6ba4b72bf02504f86c049b06a27fc2b662e334bdbd92612d94928f9267ffffffffffffffff93841681529190921660208201526001600160a01b0391909116604082015260600190565b60405180910390a150505050613112565b67ffffffffffffffff8b81166000908152600860209081526040808320888301516001600160a01b031684529091529020805467ffffffffffffffff19169184169190911790555b6000836003811115612e0157612e01614ccd565b03612e925760c084015167ffffffffffffffff16612e20836001615657565b67ffffffffffffffff1614612e925760c084015160208501516040517f852dc8e405695593e311bd83991cf39b14a328f304935eac6d3d55617f911d8992612d94928f9267ffffffffffffffff93841681529190921660208201526001600160a01b0391909116604082015260600190565b60008d604001518681518110612eaa57612eaa615526565b6020026020010151905080518561014001515114612f0e5760608501516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808f16600483015290911660248201526044016108c7565b612f1e8c866060015160016139bb565b600080612f2b8784613a63565b91509150612f3e8e8860600151846139bb565b888015612f5c57506003826003811115612f5a57612f5a614ccd565b145b8015612f7a57506000866003811115612f7757612f77614ccd565b14155b15612fba57866101800151816040517f2b11b8d90000000000000000000000000000000000000000000000000000000081526004016108c7929190615bb0565b6003826003811115612fce57612fce614ccd565b14158015612fee57506002826003811115612feb57612feb614ccd565b14155b1561302f578d8760600151836040517f926c5a3e0000000000000000000000000000000000000000000000000000000081526004016108c793929190615bc9565b600086600381111561304357613043614ccd565b036130b15767ffffffffffffffff808f1660009081526008602090815260408083208b8301516001600160a01b0316845290915281208054909216919061308983615bef565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b866101800151876060015167ffffffffffffffff168f67ffffffffffffffff167f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df28585604051613102929190615c16565b60405180910390a4505050505050505b600101612a80565b600081847f00000000000000000000000000000000000000000000000000000000000000008560405160200161317d949392919093845267ffffffffffffffff9283166020850152911660408301526001600160a01b0316606082015260800190565b6040516020818303038152906040528051906020012090505b9392505050565b604080518082019091526000808252602082015260006131c08460200151613cad565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015613245573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132699190615c36565b90506001600160a01b03811615806132b157506132af6001600160a01b0382167faff2afbf0000000000000000000000000000000000000000000000000000000061233c565b155b156132f3576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016108c7565b6000806133be633907753760e01b6040518061010001604052808d81526020018b67ffffffffffffffff1681526020018c6001600160a01b031681526020018e8152602001876001600160a01b031681526020018a6000015181526020018a6040015181526020018981525060405160240161336f9190615c53565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152600454859063ffffffff600160e01b909104166113886084613cef565b5091509150816133e3578060405163e1cd550960e01b81526004016108c7919061423a565b805160201461342b5780516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016108c7565b6000818060200190518101906134419190615d2a565b604080516001600160a01b038d16602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b03167fa9059cbb000000000000000000000000000000000000000000000000000000001790526004549192506134c4918790600160c01b900463ffffffff166113886084613cef565b509093509150826134ea578160405163e1cd550960e01b81526004016108c7919061423a565b604080518082019091526001600160a01b03909516855260208501525091925050509695505050505050565b6000613542827f01ffc9a700000000000000000000000000000000000000000000000000000000613562565b8015610eb0575061355b826001600160e01b0319613562565b1592915050565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156135ed575060208210155b80156135f95750600081115b979650505050505050565b60005b8151811015610e5b5760ff83166000908152600360205260408120835190919084908490811061363957613639615526565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff19169055600101613607565b60005b82518160ff161015610af8576000838260ff168151811061369357613693615526565b60200260200101519050600060028111156136b0576136b0614ccd565b60ff80871660009081526003602090815260408083206001600160a01b038716845290915290205461010090041660028111156136ef576136ef614ccd565b14613710576004604051631b3fab5160e11b81526004016108c79190615af4565b6001600160a01b038116613750576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff16815260200184600281111561377657613776614ccd565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff1916176101008360028111156137d3576137d3614ccd565b021790555090505050806137e690615d43565b9050613670565b60ff8116610ff057600b805467ffffffffffffffff1916905550565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b610100015160405160200161389f9897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b60405160208183030381529060405280519060200120856101200151805190602001208661014001516040516020016138d89190615d62565b604051602081830303815290604052805190602001208761016001516040516020016139049190615e17565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e0015b60405160208183030381529060405280519060200120905092915050565b600080613973858585613e15565b905061397e816115a6565b61398c5760009150506139b3565b67ffffffffffffffff86166000908152600a60209081526040808320938352929052205490505b949350505050565b600060026139ca60808561577a565b67ffffffffffffffff166139de91906157a1565b905060006139ec8585611ccd565b9050816139fb60016004615751565b901b191681836003811115613a1257613a12614ccd565b67ffffffffffffffff871660009081526009602052604081209190921b92909217918291613a416080886159fb565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517ff52121a5000000000000000000000000000000000000000000000000000000008152600090606090309063f52121a590613aa79087908790600401615e2a565b600060405180830381600087803b158015613ac157600080fd5b505af1925050508015613ad2575060015b613c92573d808015613b00576040519150601f19603f3d011682016040523d82523d6000602084013e613b05565b606091505b506000613b1182615f6f565b90507f0a8d6e8c000000000000000000000000000000000000000000000000000000006001600160e01b031982161480613b5b575063e1cd550960e01b6001600160e01b03198216145b80613b76575063046b337b60e51b6001600160e01b03198216145b80613baa57507f78ef8024000000000000000000000000000000000000000000000000000000006001600160e01b03198216145b80613bde57507f0c3b563c000000000000000000000000000000000000000000000000000000006001600160e01b03198216145b80613c1257507fae9b4ce9000000000000000000000000000000000000000000000000000000006001600160e01b03198216145b80613c4657507f09c25325000000000000000000000000000000000000000000000000000000006001600160e01b03198216145b15613c57575060039250905061212f565b856101800151826040517f2b11b8d90000000000000000000000000000000000000000000000000000000081526004016108c7929190615bb0565b50506040805160208101909152600081526002909250929050565b60008151602014613cd3578160405163046b337b60e51b81526004016108c7919061423a565b610eb082806020019051810190613cea9190615d2a565b6140b3565b6000606060008361ffff1667ffffffffffffffff811115613d1257613d126143ec565b6040519080825280601f01601f191660200182016040528015613d3c576020820181803683370190505b509150863b613d6f577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613da2577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613ddb577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613dfe5750835b808352806000602085013e50955095509592505050565b8251825160009190818303613e56576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613e6a57506101018111155b613e87576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613eb1576040516309bde33960e01b815260040160405180910390fd5b80600003613ede5786600081518110613ecc57613ecc615526565b60200260200101519350505050613196565b60008167ffffffffffffffff811115613ef957613ef96143ec565b604051908082528060200260200182016040528015613f22578160200160208202803683370190505b50905060008080805b8581101561404c5760006001821b8b811603613f865788851015613f6f578c5160018601958e918110613f6057613f60615526565b60200260200101519050613fa8565b8551600185019487918110613f6057613f60615526565b8b5160018401938d918110613f9d57613f9d615526565b602002602001015190505b600089861015613fd8578d5160018701968f918110613fc957613fc9615526565b60200260200101519050613ffa565b8651600186019588918110613fef57613fef615526565b602002602001015190505b8285111561401b576040516309bde33960e01b815260040160405180910390fd5b6140258282614107565b87848151811061403757614037615526565b60209081029190910101525050600101613f2b565b50600185038214801561405e57508683145b801561406957508581145b614086576040516309bde33960e01b815260040160405180910390fd5b83600186038151811061409b5761409b615526565b60200260200101519750505050505050509392505050565b60006001600160a01b038211806140cb575061040082105b156141035760408051602081018490520160408051601f198184030181529082905263046b337b60e51b82526108c79160040161423a565b5090565b600081831061411f5761411a8284614125565b610ead565b610ead83835b604080516001602082015290810183905260608101829052600090608001613947565b8280548282559060005260206000209081019282156141aa579160200282015b828111156141aa578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190614168565b506141039291506141d5565b604051806103e00160405280601f906020820280368337509192915050565b5b8082111561410357600081556001016141d6565b60005b838110156142055781810151838201526020016141ed565b50506000910152565b600081518084526142268160208601602086016141ea565b601f01601f19169290920160200192915050565b602081526000610ead602083018461420e565b8060608101831015610eb057600080fd5b60008083601f84011261427057600080fd5b50813567ffffffffffffffff81111561428857600080fd5b60208301915083602082850101111561212f57600080fd5b60008083601f8401126142b257600080fd5b50813567ffffffffffffffff8111156142ca57600080fd5b6020830191508360208260051b850101111561212f57600080fd5b60008060008060008060008060e0898b03121561430157600080fd5b61430b8a8a61424d565b9750606089013567ffffffffffffffff8082111561432857600080fd5b6143348c838d0161425e565b909950975060808b013591508082111561434d57600080fd5b6143598c838d016142a0565b909750955060a08b013591508082111561437257600080fd5b5061437f8b828c016142a0565b999c989b50969995989497949560c00135949350505050565b6000806000608084860312156143ad57600080fd5b6143b7858561424d565b9250606084013567ffffffffffffffff8111156143d357600080fd5b6143df8682870161425e565b9497909650939450505050565b634e487b7160e01b600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715614425576144256143ec565b60405290565b6040805190810167ffffffffffffffff81118282101715614425576144256143ec565b6040516101a0810167ffffffffffffffff81118282101715614425576144256143ec565b60405160a0810167ffffffffffffffff81118282101715614425576144256143ec565b6040516080810167ffffffffffffffff81118282101715614425576144256143ec565b6040516060810167ffffffffffffffff81118282101715614425576144256143ec565b604051601f8201601f1916810167ffffffffffffffff81118282101715614504576145046143ec565b604052919050565b6001600160a01b0381168114610ff057600080fd5b803561452c8161450c565b919050565b803563ffffffff8116811461452c57600080fd5b600060c0828403121561455757600080fd5b61455f614402565b823561456a8161450c565b815261457860208401614531565b602082015261458960408401614531565b604082015261459a60608401614531565b606082015260808301356145ad8161450c565b608082015260a08301356145c08161450c565b60a08201529392505050565b600067ffffffffffffffff8211156145e6576145e66143ec565b5060051b60200190565b67ffffffffffffffff81168114610ff057600080fd5b803561452c816145f0565b8015158114610ff057600080fd5b803561452c81614611565b600067ffffffffffffffff821115614644576146446143ec565b50601f01601f191660200190565b600082601f83011261466357600080fd5b81356146766146718261462a565b6144db565b81815284602083860101111561468b57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f8301126146b957600080fd5b813560206146c9614671836145cc565b82815260069290921b840181019181810190868411156146e857600080fd5b8286015b8481101561228e57604081890312156147055760008081fd5b61470d61442b565b81356147188161450c565b815281850135858201528352918301916040016146ec565b600082601f83011261474157600080fd5b81356020614751614671836145cc565b82815260059290921b8401810191818101908684111561477057600080fd5b8286015b8481101561228e57803567ffffffffffffffff8111156147945760008081fd5b6147a28986838b0101614652565b845250918301918301614774565b60006101a082840312156147c357600080fd5b6147cb61444e565b90506147d682614606565b81526147e460208301614521565b60208201526147f560408301614521565b604082015261480660608301614606565b60608201526080820135608082015261482160a0830161461f565b60a082015261483260c08301614606565b60c082015261484360e08301614521565b60e082015261010082810135908201526101208083013567ffffffffffffffff8082111561487057600080fd5b61487c86838701614652565b8385015261014092508285013591508082111561489857600080fd5b6148a4868387016146a8565b838501526101609250828501359150808211156148c057600080fd5b506148cd85828601614730565b82840152505061018080830135818301525092915050565b600082601f8301126148f657600080fd5b81356020614906614671836145cc565b82815260059290921b8401810191818101908684111561492557600080fd5b8286015b8481101561228e57803567ffffffffffffffff8111156149495760008081fd5b6149578986838b01016147b0565b845250918301918301614929565b600082601f83011261497657600080fd5b81356020614986614671836145cc565b82815260059290921b840181019181810190868411156149a557600080fd5b8286015b8481101561228e57803567ffffffffffffffff8111156149c95760008081fd5b6149d78986838b0101614730565b8452509183019183016149a9565b600082601f8301126149f657600080fd5b81356020614a06614671836145cc565b8083825260208201915060208460051b870101935086841115614a2857600080fd5b602086015b8481101561228e5780358352918301918301614a2d565b600082601f830112614a5557600080fd5b81356020614a65614671836145cc565b82815260059290921b84018101918181019086841115614a8457600080fd5b8286015b8481101561228e57803567ffffffffffffffff80821115614aa95760008081fd5b9088019060a0828b03601f1901811315614ac35760008081fd5b614acb614472565b614ad6888501614606565b815260408085013584811115614aec5760008081fd5b614afa8e8b838901016148e5565b8a8401525060608086013585811115614b135760008081fd5b614b218f8c838a0101614965565b8385015250608091508186013585811115614b3c5760008081fd5b614b4a8f8c838a01016149e5565b9184019190915250919093013590830152508352918301918301614a88565b6000806040808486031215614b7d57600080fd5b833567ffffffffffffffff80821115614b9557600080fd5b614ba187838801614a44565b9450602091508186013581811115614bb857600080fd5b8601601f81018813614bc957600080fd5b8035614bd7614671826145cc565b81815260059190911b8201840190848101908a831115614bf657600080fd5b8584015b83811015614c8257803586811115614c125760008081fd5b8501603f81018d13614c245760008081fd5b87810135614c34614671826145cc565b81815260059190911b82018a0190898101908f831115614c545760008081fd5b928b01925b82841015614c725783358252928a0192908a0190614c59565b8652505050918601918601614bfa565b50809750505050505050509250929050565b60008060408385031215614ca757600080fd5b8235614cb2816145f0565b91506020830135614cc2816145f0565b809150509250929050565b634e487b7160e01b600052602160045260246000fd5b60048110614cf357614cf3614ccd565b9052565b60208101610eb08284614ce3565b600060208284031215614d1757600080fd5b8135613196816145f0565b60006020808385031215614d3557600080fd5b823567ffffffffffffffff811115614d4c57600080fd5b8301601f81018513614d5d57600080fd5b8035614d6b614671826145cc565b81815260079190911b82018301908381019087831115614d8a57600080fd5b928401925b828410156135f95760808489031215614da85760008081fd5b614db0614495565b8435614dbb816145f0565b815284860135614dca81614611565b81870152604085810135614ddd8161450c565b90820152606085810135614df08161450c565b9082015282526080939093019290840190614d8f565b600060208284031215614e1857600080fd5b813567ffffffffffffffff811115614e2f57600080fd5b820160a0818503121561319657600080fd5b60008060408385031215614e5457600080fd5b8235614e5f816145f0565b91506020830135614cc28161450c565b803560ff8116811461452c57600080fd5b600060208284031215614e9257600080fd5b610ead82614e6f565b60008151808452602080850194506020840160005b83811015614ed55781516001600160a01b031687529582019590820190600101614eb0565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614f2f60e0840182614e9b565b90506040840151601f198483030160c0850152614f4c8282614e9b565b95945050505050565b60008060408385031215614f6857600080fd5b8235614f73816145f0565b946020939093013593505050565b60008060208385031215614f9457600080fd5b823567ffffffffffffffff80821115614fac57600080fd5b818501915085601f830112614fc057600080fd5b813581811115614fcf57600080fd5b8660208260061b8501011115614fe457600080fd5b60209290920196919550909350505050565b60006020828403121561500857600080fd5b81356131968161450c565b6000806040838503121561502657600080fd5b823567ffffffffffffffff8082111561503e57600080fd5b61504a868387016147b0565b9350602085013591508082111561506057600080fd5b5061506d85828601614730565b9150509250929050565b600082601f83011261508857600080fd5b81356020615098614671836145cc565b8083825260208201915060208460051b8701019350868411156150ba57600080fd5b602086015b8481101561228e5780356150d28161450c565b83529183019183016150bf565b600060208083850312156150f257600080fd5b823567ffffffffffffffff8082111561510a57600080fd5b818501915085601f83011261511e57600080fd5b813561512c614671826145cc565b81815260059190911b8301840190848101908883111561514b57600080fd5b8585015b8381101561521d5780358581111561516657600080fd5b860160c0818c03601f1901121561517d5760008081fd5b615185614402565b8882013581526040615198818401614e6f565b8a83015260606151a9818501614e6f565b82840152608091506151bc82850161461f565b9083015260a083810135898111156151d45760008081fd5b6151e28f8d83880101615077565b838501525060c08401359150888211156151fc5760008081fd5b61520a8e8c84870101615077565b908301525084525091860191860161514f565b5098975050505050505050565b60006020828403121561523c57600080fd5b5035919050565b80356001600160e01b038116811461452c57600080fd5b600082601f83011261526b57600080fd5b8135602061527b614671836145cc565b82815260069290921b8401810191818101908684111561529a57600080fd5b8286015b8481101561228e57604081890312156152b75760008081fd5b6152bf61442b565b81356152ca816145f0565b81526152d7828601615243565b8186015283529183019160400161529e565b600082601f8301126152fa57600080fd5b8135602061530a614671836145cc565b82815260079290921b8401810191818101908684111561532957600080fd5b8286015b8481101561228e5780880360808112156153475760008081fd5b61534f6144b8565b823561535a816145f0565b81526040601f1983018113156153705760008081fd5b61537861442b565b925086840135615387816145f0565b835283810135615396816145f0565b838801528187019290925260608301359181019190915283529183019160800161532d565b600060208083850312156153ce57600080fd5b823567ffffffffffffffff808211156153e657600080fd5b818501915060408083880312156153fc57600080fd5b61540461442b565b83358381111561541357600080fd5b84016040818a03121561542557600080fd5b61542d61442b565b81358581111561543c57600080fd5b8201601f81018b1361544d57600080fd5b803561545b614671826145cc565b81815260069190911b8201890190898101908d83111561547a57600080fd5b928a01925b828410156154ca5787848f0312156154975760008081fd5b61549f61442b565b84356154aa8161450c565b81526154b7858d01615243565b818d0152825292870192908a019061547f565b8452505050818701359350848411156154e257600080fd5b6154ee8a85840161525a565b818801528252508385013591508282111561550857600080fd5b615514888386016152e9565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b8181101561559357835180516001600160a01b031684528501516001600160e01b031685840152928401929185019160010161555c565b50508583015187820388850152805180835290840192506000918401905b808310156155ed578351805167ffffffffffffffff1683528501516001600160e01b0316858301529284019260019290920191908501906155b1565b50979650505050505050565b602081526000610ead602083018461553c565b67ffffffffffffffff83168152606081016131966020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff81811683821601908082111561567857615678615641565b5092915050565b60006020808352606084516040808487015261569e606087018361553c565b87850151878203601f19016040890152805180835290860193506000918601905b8083101561521d57845167ffffffffffffffff8151168352878101516156fe89850182805167ffffffffffffffff908116835260209182015116910152565b508401518287015293860193600192909201916080909101906156bf565b60006020828403121561572e57600080fd5b813567ffffffffffffffff81111561574557600080fd5b6139b384828501614a44565b81810381811115610eb057610eb0615641565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff8084168061579557615795615764565b92169190910692915050565b8082028115828204841417610eb057610eb0615641565b6000604082840312156157ca57600080fd5b6157d261442b565b82356157dd816145f0565b81526020928301359281019290925250919050565b60008151808452602080850194506020840160005b83811015614ed557815180516001600160a01b031688526020908101519088015260408701965090820190600101615807565b8051825267ffffffffffffffff60208201511660208301526000604082015160a0604085015261586d60a085018261420e565b905060608301518482036060860152615886828261420e565b91505060808301518482036080860152614f4c82826157f2565b602081526000610ead602083018461583a565b6080815260006158c6608083018761583a565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b600082601f83011261590057600080fd5b815161590e6146718261462a565b81815284602083860101111561592357600080fd5b6139b38260208301602087016141ea565b60008060006060848603121561594957600080fd5b835161595481614611565b602085015190935067ffffffffffffffff81111561597157600080fd5b61597d868287016158ef565b925050604084015190509250925092565b6000602082840312156159a057600080fd5b815161319681614611565b80820180821115610eb057610eb0615641565b60ff8181168382160190811115610eb057610eb0615641565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff80841680615a1657615a16615764565b92169190910492915050565b600060208284031215615a3457600080fd5b8151613196816145f0565b600060208284031215615a5157600080fd5b815167ffffffffffffffff80821115615a6957600080fd5b9083019060608286031215615a7d57600080fd5b615a856144b8565b825182811115615a9457600080fd5b615aa0878286016158ef565b825250602083015182811115615ab557600080fd5b615ac1878286016158ef565b602083015250604083015182811115615ad957600080fd5b615ae5878286016158ef565b60408301525095945050505050565b6020810160058310615b0857615b08614ccd565b91905290565b60ff818116838216029081169081811461567857615678615641565b600060a0820160ff88168352602087602085015260a0604085015281875480845260c086019150886000526020600020935060005b81811015615b845784546001600160a01b031683526001948501949284019201615b5f565b50508481036060860152615b988188614e9b565b935050505060ff831660808301529695505050505050565b8281526040602082015260006139b3604083018461420e565b67ffffffffffffffff848116825283166020820152606081016139b36040830184614ce3565b600067ffffffffffffffff808316818103615c0c57615c0c615641565b6001019392505050565b615c208184614ce3565b6040602082015260006139b3604083018461420e565b600060208284031215615c4857600080fd5b81516131968161450c565b6020815260008251610100806020850152615c7261012085018361420e565b91506020850151615c8f604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615cc960a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615ce6848361420e565b935060c08701519150808685030160e0870152615d03848361420e565b935060e0870151915080868503018387015250615d20838261420e565b9695505050505050565b600060208284031215615d3c57600080fd5b5051919050565b600060ff821660ff8103615d5957615d59615641565b60010192915050565b6020808252825182820181905260009190848201906040850190845b81811015615db157835180516001600160a01b031684526020908101519084015260408301938501939250600101615d7e565b50909695505050505050565b60008282518085526020808601955060208260051b8401016020860160005b84811015615e0a57601f19868403018952615df883835161420e565b98840198925090830190600101615ddc565b5090979650505050505050565b602081526000610ead6020830184615dbd565b60408152615e4560408201845167ffffffffffffffff169052565b60006020840151615e6160608401826001600160a01b03169052565b5060408401516001600160a01b038116608084015250606084015167ffffffffffffffff811660a084015250608084015160c083015260a084015180151560e08401525060c0840151610100615ec28185018367ffffffffffffffff169052565b60e08601519150610120615ee0818601846001600160a01b03169052565b81870151925061014091508282860152808701519250506101a06101608181870152615f106101e087018561420e565b9350828801519250603f19610180818887030181890152615f3186866157f2565b9550828a01519450818887030184890152615f4c8686615dbd565b9550808a01516101c089015250505050508281036020840152614f4c8185615dbd565b6000815160208301516001600160e01b031980821693506004831015615f9f5780818460040360031b1b83161693505b50505091905056fea164736f6c6343000818000a", } var EVM2EVMMultiOffRampABI = EVM2EVMMultiOffRampMetaData.ABI @@ -364,9 +360,9 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) GetExecutionState( return _EVM2EVMMultiOffRamp.Contract.GetExecutionState(&_EVM2EVMMultiOffRamp.CallOpts, sourceChainSelector, sequenceNumber) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) GetLatestPriceEpochAndRound(opts *bind.CallOpts) (uint64, error) { +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) GetLatestPriceSequenceNumber(opts *bind.CallOpts) (uint64, error) { var out []interface{} - err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "getLatestPriceEpochAndRound") + err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "getLatestPriceSequenceNumber") if err != nil { return *new(uint64), err @@ -378,12 +374,12 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) GetLatestPriceEpochAndRou } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) GetLatestPriceEpochAndRound() (uint64, error) { - return _EVM2EVMMultiOffRamp.Contract.GetLatestPriceEpochAndRound(&_EVM2EVMMultiOffRamp.CallOpts) +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) GetLatestPriceSequenceNumber() (uint64, error) { + return _EVM2EVMMultiOffRamp.Contract.GetLatestPriceSequenceNumber(&_EVM2EVMMultiOffRamp.CallOpts) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) GetLatestPriceEpochAndRound() (uint64, error) { - return _EVM2EVMMultiOffRamp.Contract.GetLatestPriceEpochAndRound(&_EVM2EVMMultiOffRamp.CallOpts) +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) GetLatestPriceSequenceNumber() (uint64, error) { + return _EVM2EVMMultiOffRamp.Contract.GetLatestPriceSequenceNumber(&_EVM2EVMMultiOffRamp.CallOpts) } func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) GetMerkleRoot(opts *bind.CallOpts, sourceChainSelector uint64, root [32]byte) (*big.Int, error) { @@ -496,28 +492,6 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) IsBlessed(root [32 return _EVM2EVMMultiOffRamp.Contract.IsBlessed(&_EVM2EVMMultiOffRamp.CallOpts, root) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) IsUnpausedAndNotCursed(opts *bind.CallOpts, sourceChainSelector uint64) (bool, error) { - var out []interface{} - err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "isUnpausedAndNotCursed", sourceChainSelector) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) IsUnpausedAndNotCursed(sourceChainSelector uint64) (bool, error) { - return _EVM2EVMMultiOffRamp.Contract.IsUnpausedAndNotCursed(&_EVM2EVMMultiOffRamp.CallOpts, sourceChainSelector) -} - -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) IsUnpausedAndNotCursed(sourceChainSelector uint64) (bool, error) { - return _EVM2EVMMultiOffRamp.Contract.IsUnpausedAndNotCursed(&_EVM2EVMMultiOffRamp.CallOpts, sourceChainSelector) -} - func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) LatestConfigDetails(opts *bind.CallOpts, ocrPluginType uint8) (MultiOCR3BaseOCRConfig, error) { var out []interface{} err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "latestConfigDetails", ocrPluginType) @@ -562,28 +536,6 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) Owner() (common.Ad return _EVM2EVMMultiOffRamp.Contract.Owner(&_EVM2EVMMultiOffRamp.CallOpts) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) Paused(opts *bind.CallOpts) (bool, error) { - var out []interface{} - err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "paused") - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) Paused() (bool, error) { - return _EVM2EVMMultiOffRamp.Contract.Paused(&_EVM2EVMMultiOffRamp.CallOpts) -} - -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) Paused() (bool, error) { - return _EVM2EVMMultiOffRamp.Contract.Paused(&_EVM2EVMMultiOffRamp.CallOpts) -} - func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { var out []interface{} err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "typeAndVersion") @@ -678,18 +630,6 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) ManuallyExecut return _EVM2EVMMultiOffRamp.Contract.ManuallyExecute(&_EVM2EVMMultiOffRamp.TransactOpts, reports, gasLimitOverrides) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.contract.Transact(opts, "pause") -} - -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) Pause() (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.Pause(&_EVM2EVMMultiOffRamp.TransactOpts) -} - -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) Pause() (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.Pause(&_EVM2EVMMultiOffRamp.TransactOpts) -} - func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset []EVM2EVMMultiOffRampUnblessedRoot) (*types.Transaction, error) { return _EVM2EVMMultiOffRamp.contract.Transact(opts, "resetUnblessedRoots", rootToReset) } @@ -714,16 +654,16 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) SetDynamicConf return _EVM2EVMMultiOffRamp.Contract.SetDynamicConfig(&_EVM2EVMMultiOffRamp.TransactOpts, dynamicConfig) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) SetLatestPriceEpochAndRound(opts *bind.TransactOpts, latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.contract.Transact(opts, "setLatestPriceEpochAndRound", latestPriceEpochAndRound) +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) SetLatestPriceSequenceNumber(opts *bind.TransactOpts, latestPriceSequenceNumber uint64) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.contract.Transact(opts, "setLatestPriceSequenceNumber", latestPriceSequenceNumber) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) SetLatestPriceEpochAndRound(latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.SetLatestPriceEpochAndRound(&_EVM2EVMMultiOffRamp.TransactOpts, latestPriceEpochAndRound) +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) SetLatestPriceSequenceNumber(latestPriceSequenceNumber uint64) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.SetLatestPriceSequenceNumber(&_EVM2EVMMultiOffRamp.TransactOpts, latestPriceSequenceNumber) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) SetLatestPriceEpochAndRound(latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.SetLatestPriceEpochAndRound(&_EVM2EVMMultiOffRamp.TransactOpts, latestPriceEpochAndRound) +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) SetLatestPriceSequenceNumber(latestPriceSequenceNumber uint64) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.SetLatestPriceSequenceNumber(&_EVM2EVMMultiOffRamp.TransactOpts, latestPriceSequenceNumber) } func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) SetOCR3Configs(opts *bind.TransactOpts, ocrConfigArgs []MultiOCR3BaseOCRConfigArgs) (*types.Transaction, error) { @@ -750,18 +690,6 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) TransferOwners return _EVM2EVMMultiOffRamp.Contract.TransferOwnership(&_EVM2EVMMultiOffRamp.TransactOpts, to) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.contract.Transact(opts, "unpause") -} - -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) Unpause() (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.Unpause(&_EVM2EVMMultiOffRamp.TransactOpts) -} - -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) Unpause() (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.Unpause(&_EVM2EVMMultiOffRamp.TransactOpts) -} - type EVM2EVMMultiOffRampCommitReportAcceptedIterator struct { Event *EVM2EVMMultiOffRampCommitReportAccepted @@ -940,8 +868,11 @@ func (it *EVM2EVMMultiOffRampConfigSetIterator) Close() error { } type EVM2EVMMultiOffRampConfigSet struct { - StaticConfig EVM2EVMMultiOffRampStaticConfig - DynamicConfig EVM2EVMMultiOffRampDynamicConfig + OcrPluginType uint8 + ConfigDigest [32]byte + Signers []common.Address + Transmitters []common.Address + F uint8 Raw types.Log } @@ -997,8 +928,8 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseConfigSet(log type return event, nil } -type EVM2EVMMultiOffRampConfigSet0Iterator struct { - Event *EVM2EVMMultiOffRampConfigSet0 +type EVM2EVMMultiOffRampDynamicConfigSetIterator struct { + Event *EVM2EVMMultiOffRampDynamicConfigSet contract *bind.BoundContract event string @@ -1009,7 +940,7 @@ type EVM2EVMMultiOffRampConfigSet0Iterator struct { fail error } -func (it *EVM2EVMMultiOffRampConfigSet0Iterator) Next() bool { +func (it *EVM2EVMMultiOffRampDynamicConfigSetIterator) Next() bool { if it.fail != nil { return false @@ -1018,7 +949,7 @@ func (it *EVM2EVMMultiOffRampConfigSet0Iterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampConfigSet0) + it.Event = new(EVM2EVMMultiOffRampDynamicConfigSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1033,7 +964,7 @@ func (it *EVM2EVMMultiOffRampConfigSet0Iterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampConfigSet0) + it.Event = new(EVM2EVMMultiOffRampDynamicConfigSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1048,36 +979,32 @@ func (it *EVM2EVMMultiOffRampConfigSet0Iterator) Next() bool { } } -func (it *EVM2EVMMultiOffRampConfigSet0Iterator) Error() error { +func (it *EVM2EVMMultiOffRampDynamicConfigSetIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOffRampConfigSet0Iterator) Close() error { +func (it *EVM2EVMMultiOffRampDynamicConfigSetIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOffRampConfigSet0 struct { - OcrPluginType uint8 - ConfigDigest [32]byte - Signers []common.Address - Transmitters []common.Address - F uint8 +type EVM2EVMMultiOffRampDynamicConfigSet struct { + DynamicConfig EVM2EVMMultiOffRampDynamicConfig Raw types.Log } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterConfigSet0(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampConfigSet0Iterator, error) { +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterDynamicConfigSet(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampDynamicConfigSetIterator, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "ConfigSet0") + logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "DynamicConfigSet") if err != nil { return nil, err } - return &EVM2EVMMultiOffRampConfigSet0Iterator{contract: _EVM2EVMMultiOffRamp.contract, event: "ConfigSet0", logs: logs, sub: sub}, nil + return &EVM2EVMMultiOffRampDynamicConfigSetIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "DynamicConfigSet", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampConfigSet0) (event.Subscription, error) { +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchDynamicConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampDynamicConfigSet) (event.Subscription, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "ConfigSet0") + logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "DynamicConfigSet") if err != nil { return nil, err } @@ -1087,8 +1014,8 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchConfigSet0(opts *b select { case log := <-logs: - event := new(EVM2EVMMultiOffRampConfigSet0) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + event := new(EVM2EVMMultiOffRampDynamicConfigSet) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "DynamicConfigSet", log); err != nil { return err } event.Raw = log @@ -1109,9 +1036,9 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchConfigSet0(opts *b }), nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseConfigSet0(log types.Log) (*EVM2EVMMultiOffRampConfigSet0, error) { - event := new(EVM2EVMMultiOffRampConfigSet0) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "ConfigSet0", log); err != nil { +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseDynamicConfigSet(log types.Log) (*EVM2EVMMultiOffRampDynamicConfigSet, error) { + event := new(EVM2EVMMultiOffRampDynamicConfigSet) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "DynamicConfigSet", log); err != nil { return nil, err } event.Raw = log @@ -1265,8 +1192,8 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseExecutionStateChan return event, nil } -type EVM2EVMMultiOffRampLatestPriceEpochAndRoundSetIterator struct { - Event *EVM2EVMMultiOffRampLatestPriceEpochAndRoundSet +type EVM2EVMMultiOffRampLatestPriceSequenceNumberSetIterator struct { + Event *EVM2EVMMultiOffRampLatestPriceSequenceNumberSet contract *bind.BoundContract event string @@ -1277,7 +1204,7 @@ type EVM2EVMMultiOffRampLatestPriceEpochAndRoundSetIterator struct { fail error } -func (it *EVM2EVMMultiOffRampLatestPriceEpochAndRoundSetIterator) Next() bool { +func (it *EVM2EVMMultiOffRampLatestPriceSequenceNumberSetIterator) Next() bool { if it.fail != nil { return false @@ -1286,7 +1213,7 @@ func (it *EVM2EVMMultiOffRampLatestPriceEpochAndRoundSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampLatestPriceEpochAndRoundSet) + it.Event = new(EVM2EVMMultiOffRampLatestPriceSequenceNumberSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1301,7 +1228,7 @@ func (it *EVM2EVMMultiOffRampLatestPriceEpochAndRoundSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampLatestPriceEpochAndRoundSet) + it.Event = new(EVM2EVMMultiOffRampLatestPriceSequenceNumberSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1316,33 +1243,33 @@ func (it *EVM2EVMMultiOffRampLatestPriceEpochAndRoundSetIterator) Next() bool { } } -func (it *EVM2EVMMultiOffRampLatestPriceEpochAndRoundSetIterator) Error() error { +func (it *EVM2EVMMultiOffRampLatestPriceSequenceNumberSetIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOffRampLatestPriceEpochAndRoundSetIterator) Close() error { +func (it *EVM2EVMMultiOffRampLatestPriceSequenceNumberSetIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOffRampLatestPriceEpochAndRoundSet struct { - OldEpochAndRound *big.Int - NewEpochAndRound *big.Int - Raw types.Log +type EVM2EVMMultiOffRampLatestPriceSequenceNumberSet struct { + OldSequenceNumber uint64 + NewSequenceNumber uint64 + Raw types.Log } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterLatestPriceEpochAndRoundSet(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampLatestPriceEpochAndRoundSetIterator, error) { +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterLatestPriceSequenceNumberSet(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampLatestPriceSequenceNumberSetIterator, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "LatestPriceEpochAndRoundSet") + logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "LatestPriceSequenceNumberSet") if err != nil { return nil, err } - return &EVM2EVMMultiOffRampLatestPriceEpochAndRoundSetIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "LatestPriceEpochAndRoundSet", logs: logs, sub: sub}, nil + return &EVM2EVMMultiOffRampLatestPriceSequenceNumberSetIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "LatestPriceSequenceNumberSet", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchLatestPriceEpochAndRoundSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampLatestPriceEpochAndRoundSet) (event.Subscription, error) { +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchLatestPriceSequenceNumberSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampLatestPriceSequenceNumberSet) (event.Subscription, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "LatestPriceEpochAndRoundSet") + logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "LatestPriceSequenceNumberSet") if err != nil { return nil, err } @@ -1352,8 +1279,8 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchLatestPriceEpochAn select { case log := <-logs: - event := new(EVM2EVMMultiOffRampLatestPriceEpochAndRoundSet) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "LatestPriceEpochAndRoundSet", log); err != nil { + event := new(EVM2EVMMultiOffRampLatestPriceSequenceNumberSet) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "LatestPriceSequenceNumberSet", log); err != nil { return err } event.Raw = log @@ -1374,9 +1301,9 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchLatestPriceEpochAn }), nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseLatestPriceEpochAndRoundSet(log types.Log) (*EVM2EVMMultiOffRampLatestPriceEpochAndRoundSet, error) { - event := new(EVM2EVMMultiOffRampLatestPriceEpochAndRoundSet) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "LatestPriceEpochAndRoundSet", log); err != nil { +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseLatestPriceSequenceNumberSet(log types.Log) (*EVM2EVMMultiOffRampLatestPriceSequenceNumberSet, error) { + event := new(EVM2EVMMultiOffRampLatestPriceSequenceNumberSet) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "LatestPriceSequenceNumberSet", log); err != nil { return nil, err } event.Raw = log @@ -1655,123 +1582,6 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseOwnershipTransferr return event, nil } -type EVM2EVMMultiOffRampPausedIterator struct { - Event *EVM2EVMMultiOffRampPaused - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *EVM2EVMMultiOffRampPausedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampPaused) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampPaused) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *EVM2EVMMultiOffRampPausedIterator) Error() error { - return it.fail -} - -func (it *EVM2EVMMultiOffRampPausedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type EVM2EVMMultiOffRampPaused struct { - Account common.Address - Raw types.Log -} - -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterPaused(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampPausedIterator, error) { - - logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "Paused") - if err != nil { - return nil, err - } - return &EVM2EVMMultiOffRampPausedIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "Paused", logs: logs, sub: sub}, nil -} - -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampPaused) (event.Subscription, error) { - - logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "Paused") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(EVM2EVMMultiOffRampPaused) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "Paused", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParsePaused(log types.Log) (*EVM2EVMMultiOffRampPaused, error) { - event := new(EVM2EVMMultiOffRampPaused) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "Paused", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - type EVM2EVMMultiOffRampRootRemovedIterator struct { Event *EVM2EVMMultiOffRampRootRemoved @@ -2490,8 +2300,8 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseSourceChainSelecto return event, nil } -type EVM2EVMMultiOffRampTransmittedIterator struct { - Event *EVM2EVMMultiOffRampTransmitted +type EVM2EVMMultiOffRampStaticConfigSetIterator struct { + Event *EVM2EVMMultiOffRampStaticConfigSet contract *bind.BoundContract event string @@ -2502,7 +2312,7 @@ type EVM2EVMMultiOffRampTransmittedIterator struct { fail error } -func (it *EVM2EVMMultiOffRampTransmittedIterator) Next() bool { +func (it *EVM2EVMMultiOffRampStaticConfigSetIterator) Next() bool { if it.fail != nil { return false @@ -2511,7 +2321,7 @@ func (it *EVM2EVMMultiOffRampTransmittedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampTransmitted) + it.Event = new(EVM2EVMMultiOffRampStaticConfigSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2526,7 +2336,7 @@ func (it *EVM2EVMMultiOffRampTransmittedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampTransmitted) + it.Event = new(EVM2EVMMultiOffRampStaticConfigSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2541,44 +2351,32 @@ func (it *EVM2EVMMultiOffRampTransmittedIterator) Next() bool { } } -func (it *EVM2EVMMultiOffRampTransmittedIterator) Error() error { +func (it *EVM2EVMMultiOffRampStaticConfigSetIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOffRampTransmittedIterator) Close() error { +func (it *EVM2EVMMultiOffRampStaticConfigSetIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOffRampTransmitted struct { - OcrPluginType uint8 - ConfigDigest [32]byte - SequenceNumber uint64 - Raw types.Log +type EVM2EVMMultiOffRampStaticConfigSet struct { + StaticConfig EVM2EVMMultiOffRampStaticConfig + Raw types.Log } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterTransmitted(opts *bind.FilterOpts, ocrPluginType []uint8) (*EVM2EVMMultiOffRampTransmittedIterator, error) { - - var ocrPluginTypeRule []interface{} - for _, ocrPluginTypeItem := range ocrPluginType { - ocrPluginTypeRule = append(ocrPluginTypeRule, ocrPluginTypeItem) - } +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterStaticConfigSet(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampStaticConfigSetIterator, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "Transmitted", ocrPluginTypeRule) + logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "StaticConfigSet") if err != nil { return nil, err } - return &EVM2EVMMultiOffRampTransmittedIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "Transmitted", logs: logs, sub: sub}, nil + return &EVM2EVMMultiOffRampStaticConfigSetIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "StaticConfigSet", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampTransmitted, ocrPluginType []uint8) (event.Subscription, error) { - - var ocrPluginTypeRule []interface{} - for _, ocrPluginTypeItem := range ocrPluginType { - ocrPluginTypeRule = append(ocrPluginTypeRule, ocrPluginTypeItem) - } +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchStaticConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampStaticConfigSet) (event.Subscription, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "Transmitted", ocrPluginTypeRule) + logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "StaticConfigSet") if err != nil { return nil, err } @@ -2588,8 +2386,8 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchTransmitted(opts * select { case log := <-logs: - event := new(EVM2EVMMultiOffRampTransmitted) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "Transmitted", log); err != nil { + event := new(EVM2EVMMultiOffRampStaticConfigSet) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "StaticConfigSet", log); err != nil { return err } event.Raw = log @@ -2610,17 +2408,17 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchTransmitted(opts * }), nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseTransmitted(log types.Log) (*EVM2EVMMultiOffRampTransmitted, error) { - event := new(EVM2EVMMultiOffRampTransmitted) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "Transmitted", log); err != nil { +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseStaticConfigSet(log types.Log) (*EVM2EVMMultiOffRampStaticConfigSet, error) { + event := new(EVM2EVMMultiOffRampStaticConfigSet) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "StaticConfigSet", log); err != nil { return nil, err } event.Raw = log return event, nil } -type EVM2EVMMultiOffRampUnpausedIterator struct { - Event *EVM2EVMMultiOffRampUnpaused +type EVM2EVMMultiOffRampTransmittedIterator struct { + Event *EVM2EVMMultiOffRampTransmitted contract *bind.BoundContract event string @@ -2631,7 +2429,7 @@ type EVM2EVMMultiOffRampUnpausedIterator struct { fail error } -func (it *EVM2EVMMultiOffRampUnpausedIterator) Next() bool { +func (it *EVM2EVMMultiOffRampTransmittedIterator) Next() bool { if it.fail != nil { return false @@ -2640,7 +2438,7 @@ func (it *EVM2EVMMultiOffRampUnpausedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampUnpaused) + it.Event = new(EVM2EVMMultiOffRampTransmitted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2655,7 +2453,7 @@ func (it *EVM2EVMMultiOffRampUnpausedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampUnpaused) + it.Event = new(EVM2EVMMultiOffRampTransmitted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2670,32 +2468,44 @@ func (it *EVM2EVMMultiOffRampUnpausedIterator) Next() bool { } } -func (it *EVM2EVMMultiOffRampUnpausedIterator) Error() error { +func (it *EVM2EVMMultiOffRampTransmittedIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOffRampUnpausedIterator) Close() error { +func (it *EVM2EVMMultiOffRampTransmittedIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOffRampUnpaused struct { - Account common.Address - Raw types.Log +type EVM2EVMMultiOffRampTransmitted struct { + OcrPluginType uint8 + ConfigDigest [32]byte + SequenceNumber uint64 + Raw types.Log } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterUnpaused(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampUnpausedIterator, error) { +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterTransmitted(opts *bind.FilterOpts, ocrPluginType []uint8) (*EVM2EVMMultiOffRampTransmittedIterator, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "Unpaused") + var ocrPluginTypeRule []interface{} + for _, ocrPluginTypeItem := range ocrPluginType { + ocrPluginTypeRule = append(ocrPluginTypeRule, ocrPluginTypeItem) + } + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "Transmitted", ocrPluginTypeRule) if err != nil { return nil, err } - return &EVM2EVMMultiOffRampUnpausedIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "Unpaused", logs: logs, sub: sub}, nil + return &EVM2EVMMultiOffRampTransmittedIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "Transmitted", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampUnpaused) (event.Subscription, error) { +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampTransmitted, ocrPluginType []uint8) (event.Subscription, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "Unpaused") + var ocrPluginTypeRule []interface{} + for _, ocrPluginTypeItem := range ocrPluginType { + ocrPluginTypeRule = append(ocrPluginTypeRule, ocrPluginTypeItem) + } + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "Transmitted", ocrPluginTypeRule) if err != nil { return nil, err } @@ -2705,8 +2515,8 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchUnpaused(opts *bin select { case log := <-logs: - event := new(EVM2EVMMultiOffRampUnpaused) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "Unpaused", log); err != nil { + event := new(EVM2EVMMultiOffRampTransmitted) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "Transmitted", log); err != nil { return err } event.Raw = log @@ -2727,9 +2537,9 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchUnpaused(opts *bin }), nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseUnpaused(log types.Log) (*EVM2EVMMultiOffRampUnpaused, error) { - event := new(EVM2EVMMultiOffRampUnpaused) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "Unpaused", log); err != nil { +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseTransmitted(log types.Log) (*EVM2EVMMultiOffRampTransmitted, error) { + event := new(EVM2EVMMultiOffRampTransmitted) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "Transmitted", log); err != nil { return nil, err } event.Raw = log @@ -2742,18 +2552,16 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRamp) ParseLog(log types.Log) (genera return _EVM2EVMMultiOffRamp.ParseCommitReportAccepted(log) case _EVM2EVMMultiOffRamp.abi.Events["ConfigSet"].ID: return _EVM2EVMMultiOffRamp.ParseConfigSet(log) - case _EVM2EVMMultiOffRamp.abi.Events["ConfigSet0"].ID: - return _EVM2EVMMultiOffRamp.ParseConfigSet0(log) + case _EVM2EVMMultiOffRamp.abi.Events["DynamicConfigSet"].ID: + return _EVM2EVMMultiOffRamp.ParseDynamicConfigSet(log) case _EVM2EVMMultiOffRamp.abi.Events["ExecutionStateChanged"].ID: return _EVM2EVMMultiOffRamp.ParseExecutionStateChanged(log) - case _EVM2EVMMultiOffRamp.abi.Events["LatestPriceEpochAndRoundSet"].ID: - return _EVM2EVMMultiOffRamp.ParseLatestPriceEpochAndRoundSet(log) + case _EVM2EVMMultiOffRamp.abi.Events["LatestPriceSequenceNumberSet"].ID: + return _EVM2EVMMultiOffRamp.ParseLatestPriceSequenceNumberSet(log) case _EVM2EVMMultiOffRamp.abi.Events["OwnershipTransferRequested"].ID: return _EVM2EVMMultiOffRamp.ParseOwnershipTransferRequested(log) case _EVM2EVMMultiOffRamp.abi.Events["OwnershipTransferred"].ID: return _EVM2EVMMultiOffRamp.ParseOwnershipTransferred(log) - case _EVM2EVMMultiOffRamp.abi.Events["Paused"].ID: - return _EVM2EVMMultiOffRamp.ParsePaused(log) case _EVM2EVMMultiOffRamp.abi.Events["RootRemoved"].ID: return _EVM2EVMMultiOffRamp.ParseRootRemoved(log) case _EVM2EVMMultiOffRamp.abi.Events["SkippedAlreadyExecutedMessage"].ID: @@ -2766,10 +2574,10 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRamp) ParseLog(log types.Log) (genera return _EVM2EVMMultiOffRamp.ParseSourceChainConfigSet(log) case _EVM2EVMMultiOffRamp.abi.Events["SourceChainSelectorAdded"].ID: return _EVM2EVMMultiOffRamp.ParseSourceChainSelectorAdded(log) + case _EVM2EVMMultiOffRamp.abi.Events["StaticConfigSet"].ID: + return _EVM2EVMMultiOffRamp.ParseStaticConfigSet(log) case _EVM2EVMMultiOffRamp.abi.Events["Transmitted"].ID: return _EVM2EVMMultiOffRamp.ParseTransmitted(log) - case _EVM2EVMMultiOffRamp.abi.Events["Unpaused"].ID: - return _EVM2EVMMultiOffRamp.ParseUnpaused(log) default: return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) @@ -2781,19 +2589,19 @@ func (EVM2EVMMultiOffRampCommitReportAccepted) Topic() common.Hash { } func (EVM2EVMMultiOffRampConfigSet) Topic() common.Hash { - return common.HexToHash("0xf778ca28f5b9f37b5d23ffa5357592348ea60ec4e42b1dce5c857a5a65b276f7") + return common.HexToHash("0xab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547") } -func (EVM2EVMMultiOffRampConfigSet0) Topic() common.Hash { - return common.HexToHash("0xab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547") +func (EVM2EVMMultiOffRampDynamicConfigSet) Topic() common.Hash { + return common.HexToHash("0x0da37fd00459f4f5f0b8210d31525e4910ae674b8bab34b561d146bb45773a4c") } func (EVM2EVMMultiOffRampExecutionStateChanged) Topic() common.Hash { return common.HexToHash("0x8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df2") } -func (EVM2EVMMultiOffRampLatestPriceEpochAndRoundSet) Topic() common.Hash { - return common.HexToHash("0xf0d557bfce33e354b41885eb9264448726cfe51f486ffa69809d2bf565456444") +func (EVM2EVMMultiOffRampLatestPriceSequenceNumberSet) Topic() common.Hash { + return common.HexToHash("0x88ad9c61d6caf19a2af116a871802a03a31e680115a2dd20e8c08801d7c82f83") } func (EVM2EVMMultiOffRampOwnershipTransferRequested) Topic() common.Hash { @@ -2804,10 +2612,6 @@ func (EVM2EVMMultiOffRampOwnershipTransferred) Topic() common.Hash { return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") } -func (EVM2EVMMultiOffRampPaused) Topic() common.Hash { - return common.HexToHash("0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258") -} - func (EVM2EVMMultiOffRampRootRemoved) Topic() common.Hash { return common.HexToHash("0x202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12") } @@ -2832,12 +2636,12 @@ func (EVM2EVMMultiOffRampSourceChainSelectorAdded) Topic() common.Hash { return common.HexToHash("0xf4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb9") } -func (EVM2EVMMultiOffRampTransmitted) Topic() common.Hash { - return common.HexToHash("0x198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0") +func (EVM2EVMMultiOffRampStaticConfigSet) Topic() common.Hash { + return common.HexToHash("0x2f56698ec552a5d53d27d6f4b3dd8b6989f6426b6151a36aff61160c1d07efdf") } -func (EVM2EVMMultiOffRampUnpaused) Topic() common.Hash { - return common.HexToHash("0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa") +func (EVM2EVMMultiOffRampTransmitted) Topic() common.Hash { + return common.HexToHash("0x198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0") } func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRamp) Address() common.Address { @@ -2851,7 +2655,7 @@ type EVM2EVMMultiOffRampInterface interface { GetExecutionState(opts *bind.CallOpts, sourceChainSelector uint64, sequenceNumber uint64) (uint8, error) - GetLatestPriceEpochAndRound(opts *bind.CallOpts) (uint64, error) + GetLatestPriceSequenceNumber(opts *bind.CallOpts) (uint64, error) GetMerkleRoot(opts *bind.CallOpts, sourceChainSelector uint64, root [32]byte) (*big.Int, error) @@ -2863,14 +2667,10 @@ type EVM2EVMMultiOffRampInterface interface { IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) - IsUnpausedAndNotCursed(opts *bind.CallOpts, sourceChainSelector uint64) (bool, error) - LatestConfigDetails(opts *bind.CallOpts, ocrPluginType uint8) (MultiOCR3BaseOCRConfig, error) Owner(opts *bind.CallOpts) (common.Address, error) - Paused(opts *bind.CallOpts) (bool, error) - TypeAndVersion(opts *bind.CallOpts) (string, error) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) @@ -2885,20 +2685,16 @@ type EVM2EVMMultiOffRampInterface interface { ManuallyExecute(opts *bind.TransactOpts, reports []InternalExecutionReportSingleChain, gasLimitOverrides [][]*big.Int) (*types.Transaction, error) - Pause(opts *bind.TransactOpts) (*types.Transaction, error) - ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset []EVM2EVMMultiOffRampUnblessedRoot) (*types.Transaction, error) SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig EVM2EVMMultiOffRampDynamicConfig) (*types.Transaction, error) - SetLatestPriceEpochAndRound(opts *bind.TransactOpts, latestPriceEpochAndRound *big.Int) (*types.Transaction, error) + SetLatestPriceSequenceNumber(opts *bind.TransactOpts, latestPriceSequenceNumber uint64) (*types.Transaction, error) SetOCR3Configs(opts *bind.TransactOpts, ocrConfigArgs []MultiOCR3BaseOCRConfigArgs) (*types.Transaction, error) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) - Unpause(opts *bind.TransactOpts) (*types.Transaction, error) - FilterCommitReportAccepted(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampCommitReportAcceptedIterator, error) WatchCommitReportAccepted(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampCommitReportAccepted) (event.Subscription, error) @@ -2911,11 +2707,11 @@ type EVM2EVMMultiOffRampInterface interface { ParseConfigSet(log types.Log) (*EVM2EVMMultiOffRampConfigSet, error) - FilterConfigSet0(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampConfigSet0Iterator, error) + FilterDynamicConfigSet(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampDynamicConfigSetIterator, error) - WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampConfigSet0) (event.Subscription, error) + WatchDynamicConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampDynamicConfigSet) (event.Subscription, error) - ParseConfigSet0(log types.Log) (*EVM2EVMMultiOffRampConfigSet0, error) + ParseDynamicConfigSet(log types.Log) (*EVM2EVMMultiOffRampDynamicConfigSet, error) FilterExecutionStateChanged(opts *bind.FilterOpts, sourceChainSelector []uint64, sequenceNumber []uint64, messageId [][32]byte) (*EVM2EVMMultiOffRampExecutionStateChangedIterator, error) @@ -2923,11 +2719,11 @@ type EVM2EVMMultiOffRampInterface interface { ParseExecutionStateChanged(log types.Log) (*EVM2EVMMultiOffRampExecutionStateChanged, error) - FilterLatestPriceEpochAndRoundSet(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampLatestPriceEpochAndRoundSetIterator, error) + FilterLatestPriceSequenceNumberSet(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampLatestPriceSequenceNumberSetIterator, error) - WatchLatestPriceEpochAndRoundSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampLatestPriceEpochAndRoundSet) (event.Subscription, error) + WatchLatestPriceSequenceNumberSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampLatestPriceSequenceNumberSet) (event.Subscription, error) - ParseLatestPriceEpochAndRoundSet(log types.Log) (*EVM2EVMMultiOffRampLatestPriceEpochAndRoundSet, error) + ParseLatestPriceSequenceNumberSet(log types.Log) (*EVM2EVMMultiOffRampLatestPriceSequenceNumberSet, error) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMMultiOffRampOwnershipTransferRequestedIterator, error) @@ -2941,12 +2737,6 @@ type EVM2EVMMultiOffRampInterface interface { ParseOwnershipTransferred(log types.Log) (*EVM2EVMMultiOffRampOwnershipTransferred, error) - FilterPaused(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampPausedIterator, error) - - WatchPaused(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampPaused) (event.Subscription, error) - - ParsePaused(log types.Log) (*EVM2EVMMultiOffRampPaused, error) - FilterRootRemoved(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampRootRemovedIterator, error) WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampRootRemoved) (event.Subscription, error) @@ -2983,17 +2773,17 @@ type EVM2EVMMultiOffRampInterface interface { ParseSourceChainSelectorAdded(log types.Log) (*EVM2EVMMultiOffRampSourceChainSelectorAdded, error) - FilterTransmitted(opts *bind.FilterOpts, ocrPluginType []uint8) (*EVM2EVMMultiOffRampTransmittedIterator, error) + FilterStaticConfigSet(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampStaticConfigSetIterator, error) - WatchTransmitted(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampTransmitted, ocrPluginType []uint8) (event.Subscription, error) + WatchStaticConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampStaticConfigSet) (event.Subscription, error) - ParseTransmitted(log types.Log) (*EVM2EVMMultiOffRampTransmitted, error) + ParseStaticConfigSet(log types.Log) (*EVM2EVMMultiOffRampStaticConfigSet, error) - FilterUnpaused(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampUnpausedIterator, error) + FilterTransmitted(opts *bind.FilterOpts, ocrPluginType []uint8) (*EVM2EVMMultiOffRampTransmittedIterator, error) - WatchUnpaused(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampUnpaused) (event.Subscription, error) + WatchTransmitted(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampTransmitted, ocrPluginType []uint8) (event.Subscription, error) - ParseUnpaused(log types.Log) (*EVM2EVMMultiOffRampUnpaused, error) + ParseTransmitted(log types.Log) (*EVM2EVMMultiOffRampTransmitted, error) ParseLog(log types.Log) (generated.AbigenLog, error) diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp/evm_2_evm_multi_onramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp/evm_2_evm_multi_onramp.go index 808a3e88a9..730012fe4e 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp/evm_2_evm_multi_onramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp/evm_2_evm_multi_onramp.go @@ -90,6 +90,7 @@ type EVM2EVMMultiOnRampStaticConfig struct { ChainSelector uint64 MaxFeeJuelsPerMsg *big.Int RmnProxy common.Address + NonceManager common.Address TokenAdminRegistry common.Address } @@ -149,8 +150,8 @@ type RateLimiterTokenBucket struct { } var EVM2EVMMultiOnRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainDynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"DestinationChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint256\"}],\"name\":\"MessageFeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"NotAFeeToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainDynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"metadataHash\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainDynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainDynamicConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeValueJuels\",\"type\":\"uint256\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeTokenWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"name\":\"PremiumMultiplierWeiPerEthUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"destChainSelector\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"name\":\"TokenTransferFeeConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainDynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPremiumMultiplierWeiPerEthUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.TokenTransferFeeConfigRemoveArgs[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"tuple[]\"}],\"name\":\"applyTokenTransferFeeConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainDynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"metadataHash\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPremiumMultiplierWeiPerEth\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFeeTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101206040523480156200001257600080fd5b506040516200736f3803806200736f83398101604081905262000035916200153c565b8233806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c08162000276565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606086018190529790950151166080909301839052600380546001600160a01b031916909417600160801b9283021760ff60a01b1916600160a01b90910217909255029091176004555085516001600160a01b0316158062000169575060208601516001600160401b0316155b8062000180575060608601516001600160a01b0316155b8062000197575060808601516001600160a01b0316155b15620001b6576040516306b7c75960e31b815260040160405180910390fd5b85516001600160a01b0390811660a05260208701516001600160401b031660c05260408701516001600160601b031660809081526060880151821660e0528701511661010052620002078562000321565b6200021284620004a6565b6200021d8262000a03565b604080516000808252602082019092526200026a9183919062000263565b60408051808201909152600080825260208201528152602001906001900390816200023b5790505b5062000acf565b5050505050506200195f565b336001600160a01b03821603620002d05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60208101516001600160a01b0316158062000347575060408101516001600160a01b0316155b1562000366576040516306b7c75960e31b815260040160405180910390fd5b8051600580546001600160a01b039283166001600160a01b03199182161790915560208084015160068054918516918416919091179055604080850151600780549186169190941617909255815160a08082018452518416815260c0516001600160401b031691810191909152608080516001600160601b03168284015260e051841660608301526101005190931692810192909252517f7d6ca86e1084c492475f59ce7b74c37ad96a7440eb9c217ff5b27c183957b9b8916200049b91849082516001600160a01b0390811682526020808501516001600160401b0316818401526040808601516001600160601b0316818501526060808701518416908501526080958601518316958401959095528351821660a0840152830151811660c083015291909201511660e08201526101000190565b60405180910390a150565b60005b8151811015620009ff576000828281518110620004ca57620004ca62001682565b602002602001015190506000838381518110620004eb57620004eb62001682565b6020026020010151600001519050806001600160401b031660001480620005225750602082015161018001516001600160401b0316155b156200054d5760405163c35aa79d60e01b81526001600160401b038216600482015260240162000084565b600060086000836001600160401b03166001600160401b0316815260200190815260200160002090506000836040015190506000604051806080016040528086602001518152602001836001600160a01b031681526020018460020160149054906101000a90046001600160401b03166001600160401b031681526020018460030154815250905080600001518360000160008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a8154816001600160401b0302191690836001600160401b031602179055506101a082015181600101600c6101000a8154816001600160401b0302191690836001600160401b031602179055506101c08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555090505082600301546000801b036200091c5760c051604080517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b360208201526001600160401b0392831691810191909152908516606082015230608082015260a00160408051601f1981840301815291905280516020909101206060820181905260038401556001600160a01b03821615620008d3576002830180546001600160a01b0319166001600160a01b0384161790555b836001600160401b03167f7a70081ee29c1fc27898089ba2a5fc35ac0106b043c82ccecd24c6fd48f6ca86846040516200090e919062001698565b60405180910390a2620009ee565b60028301546001600160a01b03838116911614620009595760405163c35aa79d60e01b81526001600160401b038516600482015260240162000084565b60208560200151610160015163ffffffff161015620009a657602085015161016001516040516312766e0160e11b81526000600482015263ffffffff909116602482015260440162000084565b836001600160401b03167f944eb884a589931130671ee4a7379fbe5fe65ed605a048ba99c454582f2460b08660200151604051620009e591906200182c565b60405180910390a25b5050505050806001019050620004a9565b5050565b60005b8151811015620009ff57600082828151811062000a275762000a2762001682565b6020026020010151600001519050600083838151811062000a4c5762000a4c62001682565b6020908102919091018101518101516001600160a01b03841660008181526009845260409081902080546001600160401b0319166001600160401b0385169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010162000a06565b60005b825181101562000d6157600083828151811062000af35762000af362001682565b6020026020010151905060008160000151905060005b82602001515181101562000d525760008360200151828151811062000b325762000b3262001682565b602002602001015160200151905060008460200151838151811062000b5b5762000b5b62001682565b60200260200101516000015190506020826080015163ffffffff16101562000bb45760808201516040516312766e0160e11b81526001600160a01b038316600482015263ffffffff909116602482015260440162000084565b6001600160401b0384166000818152600a602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c015160c08d01511515600160981b0260ff60981b19911515600160901b0260ff60901b1963ffffffff948516600160701b021664ffffffffff60701b199585166a01000000000000000000000263ffffffff60501b1961ffff90981668010000000000000000029790971665ffffffffffff60401b19988616640100000000026001600160401b0319909d1695909916949094179a909a179590951695909517929092171617949094171692909217909155519091907f16a6faa936552870f38ad6586ca4ae10b5d085667b357895aebb320becccf8d49062000d3f908690600060e08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015260c0830151151560c083015292915050565b60405180910390a3505060010162000b09565b50505080600101905062000ad2565b5060005b815181101562000e2757600082828151811062000d865762000d8662001682565b6020026020010151600001519050600083838151811062000dab5762000dab62001682565b6020908102919091018101518101516001600160401b0384166000818152600a845260408082206001600160a01b038516808452955280822080546001600160a01b03191690555192945090917ffa22e84f9c809b5b7e94f084eb45cf17a5e4703cecef8f27ed35e54b719bffcd9190a3505060010162000d65565b505050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b038111828210171562000e675762000e6762000e2c565b60405290565b6040516101e081016001600160401b038111828210171562000e675762000e6762000e2c565b604080519081016001600160401b038111828210171562000e675762000e6762000e2c565b60405160e081016001600160401b038111828210171562000e675762000e6762000e2c565b60405160a081016001600160401b038111828210171562000e675762000e6762000e2c565b604051601f8201601f191681016001600160401b038111828210171562000f2d5762000f2d62000e2c565b604052919050565b80516001600160a01b038116811462000f4d57600080fd5b919050565b80516001600160401b038116811462000f4d57600080fd5b60006060828403121562000f7d57600080fd5b62000f8762000e42565b905062000f948262000f35565b815262000fa46020830162000f35565b602082015262000fb76040830162000f35565b604082015292915050565b60006001600160401b0382111562000fde5762000fde62000e2c565b5060051b60200190565b8051801515811462000f4d57600080fd5b805161ffff8116811462000f4d57600080fd5b805163ffffffff8116811462000f4d57600080fd5b600082601f8301126200103357600080fd5b815160206200104c620010468362000fc2565b62000f02565b82815261022092830285018201928282019190878511156200106d57600080fd5b8387015b858110156200121757808903828112156200108c5760008081fd5b6200109662000e42565b620010a18362000f52565b81526101e080601f1984011215620010b95760008081fd5b620010c362000e6d565b9250620010d288850162000fe8565b83526040620010e381860162000ff9565b898501526060620010f68187016200100c565b828601526080620011098188016200100c565b8287015260a091506200111e8288016200100c565b9086015260c06200113187820162000ff9565b8287015260e09150620011468288016200100c565b908601526101006200115a87820162000ff9565b8287015261012091506200117082880162000ff9565b908601526101406200118487820162000ff9565b8287015261016091506200119a8288016200100c565b90860152610180620011ae8782016200100c565b828701526101a09150620011c482880162000f52565b908601526101c0620011d887820162000f52565b82870152620011e98488016200100c565b818701525050838984015262001203610200860162000f35565b908301525085525092840192810162001071565b5090979650505050505050565b80516001600160801b038116811462000f4d57600080fd5b6000606082840312156200124f57600080fd5b6200125962000e42565b9050620012668262000fe8565b8152620012766020830162001224565b602082015262000fb76040830162001224565b600082601f8301126200129b57600080fd5b81516020620012ae620010468362000fc2565b82815260069290921b84018101918181019086841115620012ce57600080fd5b8286015b84811015620013245760408189031215620012ed5760008081fd5b620012f762000e93565b620013028262000f35565b81526200131185830162000f52565b81860152835291830191604001620012d2565b509695505050505050565b600082601f8301126200134157600080fd5b8151602062001354620010468362000fc2565b82815260059290921b840181019181810190868411156200137457600080fd5b8286015b84811015620013245780516001600160401b03808211156200139a5760008081fd5b908801906040601f19838c038101821315620013b65760008081fd5b620013c062000e93565b620013cd89860162000f52565b81528285015184811115620013e25760008081fd5b8086019550508c603f860112620013fb57600093508384fd5b88850151935062001410620010468562000fc2565b84815260089490941b8501830193898101908e861115620014315760008081fd5b958401955b858710156200152557868f03610100811215620014535760008081fd5b6200145d62000e93565b620014688962000f35565b815260e08087840112156200147d5760008081fd5b6200148762000eb8565b9250620014968e8b016200100c565b8352620014a5888b016200100c565b8e8401526060620014b8818c0162000ff9565b898501526080620014cb818d016200100c565b8286015260a09150620014e0828d016200100c565b9085015260c0620014f38c820162000fe8565b8286015262001504838d0162000fe8565b908501525050808d019190915282526101009690960195908a019062001436565b828b01525087525050509284019250830162001378565b6000806000806000808688036101c08112156200155857600080fd5b60a08112156200156757600080fd5b506200157262000edd565b6200157d8862000f35565b81526200158d6020890162000f52565b602082015260408801516001600160601b0381168114620015ad57600080fd5b6040820152620015c06060890162000f35565b6060820152620015d36080890162000f35565b60808201529550620015e98860a0890162000f6a565b6101008801519095506001600160401b03808211156200160857600080fd5b620016168a838b0162001021565b9550620016288a6101208b016200123c565b94506101808901519150808211156200164057600080fd5b6200164e8a838b0162001289565b93506101a08901519150808211156200166657600080fd5b506200167589828a016200132f565b9150509295509295509295565b634e487b7160e01b600052603260045260246000fd5b815460ff81161515825261024082019061ffff600882901c8116602085015263ffffffff601883901c81166040860152620016e060608601828560381c1663ffffffff169052565b620016f860808601828560581c1663ffffffff169052565b6200170e60a08601838560781c1661ffff169052565b6200172660c08601828560881c1663ffffffff169052565b6200173c60e08601838560a81c1661ffff169052565b620017536101008601838560b81c1661ffff169052565b6200176a6101208601838560c81c1661ffff169052565b620017836101408601828560d81c1663ffffffff169052565b600186015463ffffffff8282161661016087015292506001600160401b03602084901c81166101808701529150620017cc6101a08601838560601c166001600160401b03169052565b620017e56101c08601828560a01c1663ffffffff169052565b5060028501546001600160a01b0381166101e08601529150620018196102008501828460a01c166001600160401b03169052565b5050600383015461022083015292915050565b8151151581526101e0810160208301516200184d602084018261ffff169052565b50604083015162001866604084018263ffffffff169052565b5060608301516200187f606084018263ffffffff169052565b50608083015162001898608084018263ffffffff169052565b5060a0830151620018af60a084018261ffff169052565b5060c0830151620018c860c084018263ffffffff169052565b5060e0830151620018df60e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501516001600160401b03908116918501919091526101a080860151909116908401526101c09384015116929091019190915290565b60805160a05160c05160e05161010051615970620019ff600039600081816102eb01528181611011015261219c0152600081816102bc015281816121740152612aae0152600081816102580152818161210f015281816130820152613847015260008181610229015281816120ea01528181612e130152612ebd0152600081816102880152818161214101528181612f7f0152612fef01526159706000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c80637437ff9f116100e3578063a69c64c01161008c578063e080bcba11610066578063e080bcba14610970578063f2fde38b14610983578063fbca3b741461099657600080fd5b8063a69c64c014610937578063c92b28321461094a578063df0aa9e91461095d57600080fd5b80638b364334116100bd5780638b364334146109005780638da5cb5b146109135780639041be3d1461092457600080fd5b80637437ff9f1461070257806379ba50971461076257806382b49eb01461076a57600080fd5b80634510d29311610145578063599f64311161011f578063599f6431146104515780636def4ce714610462578063704b6c02146106ef57600080fd5b80634510d293146103af57806348a98aa4146103c2578063546719cd146103ed57600080fd5b806320487ded1161017657806320487ded1461037157806334d560e4146103925780633a019940146103a757600080fd5b8063061877e31461019d57806306285c69146101ee578063181f5a7714610328575b600080fd5b6101d06101ab3660046142c5565b6001600160a01b031660009081526009602052604090205467ffffffffffffffff1690565b60405167ffffffffffffffff90911681526020015b60405180910390f35b61031b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040518060a001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516101e591906142e2565b6103646040518060400160405280601c81526020017f45564d3245564d4d756c74694f6e52616d7020312e362e302d6465760000000081525081565b6040516101e59190614392565b61038461037f3660046143de565b6109b6565b6040519081526020016101e5565b6103a56103a0366004614521565b610de8565b005b6103a5610dfc565b6103a56103bd366004614682565b610fc0565b6103d56103d0366004614921565b610fd6565b6040516001600160a01b0390911681526020016101e5565b6103f5611085565b6040516101e5919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6002546001600160a01b03166103d5565b6106e261047036600461495a565b604080516102608101825260006080820181815260a0830182905260c0830182905260e08301829052610100830182905261012083018290526101408301829052610160830182905261018083018290526101a083018290526101c083018290526101e0830182905261020083018290526102208301829052610240830182905282526020820181905291810182905260608101919091525067ffffffffffffffff908116600090815260086020908152604091829020825161026081018452815460ff811615156080830190815261ffff610100808404821660a086015263ffffffff63010000008504811660c08701526701000000000000008504811660e08701526b01000000000000000000000085048116918601919091526f01000000000000000000000000000000840482166101208601527101000000000000000000000000000000000084048116610140860152750100000000000000000000000000000000000000000084048216610160860152770100000000000000000000000000000000000000000000008404821661018086015279010000000000000000000000000000000000000000000000000084049091166101a08501527b0100000000000000000000000000000000000000000000000000000090920482166101c084015260018401548083166101e0850152640100000000810488166102008501526c01000000000000000000000000810488166102208501527401000000000000000000000000000000000000000090819004909216610240840152825260028301546001600160a01b0381169483019490945290920490931691810191909152600390910154606082015290565b6040516101e59190614a99565b6103a56106fd3660046142c5565b61112d565b610755604080516060810182526000808252602082018190529181019190915250604080516060810182526005546001600160a01b03908116825260065481166020830152600754169181019190915290565b6040516101e59190614ae6565b6103a56111ec565b610894610778366004614921565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091525067ffffffffffffffff82166000908152600a602090815260408083206001600160a01b0385168452825291829020825160e081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e0100000000000000000000000000008304909116608082015260ff720100000000000000000000000000000000000083048116151560a0830152730100000000000000000000000000000000000000909204909116151560c082015292915050565b6040516101e59190600060e08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015260c0830151151560c083015292915050565b6101d061090e366004614921565b6112aa565b6000546001600160a01b03166103d5565b6101d061093236600461495a565b6113a3565b6103a5610945366004614b16565b6113e7565b6103a5610958366004614bf4565b6113f8565b61038461096b366004614c38565b611460565b6103a561097e366004614ca4565b6118aa565b6103a56109913660046142c5565b6118bb565b6109a96109a436600461495a565b6118cc565b6040516101e59190614e9e565b67ffffffffffffffff82166000908152600860205260408120805460ff16610a1b576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024015b60405180910390fd5b6000610a2a6080850185614eeb565b159050610a4b57610a46610a416080860186614eeb565b611900565b610a63565b6001820154640100000000900467ffffffffffffffff165b9050610a8d85610a766020870187614eeb565b905083610a866040890189614f39565b90506119a8565b6000600981610aa260808801606089016142c5565b6001600160a01b03168152602081019190915260400160009081205467ffffffffffffffff169150819003610b1f57610ae160808601606087016142c5565b6040517fa7499d200000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610a12565b60065460009081906001600160a01b031663ffdb4b37610b4560808a0160608b016142c5565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b03909116600482015267ffffffffffffffff8b1660248201526044016040805180830381865afa158015610bb0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd49190614faf565b90925090506000808080610beb60408c018c614f39565b90501115610c2657610c1a8b610c0760808d0160608e016142c5565b87610c1560408f018f614f39565b611ab8565b91945092509050610c5d565b6001880154610c5a9074010000000000000000000000000000000000000000900463ffffffff16662386f26fc10000615008565b92505b875460009077010000000000000000000000000000000000000000000000900461ffff1615610cc957610cc68c6dffffffffffffffffffffffffffff607088901c16610cac60208f018f614eeb565b90508e8060400190610cbe9190614f39565b905086611ecb565b90505b600089600101600c9054906101000a900467ffffffffffffffff1667ffffffffffffffff168463ffffffff168b600001600f9054906101000a900461ffff1661ffff168e8060200190610d1c9190614eeb565b610d27929150615008565b8c54610d48906b010000000000000000000000900463ffffffff168d61501f565b610d52919061501f565b610d5c919061501f565b610d76906dffffffffffffffffffffffffffff8916615008565b610d809190615008565b90507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff87168282610db767ffffffffffffffff8c1689615008565b610dc1919061501f565b610dcb919061501f565b610dd59190615032565b9a50505050505050505050505b92915050565b610df0611fd1565b610df98161202d565b50565b600654604080517fcdc73d5100000000000000000000000000000000000000000000000000000000815290516000926001600160a01b03169163cdc73d5191600480830192869291908290030181865afa158015610e5e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e86919081019061506d565b6007549091506001600160a01b031660005b8251811015610fbb576000838281518110610eb557610eb56150fc565b60209081029190910101516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529091506000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610f23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f47919061512b565b90508015610fb157610f636001600160a01b03831685836121f1565b816001600160a01b0316846001600160a01b03167f508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e83604051610fa891815260200190565b60405180910390a35b5050600101610e98565b505050565b610fc8612271565b610fd282826122ce565b5050565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa15801561105a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107e9190615144565b9392505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff8082168352600160801b80830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152611128906126dc565b905090565b6000546001600160a01b0316331480159061115357506002546001600160a01b03163314155b1561118a576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c906020015b60405180910390a150565b6001546001600160a01b031633146112465760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610a12565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b67ffffffffffffffff8083166000908152600b602090815260408083206001600160a01b038616845290915281205490911680820361107e5767ffffffffffffffff84166000908152600860205260409020600201546001600160a01b0316801561139b576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015282169063856c824790602401602060405180830381865afa15801561136e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113929190615161565b92505050610de2565b509392505050565b67ffffffffffffffff8082166000908152600860205260408120600201549091610de29174010000000000000000000000000000000000000000900416600161517e565b6113ef612271565b610df98161278e565b6000546001600160a01b0316331480159061141e57506002546001600160a01b03163314155b15611455576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610df9600382612854565b67ffffffffffffffff841660009081526008602052604081208161148782888888886129fa565b905060005b816101400151518110156118405760006114a96040890189614f39565b838181106114b9576114b96150fc565b9050604002018036038101906114cf91906151a6565b905060006114e18a8360000151610fd6565b90506001600160a01b038116158061159757506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf0000000000000000000000000000000000000000000000000000000060048201526001600160a01b038216906301ffc9a790602401602060405180830381865afa158015611571573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061159591906151e0565b155b156115dc5781516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610a12565b6000816001600160a01b0316639a4575b96040518060a001604052808d80600001906116089190614eeb565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525067ffffffffffffffff8f166020808301919091526001600160a01b03808e16604080850191909152918901516060840152885116608090920191909152517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526116b391906004016151fd565b6000604051808303816000875af11580156116d2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526116fa91908101906152ca565b9050602081602001515111801561175b575067ffffffffffffffff8b166000908152600a6020908152604080832086516001600160a01b0316845282529091205490820151516e01000000000000000000000000000090910463ffffffff16105b156117a05782516040517f36f536ca0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610a12565b80516117ab906132b8565b5060408051606081019091526001600160a01b03831660808201528060a081016040516020818303038152906040528152602001826000015181526020018260200151815250604051602001611801919061535b565b6040516020818303038152906040528561016001518581518110611827576118276150fc565b602002602001018190525050505080600101905061148c565b5061184f818360030154613313565b61018082015260405167ffffffffffffffff8816907fc79f9c3e610deac14de4e704195fe17eab0983ee9916866bc04d16a00f54daa69061189190849061545d565b60405180910390a261018001519150505b949350505050565b6118b2612271565b610df98161346e565b6118c3611fd1565b610df981613a35565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f97a657c90000000000000000000000000000000000000000000000000000000061192d8385615592565b7fffffffff000000000000000000000000000000000000000000000000000000001614611986576040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61199382600481866155da565b8101906119a09190615604565b519392505050565b67ffffffffffffffff8416600090815260086020526040902080546301000000900463ffffffff16841115611a215780546040517f86933789000000000000000000000000000000000000000000000000000000008152630100000090910463ffffffff16600482015260248101859052604401610a12565b8054670100000000000000900463ffffffff16831115611a6d576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8054610100900461ffff16821115611ab1576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6000808083815b81811015611ebe576000878783818110611adb57611adb6150fc565b905060400201803603810190611af191906151a6565b905060006001600160a01b0316611b0c8c8360000151610fd6565b6001600160a01b031603611b5a5780516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610a12565b67ffffffffffffffff8b166000908152600a6020908152604080832084516001600160a01b03168452825291829020825160e081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e0100000000000000000000000000008304909116608082015260ff720100000000000000000000000000000000000083048116151560a0830152730100000000000000000000000000000000000000909204909116151560c08201819052611cea5767ffffffffffffffff8c1660009081526008602052604090208054611c8a90790100000000000000000000000000000000000000000000000000900461ffff16662386f26fc10000615008565b611c94908961501f565b8154909850611cc8907b01000000000000000000000000000000000000000000000000000000900463ffffffff1688615646565b6001820154909750611ce09063ffffffff1687615646565b9550505050611eb6565b604081015160009061ffff1615611e065760008c6001600160a01b031684600001516001600160a01b031614611da95760065484516040517f4ab35b0b0000000000000000000000000000000000000000000000000000000081526001600160a01b039182166004820152911690634ab35b0b90602401602060405180830381865afa158015611d7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611da29190615663565b9050611dac565b508a5b620186a0836040015161ffff16611dee8660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16613aeb90919063ffffffff16565b611df89190615008565b611e029190615032565b9150505b6060820151611e159088615646565b9650816080015186611e279190615646565b8251909650600090611e469063ffffffff16662386f26fc10000615008565b905080821015611e6557611e5a818a61501f565b985050505050611eb6565b6000836020015163ffffffff16662386f26fc10000611e849190615008565b905080831115611ea457611e98818b61501f565b99505050505050611eb6565b611eae838b61501f565b995050505050505b600101611abf565b5050955095509592505050565b60008063ffffffff8316611ee0608086615008565b611eec8761022061501f565b611ef6919061501f565b611f00919061501f565b67ffffffffffffffff8816600090815260086020526040812080549293509171010000000000000000000000000000000000810463ffffffff1690611f62907501000000000000000000000000000000000000000000900461ffff1685615008565b611f6c919061501f565b825490915077010000000000000000000000000000000000000000000000900461ffff16611faa6dffffffffffffffffffffffffffff8a1683615008565b611fb49190615008565b611fc490655af3107a4000615008565b9998505050505050505050565b6000546001600160a01b0316331461202b5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610a12565b565b60208101516001600160a01b03161580612052575060408101516001600160a01b0316155b15612089576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516005805473ffffffffffffffffffffffffffffffffffffffff199081166001600160a01b03938416179091556020808401516006805484169185169190911790556040808501516007805490941690851617909255815160a0810183527f0000000000000000000000000000000000000000000000000000000000000000841681527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16918101919091527f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16818301527f0000000000000000000000000000000000000000000000000000000000000000831660608201527f00000000000000000000000000000000000000000000000000000000000000009092166080830152517f7d6ca86e1084c492475f59ce7b74c37ad96a7440eb9c217ff5b27c183957b9b8916111e191849061567e565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610fbb908490613b28565b6000546001600160a01b0316331480159061229757506002546001600160a01b03163314155b1561202b576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156126105760008382815181106122ee576122ee6150fc565b6020026020010151905060008160000151905060005b82602001515181101561260257600083602001518281518110612329576123296150fc565b602002602001015160200151905060008460200151838151811061234f5761234f6150fc565b60200260200101516000015190506020826080015163ffffffff1610156123bf5760808201516040517f24ecdc020000000000000000000000000000000000000000000000000000000081526001600160a01b038316600482015263ffffffff9091166024820152604401610a12565b67ffffffffffffffff84166000818152600a602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c015160c08d01511515730100000000000000000000000000000000000000027fffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffff9115157201000000000000000000000000000000000000027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff63ffffffff9485166e01000000000000000000000000000002167fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff9585166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff61ffff9098166801000000000000000002979097167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff9886166401000000000267ffffffffffffffff19909d1695909916949094179a909a179590951695909517929092171617949094171692909217909155519091907f16a6faa936552870f38ad6586ca4ae10b5d085667b357895aebb320becccf8d4906125f0908690600060e08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015260c0830151151560c083015292915050565b60405180910390a35050600101612304565b5050508060010190506122d1565b5060005b8151811015610fbb576000828281518110612631576126316150fc565b60200260200101516000015190506000838381518110612653576126536150fc565b60209081029190910181015181015167ffffffffffffffff84166000818152600a845260408082206001600160a01b0385168084529552808220805473ffffffffffffffffffffffffffffffffffffffff191690555192945090917ffa22e84f9c809b5b7e94f084eb45cf17a5e4703cecef8f27ed35e54b719bffcd9190a35050600101612614565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261276a82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261274e919061570d565b85608001516fffffffffffffffffffffffffffffffff16613c0d565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b60005b8151811015610fd25760008282815181106127ae576127ae6150fc565b602002602001015160000151905060008383815181106127d0576127d06150fc565b6020908102919091018101518101516001600160a01b038416600081815260098452604090819020805467ffffffffffffffff191667ffffffffffffffff85169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a25050600101612791565b815460009061287090600160801b900463ffffffff164261570d565b905080156128ed57600183015483546128ab916fffffffffffffffffffffffffffffffff808216928116918591600160801b90910416613c0d565b83546fffffffffffffffffffffffffffffffff9190911673ffffffffffffffffffffffffffffffffffffffff1990911617600160801b4263ffffffff16021783555b60208201518354612913916fffffffffffffffffffffffffffffffff9081169116613c35565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff9283161717845560208301516040808501518316600160801b0291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906129ed9084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b604080516101a08101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e082018390526101008201839052610120820181905261014082018190526101608201526101808101919091526040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608086901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015612afd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b2191906151e0565b15612b64576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610a12565b6001600160a01b038216612ba4576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546001600160a01b03163314612be8576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b855460ff16612c2f576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610a12565b6000612c3e6080860186614eeb565b159050612c5a57612c55610a416080870187614eeb565b612c72565b6001870154640100000000900467ffffffffffffffff165b90506000612c836040870187614f39565b9150612ca1905087612c986020890189614eeb565b905084846119a8565b8015612e07576000805b82811015612df557612cc06040890189614f39565b82818110612cd057612cd06150fc565b90506040020160200135600003612d13576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff89166000908152600a60205260408082209190612d3b908b018b614f39565b84818110612d4b57612d4b6150fc565b612d6192602060409092020190810191506142c5565b6001600160a01b031681526020810191909152604001600020547201000000000000000000000000000000000000900460ff1615612ded57612de0612da960408a018a614f39565b83818110612db957612db96150fc565b905060400201803603810190612dcf91906151a6565b6006546001600160a01b0316613c4b565b612dea908361501f565b91505b600101612cab565b508015612e0557612e0581613d6c565b505b60006001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016612e436080890160608a016142c5565b6001600160a01b031603612e58575084612f2b565b6006546001600160a01b03166241e5be612e7860808a0160608b016142c5565b60405160e083901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039182166004820152602481018a90527f00000000000000000000000000000000000000000000000000000000000000009091166044820152606401602060405180830381865afa158015612f04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f28919061512b565b90505b612f3b60808801606089016142c5565b6001600160a01b03167f075a2720282fdf622141dae0b048ef90a21a7e57c134c76912d19d006b3b3f6f82604051612f7591815260200190565b60405180910390a27f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681111561301c576040517f6a92a483000000000000000000000000000000000000000000000000000000008152600481018290526bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610a12565b600061302889876112aa565b61303390600161517e565b67ffffffffffffffff8a81166000908152600b602090815260408083206001600160a01b038c1680855290835292819020805467ffffffffffffffff191686861617905580516101a0810182527f00000000000000000000000000000000000000000000000000000000000000009094168452908301919091529192509081016130fa6130c08b80614eeb565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506132b892505050565b6001600160a01b031681526020018b600201601481819054906101000a900467ffffffffffffffff1661312c90615720565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff1681526020018581526020016000151581526020018267ffffffffffffffff16815260200189606001602081019061319291906142c5565b6001600160a01b031681526020018881526020018980602001906131b69190614eeb565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050908252506020016131fd60408b018b614f39565b808060200260200160405190810160405280939291908181526020016000905b828210156132495761323a604083028601368190038101906151a6565b8152602001906001019061321d565b505050505081526020018467ffffffffffffffff81111561326c5761326c61442e565b60405190808252806020026020018201604052801561329f57816020015b606081526020019060019003908161328a5790505b50815260006020909101529a9950505050505050505050565b600081516020146132f757816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610a129190614392565b610de28280602001905181019061330e919061512b565b613d79565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b61010001516040516020016133a99897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b60405160208183030381529060405280519060200120856101200151805190602001208661014001516040516020016133e29190615747565b6040516020818303038152906040528051906020012087610160015160405160200161340e919061575a565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b60005b8151811015610fd257600082828151811061348e5761348e6150fc565b6020026020010151905060008383815181106134ac576134ac6150fc565b60200260200101516000015190508067ffffffffffffffff16600014806134e457506020820151610180015167ffffffffffffffff16155b15613527576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610a12565b6000600860008367ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002090506000836040015190506000604051806080016040528086602001518152602001836001600160a01b031681526020018460020160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1681526020018460030154815250905080600001518360000160008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101a082015181600101600c6101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101c08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555090505082600301546000801b0361392557604080517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b3602082015267ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692820192909252908516606082015230608082015260a00160408051601f1981840301815291905280516020909101206060820181905260038401556001600160a01b038216156138de5760028301805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384161790555b8367ffffffffffffffff167f7a70081ee29c1fc27898089ba2a5fc35ac0106b043c82ccecd24c6fd48f6ca8684604051613918919061576d565b60405180910390a2613a25565b60028301546001600160a01b0383811691161461397a576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610a12565b60208560200151610160015163ffffffff1610156139de57602085015161016001516040517f24ecdc020000000000000000000000000000000000000000000000000000000081526000600482015263ffffffff9091166024820152604401610a12565b8367ffffffffffffffff167f944eb884a589931130671ee4a7379fbe5fe65ed605a048ba99c454582f2460b08660200151604051613a1c91906158f9565b60405180910390a25b5050505050806001019050613471565b336001600160a01b03821603613a8d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610a12565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000670de0b6b3a7640000613b1e837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616615008565b61107e9190615032565b6000613b7d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613de69092919063ffffffff16565b805190915015610fbb5780806020019051810190613b9b91906151e0565b610fbb5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610a12565b6000613c2c85613c1d8486615008565b613c27908761501f565b613c35565b95945050505050565b6000818310613c44578161107e565b5090919050565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa158015613cb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cd59190615908565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116600003613d3e5783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610a12565b60208401516118a2907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff831690613aeb565b610df96003826000613df5565b60006001600160a01b03821180613d91575061040082105b15613de25760408051602081018490520160408051601f19818403018152908290527f8d666f60000000000000000000000000000000000000000000000000000000008252610a1291600401614392565b5090565b60606118a28484600085614110565b825474010000000000000000000000000000000000000000900460ff161580613e1c575081155b15613e2657505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090613e5f90600160801b900463ffffffff164261570d565b90508015613f055781831115613ea1576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154613ece90839085908490600160801b90046fffffffffffffffffffffffffffffffff16613c0d565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff16600160801b4263ffffffff160217875592505b84821015613fa2576001600160a01b038416613f57576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610a12565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b0385166044820152606401610a12565b8483101561408e57600186810154600160801b90046fffffffffffffffffffffffffffffffff16906000908290613fd9908261570d565b613fe3878a61570d565b613fed919061501f565b613ff79190615032565b90506001600160a01b038616614043576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610a12565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b0387166044820152606401610a12565b614098858461570d565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6060824710156141885760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610a12565b600080866001600160a01b031685876040516141a49190615947565b60006040518083038185875af1925050503d80600081146141e1576040519150601f19603f3d011682016040523d82523d6000602084013e6141e6565b606091505b50915091506141f787838387614202565b979650505050505050565b6060831561427157825160000361426a576001600160a01b0385163b61426a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a12565b50816118a2565b6118a283838151156142865781518083602001fd5b8060405162461bcd60e51b8152600401610a129190614392565b6001600160a01b0381168114610df957600080fd5b80356142c0816142a0565b919050565b6000602082840312156142d757600080fd5b813561107e816142a0565b60a08101610de282846001600160a01b0380825116835267ffffffffffffffff60208301511660208401526bffffffffffffffffffffffff6040830151166040840152806060830151166060840152806080830151166080840152505050565b60005b8381101561435d578181015183820152602001614345565b50506000910152565b6000815180845261437e816020860160208601614342565b601f01601f19169290920160200192915050565b60208152600061107e6020830184614366565b67ffffffffffffffff81168114610df957600080fd5b80356142c0816143a5565b600060a082840312156143d857600080fd5b50919050565b600080604083850312156143f157600080fd5b82356143fc816143a5565b9150602083013567ffffffffffffffff81111561441857600080fd5b614424858286016143c6565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156144805761448061442e565b60405290565b6040805190810167ffffffffffffffff811182821017156144805761448061442e565b60405160e0810167ffffffffffffffff811182821017156144805761448061442e565b6040516101e0810167ffffffffffffffff811182821017156144805761448061442e565b604051601f8201601f1916810167ffffffffffffffff811182821017156145195761451961442e565b604052919050565b60006060828403121561453357600080fd5b61453b61445d565b8235614546816142a0565b81526020830135614556816142a0565b60208201526040830135614569816142a0565b60408201529392505050565b600067ffffffffffffffff82111561458f5761458f61442e565b5060051b60200190565b63ffffffff81168114610df957600080fd5b80356142c081614599565b803561ffff811681146142c057600080fd5b8015158114610df957600080fd5b80356142c0816145c8565b600082601f8301126145f257600080fd5b8135602061460761460283614575565b6144f0565b82815260069290921b8401810191818101908684111561462657600080fd5b8286015b8481101561467757604081890312156146435760008081fd5b61464b614486565b8135614656816143a5565b815281850135614665816142a0565b8186015283529183019160400161462a565b509695505050505050565b6000806040838503121561469557600080fd5b67ffffffffffffffff833511156146ab57600080fd5b83601f8435850101126146bd57600080fd5b6146cd6146028435850135614575565b8335840180358083526020808401939260059290921b909101018610156146f357600080fd5b602085358601015b85358601803560051b016020018110156148eb5767ffffffffffffffff8135111561472557600080fd5b6040601f1982358835890101890301121561473f57600080fd5b614747614486565b61475a6020833589358a010101356143a5565b863587018235016020810135825267ffffffffffffffff604090910135111561478257600080fd5b86358701823501604081013501603f8101891361479e57600080fd5b6147ae6146026020830135614575565b602082810135808352908201919060081b83016040018b10156147d057600080fd5b604083015b6040602085013560081b8501018110156148d257610100818d0312156147fa57600080fd5b614802614486565b61480c82356142a0565b8135815260e0601f19838f0301121561482457600080fd5b61482c6144a9565b6148396020840135614599565b6020830135815261484d6040840135614599565b60408301356020820152614863606084016145b6565b60408201526148756080840135614599565b6080830135606082015261488c60a0840135614599565b60a083013560808201526148a260c084016145d6565b60a08201526148b360e084016145d6565b60c08201526020828101919091529084529290920191610100016147d5565b50602084810191909152928652505092830192016146fb565b5092505067ffffffffffffffff6020840135111561490857600080fd5b61491884602085013585016145e1565b90509250929050565b6000806040838503121561493457600080fd5b823561493f816143a5565b9150602083013561494f816142a0565b809150509250929050565b60006020828403121561496c57600080fd5b813561107e816143a5565b8051151582526020810151614992602084018261ffff169052565b5060408101516149aa604084018263ffffffff169052565b5060608101516149c2606084018263ffffffff169052565b5060808101516149da608084018263ffffffff169052565b5060a08101516149f060a084018261ffff169052565b5060c0810151614a0860c084018263ffffffff169052565b5060e0810151614a1e60e084018261ffff169052565b506101008181015161ffff9081169184019190915261012080830151909116908301526101408082015163ffffffff90811691840191909152610160808301518216908401526101808083015167ffffffffffffffff908116918501919091526101a080840151909116908401526101c09182015116910152565b600061024082019050614aad828451614977565b60208301516001600160a01b03166101e0830152604083015167ffffffffffffffff166102008301526060909201516102209091015290565b60608101610de2828480516001600160a01b03908116835260208083015182169084015260409182015116910152565b60006020808385031215614b2957600080fd5b823567ffffffffffffffff811115614b4057600080fd5b8301601f81018513614b5157600080fd5b8035614b5f61460282614575565b81815260069190911b82018301908381019087831115614b7e57600080fd5b928401925b828410156141f75760408489031215614b9c5760008081fd5b614ba4614486565b8435614baf816142a0565b815284860135614bbe816143a5565b8187015282526040939093019290840190614b83565b80356fffffffffffffffffffffffffffffffff811681146142c057600080fd5b600060608284031215614c0657600080fd5b614c0e61445d565b8235614c19816145c8565b8152614c2760208401614bd4565b602082015261456960408401614bd4565b60008060008060808587031215614c4e57600080fd5b8435614c59816143a5565b9350602085013567ffffffffffffffff811115614c7557600080fd5b614c81878288016143c6565b935050604085013591506060850135614c99816142a0565b939692955090935050565b60006020808385031215614cb757600080fd5b823567ffffffffffffffff811115614cce57600080fd5b8301601f81018513614cdf57600080fd5b8035614ced61460282614575565b8181526102209182028301840191848201919088841115614d0d57600080fd5b938501935b83851015614e925784890381811215614d2b5760008081fd5b614d3361445d565b8635614d3e816143a5565b81526101e0601f198301811315614d555760008081fd5b614d5d6144cc565b9250614d6a8989016145d6565b83526040614d79818a016145b6565b8a8501526060614d8a818b016145ab565b828601526080614d9b818c016145ab565b8287015260a09150614dae828c016145ab565b9086015260c0614dbf8b82016145b6565b8287015260e09150614dd2828c016145ab565b90860152610100614de48b82016145b6565b828701526101209150614df8828c016145b6565b90860152610140614e0a8b82016145b6565b828701526101609150614e1e828c016145ab565b90860152610180614e308b82016145ab565b828701526101a09150614e44828c016143bb565b908601526101c0614e568b82016143bb565b82870152614e65848c016145ab565b818701525050838a840152614e7d6102008a016142b5565b90830152508452509384019391850191614d12565b50979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614edf5783516001600160a01b031683529284019291840191600101614eba565b50909695505050505050565b6000808335601e19843603018112614f0257600080fd5b83018035915067ffffffffffffffff821115614f1d57600080fd5b602001915036819003821315614f3257600080fd5b9250929050565b6000808335601e19843603018112614f5057600080fd5b83018035915067ffffffffffffffff821115614f6b57600080fd5b6020019150600681901b3603821315614f3257600080fd5b80517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146142c057600080fd5b60008060408385031215614fc257600080fd5b614fcb83614f83565b915061491860208401614f83565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610de257610de2614fd9565b80820180821115610de257610de2614fd9565b600082615068577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602080838503121561508057600080fd5b825167ffffffffffffffff81111561509757600080fd5b8301601f810185136150a857600080fd5b80516150b661460282614575565b81815260059190911b820183019083810190878311156150d557600080fd5b928401925b828410156141f75783516150ed816142a0565b825292840192908401906150da565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561513d57600080fd5b5051919050565b60006020828403121561515657600080fd5b815161107e816142a0565b60006020828403121561517357600080fd5b815161107e816143a5565b67ffffffffffffffff81811683821601908082111561519f5761519f614fd9565b5092915050565b6000604082840312156151b857600080fd5b6151c0614486565b82356151cb816142a0565b81526020928301359281019290925250919050565b6000602082840312156151f257600080fd5b815161107e816145c8565b602081526000825160a0602084015261521960c0840182614366565b905067ffffffffffffffff602085015116604084015260408401516001600160a01b038082166060860152606086015160808601528060808701511660a086015250508091505092915050565b600082601f83011261527757600080fd5b815167ffffffffffffffff8111156152915761529161442e565b6152a46020601f19601f840116016144f0565b8181528460208386010111156152b957600080fd5b6118a2826020830160208701614342565b6000602082840312156152dc57600080fd5b815167ffffffffffffffff808211156152f457600080fd5b908301906040828603121561530857600080fd5b615310614486565b82518281111561531f57600080fd5b61532b87828601615266565b82525060208301518281111561534057600080fd5b61534c87828601615266565b60208301525095945050505050565b6020815260008251606060208401526153776080840182614366565b90506020840151601f19808584030160408601526153958383614366565b9250604086015191508085840301606086015250613c2c8282614366565b60008151808452602080850194506020840160005b838110156153f857815180516001600160a01b0316885283015183880152604090960195908201906001016153c8565b509495945050505050565b60008282518085526020808601955060208260051b8401016020860160005b8481101561545057601f1986840301895261543e838351614366565b98840198925090830190600101615422565b5090979650505050505050565b6020815261547860208201835167ffffffffffffffff169052565b6000602083015161549460408401826001600160a01b03169052565b5060408301516001600160a01b038116606084015250606083015167ffffffffffffffff8116608084015250608083015160a083015260a08301516154dd60c084018215159052565b5060c083015167ffffffffffffffff811660e08401525060e0830151610100615510818501836001600160a01b03169052565b840151610120848101919091528401516101a06101408086018290529192509061553e6101c0860184614366565b9250808601519050601f1961016081878603018188015261555f85846153b3565b94508088015192505061018081878603018188015261557e8584615403565b970151959092019490945250929392505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081358181169160048510156155d25780818660040360031b1b83161692505b505092915050565b600080858511156155ea57600080fd5b838611156155f757600080fd5b5050820193919092039150565b60006020828403121561561657600080fd5b6040516020810181811067ffffffffffffffff821117156156395761563961442e565b6040529135825250919050565b63ffffffff81811683821601908082111561519f5761519f614fd9565b60006020828403121561567557600080fd5b61107e82614f83565b61010081016156df82856001600160a01b0380825116835267ffffffffffffffff60208301511660208401526bffffffffffffffffffffffff6040830151166040840152806060830151166060840152806080830151166080840152505050565b82516001600160a01b0390811660a08401526020840151811660c084015260408401511660e083015261107e565b81810381811115610de257610de2614fd9565b600067ffffffffffffffff80831681810361573d5761573d614fd9565b6001019392505050565b60208152600061107e60208301846153b3565b60208152600061107e6020830184615403565b815460ff81161515825261024082019061ffff600882901c8116602085015263ffffffff601883901c811660408601526157b460608601828560381c1663ffffffff169052565b6157cb60808601828560581c1663ffffffff169052565b6157e060a08601838560781c1661ffff169052565b6157f760c08601828560881c1663ffffffff169052565b61580c60e08601838560a81c1661ffff169052565b6158226101008601838560b81c1661ffff169052565b6158386101208601838560c81c1661ffff169052565b6158506101408601828560d81c1663ffffffff169052565b600186015463ffffffff82821616610160870152925067ffffffffffffffff602084901c8116610180870152915061589a6101a08601838560601c1667ffffffffffffffff169052565b6158b26101c08601828560a01c1663ffffffff169052565b5060028501546001600160a01b0381166101e086015291506158e66102008501828460a01c1667ffffffffffffffff169052565b5050600383015461022083015292915050565b6101e08101610de28284614977565b60006040828403121561591a57600080fd5b615922614486565b61592b83614f83565b8152602083015161593b81614599565b60208201529392505050565b60008251615959818460208701614342565b919091019291505056fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainDynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"DestinationChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint256\"}],\"name\":\"MessageFeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"NotAFeeToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainDynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"metadataHash\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainDynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainDynamicConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeValueJuels\",\"type\":\"uint256\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeTokenWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"name\":\"PremiumMultiplierWeiPerEthUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"destChainSelector\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"name\":\"TokenTransferFeeConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainDynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPremiumMultiplierWeiPerEthUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.TokenTransferFeeConfigRemoveArgs[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"tuple[]\"}],\"name\":\"applyTokenTransferFeeConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainDynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"metadataHash\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPremiumMultiplierWeiPerEth\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFeeTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101406040523480156200001257600080fd5b50604051620073be380380620073be833981016040819052620000359162001574565b8233806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c08162000298565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606086018190529790950151166080909301839052600380546001600160a01b031916909417600160801b9283021760ff60a01b1916600160a01b90910217909255029091176004555085516001600160a01b0316158062000169575060208601516001600160401b0316155b8062000180575060608601516001600160a01b0316155b8062000197575060808601516001600160a01b0316155b80620001ae575060a08601516001600160a01b0316155b15620001cd576040516306b7c75960e31b815260040160405180910390fd5b85516001600160a01b0390811660a090815260208801516001600160401b031660c05260408801516001600160601b031660809081526060890151831660e0528801518216610100528701511661012052620002298562000343565b6200023484620004de565b6200023f8262000a3b565b604080516000808252602082019092526200028c9183919062000285565b60408051808201909152600080825260208201528152602001906001900390816200025d5790505b5062000b07565b505050505050620019aa565b336001600160a01b03821603620002f25760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60208101516001600160a01b0316158062000369575060408101516001600160a01b0316155b1562000388576040516306b7c75960e31b815260040160405180910390fd5b8051600580546001600160a01b039283166001600160a01b03199182161790915560208084015160068054918516918416919091179055604080850151600780549186169190941617909255815160c0808201845260a080518616835290516001600160401b031692820192909252608080516001600160601b03168285015260e05185166060830152610100518516908201526101205190931690830152517f881586dd9eb05fe5f83d393ba8251d24a928b3b463abcad1b822340ba0588cdc91620004d391849082516001600160a01b0390811682526020808501516001600160401b0316818401526040808601516001600160601b03168185015260608087015184169085015260808087015184169085015260a0958601518316958401959095528351821660c0840152830151811660e08301529190920151166101008201526101200190565b60405180910390a150565b60005b815181101562000a37576000828281518110620005025762000502620016cd565b602002602001015190506000838381518110620005235762000523620016cd565b6020026020010151600001519050806001600160401b0316600014806200055a5750602082015161018001516001600160401b0316155b15620005855760405163c35aa79d60e01b81526001600160401b038216600482015260240162000084565b600060086000836001600160401b03166001600160401b0316815260200190815260200160002090506000836040015190506000604051806080016040528086602001518152602001836001600160a01b031681526020018460020160149054906101000a90046001600160401b03166001600160401b031681526020018460030154815250905080600001518360000160008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a8154816001600160401b0302191690836001600160401b031602179055506101a082015181600101600c6101000a8154816001600160401b0302191690836001600160401b031602179055506101c08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555090505082600301546000801b03620009545760c051604080517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b360208201526001600160401b0392831691810191909152908516606082015230608082015260a00160408051601f1981840301815291905280516020909101206060820181905260038401556001600160a01b038216156200090b576002830180546001600160a01b0319166001600160a01b0384161790555b836001600160401b03167f7a70081ee29c1fc27898089ba2a5fc35ac0106b043c82ccecd24c6fd48f6ca8684604051620009469190620016e3565b60405180910390a262000a26565b60028301546001600160a01b03838116911614620009915760405163c35aa79d60e01b81526001600160401b038516600482015260240162000084565b60208560200151610160015163ffffffff161015620009de57602085015161016001516040516312766e0160e11b81526000600482015263ffffffff909116602482015260440162000084565b836001600160401b03167f944eb884a589931130671ee4a7379fbe5fe65ed605a048ba99c454582f2460b0866020015160405162000a1d919062001877565b60405180910390a25b5050505050806001019050620004e1565b5050565b60005b815181101562000a3757600082828151811062000a5f5762000a5f620016cd565b6020026020010151600001519050600083838151811062000a845762000a84620016cd565b6020908102919091018101518101516001600160a01b03841660008181526009845260409081902080546001600160401b0319166001600160401b0385169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010162000a3e565b60005b825181101562000d9957600083828151811062000b2b5762000b2b620016cd565b6020026020010151905060008160000151905060005b82602001515181101562000d8a5760008360200151828151811062000b6a5762000b6a620016cd565b602002602001015160200151905060008460200151838151811062000b935762000b93620016cd565b60200260200101516000015190506020826080015163ffffffff16101562000bec5760808201516040516312766e0160e11b81526001600160a01b038316600482015263ffffffff909116602482015260440162000084565b6001600160401b0384166000818152600a602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c015160c08d01511515600160981b0260ff60981b19911515600160901b0260ff60901b1963ffffffff948516600160701b021664ffffffffff60701b199585166a01000000000000000000000263ffffffff60501b1961ffff90981668010000000000000000029790971665ffffffffffff60401b19988616640100000000026001600160401b0319909d1695909916949094179a909a179590951695909517929092171617949094171692909217909155519091907f16a6faa936552870f38ad6586ca4ae10b5d085667b357895aebb320becccf8d49062000d77908690600060e08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015260c0830151151560c083015292915050565b60405180910390a3505060010162000b41565b50505080600101905062000b0a565b5060005b815181101562000e5f57600082828151811062000dbe5762000dbe620016cd565b6020026020010151600001519050600083838151811062000de35762000de3620016cd565b6020908102919091018101518101516001600160401b0384166000818152600a845260408082206001600160a01b038516808452955280822080546001600160a01b03191690555192945090917ffa22e84f9c809b5b7e94f084eb45cf17a5e4703cecef8f27ed35e54b719bffcd9190a3505060010162000d9d565b505050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b038111828210171562000e9f5762000e9f62000e64565b60405290565b6040516101e081016001600160401b038111828210171562000e9f5762000e9f62000e64565b604080519081016001600160401b038111828210171562000e9f5762000e9f62000e64565b60405160e081016001600160401b038111828210171562000e9f5762000e9f62000e64565b60405160c081016001600160401b038111828210171562000e9f5762000e9f62000e64565b604051601f8201601f191681016001600160401b038111828210171562000f655762000f6562000e64565b604052919050565b80516001600160a01b038116811462000f8557600080fd5b919050565b80516001600160401b038116811462000f8557600080fd5b60006060828403121562000fb557600080fd5b62000fbf62000e7a565b905062000fcc8262000f6d565b815262000fdc6020830162000f6d565b602082015262000fef6040830162000f6d565b604082015292915050565b60006001600160401b0382111562001016576200101662000e64565b5060051b60200190565b8051801515811462000f8557600080fd5b805161ffff8116811462000f8557600080fd5b805163ffffffff8116811462000f8557600080fd5b600082601f8301126200106b57600080fd5b81516020620010846200107e8362000ffa565b62000f3a565b8281526102209283028501820192828201919087851115620010a557600080fd5b8387015b858110156200124f5780890382811215620010c45760008081fd5b620010ce62000e7a565b620010d98362000f8a565b81526101e080601f1984011215620010f15760008081fd5b620010fb62000ea5565b92506200110a88850162001020565b835260406200111b81860162001031565b8985015260606200112e81870162001044565b8286015260806200114181880162001044565b8287015260a091506200115682880162001044565b9086015260c06200116987820162001031565b8287015260e091506200117e82880162001044565b908601526101006200119287820162001031565b828701526101209150620011a882880162001031565b90860152610140620011bc87820162001031565b828701526101609150620011d282880162001044565b90860152610180620011e687820162001044565b828701526101a09150620011fc82880162000f8a565b908601526101c06200121087820162000f8a565b828701526200122184880162001044565b81870152505083898401526200123b610200860162000f6d565b9083015250855250928401928101620010a9565b5090979650505050505050565b80516001600160801b038116811462000f8557600080fd5b6000606082840312156200128757600080fd5b6200129162000e7a565b90506200129e8262001020565b8152620012ae602083016200125c565b602082015262000fef604083016200125c565b600082601f830112620012d357600080fd5b81516020620012e66200107e8362000ffa565b82815260069290921b840181019181810190868411156200130657600080fd5b8286015b848110156200135c5760408189031215620013255760008081fd5b6200132f62000ecb565b6200133a8262000f6d565b81526200134985830162000f8a565b818601528352918301916040016200130a565b509695505050505050565b600082601f8301126200137957600080fd5b815160206200138c6200107e8362000ffa565b82815260059290921b84018101918181019086841115620013ac57600080fd5b8286015b848110156200135c5780516001600160401b0380821115620013d25760008081fd5b908801906040601f19838c038101821315620013ee5760008081fd5b620013f862000ecb565b6200140589860162000f8a565b815282850151848111156200141a5760008081fd5b8086019550508c603f8601126200143357600093508384fd5b888501519350620014486200107e8562000ffa565b84815260089490941b8501830193898101908e861115620014695760008081fd5b958401955b858710156200155d57868f036101008112156200148b5760008081fd5b6200149562000ecb565b620014a08962000f6d565b815260e0808784011215620014b55760008081fd5b620014bf62000ef0565b9250620014ce8e8b0162001044565b8352620014dd888b0162001044565b8e8401526060620014f0818c0162001031565b89850152608062001503818d0162001044565b8286015260a0915062001518828d0162001044565b9085015260c06200152b8c820162001020565b828601526200153c838d0162001020565b908501525050808d019190915282526101009690960195908a01906200146e565b828b015250875250505092840192508301620013b0565b6000806000806000808688036101e08112156200159057600080fd5b60c08112156200159f57600080fd5b50620015aa62000f15565b620015b58862000f6d565b8152620015c56020890162000f8a565b602082015260408801516001600160601b0381168114620015e557600080fd5b6040820152620015f86060890162000f6d565b60608201526200160b6080890162000f6d565b60808201526200161e60a0890162000f6d565b60a08201529550620016348860c0890162000fa2565b6101208801519095506001600160401b03808211156200165357600080fd5b620016618a838b0162001059565b9550620016738a6101408b0162001274565b94506101a08901519150808211156200168b57600080fd5b620016998a838b01620012c1565b93506101c0890151915080821115620016b157600080fd5b50620016c089828a0162001367565b9150509295509295509295565b634e487b7160e01b600052603260045260246000fd5b815460ff81161515825261024082019061ffff600882901c8116602085015263ffffffff601883901c811660408601526200172b60608601828560381c1663ffffffff169052565b6200174360808601828560581c1663ffffffff169052565b6200175960a08601838560781c1661ffff169052565b6200177160c08601828560881c1663ffffffff169052565b6200178760e08601838560a81c1661ffff169052565b6200179e6101008601838560b81c1661ffff169052565b620017b56101208601838560c81c1661ffff169052565b620017ce6101408601828560d81c1663ffffffff169052565b600186015463ffffffff8282161661016087015292506001600160401b03602084901c81166101808701529150620018176101a08601838560601c166001600160401b03169052565b620018306101c08601828560a01c1663ffffffff169052565b5060028501546001600160a01b0381166101e08601529150620018646102008501828460a01c166001600160401b03169052565b5050600383015461022083015292915050565b8151151581526101e08101602083015162001898602084018261ffff169052565b506040830151620018b1604084018263ffffffff169052565b506060830151620018ca606084018263ffffffff169052565b506080830151620018e3608084018263ffffffff169052565b5060a0830151620018fa60a084018261ffff169052565b5060c08301516200191360c084018263ffffffff169052565b5060e08301516200192a60e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501516001600160401b03908116918501919091526101a080860151909116908401526101c09384015116929091019190915290565b60805160a05160c05160e051610100516101205161595b62001a63600039600081816103160152818161102901526120e30152600081816102e7015281816120bb01526130990152600081816102b8015281816120930152612a230152600081816102540152818161202e01528181612fa701526138190152600081816102250152818161200901528181612d880152612e320152600081816102840152818161206001528181612ef40152612f64015261595b6000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c8063704b6c02116100e3578063a69c64c01161008c578063e080bcba11610066578063e080bcba14610988578063f2fde38b1461099b578063fbca3b74146109ae57600080fd5b8063a69c64c01461094f578063c92b283214610962578063df0aa9e91461097557600080fd5b806382b49eb0116100bd57806382b49eb0146107955780638da5cb5b1461092b5780639041be3d1461093c57600080fd5b8063704b6c021461071a5780637437ff9f1461072d57806379ba50971461078d57600080fd5b80633a01994011610145578063546719cd1161011f578063546719cd14610418578063599f64311461047c5780636def4ce71461048d57600080fd5b80633a019940146103d25780634510d293146103da57806348a98aa4146103ed57600080fd5b8063181f5a7711610176578063181f5a771461035357806320487ded1461039c57806334d560e4146103bd57600080fd5b8063061877e31461019257806306285c69146101e3575b600080fd5b6101c56101a0366004614297565b6001600160a01b031660009081526009602052604090205467ffffffffffffffff1690565b60405167ffffffffffffffff90911681526020015b60405180910390f35b6103466040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091526040518060c001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516101da91906142b4565b61038f6040518060400160405280601c81526020017f45564d3245564d4d756c74694f6e52616d7020312e362e302d6465760000000081525081565b6040516101da9190614370565b6103af6103aa3660046143bc565b6109ce565b6040519081526020016101da565b6103d06103cb3660046144ff565b610e00565b005b6103d0610e14565b6103d06103e8366004614660565b610fd8565b6104006103fb3660046148ff565b610fee565b6040516001600160a01b0390911681526020016101da565b61042061109d565b6040516101da919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6002546001600160a01b0316610400565b61070d61049b366004614938565b604080516102608101825260006080820181815260a0830182905260c0830182905260e08301829052610100830182905261012083018290526101408301829052610160830182905261018083018290526101a083018290526101c083018290526101e0830182905261020083018290526102208301829052610240830182905282526020820181905291810182905260608101919091525067ffffffffffffffff908116600090815260086020908152604091829020825161026081018452815460ff811615156080830190815261ffff610100808404821660a086015263ffffffff63010000008504811660c08701526701000000000000008504811660e08701526b01000000000000000000000085048116918601919091526f01000000000000000000000000000000840482166101208601527101000000000000000000000000000000000084048116610140860152750100000000000000000000000000000000000000000084048216610160860152770100000000000000000000000000000000000000000000008404821661018086015279010000000000000000000000000000000000000000000000000084049091166101a08501527b0100000000000000000000000000000000000000000000000000000090920482166101c084015260018401548083166101e0850152640100000000810488166102008501526c01000000000000000000000000810488166102208501527401000000000000000000000000000000000000000090819004909216610240840152825260028301546001600160a01b0381169483019490945290920490931691810191909152600390910154606082015290565b6040516101da9190614a77565b6103d0610728366004614297565b611145565b610780604080516060810182526000808252602082018190529181019190915250604080516060810182526005546001600160a01b03908116825260065481166020830152600754169181019190915290565b6040516101da9190614ac4565b6103d0611204565b6108bf6107a33660046148ff565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091525067ffffffffffffffff82166000908152600a602090815260408083206001600160a01b0385168452825291829020825160e081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e0100000000000000000000000000008304909116608082015260ff720100000000000000000000000000000000000083048116151560a0830152730100000000000000000000000000000000000000909204909116151560c082015292915050565b6040516101da9190600060e08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015260c0830151151560c083015292915050565b6000546001600160a01b0316610400565b6101c561094a366004614938565b6112c2565b6103d061095d366004614af4565b611306565b6103d0610970366004614bd2565b611317565b6103af610983366004614c16565b61137f565b6103d0610996366004614c82565b6117c9565b6103d06109a9366004614297565b6117da565b6109c16109bc366004614938565b6117eb565b6040516101da9190614e7c565b67ffffffffffffffff82166000908152600860205260408120805460ff16610a33576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024015b60405180910390fd5b6000610a426080850185614ec9565b159050610a6357610a5e610a596080860186614ec9565b61181f565b610a7b565b6001820154640100000000900467ffffffffffffffff165b9050610aa585610a8e6020870187614ec9565b905083610a9e6040890189614f17565b90506118c7565b6000600981610aba6080880160608901614297565b6001600160a01b03168152602081019190915260400160009081205467ffffffffffffffff169150819003610b3757610af96080860160608701614297565b6040517fa7499d200000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610a2a565b60065460009081906001600160a01b031663ffdb4b37610b5d60808a0160608b01614297565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b03909116600482015267ffffffffffffffff8b1660248201526044016040805180830381865afa158015610bc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bec9190614f8d565b90925090506000808080610c0360408c018c614f17565b90501115610c3e57610c328b610c1f60808d0160608e01614297565b87610c2d60408f018f614f17565b6119d7565b91945092509050610c75565b6001880154610c729074010000000000000000000000000000000000000000900463ffffffff16662386f26fc10000614fe6565b92505b875460009077010000000000000000000000000000000000000000000000900461ffff1615610ce157610cde8c6dffffffffffffffffffffffffffff607088901c16610cc460208f018f614ec9565b90508e8060400190610cd69190614f17565b905086611dea565b90505b600089600101600c9054906101000a900467ffffffffffffffff1667ffffffffffffffff168463ffffffff168b600001600f9054906101000a900461ffff1661ffff168e8060200190610d349190614ec9565b610d3f929150614fe6565b8c54610d60906b010000000000000000000000900463ffffffff168d614ffd565b610d6a9190614ffd565b610d749190614ffd565b610d8e906dffffffffffffffffffffffffffff8916614fe6565b610d989190614fe6565b90507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff87168282610dcf67ffffffffffffffff8c1689614fe6565b610dd99190614ffd565b610de39190614ffd565b610ded9190615010565b9a50505050505050505050505b92915050565b610e08611ef0565b610e1181611f4c565b50565b600654604080517fcdc73d5100000000000000000000000000000000000000000000000000000000815290516000926001600160a01b03169163cdc73d5191600480830192869291908290030181865afa158015610e76573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e9e919081019061504b565b6007549091506001600160a01b031660005b8251811015610fd3576000838281518110610ecd57610ecd6150da565b60209081029190910101516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529091506000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610f3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5f9190615109565b90508015610fc957610f7b6001600160a01b0383168583612138565b816001600160a01b0316846001600160a01b03167f508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e83604051610fc091815260200190565b60405180910390a35b5050600101610eb0565b505050565b610fe06121b8565b610fea8282612215565b5050565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa158015611072573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110969190615122565b9392505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff8082168352600160801b80830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff1615159383019390935260045480841660608401520490911660808201526111409061263a565b905090565b6000546001600160a01b0316331480159061116b57506002546001600160a01b03163314155b156111a2576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c906020015b60405180910390a150565b6001546001600160a01b0316331461125e5760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610a2a565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b67ffffffffffffffff8082166000908152600860205260408120600201549091610dfa9174010000000000000000000000000000000000000000900416600161513f565b61130e6121b8565b610e11816126ec565b6000546001600160a01b0316331480159061133d57506002546001600160a01b03163314155b15611374576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e116003826127c9565b67ffffffffffffffff84166000908152600860205260408120816113a6828888888861296f565b905060005b8161014001515181101561175f5760006113c86040890189614f17565b838181106113d8576113d86150da565b9050604002018036038101906113ee9190615167565b905060006114008a8360000151610fee565b90506001600160a01b03811615806114b657506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf0000000000000000000000000000000000000000000000000000000060048201526001600160a01b038216906301ffc9a790602401602060405180830381865afa158015611490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114b491906151a1565b155b156114fb5781516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610a2a565b6000816001600160a01b0316639a4575b96040518060a001604052808d80600001906115279190614ec9565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525067ffffffffffffffff8f166020808301919091526001600160a01b03808e16604080850191909152918901516060840152885116608090920191909152517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526115d291906004016151be565b6000604051808303816000875af11580156115f1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611619919081019061528b565b9050602081602001515111801561167a575067ffffffffffffffff8b166000908152600a6020908152604080832086516001600160a01b0316845282529091205490820151516e01000000000000000000000000000090910463ffffffff16105b156116bf5782516040517f36f536ca0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610a2a565b80516116ca9061328a565b5060408051606081019091526001600160a01b03831660808201528060a081016040516020818303038152906040528152602001826000015181526020018260200151815250604051602001611720919061531c565b6040516020818303038152906040528561016001518581518110611746576117466150da565b60200260200101819052505050508060010190506113ab565b5061176e8183600301546132e5565b61018082015260405167ffffffffffffffff8816907fc79f9c3e610deac14de4e704195fe17eab0983ee9916866bc04d16a00f54daa6906117b090849061541e565b60405180910390a261018001519150505b949350505050565b6117d16121b8565b610e1181613440565b6117e2611ef0565b610e1181613a07565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f97a657c90000000000000000000000000000000000000000000000000000000061184c8385615553565b7fffffffff0000000000000000000000000000000000000000000000000000000016146118a5576040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118b2826004818661559b565b8101906118bf91906155c5565b519392505050565b67ffffffffffffffff8416600090815260086020526040902080546301000000900463ffffffff168411156119405780546040517f86933789000000000000000000000000000000000000000000000000000000008152630100000090910463ffffffff16600482015260248101859052604401610a2a565b8054670100000000000000900463ffffffff1683111561198c576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8054610100900461ffff168211156119d0576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6000808083815b81811015611ddd5760008787838181106119fa576119fa6150da565b905060400201803603810190611a109190615167565b905060006001600160a01b0316611a2b8c8360000151610fee565b6001600160a01b031603611a795780516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610a2a565b67ffffffffffffffff8b166000908152600a6020908152604080832084516001600160a01b03168452825291829020825160e081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e0100000000000000000000000000008304909116608082015260ff720100000000000000000000000000000000000083048116151560a0830152730100000000000000000000000000000000000000909204909116151560c08201819052611c095767ffffffffffffffff8c1660009081526008602052604090208054611ba990790100000000000000000000000000000000000000000000000000900461ffff16662386f26fc10000614fe6565b611bb39089614ffd565b8154909850611be7907b01000000000000000000000000000000000000000000000000000000900463ffffffff1688615607565b6001820154909750611bff9063ffffffff1687615607565b9550505050611dd5565b604081015160009061ffff1615611d255760008c6001600160a01b031684600001516001600160a01b031614611cc85760065484516040517f4ab35b0b0000000000000000000000000000000000000000000000000000000081526001600160a01b039182166004820152911690634ab35b0b90602401602060405180830381865afa158015611c9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cc19190615624565b9050611ccb565b508a5b620186a0836040015161ffff16611d0d8660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16613abd90919063ffffffff16565b611d179190614fe6565b611d219190615010565b9150505b6060820151611d349088615607565b9650816080015186611d469190615607565b8251909650600090611d659063ffffffff16662386f26fc10000614fe6565b905080821015611d8457611d79818a614ffd565b985050505050611dd5565b6000836020015163ffffffff16662386f26fc10000611da39190614fe6565b905080831115611dc357611db7818b614ffd565b99505050505050611dd5565b611dcd838b614ffd565b995050505050505b6001016119de565b5050955095509592505050565b60008063ffffffff8316611dff608086614fe6565b611e0b87610220614ffd565b611e159190614ffd565b611e1f9190614ffd565b67ffffffffffffffff8816600090815260086020526040812080549293509171010000000000000000000000000000000000810463ffffffff1690611e81907501000000000000000000000000000000000000000000900461ffff1685614fe6565b611e8b9190614ffd565b825490915077010000000000000000000000000000000000000000000000900461ffff16611ec96dffffffffffffffffffffffffffff8a1683614fe6565b611ed39190614fe6565b611ee390655af3107a4000614fe6565b9998505050505050505050565b6000546001600160a01b03163314611f4a5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610a2a565b565b60208101516001600160a01b03161580611f71575060408101516001600160a01b0316155b15611fa8576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516005805473ffffffffffffffffffffffffffffffffffffffff199081166001600160a01b03938416179091556020808401516006805484169185169190911790556040808501516007805490941690851617909255815160c0810183527f0000000000000000000000000000000000000000000000000000000000000000841681527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16918101919091527f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16818301527f0000000000000000000000000000000000000000000000000000000000000000831660608201527f0000000000000000000000000000000000000000000000000000000000000000831660808201527f000000000000000000000000000000000000000000000000000000000000000090921660a0830152517f881586dd9eb05fe5f83d393ba8251d24a928b3b463abcad1b822340ba0588cdc916111f991849061563f565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610fd3908490613afa565b6000546001600160a01b031633148015906121de57506002546001600160a01b03163314155b15611f4a576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561256e576000838281518110612235576122356150da565b6020026020010151905060008160000151905060005b82602001515181101561256057600083602001518281518110612270576122706150da565b6020026020010151602001519050600084602001518381518110612296576122966150da565b60200260200101516000015190506020826080015163ffffffff1610156123065760808201516040517f24ecdc020000000000000000000000000000000000000000000000000000000081526001600160a01b038316600482015263ffffffff9091166024820152604401610a2a565b67ffffffffffffffff84166000818152600a602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c015160c08d01511515730100000000000000000000000000000000000000027fffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffff9115157201000000000000000000000000000000000000027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff63ffffffff9485166e01000000000000000000000000000002167fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff9585166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff61ffff9098166801000000000000000002979097167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff988616640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909d1695909916949094179a909a179590951695909517929092171617949094171692909217909155519091907f16a6faa936552870f38ad6586ca4ae10b5d085667b357895aebb320becccf8d49061254e908690600060e08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015260c0830151151560c083015292915050565b60405180910390a3505060010161224b565b505050806001019050612218565b5060005b8151811015610fd357600082828151811061258f5761258f6150da565b602002602001015160000151905060008383815181106125b1576125b16150da565b60209081029190910181015181015167ffffffffffffffff84166000818152600a845260408082206001600160a01b0385168084529552808220805473ffffffffffffffffffffffffffffffffffffffff191690555192945090917ffa22e84f9c809b5b7e94f084eb45cf17a5e4703cecef8f27ed35e54b719bffcd9190a35050600101612572565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526126c882606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426126ac91906156db565b85608001516fffffffffffffffffffffffffffffffff16613bdf565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b60005b8151811015610fea57600082828151811061270c5761270c6150da565b6020026020010151600001519050600083838151811061272e5761272e6150da565b6020908102919091018101518101516001600160a01b03841660008181526009845260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a250506001016126ef565b81546000906127e590600160801b900463ffffffff16426156db565b905080156128625760018301548354612820916fffffffffffffffffffffffffffffffff808216928116918591600160801b90910416613bdf565b83546fffffffffffffffffffffffffffffffff9190911673ffffffffffffffffffffffffffffffffffffffff1990911617600160801b4263ffffffff16021783555b60208201518354612888916fffffffffffffffffffffffffffffffff9081169116613c07565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff9283161717845560208301516040808501518316600160801b0291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906129629084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b604080516101a08101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e082018390526101008201839052610120820181905261014082018190526101608201526101808101919091526040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608086901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015612a72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a9691906151a1565b15612ad9576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610a2a565b6001600160a01b038216612b19576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546001600160a01b03163314612b5d576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b855460ff16612ba4576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610a2a565b6000612bb36080860186614ec9565b159050612bcf57612bca610a596080870187614ec9565b612be7565b6001870154640100000000900467ffffffffffffffff165b90506000612bf86040870187614f17565b9150612c16905087612c0d6020890189614ec9565b905084846118c7565b8015612d7c576000805b82811015612d6a57612c356040890189614f17565b82818110612c4557612c456150da565b90506040020160200135600003612c88576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff89166000908152600a60205260408082209190612cb0908b018b614f17565b84818110612cc057612cc06150da565b612cd69260206040909202019081019150614297565b6001600160a01b031681526020810191909152604001600020547201000000000000000000000000000000000000900460ff1615612d6257612d55612d1e60408a018a614f17565b83818110612d2e57612d2e6150da565b905060400201803603810190612d449190615167565b6006546001600160a01b0316613c1d565b612d5f9083614ffd565b91505b600101612c20565b508015612d7a57612d7a81613d3e565b505b60006001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016612db86080890160608a01614297565b6001600160a01b031603612dcd575084612ea0565b6006546001600160a01b03166241e5be612ded60808a0160608b01614297565b60405160e083901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039182166004820152602481018a90527f00000000000000000000000000000000000000000000000000000000000000009091166044820152606401602060405180830381865afa158015612e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9d9190615109565b90505b612eb06080880160608901614297565b6001600160a01b03167f075a2720282fdf622141dae0b048ef90a21a7e57c134c76912d19d006b3b3f6f82604051612eea91815260200190565b60405180910390a27f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16811115612f91576040517f6a92a483000000000000000000000000000000000000000000000000000000008152600481018290526bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610a2a565b604080516101a08101825267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526001600160a01b0387166020820152908101613022612fe88a80614ec9565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061328a92505050565b6001600160a01b031681526020018a600201601481819054906101000a900467ffffffffffffffff16613054906156ee565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff1681526020018481526020016000151581526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ea458c0c8b896040518363ffffffff1660e01b815260040161310392919067ffffffffffffffff9290921682526001600160a01b0316602082015260400190565b6020604051808303816000875af1158015613122573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131469190615715565b67ffffffffffffffff16815260200161316560808a0160608b01614297565b6001600160a01b031681526020018781526020018880602001906131899190614ec9565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050908252506020016131d060408a018a614f17565b808060200260200160405190810160405280939291908181526020016000905b8282101561321c5761320d60408302860136819003810190615167565b815260200190600101906131f0565b505050505081526020018367ffffffffffffffff81111561323f5761323f61440c565b60405190808252806020026020018201604052801561327257816020015b606081526020019060019003908161325d5790505b50815260006020909101529998505050505050505050565b600081516020146132c957816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610a2a9190614370565b610dfa828060200190518101906132e09190615109565b613d4b565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b610100015160405160200161337b9897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b60405160208183030381529060405280519060200120856101200151805190602001208661014001516040516020016133b49190615732565b604051602081830303815290604052805190602001208761016001516040516020016133e09190615745565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b60005b8151811015610fea576000828281518110613460576134606150da565b60200260200101519050600083838151811061347e5761347e6150da565b60200260200101516000015190508067ffffffffffffffff16600014806134b657506020820151610180015167ffffffffffffffff16155b156134f9576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610a2a565b6000600860008367ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002090506000836040015190506000604051806080016040528086602001518152602001836001600160a01b031681526020018460020160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1681526020018460030154815250905080600001518360000160008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101a082015181600101600c6101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101c08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555090505082600301546000801b036138f757604080517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b3602082015267ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692820192909252908516606082015230608082015260a00160408051601f1981840301815291905280516020909101206060820181905260038401556001600160a01b038216156138b05760028301805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384161790555b8367ffffffffffffffff167f7a70081ee29c1fc27898089ba2a5fc35ac0106b043c82ccecd24c6fd48f6ca86846040516138ea9190615758565b60405180910390a26139f7565b60028301546001600160a01b0383811691161461394c576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610a2a565b60208560200151610160015163ffffffff1610156139b057602085015161016001516040517f24ecdc020000000000000000000000000000000000000000000000000000000081526000600482015263ffffffff9091166024820152604401610a2a565b8367ffffffffffffffff167f944eb884a589931130671ee4a7379fbe5fe65ed605a048ba99c454582f2460b086602001516040516139ee91906158e4565b60405180910390a25b5050505050806001019050613443565b336001600160a01b03821603613a5f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610a2a565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000670de0b6b3a7640000613af0837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616614fe6565b6110969190615010565b6000613b4f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613db89092919063ffffffff16565b805190915015610fd35780806020019051810190613b6d91906151a1565b610fd35760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610a2a565b6000613bfe85613bef8486614fe6565b613bf99087614ffd565b613c07565b95945050505050565b6000818310613c165781611096565b5090919050565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa158015613c83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ca791906158f3565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116600003613d105783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610a2a565b60208401516117c1907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff831690613abd565b610e116003826000613dc7565b60006001600160a01b03821180613d63575061040082105b15613db45760408051602081018490520160408051601f19818403018152908290527f8d666f60000000000000000000000000000000000000000000000000000000008252610a2a91600401614370565b5090565b60606117c184846000856140e2565b825474010000000000000000000000000000000000000000900460ff161580613dee575081155b15613df857505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090613e3190600160801b900463ffffffff16426156db565b90508015613ed75781831115613e73576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154613ea090839085908490600160801b90046fffffffffffffffffffffffffffffffff16613bdf565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff16600160801b4263ffffffff160217875592505b84821015613f74576001600160a01b038416613f29576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610a2a565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b0385166044820152606401610a2a565b8483101561406057600186810154600160801b90046fffffffffffffffffffffffffffffffff16906000908290613fab90826156db565b613fb5878a6156db565b613fbf9190614ffd565b613fc99190615010565b90506001600160a01b038616614015576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610a2a565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b0387166044820152606401610a2a565b61406a85846156db565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b60608247101561415a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610a2a565b600080866001600160a01b031685876040516141769190615932565b60006040518083038185875af1925050503d80600081146141b3576040519150601f19603f3d011682016040523d82523d6000602084013e6141b8565b606091505b50915091506141c9878383876141d4565b979650505050505050565b6060831561424357825160000361423c576001600160a01b0385163b61423c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a2a565b50816117c1565b6117c183838151156142585781518083602001fd5b8060405162461bcd60e51b8152600401610a2a9190614370565b6001600160a01b0381168114610e1157600080fd5b803561429281614272565b919050565b6000602082840312156142a957600080fd5b813561109681614272565b60c08101610dfa82846001600160a01b0380825116835267ffffffffffffffff60208301511660208401526bffffffffffffffffffffffff60408301511660408401528060608301511660608401528060808301511660808401528060a08301511660a0840152505050565b60005b8381101561433b578181015183820152602001614323565b50506000910152565b6000815180845261435c816020860160208601614320565b601f01601f19169290920160200192915050565b6020815260006110966020830184614344565b67ffffffffffffffff81168114610e1157600080fd5b803561429281614383565b600060a082840312156143b657600080fd5b50919050565b600080604083850312156143cf57600080fd5b82356143da81614383565b9150602083013567ffffffffffffffff8111156143f657600080fd5b614402858286016143a4565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561445e5761445e61440c565b60405290565b6040805190810167ffffffffffffffff8111828210171561445e5761445e61440c565b60405160e0810167ffffffffffffffff8111828210171561445e5761445e61440c565b6040516101e0810167ffffffffffffffff8111828210171561445e5761445e61440c565b604051601f8201601f1916810167ffffffffffffffff811182821017156144f7576144f761440c565b604052919050565b60006060828403121561451157600080fd5b61451961443b565b823561452481614272565b8152602083013561453481614272565b6020820152604083013561454781614272565b60408201529392505050565b600067ffffffffffffffff82111561456d5761456d61440c565b5060051b60200190565b63ffffffff81168114610e1157600080fd5b803561429281614577565b803561ffff8116811461429257600080fd5b8015158114610e1157600080fd5b8035614292816145a6565b600082601f8301126145d057600080fd5b813560206145e56145e083614553565b6144ce565b82815260069290921b8401810191818101908684111561460457600080fd5b8286015b8481101561465557604081890312156146215760008081fd5b614629614464565b813561463481614383565b81528185013561464381614272565b81860152835291830191604001614608565b509695505050505050565b6000806040838503121561467357600080fd5b67ffffffffffffffff8335111561468957600080fd5b83601f84358501011261469b57600080fd5b6146ab6145e08435850135614553565b8335840180358083526020808401939260059290921b909101018610156146d157600080fd5b602085358601015b85358601803560051b016020018110156148c95767ffffffffffffffff8135111561470357600080fd5b6040601f1982358835890101890301121561471d57600080fd5b614725614464565b6147386020833589358a01010135614383565b863587018235016020810135825267ffffffffffffffff604090910135111561476057600080fd5b86358701823501604081013501603f8101891361477c57600080fd5b61478c6145e06020830135614553565b602082810135808352908201919060081b83016040018b10156147ae57600080fd5b604083015b6040602085013560081b8501018110156148b057610100818d0312156147d857600080fd5b6147e0614464565b6147ea8235614272565b8135815260e0601f19838f0301121561480257600080fd5b61480a614487565b6148176020840135614577565b6020830135815261482b6040840135614577565b6040830135602082015261484160608401614594565b60408201526148536080840135614577565b6080830135606082015261486a60a0840135614577565b60a0830135608082015261488060c084016145b4565b60a082015261489160e084016145b4565b60c08201526020828101919091529084529290920191610100016147b3565b50602084810191909152928652505092830192016146d9565b5092505067ffffffffffffffff602084013511156148e657600080fd5b6148f684602085013585016145bf565b90509250929050565b6000806040838503121561491257600080fd5b823561491d81614383565b9150602083013561492d81614272565b809150509250929050565b60006020828403121561494a57600080fd5b813561109681614383565b8051151582526020810151614970602084018261ffff169052565b506040810151614988604084018263ffffffff169052565b5060608101516149a0606084018263ffffffff169052565b5060808101516149b8608084018263ffffffff169052565b5060a08101516149ce60a084018261ffff169052565b5060c08101516149e660c084018263ffffffff169052565b5060e08101516149fc60e084018261ffff169052565b506101008181015161ffff9081169184019190915261012080830151909116908301526101408082015163ffffffff90811691840191909152610160808301518216908401526101808083015167ffffffffffffffff908116918501919091526101a080840151909116908401526101c09182015116910152565b600061024082019050614a8b828451614955565b60208301516001600160a01b03166101e0830152604083015167ffffffffffffffff166102008301526060909201516102209091015290565b60608101610dfa828480516001600160a01b03908116835260208083015182169084015260409182015116910152565b60006020808385031215614b0757600080fd5b823567ffffffffffffffff811115614b1e57600080fd5b8301601f81018513614b2f57600080fd5b8035614b3d6145e082614553565b81815260069190911b82018301908381019087831115614b5c57600080fd5b928401925b828410156141c95760408489031215614b7a5760008081fd5b614b82614464565b8435614b8d81614272565b815284860135614b9c81614383565b8187015282526040939093019290840190614b61565b80356fffffffffffffffffffffffffffffffff8116811461429257600080fd5b600060608284031215614be457600080fd5b614bec61443b565b8235614bf7816145a6565b8152614c0560208401614bb2565b602082015261454760408401614bb2565b60008060008060808587031215614c2c57600080fd5b8435614c3781614383565b9350602085013567ffffffffffffffff811115614c5357600080fd5b614c5f878288016143a4565b935050604085013591506060850135614c7781614272565b939692955090935050565b60006020808385031215614c9557600080fd5b823567ffffffffffffffff811115614cac57600080fd5b8301601f81018513614cbd57600080fd5b8035614ccb6145e082614553565b8181526102209182028301840191848201919088841115614ceb57600080fd5b938501935b83851015614e705784890381811215614d095760008081fd5b614d1161443b565b8635614d1c81614383565b81526101e0601f198301811315614d335760008081fd5b614d3b6144aa565b9250614d488989016145b4565b83526040614d57818a01614594565b8a8501526060614d68818b01614589565b828601526080614d79818c01614589565b8287015260a09150614d8c828c01614589565b9086015260c0614d9d8b8201614594565b8287015260e09150614db0828c01614589565b90860152610100614dc28b8201614594565b828701526101209150614dd6828c01614594565b90860152610140614de88b8201614594565b828701526101609150614dfc828c01614589565b90860152610180614e0e8b8201614589565b828701526101a09150614e22828c01614399565b908601526101c0614e348b8201614399565b82870152614e43848c01614589565b818701525050838a840152614e5b6102008a01614287565b90830152508452509384019391850191614cf0565b50979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614ebd5783516001600160a01b031683529284019291840191600101614e98565b50909695505050505050565b6000808335601e19843603018112614ee057600080fd5b83018035915067ffffffffffffffff821115614efb57600080fd5b602001915036819003821315614f1057600080fd5b9250929050565b6000808335601e19843603018112614f2e57600080fd5b83018035915067ffffffffffffffff821115614f4957600080fd5b6020019150600681901b3603821315614f1057600080fd5b80517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461429257600080fd5b60008060408385031215614fa057600080fd5b614fa983614f61565b91506148f660208401614f61565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610dfa57610dfa614fb7565b80820180821115610dfa57610dfa614fb7565b600082615046577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602080838503121561505e57600080fd5b825167ffffffffffffffff81111561507557600080fd5b8301601f8101851361508657600080fd5b80516150946145e082614553565b81815260059190911b820183019083810190878311156150b357600080fd5b928401925b828410156141c95783516150cb81614272565b825292840192908401906150b8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561511b57600080fd5b5051919050565b60006020828403121561513457600080fd5b815161109681614272565b67ffffffffffffffff81811683821601908082111561516057615160614fb7565b5092915050565b60006040828403121561517957600080fd5b615181614464565b823561518c81614272565b81526020928301359281019290925250919050565b6000602082840312156151b357600080fd5b8151611096816145a6565b602081526000825160a060208401526151da60c0840182614344565b905067ffffffffffffffff602085015116604084015260408401516001600160a01b038082166060860152606086015160808601528060808701511660a086015250508091505092915050565b600082601f83011261523857600080fd5b815167ffffffffffffffff8111156152525761525261440c565b6152656020601f19601f840116016144ce565b81815284602083860101111561527a57600080fd5b6117c1826020830160208701614320565b60006020828403121561529d57600080fd5b815167ffffffffffffffff808211156152b557600080fd5b90830190604082860312156152c957600080fd5b6152d1614464565b8251828111156152e057600080fd5b6152ec87828601615227565b82525060208301518281111561530157600080fd5b61530d87828601615227565b60208301525095945050505050565b6020815260008251606060208401526153386080840182614344565b90506020840151601f19808584030160408601526153568383614344565b9250604086015191508085840301606086015250613bfe8282614344565b60008151808452602080850194506020840160005b838110156153b957815180516001600160a01b031688528301518388015260409096019590820190600101615389565b509495945050505050565b60008282518085526020808601955060208260051b8401016020860160005b8481101561541157601f198684030189526153ff838351614344565b988401989250908301906001016153e3565b5090979650505050505050565b6020815261543960208201835167ffffffffffffffff169052565b6000602083015161545560408401826001600160a01b03169052565b5060408301516001600160a01b038116606084015250606083015167ffffffffffffffff8116608084015250608083015160a083015260a083015161549e60c084018215159052565b5060c083015167ffffffffffffffff811660e08401525060e08301516101006154d1818501836001600160a01b03169052565b840151610120848101919091528401516101a0610140808601829052919250906154ff6101c0860184614344565b9250808601519050601f196101608187860301818801526155208584615374565b94508088015192505061018081878603018188015261553f85846153c4565b970151959092019490945250929392505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081358181169160048510156155935780818660040360031b1b83161692505b505092915050565b600080858511156155ab57600080fd5b838611156155b857600080fd5b5050820193919092039150565b6000602082840312156155d757600080fd5b6040516020810181811067ffffffffffffffff821117156155fa576155fa61440c565b6040529135825250919050565b63ffffffff81811683821601908082111561516057615160614fb7565b60006020828403121561563657600080fd5b61109682614f61565b61012081016156ac82856001600160a01b0380825116835267ffffffffffffffff60208301511660208401526bffffffffffffffffffffffff60408301511660408401528060608301511660608401528060808301511660808401528060a08301511660a0840152505050565b82516001600160a01b0390811660c08401526020840151811660e0840152604084015116610100830152611096565b81810381811115610dfa57610dfa614fb7565b600067ffffffffffffffff80831681810361570b5761570b614fb7565b6001019392505050565b60006020828403121561572757600080fd5b815161109681614383565b6020815260006110966020830184615374565b60208152600061109660208301846153c4565b815460ff81161515825261024082019061ffff600882901c8116602085015263ffffffff601883901c8116604086015261579f60608601828560381c1663ffffffff169052565b6157b660808601828560581c1663ffffffff169052565b6157cb60a08601838560781c1661ffff169052565b6157e260c08601828560881c1663ffffffff169052565b6157f760e08601838560a81c1661ffff169052565b61580d6101008601838560b81c1661ffff169052565b6158236101208601838560c81c1661ffff169052565b61583b6101408601828560d81c1663ffffffff169052565b600186015463ffffffff82821616610160870152925067ffffffffffffffff602084901c811661018087015291506158856101a08601838560601c1667ffffffffffffffff169052565b61589d6101c08601828560a01c1663ffffffff169052565b5060028501546001600160a01b0381166101e086015291506158d16102008501828460a01c1667ffffffffffffffff169052565b5050600383015461022083015292915050565b6101e08101610dfa8284614955565b60006040828403121561590557600080fd5b61590d614464565b61591683614f61565b8152602083015161592681614577565b60208201529392505050565b60008251615944818460208701614320565b919091019291505056fea164736f6c6343000818000a", } var EVM2EVMMultiOnRampABI = EVM2EVMMultiOnRampMetaData.ABI @@ -443,28 +444,6 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerSession) GetPremiumMultiplier return _EVM2EVMMultiOnRamp.Contract.GetPremiumMultiplierWeiPerEth(&_EVM2EVMMultiOnRamp.CallOpts, token) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetSenderNonce(opts *bind.CallOpts, destChainSelector uint64, sender common.Address) (uint64, error) { - var out []interface{} - err := _EVM2EVMMultiOnRamp.contract.Call(opts, &out, "getSenderNonce", destChainSelector, sender) - - if err != nil { - return *new(uint64), err - } - - out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) - - return out0, err - -} - -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) GetSenderNonce(destChainSelector uint64, sender common.Address) (uint64, error) { - return _EVM2EVMMultiOnRamp.Contract.GetSenderNonce(&_EVM2EVMMultiOnRamp.CallOpts, destChainSelector, sender) -} - -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerSession) GetSenderNonce(destChainSelector uint64, sender common.Address) (uint64, error) { - return _EVM2EVMMultiOnRamp.Contract.GetSenderNonce(&_EVM2EVMMultiOnRamp.CallOpts, destChainSelector, sender) -} - func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetStaticConfig(opts *bind.CallOpts) (EVM2EVMMultiOnRampStaticConfig, error) { var out []interface{} err := _EVM2EVMMultiOnRamp.contract.Call(opts, &out, "getStaticConfig") @@ -2557,7 +2536,7 @@ func (EVM2EVMMultiOnRampConfigChanged) Topic() common.Hash { } func (EVM2EVMMultiOnRampConfigSet) Topic() common.Hash { - return common.HexToHash("0x7d6ca86e1084c492475f59ce7b74c37ad96a7440eb9c217ff5b27c183957b9b8") + return common.HexToHash("0x881586dd9eb05fe5f83d393ba8251d24a928b3b463abcad1b822340ba0588cdc") } func (EVM2EVMMultiOnRampDestChainAdded) Topic() common.Hash { @@ -2619,8 +2598,6 @@ type EVM2EVMMultiOnRampInterface interface { GetPremiumMultiplierWeiPerEth(opts *bind.CallOpts, token common.Address) (uint64, error) - GetSenderNonce(opts *bind.CallOpts, destChainSelector uint64, sender common.Address) (uint64, error) - GetStaticConfig(opts *bind.CallOpts) (EVM2EVMMultiOnRampStaticConfig, error) GetSupportedTokens(opts *bind.CallOpts, arg0 uint64) ([]common.Address, error) diff --git a/core/gethwrappers/ccip/generated/multi_aggregate_rate_limiter/multi_aggregate_rate_limiter.go b/core/gethwrappers/ccip/generated/multi_aggregate_rate_limiter/multi_aggregate_rate_limiter.go index 8d2f832a26..e5ee794bbf 100644 --- a/core/gethwrappers/ccip/generated/multi_aggregate_rate_limiter/multi_aggregate_rate_limiter.go +++ b/core/gethwrappers/ccip/generated/multi_aggregate_rate_limiter/multi_aggregate_rate_limiter.go @@ -30,6 +30,11 @@ var ( _ = abi.ConvertType ) +type AuthorizedCallersAuthorizedCallerArgs struct { + AddedCallers []common.Address + RemovedCallers []common.Address +} + type ClientAny2EVMMessage struct { MessageId [32]byte SourceChainSelector uint64 @@ -51,11 +56,6 @@ type ClientEVMTokenAmount struct { Amount *big.Int } -type MultiAggregateRateLimiterAuthorizedCallerArgs struct { - AddedCallers []common.Address - RemovedCallers []common.Address -} - type MultiAggregateRateLimiterLocalRateLimitToken struct { RemoteChainSelector uint64 LocalToken common.Address @@ -68,7 +68,7 @@ type MultiAggregateRateLimiterRateLimitTokenArgs struct { type MultiAggregateRateLimiterRateLimiterConfigArgs struct { RemoteChainSelector uint64 - IsOutgoingLane bool + IsOutboundLane bool RateLimiterConfig RateLimiterConfig } @@ -87,8 +87,8 @@ type RateLimiterTokenBucket struct { } var MultiAggregateRateLimiterMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"authorizedCallers\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newPriceRegistry\",\"type\":\"address\"}],\"name\":\"PriceRegistrySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isOutgoingLane\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"RateLimiterConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"remoteToken\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structMultiAggregateRateLimiter.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isOutgoingLane\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structMultiAggregateRateLimiter.RateLimiterConfigArgs[]\",\"name\":\"rateLimiterUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applyRateLimiterConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isOutgoingLane\",\"type\":\"bool\"}],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"localTokens\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"remoteTokens\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPriceRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"onIncomingMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"onOutgoingMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newPriceRegistry\",\"type\":\"address\"}],\"name\":\"setPriceRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structMultiAggregateRateLimiter.LocalRateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structMultiAggregateRateLimiter.LocalRateLimitToken\",\"name\":\"localTokenArgs\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"remoteToken\",\"type\":\"bytes32\"}],\"internalType\":\"structMultiAggregateRateLimiter.RateLimitTokenArgs[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b5060405162002db038038062002db083398101604081905262000034916200053c565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be8162000106565b505050620000d282620001b160201b60201c565b604080518082018252828152815160008152602080820190935291810191909152620000fe906200022d565b505062000673565b336001600160a01b03821603620001605760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b038116620001d9576040516342bcdf7f60e11b815260040160405180910390fd5b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527fdeaac1a8daeabcc5254b10b54edf3678fdfcd1cea89fe9d364b6285f6ace2df99060200160405180910390a150565b602081015160005b8151811015620002bd57600082828151811062000256576200025662000625565b60209081029190910101519050620002706003826200037c565b15620002b3576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b5060010162000235565b50815160005b815181101562000376576000828281518110620002e457620002e462000625565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000322576040516342bcdf7f60e11b815260040160405180910390fd5b6200032f6003826200039c565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a150600101620002c3565b50505050565b600062000393836001600160a01b038416620003b3565b90505b92915050565b600062000393836001600160a01b038416620004b7565b60008181526001830160205260408120548015620004ac576000620003da6001836200063b565b8554909150600090620003f0906001906200063b565b90508181146200045c57600086600001828154811062000414576200041462000625565b90600052602060002001549050808760000184815481106200043a576200043a62000625565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047057620004706200065d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000396565b600091505062000396565b6000818152600183016020526040812054620005005750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000396565b50600062000396565b80516001600160a01b03811681146200052157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156200055057600080fd5b6200055b8362000509565b602084810151919350906001600160401b03808211156200057b57600080fd5b818601915086601f8301126200059057600080fd5b815181811115620005a557620005a562000526565b8060051b604051601f19603f83011681018181108582111715620005cd57620005cd62000526565b604052918252848201925083810185019189831115620005ec57600080fd5b938501935b828510156200061557620006058562000509565b84529385019392850192620005f1565b8096505050505050509250929050565b634e487b7160e01b600052603260045260246000fd5b818103818111156200039657634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b61272d80620006836000396000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c806379ba50971161008c57806391a2749a1161006657806391a2749a14610231578063a219f6e514610244578063f2fde38b14610257578063fe843cd01461026a57600080fd5b806379ba5097146101f85780637c8b5e9a146102005780638da5cb5b1461021357600080fd5b80632451a627116100bd5780632451a627146101af578063508ee9de146101c4578063537e304e146101d757600080fd5b806303a44ffb146100e45780630a35bcc4146100f85780630d6c107e14610170575b600080fd5b6100f66100f2366004611e58565b5050565b005b61010b610106366004611f64565b61027d565b604051610167919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60405180910390f35b60055473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610167565b6101b7610342565b6040516101679190611fe0565b6100f66101d2366004611ff3565b610353565b6101ea6101e536600461200e565b610367565b604051610167929190612029565b6100f66104ca565b6100f661020e36600461214a565b6105cc565b60005473ffffffffffffffffffffffffffffffffffffffff1661018a565b6100f661023f36600461227b565b61081b565b6100f661025236600461230c565b61082c565b6100f6610265366004611ff3565b610950565b6100f66102783660046123fc565b610961565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526103396102b58484610ca0565b6040805160a08101825282546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff16151593830193909352600190930154808316606083015292909204166080820152610cd0565b90505b92915050565b606061034e6003610d82565b905090565b61035b610d96565b61036481610e19565b50565b67ffffffffffffffff81166000908152600260205260408120606091829161038e90610edf565b90508067ffffffffffffffff8111156103a9576103a9611be2565b6040519080825280602002602001820160405280156103d2578160200160208202803683370190505b5092508067ffffffffffffffff8111156103ee576103ee611be2565b604051908082528060200260200182016040528015610417578160200160208202803683370190505b50915060005b818110156104c35767ffffffffffffffff85166000908152600260205260408120819061044a9084610eea565b915091508186848151811061046157610461612530565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050808584815181106104ae576104ae612530565b6020908102919091010152505060010161041d565b5050915091565b60015473ffffffffffffffffffffffffffffffffffffffff163314610550576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6105d4610d96565b60005b82518110156106b25760008382815181106105f4576105f4612530565b6020026020010151602001519050600084838151811061061657610616612530565b6020908102919091018101515167ffffffffffffffff811660009081526002909252604090912090915061064a9083610f06565b156106a8576040805167ffffffffffffffff8316815273ffffffffffffffffffffffffffffffffffffffff841660208201527f530cabd30786b7235e124a6c0db77e0b685ef22813b1fe87554247f404eb8ed6910160405180910390a15b50506001016105d7565b5060005b81518110156108165760008282815181106106d3576106d3612530565b602002602001015160000151905060008383815181106106f5576106f5612530565b6020026020010151602001519050600082602001519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610745575081155b1561077c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b825167ffffffffffffffff811660009081526002602052604090206107a2908385610f28565b15610807576040805167ffffffffffffffff831681526020810185905273ffffffffffffffffffffffffffffffffffffffff84168183015290517ffd96f5ca8894a9584abba5645131a95480f9340bd5e0046ceff789111ff16c6d9181900360600190a15b505050508060010190506106b6565b505050565b610823610d96565b61036481610f53565b6108376003336110e5565b61086f576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610547565b602081015160006108808282610ca0565b805490915074010000000000000000000000000000000000000000900460ff1615610816576080830151600090815b8151811015610936576108fa8282815181106108cd576108cd612530565b6020908102919091018101515167ffffffffffffffff881660009081526002909252604090912090611114565b1561092e5761092182828151811061091457610914612530565b6020026020010151611136565b61092b908461258e565b92505b6001016108af565b5081156109495761094983836000611272565b5050505050565b610958610d96565b610364816115f5565b610969610d96565b60005b81518110156100f257600082828151811061098957610989612530565b6020908102919091010151604081015181519192509067ffffffffffffffff81166000036109e3576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015160006109f48383610ca0565b8054909150700100000000000000000000000000000000900463ffffffff16600003610c42576040805160a081018252602080870180516fffffffffffffffffffffffffffffffff908116845263ffffffff421692840192909252875115158385015251811660608301529186015190911660808201528215610b5b5767ffffffffffffffff8416600090815260066020908152604091829020835160028201805493860151948601516fffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff00000000000000000000000000000000000000009095169490941770010000000000000000000000000000000063ffffffff9096168602177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000941515949094029390931790925560608401516080850151908316921690920217600390910155610c3c565b67ffffffffffffffff84166000908152600660209081526040918290208351815492850151938501516fffffffffffffffffffffffffffffffff9182167fffffffffffffffffffffffff00000000000000000000000000000000000000009094169390931770010000000000000000000000000000000063ffffffff9095168502177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000093151593909302929092178155606084015160808501519083169216909202176001909101555b50610c4c565b610c4c81856116ea565b8267ffffffffffffffff167ff14a5415ce6988a9e870a85fff0b9d7b7dd79bbc228cb63cad610daf6f7b6b978386604051610c889291906125a1565b60405180910390a2505050505080600101905061096c565b67ffffffffffffffff821660009081526006602052604081208215610cc957600201905061033c565b905061033c565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152610d5e82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642610d4291906125e5565b85608001516fffffffffffffffffffffffffffffffff16611899565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b60606000610d8f836118c1565b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610547565b565b73ffffffffffffffffffffffffffffffffffffffff8116610e66576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fdeaac1a8daeabcc5254b10b54edf3678fdfcd1cea89fe9d364b6285f6ace2df99060200160405180910390a150565b600061033c8261191d565b6000808080610ef98686611928565b9097909650945050505050565b60006103398373ffffffffffffffffffffffffffffffffffffffff8416611953565b6000610f4b8473ffffffffffffffffffffffffffffffffffffffff851684611970565b949350505050565b602081015160005b8151811015610fee576000828281518110610f7857610f78612530565b60200260200101519050610f9681600361198d90919063ffffffff16565b15610fe55760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101610f5b565b50815160005b81518110156110df57600082828151811061101157611011612530565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611081576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61108c6003826119af565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a150600101610ff4565b50505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610339565b60006103398373ffffffffffffffffffffffffffffffffffffffff84166119d1565b60055481516040517fd02641a000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526000928392169063d02641a0906024016040805180830381865afa1580156111aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ce91906125f8565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81166000036112445782516040517f9a655f7b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610547565b6020830151610d8f907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316906119dd565b825474010000000000000000000000000000000000000000900460ff161580611299575081155b156112a357505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906112e990700100000000000000000000000000000000900463ffffffff16426125e5565b905080156113a9578183111561132b576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546113659083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16611899565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156114605773ffffffffffffffffffffffffffffffffffffffff8416611408576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610547565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610547565b848310156115735760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906114a490826125e5565b6114ae878a6125e5565b6114b8919061258e565b6114c29190612663565b905073ffffffffffffffffffffffffffffffffffffffff861661151b576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610547565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610547565b61157d85846125e5565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603611674576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610547565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b815460009061171390700100000000000000000000000000000000900463ffffffff16426125e5565b905080156117b5576001830154835461175b916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416611899565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546117db916fffffffffffffffffffffffffffffffff9081169116611a1a565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061188c90849061269e565b60405180910390a1505050565b60006118b8856118a984866126da565b6118b3908761258e565b611a1a565b95945050505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561191157602002820191906000526020600020905b8154815260200190600101908083116118fd575b50505050509050919050565b600061033c82611a30565b600080806119368585611a3a565b600081815260029690960160205260409095205494959350505050565b600081815260028301602052604081208190556103398383611a46565b60008281526002840160205260408120829055610f4b8484611a52565b60006103398373ffffffffffffffffffffffffffffffffffffffff8416611a5e565b60006103398373ffffffffffffffffffffffffffffffffffffffff8416611b51565b60006103398383611ba0565b6000670de0b6b3a7640000611a10837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166126da565b6103399190612663565b6000818310611a295781610339565b5090919050565b600061033c825490565b60006103398383611bb8565b60006103398383611a5e565b60006103398383611b51565b60008181526001830160205260408120548015611b47576000611a826001836125e5565b8554909150600090611a96906001906125e5565b9050818114611afb576000866000018281548110611ab657611ab6612530565b9060005260206000200154905080876000018481548110611ad957611ad9612530565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611b0c57611b0c6126f1565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061033c565b600091505061033c565b6000818152600183016020526040812054611b985750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561033c565b50600061033c565b60008181526001830160205260408120541515610339565b6000826000018281548110611bcf57611bcf612530565b9060005260206000200154905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611c3457611c34611be2565b60405290565b60405160a0810167ffffffffffffffff81118282101715611c3457611c34611be2565b6040516060810167ffffffffffffffff81118282101715611c3457611c34611be2565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611cc757611cc7611be2565b604052919050565b600082601f830112611ce057600080fd5b813567ffffffffffffffff811115611cfa57611cfa611be2565b611d2b60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611c80565b818152846020838601011115611d4057600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff821115611d7757611d77611be2565b5060051b60200190565b803573ffffffffffffffffffffffffffffffffffffffff81168114611da557600080fd5b919050565b600082601f830112611dbb57600080fd5b81356020611dd0611dcb83611d5d565b611c80565b82815260069290921b84018101918181019086841115611def57600080fd5b8286015b84811015611e355760408189031215611e0c5760008081fd5b611e14611c11565b611e1d82611d81565b81528185013585820152835291830191604001611df3565b509695505050505050565b803567ffffffffffffffff81168114611da557600080fd5b60008060408385031215611e6b57600080fd5b823567ffffffffffffffff80821115611e8357600080fd5b9084019060a08287031215611e9757600080fd5b611e9f611c3a565b823582811115611eae57600080fd5b611eba88828601611ccf565b825250602083013582811115611ecf57600080fd5b611edb88828601611ccf565b602083015250604083013582811115611ef357600080fd5b611eff88828601611daa565b604083015250611f1160608401611d81565b6060820152608083013582811115611f2857600080fd5b611f3488828601611ccf565b6080830152509350611f4b91505060208401611e40565b90509250929050565b80358015158114611da557600080fd5b60008060408385031215611f7757600080fd5b611f8083611e40565b9150611f4b60208401611f54565b60008151808452602080850194506020840160005b83811015611fd557815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101611fa3565b509495945050505050565b6020815260006103396020830184611f8e565b60006020828403121561200557600080fd5b61033982611d81565b60006020828403121561202057600080fd5b61033982611e40565b60408152600061203c6040830185611f8e565b82810360208481019190915284518083528582019282019060005b8181101561207357845183529383019391830191600101612057565b5090979650505050505050565b60006040828403121561209257600080fd5b61209a611c11565b90506120a582611e40565b81526120b360208301611d81565b602082015292915050565b600082601f8301126120cf57600080fd5b813560206120df611dcb83611d5d565b80838252602082019150606060206060860288010194508785111561210357600080fd5b602087015b858110156120735781818a0312156121205760008081fd5b612128611c11565b6121328a83612080565b81526040820135868201528452928401928101612108565b600080604080848603121561215e57600080fd5b833567ffffffffffffffff8082111561217657600080fd5b818601915086601f83011261218a57600080fd5b8135602061219a611dcb83611d5d565b8083825260208201915060208460061b87010193508a8411156121bc57600080fd5b6020860195505b838610156121e4576121d58b87612080565b825294860194908201906121c3565b975050505060208601359250808311156121fd57600080fd5b505061220b858286016120be565b9150509250929050565b600082601f83011261222657600080fd5b81356020612236611dcb83611d5d565b8083825260208201915060208460051b87010193508684111561225857600080fd5b602086015b84811015611e355761226e81611d81565b835291830191830161225d565b60006020828403121561228d57600080fd5b813567ffffffffffffffff808211156122a557600080fd5b90830190604082860312156122b957600080fd5b6122c1611c11565b8235828111156122d057600080fd5b6122dc87828601612215565b8252506020830135828111156122f157600080fd5b6122fd87828601612215565b60208301525095945050505050565b60006020828403121561231e57600080fd5b813567ffffffffffffffff8082111561233657600080fd5b9083019060a0828603121561234a57600080fd5b612352611c3a565b8235815261236260208401611e40565b602082015260408301358281111561237957600080fd5b61238587828601611ccf565b60408301525060608301358281111561239d57600080fd5b6123a987828601611ccf565b6060830152506080830135828111156123c157600080fd5b6123cd87828601611daa565b60808301525095945050505050565b80356fffffffffffffffffffffffffffffffff81168114611da557600080fd5b6000602080838503121561240f57600080fd5b823567ffffffffffffffff81111561242657600080fd5b8301601f8101851361243757600080fd5b8035612445611dcb82611d5d565b81815260a0918202830184019184820191908884111561246457600080fd5b938501935b8385101561252457848903818112156124825760008081fd5b61248a611c5d565b61249387611e40565b81526124a0888801611f54565b8882015260406060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0850112156124d85760008081fd5b6124e0611c5d565b93506124ed828a01611f54565b84526124fa818a016123dc565b8a8501525061250b608089016123dc565b8382015281019190915283529384019391850191612469565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561033c5761033c61255f565b821515815260808101610d8f60208301848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b8181038181111561033c5761033c61255f565b60006040828403121561260a57600080fd5b612612611c11565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461263e57600080fd5b8152602083015163ffffffff8116811461265757600080fd5b60208201529392505050565b600082612699577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6060810161033c82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b808202811582820484141761033c5761033c61255f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"authorizedCallers\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newPriceRegistry\",\"type\":\"address\"}],\"name\":\"PriceRegistrySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"RateLimiterConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"remoteToken\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structMultiAggregateRateLimiter.RateLimiterConfigArgs[]\",\"name\":\"rateLimiterUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applyRateLimiterConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"}],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"localTokens\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"remoteTokens\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPriceRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"onInboundMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"onOutboundMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newPriceRegistry\",\"type\":\"address\"}],\"name\":\"setPriceRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structMultiAggregateRateLimiter.LocalRateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structMultiAggregateRateLimiter.LocalRateLimitToken\",\"name\":\"localTokenArgs\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"remoteToken\",\"type\":\"bytes32\"}],\"internalType\":\"structMultiAggregateRateLimiter.RateLimitTokenArgs[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b5060405162002db038038062002db0833981016040819052620000349162000538565b8033806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000102565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620001ad565b50620000fa82620002fc565b50506200066f565b336001600160a01b038216036200015c5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b81518110156200023d576000828281518110620001d657620001d662000621565b60209081029190910101519050620001f060028262000378565b1562000233576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620001b5565b50815160005b8151811015620002f657600082828151811062000264576200026462000621565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002a2576040516342bcdf7f60e11b815260040160405180910390fd5b620002af60028262000398565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000243565b50505050565b6001600160a01b03811662000324576040516342bcdf7f60e11b815260040160405180910390fd5b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527fdeaac1a8daeabcc5254b10b54edf3678fdfcd1cea89fe9d364b6285f6ace2df99060200160405180910390a150565b60006200038f836001600160a01b038416620003af565b90505b92915050565b60006200038f836001600160a01b038416620004b3565b60008181526001830160205260408120548015620004a8576000620003d660018362000637565b8554909150600090620003ec9060019062000637565b90508181146200045857600086600001828154811062000410576200041062000621565b906000526020600020015490508087600001848154811062000436576200043662000621565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200046c576200046c62000659565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000392565b600091505062000392565b6000818152600183016020526040812054620004fc5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000392565b50600062000392565b80516001600160a01b03811681146200051d57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156200054c57600080fd5b620005578362000505565b602084810151919350906001600160401b03808211156200057757600080fd5b818601915086601f8301126200058c57600080fd5b815181811115620005a157620005a162000522565b8060051b604051601f19603f83011681018181108582111715620005c957620005c962000522565b604052918252848201925083810185019189831115620005e857600080fd5b938501935b828510156200061157620006018562000505565b84529385019392850192620005ed565b8096505050505050509250929050565b634e487b7160e01b600052603260045260246000fd5b818103818111156200039257634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b612731806200067f6000396000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c806379ba50971161008c57806391a2749a1161006657806391a2749a14610232578063d918e00514610245578063f2fde38b14610257578063fe843cd01461026a57600080fd5b806379ba5097146101f95780637c8b5e9a146102015780638da5cb5b1461021457600080fd5b80632451a627116100bd5780632451a627146101b0578063508ee9de146101c5578063537e304e146101d857600080fd5b806308d450a1146100e45780630a35bcc4146100f95780630d6c107e14610171575b600080fd5b6100f76100f2366004611e5c565b61027d565b005b61010c610107366004611f3c565b610367565b604051610168919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60405180910390f35b60055473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610168565b6101b861042c565b6040516101689190611fc1565b6100f76101d3366004611fd4565b61043d565b6101eb6101e6366004611fef565b610451565b60405161016892919061200a565b6100f76105b4565b6100f761020f36600461212b565b6106b6565b60005473ffffffffffffffffffffffffffffffffffffffff1661018b565b6100f761024036600461225c565b610900565b6100f76102533660046122ed565b5050565b6100f7610265366004611fd4565b610911565b6100f7610278366004612400565b610922565b610285610c61565b602081015160006102968282610ca6565b805490915074010000000000000000000000000000000000000000900460ff1615610362576080830151600090815b815181101561034c576103108282815181106102e3576102e3612534565b6020908102919091018101515167ffffffffffffffff881660009081526004909252604090912090610cd6565b156103445761033782828151811061032a5761032a612534565b6020026020010151610cf8565b6103419084612592565b92505b6001016102c5565b50811561035f5761035f83836000610e3b565b50505b505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261042361039f8484610ca6565b6040805160a08101825282546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526001909301548083166060830152929092041660808201526111be565b90505b92915050565b60606104386002611270565b905090565b61044561127d565b61044e816112fe565b50565b67ffffffffffffffff811660009081526004602052604081206060918291610478906113c4565b90508067ffffffffffffffff81111561049357610493611be6565b6040519080825280602002602001820160405280156104bc578160200160208202803683370190505b5092508067ffffffffffffffff8111156104d8576104d8611be6565b604051908082528060200260200182016040528015610501578160200160208202803683370190505b50915060005b818110156105ad5767ffffffffffffffff85166000908152600460205260408120819061053490846113cf565b915091508186848151811061054b5761054b612534565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508085848151811061059857610598612534565b60209081029190910101525050600101610507565b5050915091565b60015473ffffffffffffffffffffffffffffffffffffffff16331461063a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6106be61127d565b60005b825181101561079c5760008382815181106106de576106de612534565b6020026020010151602001519050600084838151811061070057610700612534565b6020908102919091018101515167ffffffffffffffff811660009081526004909252604090912090915061073490836113eb565b15610792576040805167ffffffffffffffff8316815273ffffffffffffffffffffffffffffffffffffffff841660208201527f530cabd30786b7235e124a6c0db77e0b685ef22813b1fe87554247f404eb8ed6910160405180910390a15b50506001016106c1565b5060005b81518110156103625760008282815181106107bd576107bd612534565b602002602001015160000151905060008383815181106107df576107df612534565b6020026020010151602001519050600082602001519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16148061082f575081155b15610866576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b825167ffffffffffffffff8116600090815260046020526040902061088c90838561140d565b156108f1576040805167ffffffffffffffff831681526020810185905273ffffffffffffffffffffffffffffffffffffffff84168183015290517ffd96f5ca8894a9584abba5645131a95480f9340bd5e0046ceff789111ff16c6d9181900360600190a15b505050508060010190506107a0565b61090861127d565b61044e81611438565b61091961127d565b61044e816115ca565b61092a61127d565b60005b815181101561025357600082828151811061094a5761094a612534565b6020908102919091010151604081015181519192509067ffffffffffffffff81166000036109a4576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015160006109b58383610ca6565b8054909150700100000000000000000000000000000000900463ffffffff16600003610c03576040805160a081018252602080870180516fffffffffffffffffffffffffffffffff908116845263ffffffff421692840192909252875115158385015251811660608301529186015190911660808201528215610b1c5767ffffffffffffffff8416600090815260066020908152604091829020835160028201805493860151948601516fffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff00000000000000000000000000000000000000009095169490941770010000000000000000000000000000000063ffffffff9096168602177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000941515949094029390931790925560608401516080850151908316921690920217600390910155610bfd565b67ffffffffffffffff84166000908152600660209081526040918290208351815492850151938501516fffffffffffffffffffffffffffffffff9182167fffffffffffffffffffffffff00000000000000000000000000000000000000009094169390931770010000000000000000000000000000000063ffffffff9095168502177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000093151593909302929092178155606084015160808501519083169216909202176001909101555b50610c0d565b610c0d81856116bf565b8267ffffffffffffffff167ff14a5415ce6988a9e870a85fff0b9d7b7dd79bbc228cb63cad610daf6f7b6b978386604051610c499291906125a5565b60405180910390a2505050505080600101905061092d565b610c6c60023361186e565b610ca4576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610631565b565b67ffffffffffffffff821660009081526006602052604081208215610ccf576002019050610426565b9050610426565b60006104238373ffffffffffffffffffffffffffffffffffffffff841661189d565b60055481516040517fd02641a000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526000928392169063d02641a0906024016040805180830381865afa158015610d6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9091906125e9565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116600003610e065782516040517f9a655f7b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610631565b6020830151610e34907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316906118a9565b9392505050565b825474010000000000000000000000000000000000000000900460ff161580610e62575081155b15610e6c57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090610eb290700100000000000000000000000000000000900463ffffffff1642612654565b90508015610f725781831115610ef4576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154610f2e9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166118e6565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156110295773ffffffffffffffffffffffffffffffffffffffff8416610fd1576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610631565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610631565b8483101561113c5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061106d9082612654565b611077878a612654565b6110819190612592565b61108b9190612667565b905073ffffffffffffffffffffffffffffffffffffffff86166110e4576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610631565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610631565b6111468584612654565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261124c82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426112309190612654565b85608001516fffffffffffffffffffffffffffffffff166118e6565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b60606000610e348361190e565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ca4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610631565b73ffffffffffffffffffffffffffffffffffffffff811661134b576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fdeaac1a8daeabcc5254b10b54edf3678fdfcd1cea89fe9d364b6285f6ace2df99060200160405180910390a150565b60006104268261196a565b60008080806113de8686611975565b9097909650945050505050565b60006104238373ffffffffffffffffffffffffffffffffffffffff84166119a0565b60006114308473ffffffffffffffffffffffffffffffffffffffff8516846119bd565b949350505050565b602081015160005b81518110156114d357600082828151811061145d5761145d612534565b6020026020010151905061147b8160026119da90919063ffffffff16565b156114ca5760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101611440565b50815160005b81518110156115c45760008282815181106114f6576114f6612534565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611566576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6115716002826119fc565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a1506001016114d9565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff821603611649576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610631565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b81546000906116e890700100000000000000000000000000000000900463ffffffff1642612654565b9050801561178a5760018301548354611730916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166118e6565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546117b0916fffffffffffffffffffffffffffffffff9081169116611a1e565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906118619084906126a2565b60405180910390a1505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610423565b60006104238383611a34565b6000670de0b6b3a76400006118dc837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166126de565b6104239190612667565b6000611905856118f684866126de565b6119009087612592565b611a1e565b95945050505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561195e57602002820191906000526020600020905b81548152602001906001019080831161194a575b50505050509050919050565b600061042682611a4c565b600080806119838585611a56565b600081815260029690960160205260409095205494959350505050565b600081815260028301602052604081208190556104238383611a62565b600082815260028401602052604081208290556114308484611a6e565b60006104238373ffffffffffffffffffffffffffffffffffffffff8416611a7a565b60006104238373ffffffffffffffffffffffffffffffffffffffff8416611b6d565b6000818310611a2d5781610423565b5090919050565b60008181526001830160205260408120541515610423565b6000610426825490565b60006104238383611bbc565b60006104238383611a7a565b60006104238383611b6d565b60008181526001830160205260408120548015611b63576000611a9e600183612654565b8554909150600090611ab290600190612654565b9050818114611b17576000866000018281548110611ad257611ad2612534565b9060005260206000200154905080876000018481548110611af557611af5612534565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611b2857611b286126f5565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610426565b6000915050610426565b6000818152600183016020526040812054611bb457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610426565b506000610426565b6000826000018281548110611bd357611bd3612534565b9060005260206000200154905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611c3857611c38611be6565b60405290565b60405160a0810167ffffffffffffffff81118282101715611c3857611c38611be6565b6040516060810167ffffffffffffffff81118282101715611c3857611c38611be6565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611ccb57611ccb611be6565b604052919050565b803567ffffffffffffffff81168114611ceb57600080fd5b919050565b600082601f830112611d0157600080fd5b813567ffffffffffffffff811115611d1b57611d1b611be6565b611d4c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611c84565b818152846020838601011115611d6157600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff821115611d9857611d98611be6565b5060051b60200190565b803573ffffffffffffffffffffffffffffffffffffffff81168114611ceb57600080fd5b600082601f830112611dd757600080fd5b81356020611dec611de783611d7e565b611c84565b82815260069290921b84018101918181019086841115611e0b57600080fd5b8286015b84811015611e515760408189031215611e285760008081fd5b611e30611c15565b611e3982611da2565b81528185013585820152835291830191604001611e0f565b509695505050505050565b600060208284031215611e6e57600080fd5b813567ffffffffffffffff80821115611e8657600080fd5b9083019060a08286031215611e9a57600080fd5b611ea2611c3e565b82358152611eb260208401611cd3565b6020820152604083013582811115611ec957600080fd5b611ed587828601611cf0565b604083015250606083013582811115611eed57600080fd5b611ef987828601611cf0565b606083015250608083013582811115611f1157600080fd5b611f1d87828601611dc6565b60808301525095945050505050565b80358015158114611ceb57600080fd5b60008060408385031215611f4f57600080fd5b611f5883611cd3565b9150611f6660208401611f2c565b90509250929050565b60008151808452602080850194506020840160005b83811015611fb657815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101611f84565b509495945050505050565b6020815260006104236020830184611f6f565b600060208284031215611fe657600080fd5b61042382611da2565b60006020828403121561200157600080fd5b61042382611cd3565b60408152600061201d6040830185611f6f565b82810360208481019190915284518083528582019282019060005b8181101561205457845183529383019391830191600101612038565b5090979650505050505050565b60006040828403121561207357600080fd5b61207b611c15565b905061208682611cd3565b815261209460208301611da2565b602082015292915050565b600082601f8301126120b057600080fd5b813560206120c0611de783611d7e565b8083825260208201915060606020606086028801019450878511156120e457600080fd5b602087015b858110156120545781818a0312156121015760008081fd5b612109611c15565b6121138a83612061565b815260408201358682015284529284019281016120e9565b600080604080848603121561213f57600080fd5b833567ffffffffffffffff8082111561215757600080fd5b818601915086601f83011261216b57600080fd5b8135602061217b611de783611d7e565b8083825260208201915060208460061b87010193508a84111561219d57600080fd5b6020860195505b838610156121c5576121b68b87612061565b825294860194908201906121a4565b975050505060208601359250808311156121de57600080fd5b50506121ec8582860161209f565b9150509250929050565b600082601f83011261220757600080fd5b81356020612217611de783611d7e565b8083825260208201915060208460051b87010193508684111561223957600080fd5b602086015b84811015611e515761224f81611da2565b835291830191830161223e565b60006020828403121561226e57600080fd5b813567ffffffffffffffff8082111561228657600080fd5b908301906040828603121561229a57600080fd5b6122a2611c15565b8235828111156122b157600080fd5b6122bd878286016121f6565b8252506020830135828111156122d257600080fd5b6122de878286016121f6565b60208301525095945050505050565b6000806040838503121561230057600080fd5b823567ffffffffffffffff8082111561231857600080fd5b9084019060a0828703121561232c57600080fd5b612334611c3e565b82358281111561234357600080fd5b61234f88828601611cf0565b82525060208301358281111561236457600080fd5b61237088828601611cf0565b60208301525060408301358281111561238857600080fd5b61239488828601611dc6565b6040830152506123a660608401611da2565b60608201526080830135828111156123bd57600080fd5b6123c988828601611cf0565b6080830152509350611f6691505060208401611cd3565b80356fffffffffffffffffffffffffffffffff81168114611ceb57600080fd5b6000602080838503121561241357600080fd5b823567ffffffffffffffff81111561242a57600080fd5b8301601f8101851361243b57600080fd5b8035612449611de782611d7e565b81815260a0918202830184019184820191908884111561246857600080fd5b938501935b8385101561252857848903818112156124865760008081fd5b61248e611c61565b61249787611cd3565b81526124a4888801611f2c565b8882015260406060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0850112156124dc5760008081fd5b6124e4611c61565b93506124f1828a01611f2c565b84526124fe818a016123e0565b8a8501525061250f608089016123e0565b838201528101919091528352938401939185019161246d565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561042657610426612563565b821515815260808101610e3460208301848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000604082840312156125fb57600080fd5b612603611c15565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461262f57600080fd5b8152602083015163ffffffff8116811461264857600080fd5b60208201529392505050565b8181038181111561042657610426612563565b60008261269d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6060810161042682848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b808202811582820484141761042657610426612563565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var MultiAggregateRateLimiterABI = MultiAggregateRateLimiterMetaData.ABI @@ -227,9 +227,9 @@ func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorRaw) Transa return _MultiAggregateRateLimiter.Contract.contract.Transact(opts, method, params...) } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCaller) CurrentRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64, isOutgoingLane bool) (RateLimiterTokenBucket, error) { +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCaller) CurrentRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64, isOutboundLane bool) (RateLimiterTokenBucket, error) { var out []interface{} - err := _MultiAggregateRateLimiter.contract.Call(opts, &out, "currentRateLimiterState", remoteChainSelector, isOutgoingLane) + err := _MultiAggregateRateLimiter.contract.Call(opts, &out, "currentRateLimiterState", remoteChainSelector, isOutboundLane) if err != nil { return *new(RateLimiterTokenBucket), err @@ -241,12 +241,12 @@ func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCaller) CurrentRateLi } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) CurrentRateLimiterState(remoteChainSelector uint64, isOutgoingLane bool) (RateLimiterTokenBucket, error) { - return _MultiAggregateRateLimiter.Contract.CurrentRateLimiterState(&_MultiAggregateRateLimiter.CallOpts, remoteChainSelector, isOutgoingLane) +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) CurrentRateLimiterState(remoteChainSelector uint64, isOutboundLane bool) (RateLimiterTokenBucket, error) { + return _MultiAggregateRateLimiter.Contract.CurrentRateLimiterState(&_MultiAggregateRateLimiter.CallOpts, remoteChainSelector, isOutboundLane) } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCallerSession) CurrentRateLimiterState(remoteChainSelector uint64, isOutgoingLane bool) (RateLimiterTokenBucket, error) { - return _MultiAggregateRateLimiter.Contract.CurrentRateLimiterState(&_MultiAggregateRateLimiter.CallOpts, remoteChainSelector, isOutgoingLane) +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCallerSession) CurrentRateLimiterState(remoteChainSelector uint64, isOutboundLane bool) (RateLimiterTokenBucket, error) { + return _MultiAggregateRateLimiter.Contract.CurrentRateLimiterState(&_MultiAggregateRateLimiter.CallOpts, remoteChainSelector, isOutboundLane) } func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCaller) GetAllAuthorizedCallers(opts *bind.CallOpts) ([]common.Address, error) { @@ -357,15 +357,15 @@ func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorSession) Ac return _MultiAggregateRateLimiter.Contract.AcceptOwnership(&_MultiAggregateRateLimiter.TransactOpts) } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactor) ApplyAuthorizedCallerUpdates(opts *bind.TransactOpts, authorizedCallerArgs MultiAggregateRateLimiterAuthorizedCallerArgs) (*types.Transaction, error) { +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactor) ApplyAuthorizedCallerUpdates(opts *bind.TransactOpts, authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { return _MultiAggregateRateLimiter.contract.Transact(opts, "applyAuthorizedCallerUpdates", authorizedCallerArgs) } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) ApplyAuthorizedCallerUpdates(authorizedCallerArgs MultiAggregateRateLimiterAuthorizedCallerArgs) (*types.Transaction, error) { +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) ApplyAuthorizedCallerUpdates(authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { return _MultiAggregateRateLimiter.Contract.ApplyAuthorizedCallerUpdates(&_MultiAggregateRateLimiter.TransactOpts, authorizedCallerArgs) } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorSession) ApplyAuthorizedCallerUpdates(authorizedCallerArgs MultiAggregateRateLimiterAuthorizedCallerArgs) (*types.Transaction, error) { +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorSession) ApplyAuthorizedCallerUpdates(authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { return _MultiAggregateRateLimiter.Contract.ApplyAuthorizedCallerUpdates(&_MultiAggregateRateLimiter.TransactOpts, authorizedCallerArgs) } @@ -381,28 +381,28 @@ func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorSession) Ap return _MultiAggregateRateLimiter.Contract.ApplyRateLimiterConfigUpdates(&_MultiAggregateRateLimiter.TransactOpts, rateLimiterUpdates) } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactor) OnIncomingMessage(opts *bind.TransactOpts, message ClientAny2EVMMessage) (*types.Transaction, error) { - return _MultiAggregateRateLimiter.contract.Transact(opts, "onIncomingMessage", message) +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactor) OnInboundMessage(opts *bind.TransactOpts, message ClientAny2EVMMessage) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.contract.Transact(opts, "onInboundMessage", message) } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) OnIncomingMessage(message ClientAny2EVMMessage) (*types.Transaction, error) { - return _MultiAggregateRateLimiter.Contract.OnIncomingMessage(&_MultiAggregateRateLimiter.TransactOpts, message) +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) OnInboundMessage(message ClientAny2EVMMessage) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.OnInboundMessage(&_MultiAggregateRateLimiter.TransactOpts, message) } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorSession) OnIncomingMessage(message ClientAny2EVMMessage) (*types.Transaction, error) { - return _MultiAggregateRateLimiter.Contract.OnIncomingMessage(&_MultiAggregateRateLimiter.TransactOpts, message) +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorSession) OnInboundMessage(message ClientAny2EVMMessage) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.OnInboundMessage(&_MultiAggregateRateLimiter.TransactOpts, message) } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactor) OnOutgoingMessage(opts *bind.TransactOpts, message ClientEVM2AnyMessage, destChainSelector uint64) (*types.Transaction, error) { - return _MultiAggregateRateLimiter.contract.Transact(opts, "onOutgoingMessage", message, destChainSelector) +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactor) OnOutboundMessage(opts *bind.TransactOpts, message ClientEVM2AnyMessage, destChainSelector uint64) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.contract.Transact(opts, "onOutboundMessage", message, destChainSelector) } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) OnOutgoingMessage(message ClientEVM2AnyMessage, destChainSelector uint64) (*types.Transaction, error) { - return _MultiAggregateRateLimiter.Contract.OnOutgoingMessage(&_MultiAggregateRateLimiter.TransactOpts, message, destChainSelector) +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) OnOutboundMessage(message ClientEVM2AnyMessage, destChainSelector uint64) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.OnOutboundMessage(&_MultiAggregateRateLimiter.TransactOpts, message, destChainSelector) } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorSession) OnOutgoingMessage(message ClientEVM2AnyMessage, destChainSelector uint64) (*types.Transaction, error) { - return _MultiAggregateRateLimiter.Contract.OnOutgoingMessage(&_MultiAggregateRateLimiter.TransactOpts, message, destChainSelector) +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorSession) OnOutboundMessage(message ClientEVM2AnyMessage, destChainSelector uint64) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.OnOutboundMessage(&_MultiAggregateRateLimiter.TransactOpts, message, destChainSelector) } func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactor) SetPriceRegistry(opts *bind.TransactOpts, newPriceRegistry common.Address) (*types.Transaction, error) { @@ -1243,7 +1243,7 @@ func (it *MultiAggregateRateLimiterRateLimiterConfigUpdatedIterator) Close() err type MultiAggregateRateLimiterRateLimiterConfigUpdated struct { RemoteChainSelector uint64 - IsOutgoingLane bool + IsOutboundLane bool Config RateLimiterConfig Raw types.Log } @@ -1742,7 +1742,7 @@ func (_MultiAggregateRateLimiter *MultiAggregateRateLimiter) Address() common.Ad } type MultiAggregateRateLimiterInterface interface { - CurrentRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64, isOutgoingLane bool) (RateLimiterTokenBucket, error) + CurrentRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64, isOutboundLane bool) (RateLimiterTokenBucket, error) GetAllAuthorizedCallers(opts *bind.CallOpts) ([]common.Address, error) @@ -1756,13 +1756,13 @@ type MultiAggregateRateLimiterInterface interface { AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) - ApplyAuthorizedCallerUpdates(opts *bind.TransactOpts, authorizedCallerArgs MultiAggregateRateLimiterAuthorizedCallerArgs) (*types.Transaction, error) + ApplyAuthorizedCallerUpdates(opts *bind.TransactOpts, authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) ApplyRateLimiterConfigUpdates(opts *bind.TransactOpts, rateLimiterUpdates []MultiAggregateRateLimiterRateLimiterConfigArgs) (*types.Transaction, error) - OnIncomingMessage(opts *bind.TransactOpts, message ClientAny2EVMMessage) (*types.Transaction, error) + OnInboundMessage(opts *bind.TransactOpts, message ClientAny2EVMMessage) (*types.Transaction, error) - OnOutgoingMessage(opts *bind.TransactOpts, message ClientEVM2AnyMessage, destChainSelector uint64) (*types.Transaction, error) + OnOutboundMessage(opts *bind.TransactOpts, message ClientEVM2AnyMessage, destChainSelector uint64) (*types.Transaction, error) SetPriceRegistry(opts *bind.TransactOpts, newPriceRegistry common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generated/nonce_manager/nonce_manager.go b/core/gethwrappers/ccip/generated/nonce_manager/nonce_manager.go new file mode 100644 index 0000000000..717aeb336d --- /dev/null +++ b/core/gethwrappers/ccip/generated/nonce_manager/nonce_manager.go @@ -0,0 +1,1064 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package nonce_manager + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type AuthorizedCallersAuthorizedCallerArgs struct { + AddedCallers []common.Address + RemovedCallers []common.Address +} + +type NonceManagerPreviousRamps struct { + PrevOnRamp common.Address +} + +type NonceManagerPreviousRampsArgs struct { + RemotChainSelector uint64 + PrevRamps NonceManagerPreviousRamps +} + +var NonceManagerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"authorizedCallers\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"PreviousRampAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"}],\"name\":\"PreviousOnRampUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remotChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"}],\"internalType\":\"structNonceManager.PreviousRamps\",\"name\":\"prevRamps\",\"type\":\"tuple\"}],\"internalType\":\"structNonceManager.PreviousRampsArgs[]\",\"name\":\"previousRampsArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPreviousRampsUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"getIncrementedOutboundNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"getOutboundNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getPreviousRamps\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"}],\"internalType\":\"structNonceManager.PreviousRamps\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b5060405162001659380380620016598339810160408190526200003491620004b0565b8033806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620000f6565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620001a1565b5050620005d0565b336001600160a01b03821603620001505760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000231576000828281518110620001ca57620001ca62000582565b60209081029190910101519050620001e4600282620002f0565b1562000227576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620001a9565b50815160005b8151811015620002ea57600082828151811062000258576200025862000582565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000296576040516342bcdf7f60e11b815260040160405180910390fd5b620002a360028262000310565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000237565b50505050565b600062000307836001600160a01b03841662000327565b90505b92915050565b600062000307836001600160a01b0384166200042b565b60008181526001830160205260408120548015620004205760006200034e60018362000598565b8554909150600090620003649060019062000598565b9050818114620003d057600086600001828154811062000388576200038862000582565b9060005260206000200154905080876000018481548110620003ae57620003ae62000582565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620003e457620003e4620005ba565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200030a565b60009150506200030a565b600081815260018301602052604081205462000474575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200030a565b5060006200030a565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b0381168114620004ab57600080fd5b919050565b60006020808385031215620004c457600080fd5b82516001600160401b0380821115620004dc57600080fd5b818501915085601f830112620004f157600080fd5b8151818111156200050657620005066200047d565b8060051b604051601f19603f830116810181811085821117156200052e576200052e6200047d565b6040529182528482019250838101850191888311156200054d57600080fd5b938501935b828510156200057657620005668562000493565b8452938501939285019262000552565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b818103818111156200030a57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b61107980620005e06000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c806379ba50971161007657806391a2749a1161005b57806391a2749a146101b5578063d18be31b146101c8578063f2fde38b146101db57600080fd5b806379ba5097146101855780638da5cb5b1461018d57600080fd5b80631ce2b142146100a85780632451a627146100bd578063294b5630146100db57806331b89ff314610159575b600080fd5b6100bb6100b6366004610c1d565b6101ee565b005b6100c5610363565b6040516100d29190610c92565b60405180910390f35b6101346100e9366004610d02565b604080516020808201835260009182905267ffffffffffffffff9390931681526004835281902081519283019091525473ffffffffffffffffffffffffffffffffffffffff16815290565b604051905173ffffffffffffffffffffffffffffffffffffffff1681526020016100d2565b61016c610167366004610d1f565b610374565b60405167ffffffffffffffff90911681526020016100d2565b6100bb61038b565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100d2565b6100bb6101c3366004610eba565b61048d565b61016c6101d6366004610d1f565b6104a1565b6100bb6101e9366004610f61565b610543565b6101f6610554565b60005b8181101561035e573683838381811061021457610214610f7e565b604002919091019150600090506004816102316020850185610d02565b67ffffffffffffffff1681526020810191909152604001600020805490915073ffffffffffffffffffffffffffffffffffffffff161561029d576040517fc6117ae200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6102ad6040830160208401610f61565b81547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff919091161781556102fa6020830183610d02565b815460405173ffffffffffffffffffffffffffffffffffffffff909116815267ffffffffffffffff91909116907f89d2355e2829b1e15855fec87fb400638aebc9f03728949d702d3b5d4ea999549060200160405180910390a250506001016101f9565b505050565b606061036f60026105d7565b905090565b60006103818484846105e4565b90505b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610411576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610495610554565b61049e81610732565b50565b60006104ab6108c4565b60006104b88585856105e4565b6104c3906001610fdc565b67ffffffffffffffff861660009081526005602052604090819020905191925082916104f29087908790610ffd565b908152604051908190036020019020805467ffffffffffffffff929092167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090921691909117905590509392505050565b61054b610554565b61049e81610907565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610408565b565b60606000610384836109fc565b67ffffffffffffffff831660009081526005602052604080822090518291906106109086908690610ffd565b9081526040519081900360200190205467ffffffffffffffff16905060008190036103815767ffffffffffffffff851660009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1680156107295773ffffffffffffffffffffffffffffffffffffffff811663856c824761069386880188610f61565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401602060405180830381865afa1580156106fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610720919061100d565b92505050610384565b50949350505050565b602081015160005b81518110156107cd57600082828151811061075757610757610f7e565b60200260200101519050610775816002610a5890919063ffffffff16565b156107c45760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b5060010161073a565b50815160005b81518110156108be5760008282815181106107f0576107f0610f7e565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610860576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61086b600282610a83565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a1506001016107d3565b50505050565b6108cf600233610aa5565b6105d5576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610408565b3373ffffffffffffffffffffffffffffffffffffffff821603610986576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610408565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b606081600001805480602002602001604051908101604052809291908181526020018280548015610a4c57602002820191906000526020600020905b815481526020019060010190808311610a38575b50505050509050919050565b6000610a7a8373ffffffffffffffffffffffffffffffffffffffff8416610ad4565b90505b92915050565b6000610a7a8373ffffffffffffffffffffffffffffffffffffffff8416610bce565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610a7a565b60008181526001830160205260408120548015610bbd576000610af860018361102a565b8554909150600090610b0c9060019061102a565b9050818114610b71576000866000018281548110610b2c57610b2c610f7e565b9060005260206000200154905080876000018481548110610b4f57610b4f610f7e565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610b8257610b8261103d565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610a7d565b6000915050610a7d565b5092915050565b6000818152600183016020526040812054610c1557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610a7d565b506000610a7d565b60008060208385031215610c3057600080fd5b823567ffffffffffffffff80821115610c4857600080fd5b818501915085601f830112610c5c57600080fd5b813581811115610c6b57600080fd5b8660208260061b8501011115610c8057600080fd5b60209290920196919550909350505050565b6020808252825182820181905260009190848201906040850190845b81811015610ce057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610cae565b50909695505050505050565b67ffffffffffffffff8116811461049e57600080fd5b600060208284031215610d1457600080fd5b813561038481610cec565b600080600060408486031215610d3457600080fd5b8335610d3f81610cec565b9250602084013567ffffffffffffffff80821115610d5c57600080fd5b818601915086601f830112610d7057600080fd5b813581811115610d7f57600080fd5b876020828501011115610d9157600080fd5b6020830194508093505050509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461049e57600080fd5b600082601f830112610e0657600080fd5b8135602067ffffffffffffffff80831115610e2357610e23610da4565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715610e6657610e66610da4565b6040529384526020818701810194908101925087851115610e8657600080fd5b6020870191505b84821015610eaf578135610ea081610dd3565b83529183019190830190610e8d565b979650505050505050565b600060208284031215610ecc57600080fd5b813567ffffffffffffffff80821115610ee457600080fd5b9083019060408286031215610ef857600080fd5b604051604081018181108382111715610f1357610f13610da4565b604052823582811115610f2557600080fd5b610f3187828601610df5565b825250602083013582811115610f4657600080fd5b610f5287828601610df5565b60208301525095945050505050565b600060208284031215610f7357600080fd5b813561038481610dd3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff818116838216019080821115610bc757610bc7610fad565b8183823760009101908152919050565b60006020828403121561101f57600080fd5b815161038481610cec565b81810381811115610a7d57610a7d610fad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", +} + +var NonceManagerABI = NonceManagerMetaData.ABI + +var NonceManagerBin = NonceManagerMetaData.Bin + +func DeployNonceManager(auth *bind.TransactOpts, backend bind.ContractBackend, authorizedCallers []common.Address) (common.Address, *types.Transaction, *NonceManager, error) { + parsed, err := NonceManagerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(NonceManagerBin), backend, authorizedCallers) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &NonceManager{address: address, abi: *parsed, NonceManagerCaller: NonceManagerCaller{contract: contract}, NonceManagerTransactor: NonceManagerTransactor{contract: contract}, NonceManagerFilterer: NonceManagerFilterer{contract: contract}}, nil +} + +type NonceManager struct { + address common.Address + abi abi.ABI + NonceManagerCaller + NonceManagerTransactor + NonceManagerFilterer +} + +type NonceManagerCaller struct { + contract *bind.BoundContract +} + +type NonceManagerTransactor struct { + contract *bind.BoundContract +} + +type NonceManagerFilterer struct { + contract *bind.BoundContract +} + +type NonceManagerSession struct { + Contract *NonceManager + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type NonceManagerCallerSession struct { + Contract *NonceManagerCaller + CallOpts bind.CallOpts +} + +type NonceManagerTransactorSession struct { + Contract *NonceManagerTransactor + TransactOpts bind.TransactOpts +} + +type NonceManagerRaw struct { + Contract *NonceManager +} + +type NonceManagerCallerRaw struct { + Contract *NonceManagerCaller +} + +type NonceManagerTransactorRaw struct { + Contract *NonceManagerTransactor +} + +func NewNonceManager(address common.Address, backend bind.ContractBackend) (*NonceManager, error) { + abi, err := abi.JSON(strings.NewReader(NonceManagerABI)) + if err != nil { + return nil, err + } + contract, err := bindNonceManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &NonceManager{address: address, abi: abi, NonceManagerCaller: NonceManagerCaller{contract: contract}, NonceManagerTransactor: NonceManagerTransactor{contract: contract}, NonceManagerFilterer: NonceManagerFilterer{contract: contract}}, nil +} + +func NewNonceManagerCaller(address common.Address, caller bind.ContractCaller) (*NonceManagerCaller, error) { + contract, err := bindNonceManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &NonceManagerCaller{contract: contract}, nil +} + +func NewNonceManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*NonceManagerTransactor, error) { + contract, err := bindNonceManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &NonceManagerTransactor{contract: contract}, nil +} + +func NewNonceManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*NonceManagerFilterer, error) { + contract, err := bindNonceManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &NonceManagerFilterer{contract: contract}, nil +} + +func bindNonceManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := NonceManagerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_NonceManager *NonceManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NonceManager.Contract.NonceManagerCaller.contract.Call(opts, result, method, params...) +} + +func (_NonceManager *NonceManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NonceManager.Contract.NonceManagerTransactor.contract.Transfer(opts) +} + +func (_NonceManager *NonceManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NonceManager.Contract.NonceManagerTransactor.contract.Transact(opts, method, params...) +} + +func (_NonceManager *NonceManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NonceManager.Contract.contract.Call(opts, result, method, params...) +} + +func (_NonceManager *NonceManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NonceManager.Contract.contract.Transfer(opts) +} + +func (_NonceManager *NonceManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NonceManager.Contract.contract.Transact(opts, method, params...) +} + +func (_NonceManager *NonceManagerCaller) GetAllAuthorizedCallers(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _NonceManager.contract.Call(opts, &out, "getAllAuthorizedCallers") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_NonceManager *NonceManagerSession) GetAllAuthorizedCallers() ([]common.Address, error) { + return _NonceManager.Contract.GetAllAuthorizedCallers(&_NonceManager.CallOpts) +} + +func (_NonceManager *NonceManagerCallerSession) GetAllAuthorizedCallers() ([]common.Address, error) { + return _NonceManager.Contract.GetAllAuthorizedCallers(&_NonceManager.CallOpts) +} + +func (_NonceManager *NonceManagerCaller) GetOutboundNonce(opts *bind.CallOpts, destChainSelector uint64, sender []byte) (uint64, error) { + var out []interface{} + err := _NonceManager.contract.Call(opts, &out, "getOutboundNonce", destChainSelector, sender) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_NonceManager *NonceManagerSession) GetOutboundNonce(destChainSelector uint64, sender []byte) (uint64, error) { + return _NonceManager.Contract.GetOutboundNonce(&_NonceManager.CallOpts, destChainSelector, sender) +} + +func (_NonceManager *NonceManagerCallerSession) GetOutboundNonce(destChainSelector uint64, sender []byte) (uint64, error) { + return _NonceManager.Contract.GetOutboundNonce(&_NonceManager.CallOpts, destChainSelector, sender) +} + +func (_NonceManager *NonceManagerCaller) GetPreviousRamps(opts *bind.CallOpts, chainSelector uint64) (NonceManagerPreviousRamps, error) { + var out []interface{} + err := _NonceManager.contract.Call(opts, &out, "getPreviousRamps", chainSelector) + + if err != nil { + return *new(NonceManagerPreviousRamps), err + } + + out0 := *abi.ConvertType(out[0], new(NonceManagerPreviousRamps)).(*NonceManagerPreviousRamps) + + return out0, err + +} + +func (_NonceManager *NonceManagerSession) GetPreviousRamps(chainSelector uint64) (NonceManagerPreviousRamps, error) { + return _NonceManager.Contract.GetPreviousRamps(&_NonceManager.CallOpts, chainSelector) +} + +func (_NonceManager *NonceManagerCallerSession) GetPreviousRamps(chainSelector uint64) (NonceManagerPreviousRamps, error) { + return _NonceManager.Contract.GetPreviousRamps(&_NonceManager.CallOpts, chainSelector) +} + +func (_NonceManager *NonceManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NonceManager.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_NonceManager *NonceManagerSession) Owner() (common.Address, error) { + return _NonceManager.Contract.Owner(&_NonceManager.CallOpts) +} + +func (_NonceManager *NonceManagerCallerSession) Owner() (common.Address, error) { + return _NonceManager.Contract.Owner(&_NonceManager.CallOpts) +} + +func (_NonceManager *NonceManagerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NonceManager.contract.Transact(opts, "acceptOwnership") +} + +func (_NonceManager *NonceManagerSession) AcceptOwnership() (*types.Transaction, error) { + return _NonceManager.Contract.AcceptOwnership(&_NonceManager.TransactOpts) +} + +func (_NonceManager *NonceManagerTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _NonceManager.Contract.AcceptOwnership(&_NonceManager.TransactOpts) +} + +func (_NonceManager *NonceManagerTransactor) ApplyAuthorizedCallerUpdates(opts *bind.TransactOpts, authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { + return _NonceManager.contract.Transact(opts, "applyAuthorizedCallerUpdates", authorizedCallerArgs) +} + +func (_NonceManager *NonceManagerSession) ApplyAuthorizedCallerUpdates(authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { + return _NonceManager.Contract.ApplyAuthorizedCallerUpdates(&_NonceManager.TransactOpts, authorizedCallerArgs) +} + +func (_NonceManager *NonceManagerTransactorSession) ApplyAuthorizedCallerUpdates(authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { + return _NonceManager.Contract.ApplyAuthorizedCallerUpdates(&_NonceManager.TransactOpts, authorizedCallerArgs) +} + +func (_NonceManager *NonceManagerTransactor) ApplyPreviousRampsUpdates(opts *bind.TransactOpts, previousRampsArgs []NonceManagerPreviousRampsArgs) (*types.Transaction, error) { + return _NonceManager.contract.Transact(opts, "applyPreviousRampsUpdates", previousRampsArgs) +} + +func (_NonceManager *NonceManagerSession) ApplyPreviousRampsUpdates(previousRampsArgs []NonceManagerPreviousRampsArgs) (*types.Transaction, error) { + return _NonceManager.Contract.ApplyPreviousRampsUpdates(&_NonceManager.TransactOpts, previousRampsArgs) +} + +func (_NonceManager *NonceManagerTransactorSession) ApplyPreviousRampsUpdates(previousRampsArgs []NonceManagerPreviousRampsArgs) (*types.Transaction, error) { + return _NonceManager.Contract.ApplyPreviousRampsUpdates(&_NonceManager.TransactOpts, previousRampsArgs) +} + +func (_NonceManager *NonceManagerTransactor) GetIncrementedOutboundNonce(opts *bind.TransactOpts, destChainSelector uint64, sender []byte) (*types.Transaction, error) { + return _NonceManager.contract.Transact(opts, "getIncrementedOutboundNonce", destChainSelector, sender) +} + +func (_NonceManager *NonceManagerSession) GetIncrementedOutboundNonce(destChainSelector uint64, sender []byte) (*types.Transaction, error) { + return _NonceManager.Contract.GetIncrementedOutboundNonce(&_NonceManager.TransactOpts, destChainSelector, sender) +} + +func (_NonceManager *NonceManagerTransactorSession) GetIncrementedOutboundNonce(destChainSelector uint64, sender []byte) (*types.Transaction, error) { + return _NonceManager.Contract.GetIncrementedOutboundNonce(&_NonceManager.TransactOpts, destChainSelector, sender) +} + +func (_NonceManager *NonceManagerTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _NonceManager.contract.Transact(opts, "transferOwnership", to) +} + +func (_NonceManager *NonceManagerSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _NonceManager.Contract.TransferOwnership(&_NonceManager.TransactOpts, to) +} + +func (_NonceManager *NonceManagerTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _NonceManager.Contract.TransferOwnership(&_NonceManager.TransactOpts, to) +} + +type NonceManagerAuthorizedCallerAddedIterator struct { + Event *NonceManagerAuthorizedCallerAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *NonceManagerAuthorizedCallerAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(NonceManagerAuthorizedCallerAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(NonceManagerAuthorizedCallerAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *NonceManagerAuthorizedCallerAddedIterator) Error() error { + return it.fail +} + +func (it *NonceManagerAuthorizedCallerAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type NonceManagerAuthorizedCallerAdded struct { + Caller common.Address + Raw types.Log +} + +func (_NonceManager *NonceManagerFilterer) FilterAuthorizedCallerAdded(opts *bind.FilterOpts) (*NonceManagerAuthorizedCallerAddedIterator, error) { + + logs, sub, err := _NonceManager.contract.FilterLogs(opts, "AuthorizedCallerAdded") + if err != nil { + return nil, err + } + return &NonceManagerAuthorizedCallerAddedIterator{contract: _NonceManager.contract, event: "AuthorizedCallerAdded", logs: logs, sub: sub}, nil +} + +func (_NonceManager *NonceManagerFilterer) WatchAuthorizedCallerAdded(opts *bind.WatchOpts, sink chan<- *NonceManagerAuthorizedCallerAdded) (event.Subscription, error) { + + logs, sub, err := _NonceManager.contract.WatchLogs(opts, "AuthorizedCallerAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(NonceManagerAuthorizedCallerAdded) + if err := _NonceManager.contract.UnpackLog(event, "AuthorizedCallerAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_NonceManager *NonceManagerFilterer) ParseAuthorizedCallerAdded(log types.Log) (*NonceManagerAuthorizedCallerAdded, error) { + event := new(NonceManagerAuthorizedCallerAdded) + if err := _NonceManager.contract.UnpackLog(event, "AuthorizedCallerAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type NonceManagerAuthorizedCallerRemovedIterator struct { + Event *NonceManagerAuthorizedCallerRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *NonceManagerAuthorizedCallerRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(NonceManagerAuthorizedCallerRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(NonceManagerAuthorizedCallerRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *NonceManagerAuthorizedCallerRemovedIterator) Error() error { + return it.fail +} + +func (it *NonceManagerAuthorizedCallerRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type NonceManagerAuthorizedCallerRemoved struct { + Caller common.Address + Raw types.Log +} + +func (_NonceManager *NonceManagerFilterer) FilterAuthorizedCallerRemoved(opts *bind.FilterOpts) (*NonceManagerAuthorizedCallerRemovedIterator, error) { + + logs, sub, err := _NonceManager.contract.FilterLogs(opts, "AuthorizedCallerRemoved") + if err != nil { + return nil, err + } + return &NonceManagerAuthorizedCallerRemovedIterator{contract: _NonceManager.contract, event: "AuthorizedCallerRemoved", logs: logs, sub: sub}, nil +} + +func (_NonceManager *NonceManagerFilterer) WatchAuthorizedCallerRemoved(opts *bind.WatchOpts, sink chan<- *NonceManagerAuthorizedCallerRemoved) (event.Subscription, error) { + + logs, sub, err := _NonceManager.contract.WatchLogs(opts, "AuthorizedCallerRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(NonceManagerAuthorizedCallerRemoved) + if err := _NonceManager.contract.UnpackLog(event, "AuthorizedCallerRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_NonceManager *NonceManagerFilterer) ParseAuthorizedCallerRemoved(log types.Log) (*NonceManagerAuthorizedCallerRemoved, error) { + event := new(NonceManagerAuthorizedCallerRemoved) + if err := _NonceManager.contract.UnpackLog(event, "AuthorizedCallerRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type NonceManagerOwnershipTransferRequestedIterator struct { + Event *NonceManagerOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *NonceManagerOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(NonceManagerOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(NonceManagerOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *NonceManagerOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *NonceManagerOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type NonceManagerOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_NonceManager *NonceManagerFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*NonceManagerOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _NonceManager.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &NonceManagerOwnershipTransferRequestedIterator{contract: _NonceManager.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_NonceManager *NonceManagerFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *NonceManagerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _NonceManager.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(NonceManagerOwnershipTransferRequested) + if err := _NonceManager.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_NonceManager *NonceManagerFilterer) ParseOwnershipTransferRequested(log types.Log) (*NonceManagerOwnershipTransferRequested, error) { + event := new(NonceManagerOwnershipTransferRequested) + if err := _NonceManager.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type NonceManagerOwnershipTransferredIterator struct { + Event *NonceManagerOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *NonceManagerOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(NonceManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(NonceManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *NonceManagerOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *NonceManagerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type NonceManagerOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_NonceManager *NonceManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*NonceManagerOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _NonceManager.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &NonceManagerOwnershipTransferredIterator{contract: _NonceManager.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_NonceManager *NonceManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *NonceManagerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _NonceManager.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(NonceManagerOwnershipTransferred) + if err := _NonceManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_NonceManager *NonceManagerFilterer) ParseOwnershipTransferred(log types.Log) (*NonceManagerOwnershipTransferred, error) { + event := new(NonceManagerOwnershipTransferred) + if err := _NonceManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type NonceManagerPreviousOnRampUpdatedIterator struct { + Event *NonceManagerPreviousOnRampUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *NonceManagerPreviousOnRampUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(NonceManagerPreviousOnRampUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(NonceManagerPreviousOnRampUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *NonceManagerPreviousOnRampUpdatedIterator) Error() error { + return it.fail +} + +func (it *NonceManagerPreviousOnRampUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type NonceManagerPreviousOnRampUpdated struct { + DestChainSelector uint64 + PrevOnRamp common.Address + Raw types.Log +} + +func (_NonceManager *NonceManagerFilterer) FilterPreviousOnRampUpdated(opts *bind.FilterOpts, destChainSelector []uint64) (*NonceManagerPreviousOnRampUpdatedIterator, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _NonceManager.contract.FilterLogs(opts, "PreviousOnRampUpdated", destChainSelectorRule) + if err != nil { + return nil, err + } + return &NonceManagerPreviousOnRampUpdatedIterator{contract: _NonceManager.contract, event: "PreviousOnRampUpdated", logs: logs, sub: sub}, nil +} + +func (_NonceManager *NonceManagerFilterer) WatchPreviousOnRampUpdated(opts *bind.WatchOpts, sink chan<- *NonceManagerPreviousOnRampUpdated, destChainSelector []uint64) (event.Subscription, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _NonceManager.contract.WatchLogs(opts, "PreviousOnRampUpdated", destChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(NonceManagerPreviousOnRampUpdated) + if err := _NonceManager.contract.UnpackLog(event, "PreviousOnRampUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_NonceManager *NonceManagerFilterer) ParsePreviousOnRampUpdated(log types.Log) (*NonceManagerPreviousOnRampUpdated, error) { + event := new(NonceManagerPreviousOnRampUpdated) + if err := _NonceManager.contract.UnpackLog(event, "PreviousOnRampUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_NonceManager *NonceManager) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _NonceManager.abi.Events["AuthorizedCallerAdded"].ID: + return _NonceManager.ParseAuthorizedCallerAdded(log) + case _NonceManager.abi.Events["AuthorizedCallerRemoved"].ID: + return _NonceManager.ParseAuthorizedCallerRemoved(log) + case _NonceManager.abi.Events["OwnershipTransferRequested"].ID: + return _NonceManager.ParseOwnershipTransferRequested(log) + case _NonceManager.abi.Events["OwnershipTransferred"].ID: + return _NonceManager.ParseOwnershipTransferred(log) + case _NonceManager.abi.Events["PreviousOnRampUpdated"].ID: + return _NonceManager.ParsePreviousOnRampUpdated(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (NonceManagerAuthorizedCallerAdded) Topic() common.Hash { + return common.HexToHash("0xeb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef") +} + +func (NonceManagerAuthorizedCallerRemoved) Topic() common.Hash { + return common.HexToHash("0xc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda77580") +} + +func (NonceManagerOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (NonceManagerOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (NonceManagerPreviousOnRampUpdated) Topic() common.Hash { + return common.HexToHash("0x89d2355e2829b1e15855fec87fb400638aebc9f03728949d702d3b5d4ea99954") +} + +func (_NonceManager *NonceManager) Address() common.Address { + return _NonceManager.address +} + +type NonceManagerInterface interface { + GetAllAuthorizedCallers(opts *bind.CallOpts) ([]common.Address, error) + + GetOutboundNonce(opts *bind.CallOpts, destChainSelector uint64, sender []byte) (uint64, error) + + GetPreviousRamps(opts *bind.CallOpts, chainSelector uint64) (NonceManagerPreviousRamps, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyAuthorizedCallerUpdates(opts *bind.TransactOpts, authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) + + ApplyPreviousRampsUpdates(opts *bind.TransactOpts, previousRampsArgs []NonceManagerPreviousRampsArgs) (*types.Transaction, error) + + GetIncrementedOutboundNonce(opts *bind.TransactOpts, destChainSelector uint64, sender []byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterAuthorizedCallerAdded(opts *bind.FilterOpts) (*NonceManagerAuthorizedCallerAddedIterator, error) + + WatchAuthorizedCallerAdded(opts *bind.WatchOpts, sink chan<- *NonceManagerAuthorizedCallerAdded) (event.Subscription, error) + + ParseAuthorizedCallerAdded(log types.Log) (*NonceManagerAuthorizedCallerAdded, error) + + FilterAuthorizedCallerRemoved(opts *bind.FilterOpts) (*NonceManagerAuthorizedCallerRemovedIterator, error) + + WatchAuthorizedCallerRemoved(opts *bind.WatchOpts, sink chan<- *NonceManagerAuthorizedCallerRemoved) (event.Subscription, error) + + ParseAuthorizedCallerRemoved(log types.Log) (*NonceManagerAuthorizedCallerRemoved, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*NonceManagerOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *NonceManagerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*NonceManagerOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*NonceManagerOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *NonceManagerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*NonceManagerOwnershipTransferred, error) + + FilterPreviousOnRampUpdated(opts *bind.FilterOpts, destChainSelector []uint64) (*NonceManagerPreviousOnRampUpdatedIterator, error) + + WatchPreviousOnRampUpdated(opts *bind.WatchOpts, sink chan<- *NonceManagerPreviousOnRampUpdated, destChainSelector []uint64) (event.Subscription, error) + + ParsePreviousOnRampUpdated(log types.Log) (*NonceManagerPreviousOnRampUpdated, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index bd627364d8..35d6966230 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -5,12 +5,12 @@ burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin fee3f82935ce7a26c65e12f19a472a4fccdae62755abdb42d8b0a01f0f06981a burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin c7efa00d2be62a97a814730c8e13aa70794ebfdd38a9f3b3c11554a5dfd70478 burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin a0728e186af74968101135a58a483320ced9ab79b22b1b24ac6994254ee79097 +ccip_capability_configuration: ../../../contracts/solc/v0.8.24/CCIPCapabilityConfiguration/CCIPCapabilityConfiguration.abi ../../../contracts/solc/v0.8.24/CCIPCapabilityConfiguration/CCIPCapabilityConfiguration.bin 75d617a77f82e09a8a4453689fa730a1f369dcf906de750126a3c782b3f885e9 commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin ddc26c10c2a52b59624faae9005827b09b98db4566887a736005e8cc37cf8a51 commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin ebd8aac686fa28a71d4212bcd25a28f8f640d50dce5e50498b2f6b8534890b69 -custom_token_pool: ../../../contracts/solc/v0.8.24/CustomTokenPool/CustomTokenPool.abi ../../../contracts/solc/v0.8.24/CustomTokenPool/CustomTokenPool.bin 488bd34d63be7b731f4fbdf0cd353f7e4fbee990cfa4db26be91973297d3f803 ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de -evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin c6f23bb7bb4f59807a0f3405557c6ad633f1ba441e12b44e135681290f22c51e -evm_2_evm_multi_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.bin da3b401b00dae39a2851740d00f2ed81d498ad9287b7ab9276f8b10021743d20 +evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin 10d6c838592c1f928fc23a7ba0bd95dcca76ccbb0205b424b21dd16e6feb0294 +evm_2_evm_multi_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.bin fc892dd148dc7147439443322d7ff7b878a35a61c5111094c7a3dd97805dc068 evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin b6132cb22370d62b1b20174bbe832ec87df61f6ab65f7fe2515733bdd10a30f5 evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin 383e9930fbc1b7fbb6554cc8857229d207fd6742e87c7fb1a37002347e8de8e2 lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin c65c226e1e4d38414bd4a1b76fc8aca3cb3dd98df61268424c44564f455d3752 @@ -20,7 +20,8 @@ mock_arm_contract: ../../../contracts/solc/v0.8.24/MockRMN/MockRMN.abi ../../../ mock_usdc_token_messenger: ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.bin e0cf17a38b438239fc6294ddca88f86b6c39e4542aefd9815b2d92987191b8bd mock_usdc_token_transmitter: ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.bin 33bdad70822e889de7c720ed20085cf9cd3f8eba8b68f26bd6535197749595fe mock_v3_aggregator_contract: ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.abi ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.bin 518e19efa2ff52b0fefd8e597b05765317ee7638189bfe34ca43de2f6599faf4 -multi_aggregate_rate_limiter: ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.abi ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.bin 973e51e0e96758c85b52ae699b1d2f978f8ed3d42508b17b8c78a72d19ef4ddc +multi_aggregate_rate_limiter: ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.abi ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.bin 2c88280a2d8c485bc775b8cce6acc77a687216a22b3805b038f689bbc80d4626 +nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin cdc11c1ab4c1c3fd77f30215e9c579404a6e60eb9adc213d73ca0773c3bb5784 ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin 1588313bb5e781d181a825247d30828f59007700f36b4b9b00391592b06ff4b4 price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin 68d1a92a6b7d6a864ef23723984723848d90bbdf58e49391c6767fe2bfb6c5a7 registry_module_owner_custom: ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin cbe7698bfd811b485ac3856daf073a7bdebeefdf2583403ca4a19d5b7e2d4ae8 diff --git a/core/gethwrappers/ccip/go_generate.go b/core/gethwrappers/ccip/go_generate.go index 2961094925..57a05ae411 100644 --- a/core/gethwrappers/ccip/go_generate.go +++ b/core/gethwrappers/ccip/go_generate.go @@ -28,6 +28,7 @@ package ccip //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.abi ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.bin MultiAggregateRateLimiter multi_aggregate_rate_limiter //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin Router router //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin PriceRegistry price_registry +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/CCIPCapabilityConfiguration/CCIPCapabilityConfiguration.abi ../../../contracts/solc/v0.8.24/CCIPCapabilityConfiguration/CCIPCapabilityConfiguration.bin CCIPCapabilityConfiguration ccip_capability_configuration //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin MaybeRevertMessageReceiver maybe_revert_message_receiver //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin PingPongDemo ping_pong_demo diff --git a/core/services/ocr2/plugins/ccip/ccipcommit/initializers.go b/core/services/ocr2/plugins/ccip/ccipcommit/initializers.go index e61195e01d..97730ce85b 100644 --- a/core/services/ocr2/plugins/ccip/ccipcommit/initializers.go +++ b/core/services/ocr2/plugins/ccip/ccipcommit/initializers.go @@ -106,7 +106,7 @@ func UnregisterCommitPluginLpFilters(ctx context.Context, lggr logger.Logger, jb versionFinder := factory.NewEvmVersionFinder() unregisterFuncs := []func() error{ func() error { - return factory.CloseCommitStoreReader(lggr, versionFinder, params.commitStoreAddress, params.destChain.Client(), params.destChain.LogPoller(), params.sourceChain.GasEstimator(), params.sourceChain.Config().EVM().GasEstimator().PriceMax().ToInt()) + return factory.CloseCommitStoreReader(lggr, versionFinder, params.commitStoreAddress, params.destChain.Client(), params.destChain.LogPoller()) }, func() error { return factory.CloseOnRampReader(lggr, versionFinder, params.commitStoreStaticCfg.SourceChainSelector, params.commitStoreStaticCfg.ChainSelector, cciptypes.Address(params.commitStoreStaticCfg.OnRamp.String()), params.sourceChain.LogPoller(), params.sourceChain.Client()) @@ -140,10 +140,21 @@ func jobSpecToCommitPluginConfig(ctx context.Context, orm cciporm.ORM, lggr logg "DestChainSelector", params.commitStoreStaticCfg.ChainSelector) versionFinder := factory.NewEvmVersionFinder() - commitStoreReader, err := factory.NewCommitStoreReader(lggr, versionFinder, params.commitStoreAddress, params.destChain.Client(), params.destChain.LogPoller(), params.sourceChain.GasEstimator(), params.sourceChain.Config().EVM().GasEstimator().PriceMax().ToInt()) + commitStoreReader, err := factory.NewCommitStoreReader(lggr, versionFinder, params.commitStoreAddress, params.destChain.Client(), params.destChain.LogPoller()) if err != nil { return nil, nil, nil, nil, errors.Wrap(err, "could not create commitStore reader") } + + err = commitStoreReader.SetGasEstimator(ctx, params.sourceChain.GasEstimator()) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("could not set gas estimator: %w", err) + } + + err = commitStoreReader.SetSourceMaxGasPrice(ctx, params.sourceChain.Config().EVM().GasEstimator().PriceMax().ToInt()) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("could not set source max gas price: %w", err) + } + sourceChainName, destChainName, err := ccipconfig.ResolveChainNames(params.sourceChain.ID().Int64(), params.destChain.ID().Int64()) if err != nil { return nil, nil, nil, nil, err diff --git a/core/services/ocr2/plugins/ccip/ccipcommit/ocr2_test.go b/core/services/ocr2/plugins/ccip/ccipcommit/ocr2_test.go index 9fdc3dbbf9..e121a8906d 100644 --- a/core/services/ocr2/plugins/ccip/ccipcommit/ocr2_test.go +++ b/core/services/ocr2/plugins/ccip/ccipcommit/ocr2_test.go @@ -344,7 +344,7 @@ func TestCommitReportingPlugin_Report(t *testing.T) { })).Return(destDecimals, nil).Maybe() lp := mocks2.NewLogPoller(t) - commitStoreReader, err := v1_2_0.NewCommitStore(logger.TestLogger(t), utils.RandomAddress(), nil, lp, nil, nil) + commitStoreReader, err := v1_2_0.NewCommitStore(logger.TestLogger(t), utils.RandomAddress(), nil, lp) assert.NoError(t, err) healthCheck := ccipcachemocks.NewChainHealthcheck(t) diff --git a/core/services/ocr2/plugins/ccip/ccipexec/initializers.go b/core/services/ocr2/plugins/ccip/ccipexec/initializers.go index e27816a8b2..9631a59676 100644 --- a/core/services/ocr2/plugins/ccip/ccipexec/initializers.go +++ b/core/services/ocr2/plugins/ccip/ccipexec/initializers.go @@ -113,7 +113,7 @@ func UnregisterExecPluginLpFilters(ctx context.Context, lggr logger.Logger, jb j versionFinder := factory.NewEvmVersionFinder() unregisterFuncs := []func() error{ func() error { - return factory.CloseCommitStoreReader(lggr, versionFinder, params.offRampConfig.CommitStore, params.destChain.Client(), params.destChain.LogPoller(), params.sourceChain.GasEstimator(), params.sourceChain.Config().EVM().GasEstimator().PriceMax().ToInt()) + return factory.CloseCommitStoreReader(lggr, versionFinder, params.offRampConfig.CommitStore, params.destChain.Client(), params.destChain.LogPoller()) }, func() error { return factory.CloseOnRampReader(lggr, versionFinder, params.offRampConfig.SourceChainSelector, params.offRampConfig.ChainSelector, params.offRampConfig.OnRamp, params.sourceChain.LogPoller(), params.sourceChain.Client()) @@ -223,11 +223,21 @@ func jobSpecToExecPluginConfig(ctx context.Context, lggr logger.Logger, jb job.J return nil, nil, nil, nil, errors.Wrap(err, "could not get source native token") } - commitStoreReader, err := factory.NewCommitStoreReader(lggr, versionFinder, params.offRampConfig.CommitStore, params.destChain.Client(), params.destChain.LogPoller(), params.sourceChain.GasEstimator(), params.sourceChain.Config().EVM().GasEstimator().PriceMax().ToInt()) + commitStoreReader, err := factory.NewCommitStoreReader(lggr, versionFinder, params.offRampConfig.CommitStore, params.destChain.Client(), params.destChain.LogPoller()) if err != nil { return nil, nil, nil, nil, errors.Wrap(err, "could not load commitStoreReader reader") } + err = commitStoreReader.SetGasEstimator(ctx, params.sourceChain.GasEstimator()) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("could not set gas estimator: %w", err) + } + + err = commitStoreReader.SetSourceMaxGasPrice(ctx, params.sourceChain.Config().EVM().GasEstimator().PriceMax().ToInt()) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("could not set source max gas price: %w", err) + } + tokenDataProviders, err := initTokenDataProviders(lggr, jobIDToString(jb.ID), params.pluginConfig, params.sourceChain.LogPoller()) if err != nil { return nil, nil, nil, nil, errors.Wrap(err, "could not get token data providers") diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go index 1284e93420..a0d84e403d 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go @@ -1,8 +1,12 @@ package ccipdata import ( + "context" + "math/big" "time" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" @@ -56,6 +60,8 @@ func NewCommitOffchainConfig( //go:generate mockery --quiet --name CommitStoreReader --filename commit_store_reader_mock.go --case=underscore type CommitStoreReader interface { cciptypes.CommitStoreReader + SetGasEstimator(ctx context.Context, gpe gas.EvmFeeEstimator) error + SetSourceMaxGasPrice(ctx context.Context, sourceMaxGasPrice *big.Int) error } // FetchCommitStoreStaticConfig provides access to a commitStore's static config, which is required to access the source chain ID. diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go index e94e11eb52..bf5e450f48 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go @@ -189,10 +189,18 @@ func TestCommitStoreReaders(t *testing.T) { ge.On("L1Oracle").Return(lm) maxGasPrice := big.NewInt(1e8) - c10r, err := factory.NewCommitStoreReader(lggr, factory.NewEvmVersionFinder(), ccipcalc.EvmAddrToGeneric(addr), ec, lp, ge, maxGasPrice) + c10r, err := factory.NewCommitStoreReader(lggr, factory.NewEvmVersionFinder(), ccipcalc.EvmAddrToGeneric(addr), ec, lp) // ge, maxGasPrice + require.NoError(t, err) + err = c10r.SetGasEstimator(ctx, ge) + require.NoError(t, err) + err = c10r.SetSourceMaxGasPrice(ctx, maxGasPrice) require.NoError(t, err) assert.Equal(t, reflect.TypeOf(c10r).String(), reflect.TypeOf(&v1_0_0.CommitStore{}).String()) - c12r, err := factory.NewCommitStoreReader(lggr, factory.NewEvmVersionFinder(), ccipcalc.EvmAddrToGeneric(addr2), ec, lp, ge, maxGasPrice) + c12r, err := factory.NewCommitStoreReader(lggr, factory.NewEvmVersionFinder(), ccipcalc.EvmAddrToGeneric(addr2), ec, lp) + require.NoError(t, err) + err = c12r.SetGasEstimator(ctx, ge) + require.NoError(t, err) + err = c12r.SetSourceMaxGasPrice(ctx, maxGasPrice) require.NoError(t, err) assert.Equal(t, reflect.TypeOf(c12r).String(), reflect.TypeOf(&v1_2_0.CommitStore{}).String()) @@ -399,7 +407,7 @@ func TestNewCommitStoreReader(t *testing.T) { if tc.expectedErr == "" { lp.On("RegisterFilter", mock.Anything, mock.Anything).Return(nil) } - _, err = factory.NewCommitStoreReader(logger.TestLogger(t), factory.NewEvmVersionFinder(), addr, c, lp, nil, nil) + _, err = factory.NewCommitStoreReader(logger.TestLogger(t), factory.NewEvmVersionFinder(), addr, c, lp) if tc.expectedErr != "" { require.EqualError(t, err, tc.expectedErr) } else { diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store.go index d4e93b89ea..d431d2863a 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store.go @@ -1,15 +1,12 @@ package factory import ( - "math/big" - "github.com/Masterminds/semver/v3" "github.com/pkg/errors" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" @@ -24,16 +21,16 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0" ) -func NewCommitStoreReader(lggr logger.Logger, versionFinder VersionFinder, address cciptypes.Address, ec client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator, sourceMaxGasPrice *big.Int) (ccipdata.CommitStoreReader, error) { - return initOrCloseCommitStoreReader(lggr, versionFinder, address, ec, lp, estimator, sourceMaxGasPrice, false) +func NewCommitStoreReader(lggr logger.Logger, versionFinder VersionFinder, address cciptypes.Address, ec client.Client, lp logpoller.LogPoller) (ccipdata.CommitStoreReader, error) { + return initOrCloseCommitStoreReader(lggr, versionFinder, address, ec, lp, false) } -func CloseCommitStoreReader(lggr logger.Logger, versionFinder VersionFinder, address cciptypes.Address, ec client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator, sourceMaxGasPrice *big.Int) error { - _, err := initOrCloseCommitStoreReader(lggr, versionFinder, address, ec, lp, estimator, sourceMaxGasPrice, true) +func CloseCommitStoreReader(lggr logger.Logger, versionFinder VersionFinder, address cciptypes.Address, ec client.Client, lp logpoller.LogPoller) error { + _, err := initOrCloseCommitStoreReader(lggr, versionFinder, address, ec, lp, true) return err } -func initOrCloseCommitStoreReader(lggr logger.Logger, versionFinder VersionFinder, address cciptypes.Address, ec client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator, sourceMaxGasPrice *big.Int, closeReader bool) (ccipdata.CommitStoreReader, error) { +func initOrCloseCommitStoreReader(lggr logger.Logger, versionFinder VersionFinder, address cciptypes.Address, ec client.Client, lp logpoller.LogPoller, closeReader bool) (ccipdata.CommitStoreReader, error) { contractType, version, err := versionFinder.TypeAndVersion(address, ec) if err != nil { return nil, errors.Wrapf(err, "unable to read type and version") @@ -47,11 +44,11 @@ func initOrCloseCommitStoreReader(lggr logger.Logger, versionFinder VersionFinde return nil, err } - lggr.Infow("Initializing CommitStore Reader", "version", version.String(), "sourceMaxGasPrice", sourceMaxGasPrice.String()) + lggr.Infow("Initializing CommitStore Reader", "version", version.String()) switch version.String() { case ccipdata.V1_0_0, ccipdata.V1_1_0: // Versions are identical - cs, err := v1_0_0.NewCommitStore(lggr, evmAddr, ec, lp, estimator, sourceMaxGasPrice) + cs, err := v1_0_0.NewCommitStore(lggr, evmAddr, ec, lp) if err != nil { return nil, err } @@ -60,7 +57,7 @@ func initOrCloseCommitStoreReader(lggr logger.Logger, versionFinder VersionFinde } return cs, cs.RegisterFilters() case ccipdata.V1_2_0: - cs, err := v1_2_0.NewCommitStore(lggr, evmAddr, ec, lp, estimator, sourceMaxGasPrice) + cs, err := v1_2_0.NewCommitStore(lggr, evmAddr, ec, lp) if err != nil { return nil, err } @@ -69,7 +66,7 @@ func initOrCloseCommitStoreReader(lggr logger.Logger, versionFinder VersionFinde } return cs, cs.RegisterFilters() case ccipdata.V1_5_0: - cs, err := v1_5_0.NewCommitStore(lggr, evmAddr, ec, lp, estimator, sourceMaxGasPrice) + cs, err := v1_5_0.NewCommitStore(lggr, evmAddr, ec, lp) if err != nil { return nil, err } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store_test.go index ddf3ea1827..e1b8ff929c 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store_test.go @@ -26,12 +26,12 @@ func TestCommitStore(t *testing.T) { lp.On("RegisterFilter", mock.Anything, mock.Anything).Return(nil) versionFinder := newMockVersionFinder(ccipconfig.CommitStore, *semver.MustParse(versionStr), nil) - _, err := NewCommitStoreReader(lggr, versionFinder, addr, nil, lp, nil, nil) + _, err := NewCommitStoreReader(lggr, versionFinder, addr, nil, lp) assert.NoError(t, err) expFilterName := logpoller.FilterName(v1_0_0.EXEC_REPORT_ACCEPTS, addr) lp.On("UnregisterFilter", mock.Anything, expFilterName).Return(nil) - err = CloseCommitStoreReader(lggr, versionFinder, addr, nil, lp, nil, nil) + err = CloseCommitStoreReader(lggr, versionFinder, addr, nil, lp) assert.NoError(t, err) } } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/commit_store_reader_mock.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/commit_store_reader_mock.go index 3690f9273f..5f884e11de 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/commit_store_reader_mock.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/commit_store_reader_mock.go @@ -3,10 +3,14 @@ package mocks import ( + big "math/big" + ccip "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" context "context" + gas "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + mock "github.com/stretchr/testify/mock" time "time" @@ -407,6 +411,42 @@ func (_m *CommitStoreReader) OffchainConfig(ctx context.Context) (ccip.CommitOff return r0, r1 } +// SetGasEstimator provides a mock function with given fields: ctx, gpe +func (_m *CommitStoreReader) SetGasEstimator(ctx context.Context, gpe gas.EvmFeeEstimator) error { + ret := _m.Called(ctx, gpe) + + if len(ret) == 0 { + panic("no return value specified for SetGasEstimator") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, gas.EvmFeeEstimator) error); ok { + r0 = rf(ctx, gpe) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// SetSourceMaxGasPrice provides a mock function with given fields: ctx, sourceMaxGasPrice +func (_m *CommitStoreReader) SetSourceMaxGasPrice(ctx context.Context, sourceMaxGasPrice *big.Int) error { + ret := _m.Called(ctx, sourceMaxGasPrice) + + if len(ret) == 0 { + panic("no return value specified for SetSourceMaxGasPrice") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *big.Int) error); ok { + r0 = rf(ctx, sourceMaxGasPrice) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // VerifyExecutionReport provides a mock function with given fields: ctx, report func (_m *CommitStoreReader) VerifyExecutionReport(ctx context.Context, report ccip.ExecReport) (bool, error) { ret := _m.Called(ctx, report) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store.go index 75087a537a..cfdf4d031b 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store.go @@ -44,7 +44,7 @@ type CommitStore struct { lggr logger.Logger lp logpoller.LogPoller address common.Address - estimator gas.EvmFeeEstimator + estimator *gas.EvmFeeEstimator sourceMaxGasPrice *big.Int filters []logpoller.Filter reportAcceptedSig common.Hash @@ -183,6 +183,20 @@ func (c *CommitStore) GasPriceEstimator(context.Context) (cciptypes.GasPriceEsti return c.gasPriceEstimator, nil } +func (c *CommitStore) SetGasEstimator(ctx context.Context, gpe gas.EvmFeeEstimator) error { + c.configMu.RLock() + defer c.configMu.RUnlock() + c.estimator = &gpe + return nil +} + +func (c *CommitStore) SetSourceMaxGasPrice(ctx context.Context, sourceMaxGasPrice *big.Int) error { + c.configMu.RLock() + defer c.configMu.RUnlock() + c.sourceMaxGasPrice = sourceMaxGasPrice + return nil +} + // CommitOffchainConfig is a legacy version of CommitOffchainConfig, used for CommitStore version 1.0.0 and 1.1.0 type CommitOffchainConfig struct { SourceFinalityDepth uint32 @@ -224,8 +238,18 @@ func (c *CommitStore) ChangeConfig(_ context.Context, onchainConfig []byte, offc return "", err } c.configMu.Lock() + defer c.configMu.Unlock() + + if c.estimator == nil { + return "", fmt.Errorf("this CommitStore estimator is nil. SetGasEstimator should be called before ChangeConfig") + } + + if c.sourceMaxGasPrice == nil { + return "", fmt.Errorf("this CommitStore sourceMaxGasPrice is nil. SetSourceMaxGasPrice should be called before ChangeConfig") + } + c.gasPriceEstimator = prices.NewExecGasPriceEstimator( - c.estimator, + *c.estimator, c.sourceMaxGasPrice, int64(offchainConfigV1.FeeUpdateDeviationPPB)) c.offchainConfig = ccipdata.NewCommitOffchainConfig( @@ -235,7 +259,6 @@ func (c *CommitStore) ChangeConfig(_ context.Context, onchainConfig []byte, offc offchainConfigV1.FeeUpdateHeartBeat.Duration(), offchainConfigV1.InflightCacheExpiry.Duration(), offchainConfigV1.PriceReportingDisabled) - c.configMu.Unlock() c.lggr.Infow("ChangeConfig", "offchainConfig", offchainConfigV1, "onchainConfig", onchainConfigParsed, @@ -379,7 +402,7 @@ func (c *CommitStore) RegisterFilters() error { return logpollerutil.RegisterLpFilters(c.lp, c.filters) } -func NewCommitStore(lggr logger.Logger, addr common.Address, ec client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator, sourceMaxGasPrice *big.Int) (*CommitStore, error) { +func NewCommitStore(lggr logger.Logger, addr common.Address, ec client.Client, lp logpoller.LogPoller) (*CommitStore, error) { commitStore, err := commit_store_1_0_0.NewCommitStore(addr, ec) if err != nil { return nil, err @@ -396,12 +419,13 @@ func NewCommitStore(lggr logger.Logger, addr common.Address, ec client.Client, l }, } return &CommitStore{ - commitStore: commitStore, - address: addr, - lggr: lggr, - lp: lp, - estimator: estimator, - sourceMaxGasPrice: sourceMaxGasPrice, + commitStore: commitStore, + address: addr, + lggr: lggr, + lp: lp, + + // Note that sourceMaxGasPrice and estimator now have explicit setters (CCIP-2493) + filters: filters, commitReportArgs: commitReportArgs, reportAcceptedSig: eventSig, diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store_test.go index a201db6955..31bcaf8a18 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store_test.go @@ -35,7 +35,7 @@ func TestCommitReportEncoding(t *testing.T) { Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 10}, } - c, err := NewCommitStore(logger.TestLogger(t), utils.RandomAddress(), nil, mocks.NewLogPoller(t), nil, nil) + c, err := NewCommitStore(logger.TestLogger(t), utils.RandomAddress(), nil, mocks.NewLogPoller(t)) assert.NoError(t, err) encodedReport, err := c.EncodeCommitReport(ctx, report) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store.go index ad0c48106f..34ce05c2d2 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store.go @@ -40,7 +40,7 @@ type CommitStore struct { lggr logger.Logger lp logpoller.LogPoller address common.Address - estimator gas.EvmFeeEstimator + estimator *gas.EvmFeeEstimator sourceMaxGasPrice *big.Int filters []logpoller.Filter reportAcceptedSig common.Hash @@ -180,6 +180,20 @@ func (c *CommitStore) GasPriceEstimator(context.Context) (cciptypes.GasPriceEsti return c.gasPriceEstimator, nil } +func (c *CommitStore) SetGasEstimator(ctx context.Context, gpe gas.EvmFeeEstimator) error { + c.configMu.RLock() + defer c.configMu.RUnlock() + c.estimator = &gpe + return nil +} + +func (c *CommitStore) SetSourceMaxGasPrice(ctx context.Context, sourceMaxGasPrice *big.Int) error { + c.configMu.RLock() + defer c.configMu.RUnlock() + c.sourceMaxGasPrice = sourceMaxGasPrice + return nil +} + // Do not change the JSON format of this struct without consulting with the RDD people first. type JSONCommitOffchainConfig struct { SourceFinalityDepth uint32 @@ -225,9 +239,18 @@ func (c *CommitStore) ChangeConfig(_ context.Context, onchainConfig []byte, offc return "", err } c.configMu.Lock() + defer c.configMu.Unlock() + + if c.estimator == nil { + return "", fmt.Errorf("this CommitStore estimator is nil. SetGasEstimator should be called before ChangeConfig") + } + + if c.sourceMaxGasPrice == nil { + return "", fmt.Errorf("this CommitStore sourceMaxGasPrice is nil. SetSourceMaxGasPrice should be called before ChangeConfig") + } c.gasPriceEstimator = prices.NewDAGasPriceEstimator( - c.estimator, + *c.estimator, c.sourceMaxGasPrice, int64(offchainConfigParsed.ExecGasPriceDeviationPPB), int64(offchainConfigParsed.DAGasPriceDeviationPPB), @@ -240,7 +263,6 @@ func (c *CommitStore) ChangeConfig(_ context.Context, onchainConfig []byte, offc offchainConfigParsed.InflightCacheExpiry.Duration(), offchainConfigParsed.PriceReportingDisabled, ) - c.configMu.Unlock() c.lggr.Infow("ChangeConfig", "offchainConfig", offchainConfigParsed, @@ -392,7 +414,7 @@ func (c *CommitStore) RegisterFilters() error { return logpollerutil.RegisterLpFilters(c.lp, c.filters) } -func NewCommitStore(lggr logger.Logger, addr common.Address, ec client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator, sourceMaxGasPrice *big.Int) (*CommitStore, error) { +func NewCommitStore(lggr logger.Logger, addr common.Address, ec client.Client, lp logpoller.LogPoller) (*CommitStore, error) { commitStore, err := commit_store_1_2_0.NewCommitStore(addr, ec) if err != nil { return nil, err @@ -410,12 +432,13 @@ func NewCommitStore(lggr logger.Logger, addr common.Address, ec client.Client, l } return &CommitStore{ - commitStore: commitStore, - address: addr, - lggr: lggr, - lp: lp, - estimator: estimator, - sourceMaxGasPrice: sourceMaxGasPrice, + commitStore: commitStore, + address: addr, + lggr: lggr, + lp: lp, + + // Note that sourceMaxGasPrice and estimator now have explicit setters (CCIP-2493) + filters: filters, commitReportArgs: commitReportArgs, reportAcceptedSig: eventSig, diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store_test.go index ca505a010b..8b29309633 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store_test.go @@ -48,7 +48,7 @@ func TestCommitReportEncoding(t *testing.T) { Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 10}, } - c, err := NewCommitStore(logger.TestLogger(t), utils.RandomAddress(), nil, mocks.NewLogPoller(t), nil, nil) + c, err := NewCommitStore(logger.TestLogger(t), utils.RandomAddress(), nil, mocks.NewLogPoller(t)) assert.NoError(t, err) encodedReport, err := c.EncodeCommitReport(ctx, report) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/commit_store.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/commit_store.go index d92f4a46f2..3bb582f3a2 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/commit_store.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/commit_store.go @@ -2,7 +2,6 @@ package v1_5_0 import ( "context" - "math/big" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" @@ -10,7 +9,6 @@ import ( cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -43,8 +41,8 @@ func (c *CommitStore) IsDown(ctx context.Context) (bool, error) { return !unPausedAndNotCursed, nil } -func NewCommitStore(lggr logger.Logger, addr common.Address, ec client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator, sourceMaxGasPrice *big.Int) (*CommitStore, error) { - v120, err := v1_2_0.NewCommitStore(lggr, addr, ec, lp, estimator, sourceMaxGasPrice) +func NewCommitStore(lggr logger.Logger, addr common.Address, ec client.Client, lp logpoller.LogPoller) (*CommitStore, error) { + v120, err := v1_2_0.NewCommitStore(lggr, addr, ec, lp) if err != nil { return nil, err } diff --git a/core/services/ocr2/plugins/liquiditymanager/discoverer/evm.go b/core/services/ocr2/plugins/liquiditymanager/discoverer/evm.go index 8b2a48bb9e..4cc3377705 100644 --- a/core/services/ocr2/plugins/liquiditymanager/discoverer/evm.go +++ b/core/services/ocr2/plugins/liquiditymanager/discoverer/evm.go @@ -47,11 +47,12 @@ func (e *evmDiscoverer) Discover(ctx context.Context) (graph.Graph, error) { NetworkSelector: e.masterSelector, LiquidityManager: e.masterLiquidityManager, }, func(ctx context.Context, v graph.Vertex) (graph.Data, []graph.Vertex, error) { + lggr := e.lggr.With("selector", v.NetworkSelector, "chainID", v.NetworkSelector.ChainID(), "addr", v.LiquidityManager) d, n, err := e.getVertexData(ctx, v) if err != nil { - e.lggr.Warnw("failed to get vertex data", "selector", v.NetworkSelector, "addr", v.LiquidityManager, "error", err) + lggr.Warnw("failed to get vertex data", "error", err) } else { - e.lggr.Debugw("Got vertex data", "selector", v.NetworkSelector, "addr", v.LiquidityManager, "data", d) + lggr.Debugw("Got vertex data", "data", d) } return d, n, err }) @@ -165,13 +166,13 @@ func (e *evmDiscoverer) getVertexData(ctx context.Context, v graph.Vertex) (grap func (e *evmDiscoverer) updateLiquidity(ctx context.Context, selector models.NetworkSelector, g graph.Graph, liquidityGetter evmLiquidityGetter) error { lmAddress, err := g.GetLiquidityManagerAddress(selector) if err != nil { - return fmt.Errorf("get rebalancer address: %w", err) + return fmt.Errorf("get rebalancer address(%d, %s): %w", selector, lmAddress, err) } liquidity, err := liquidityGetter(ctx, selector, common.Address(lmAddress)) if err != nil { - return fmt.Errorf("get liquidity: %w", err) + return fmt.Errorf("get liquidity (%d, %s): %w", selector, lmAddress, err) } - e.lggr.Debugw("Updating liquidity", "liquidity", liquidity, "selector", selector, "lmAddress", lmAddress) + e.lggr.Debugw("Updating liquidity", "liquidity", liquidity, "selector", selector, "chainID", selector.ChainID(), "lmAddress", lmAddress) _ = g.SetLiquidity(selector, liquidity) // TODO: handle non-existing network return nil } @@ -190,11 +191,11 @@ func (e *evmDiscoverer) getDep(selector models.NetworkSelector) (*evmDep, bool) func (e *evmDiscoverer) defaultLiquidityGetter(ctx context.Context, selector models.NetworkSelector, lmAddress common.Address) (*big.Int, error) { dep, ok := e.getDep(selector) if !ok { - return nil, fmt.Errorf("no client for master chain %+v", selector) + return nil, fmt.Errorf("no client for master chain %d", selector) } rebal, err := liquiditymanager.NewLiquidityManager(lmAddress, dep.ethClient) if err != nil { - return nil, fmt.Errorf("new liquiditymanager: %w", err) + return nil, fmt.Errorf("new liquiditymanager (%d, %s): %w", selector, lmAddress, err) } return rebal.GetLiquidity(&bind.CallOpts{ Context: ctx, diff --git a/core/services/ocr2/plugins/liquiditymanager/graph/graph.go b/core/services/ocr2/plugins/liquiditymanager/graph/graph.go index 6d15afa566..625c8ac81e 100644 --- a/core/services/ocr2/plugins/liquiditymanager/graph/graph.go +++ b/core/services/ocr2/plugins/liquiditymanager/graph/graph.go @@ -136,7 +136,20 @@ func (g *liquidityGraph) String() string { g.lock.RLock() defer g.lock.RUnlock() - return fmt.Sprintf("Graph{networksGraph: %+v, networkBalance: %+v}", g.adj, g.data) + type network struct { + Selector models.NetworkSelector + ChainID uint64 + } + adj := make([]network, 0, len(g.adj)) + for n := range g.adj { + adj = append(adj, network{Selector: n, ChainID: n.ChainID()}) + } + data := make(map[network]Data, len(g.data)) + for n, d := range g.data { + data[network{Selector: n, ChainID: n.ChainID()}] = d + } + + return fmt.Sprintf("Graph{graph: %+v, data: %+v}", adj, data) } func (g *liquidityGraph) Reset() { diff --git a/core/services/ocr2/plugins/liquiditymanager/models/models.go b/core/services/ocr2/plugins/liquiditymanager/models/models.go index 4c116de964..e9880590fe 100644 --- a/core/services/ocr2/plugins/liquiditymanager/models/models.go +++ b/core/services/ocr2/plugins/liquiditymanager/models/models.go @@ -52,6 +52,11 @@ func (n NetworkSelector) Type() NetworkType { return NetworkTypeUnknown } +func (n NetworkSelector) ChainID() uint64 { + chainID, _ := chainsel.ChainIdFromSelector(uint64(n)) + return chainID +} + type NetworkType string // ProposedTransfer is a transfer that is proposed by the rebalancing algorithm. diff --git a/core/services/ocr2/plugins/liquiditymanager/plugin.go b/core/services/ocr2/plugins/liquiditymanager/plugin.go index 9b89bc7c7e..23a6f21136 100644 --- a/core/services/ocr2/plugins/liquiditymanager/plugin.go +++ b/core/services/ocr2/plugins/liquiditymanager/plugin.go @@ -439,7 +439,8 @@ func (p *Plugin) Close() error { var errs []error for _, networkID := range p.liquidityGraph.GetNetworks() { - p.lggr.Infow("closing liquidityManager network", "network", networkID) + lggr := p.lggr.With("network", networkID, "chainID", networkID.ChainID()) + lggr.Infow("closing liquidityManager network") liquidityManagerAddress, err := p.liquidityGraph.GetLiquidityManagerAddress(networkID) if err != nil { @@ -458,7 +459,7 @@ func (p *Plugin) Close() error { continue } - p.lggr.Infow("finished closing liquidityManager network", "network", networkID, "liquidityManager", liquidityManagerAddress.String()) + lggr.Infow("finished closing liquidityManager network", "liquidityManager", liquidityManagerAddress.String()) } return multierr.Combine(errs...) @@ -497,7 +498,7 @@ func (p *Plugin) syncGraph(ctx context.Context) error { } func (p *Plugin) loadPendingTransfers(ctx context.Context, lggr logger.Logger) ([]models.PendingTransfer, error) { - p.lggr.Infow("loading pending transfers") + lggr.Infow("loading pending transfers") pendingTransfers := make([]models.PendingTransfer, 0) edges, err := p.liquidityGraph.GetEdges() @@ -505,13 +506,14 @@ func (p *Plugin) loadPendingTransfers(ctx context.Context, lggr logger.Logger) ( return nil, fmt.Errorf("get edges: %w", err) } for _, edge := range edges { + logger := lggr.With("sourceNetwork", edge.Source, "sourceChainID", edge.Source.ChainID(), "destNetwork", edge.Dest, "destChainID", edge.Dest.ChainID()) bridge, err := p.bridgeFactory.NewBridge(edge.Source, edge.Dest) if err != nil { return nil, fmt.Errorf("init bridge: %w", err) } if bridge == nil { - lggr.Warnw("no bridge found for network pair", "sourceNetwork", edge.Source, "destNetwork", edge.Dest) + logger.Warn("no bridge found for network pair") continue } @@ -529,11 +531,10 @@ func (p *Plugin) loadPendingTransfers(ctx context.Context, lggr logger.Logger) ( return nil, fmt.Errorf("get pending transfers: %w", err) } - lggr.Infow("loaded pending transfers for network", "network", edge.Source, "pendingTransfers", netPendingTransfers) + logger.Infow("loaded pending transfers for network", "pendingTransfers", netPendingTransfers) pendingTransfers = append(pendingTransfers, netPendingTransfers...) } - // todo: why do we add this here? it's not used anywhere return pendingTransfers, nil } diff --git a/core/services/ocr2/plugins/liquiditymanager/plugin_validate.go b/core/services/ocr2/plugins/liquiditymanager/plugin_validate.go index 1774772066..491b885065 100644 --- a/core/services/ocr2/plugins/liquiditymanager/plugin_validate.go +++ b/core/services/ocr2/plugins/liquiditymanager/plugin_validate.go @@ -93,11 +93,11 @@ func validateItems[T any](keyFn func(T) string, items []T, validateFns ...func(T for _, item := range items { k := keyFn(item) if existing[k] { - return fmt.Errorf("duplicated item") + return fmt.Errorf("duplicated item (%s)", k) } for _, validateFn := range validateFns { if err := validateFn(item); err != nil { - return fmt.Errorf("invalid item: %w", err) + return fmt.Errorf("invalid item (%s): %w", k, err) } } existing[k] = true diff --git a/core/services/relay/evm/liquidity_manager.go b/core/services/relay/evm/liquidity_manager.go index fdb581abf4..41d10aac78 100644 --- a/core/services/relay/evm/liquidity_manager.go +++ b/core/services/relay/evm/liquidity_manager.go @@ -32,6 +32,10 @@ import ( relaytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) +const ( + lmGasLimit = 5e6 +) + var ( ocr3ABI = evmtypes.MustGetABI(no_op_ocr3.NoOpOCR3MetaData.ABI) ) @@ -89,7 +93,7 @@ func (r *rebalancerRelayer) NewRebalancerProvider(ctx context.Context, rargs com tm, err2 := ocrcommon.NewTransmitter( chain.TxManager(), fromAddresses, - 1e6, // TODO: gas limit may vary depending on tx + lmGasLimit, fromAddresses[0], txmgr.NewSendEveryStrategy(), txmgrtypes.TransmitCheckerSpec[common.Address]{}, diff --git a/integration-tests/ccip-tests/load/ccip_loadgen.go b/integration-tests/ccip-tests/load/ccip_loadgen.go index 30048d77ba..8be083ccd2 100644 --- a/integration-tests/ccip-tests/load/ccip_loadgen.go +++ b/integration-tests/ccip-tests/load/ccip_loadgen.go @@ -286,23 +286,29 @@ func (c *CCIPE2ELoad) Call(_ *wasp.Generator) *wasp.Response { lggr.Info().Str("tx", sendTx.Hash().Hex()).Msg("waiting for tx to be mined") ctx, cancel := context.WithTimeout(context.Background(), sourceCCIP.Common.ChainClient.GetNetworkConfig().Timeout.Duration) defer cancel() - rcpt, err1 := bind.WaitMined(ctx, sourceCCIP.Common.ChainClient.DeployBackend(), sendTx) - if err1 == nil { - hdr, err1 := c.Lane.Source.Common.ChainClient.HeaderByNumber(context.Background(), rcpt.BlockNumber) - if err1 == nil { - txConfirmationTime = hdr.Timestamp - } + rcpt, err := bind.WaitMined(ctx, sourceCCIP.Common.ChainClient.DeployBackend(), sendTx) + if err != nil { + res.Error = fmt.Sprintf("ccip-send request tx not mined, err=%s", err.Error()) + res.Failed = true + res.Data = stats.StatusByPhase + return res } - lggr = lggr.With().Str("Msg Tx", sendTx.Hash().String()).Logger() - var gasUsed uint64 - if rcpt != nil { - gasUsed = rcpt.GasUsed + if rcpt == nil { + res.Error = "ccip-send request tx not mined, receipt is nil" + res.Failed = true + res.Data = stats.StatusByPhase + return res } + hdr, err := c.Lane.Source.Common.ChainClient.HeaderByNumber(context.Background(), rcpt.BlockNumber) + if err == nil && hdr != nil { + txConfirmationTime = hdr.Timestamp + } + lggr = lggr.With().Str("Msg Tx", sendTx.Hash().String()).Logger() if rcpt.Status != types.ReceiptStatusSuccessful { stats.UpdateState(&lggr, 0, testreporters.TX, txConfirmationTime.Sub(startTime), testreporters.Failure, testreporters.TransactionStats{ Fee: fee.String(), - GasUsed: gasUsed, + GasUsed: rcpt.GasUsed, TxHash: sendTx.Hash().Hex(), NoOfTokensSent: len(msg.TokenAmounts), MessageBytesLength: int64(len(msg.Data)), @@ -319,7 +325,7 @@ func (c *CCIPE2ELoad) Call(_ *wasp.Generator) *wasp.Response { stats.UpdateState(&lggr, 0, testreporters.TX, txConfirmationTime.Sub(startTime), testreporters.Success, testreporters.TransactionStats{ Fee: fee.String(), - GasUsed: gasUsed, + GasUsed: rcpt.GasUsed, TxHash: sendTx.Hash().Hex(), NoOfTokensSent: len(msg.TokenAmounts), MessageBytesLength: int64(len(msg.Data)),