From f24af7895275f9edb5068c130cd42e8de05ef039 Mon Sep 17 00:00:00 2001 From: Amir Y <83904651+amirylm@users.noreply.github.com> Date: Fri, 21 Jun 2024 09:45:43 +0300 Subject: [PATCH 1/8] Log chain ids in addition to chain selectors (#1063) ## Motivation ## Solution --- .changeset/early-readers-work.md | 6 ++++++ .../plugins/liquiditymanager/discoverer/evm.go | 15 ++++++++------- .../ocr2/plugins/liquiditymanager/graph/graph.go | 15 ++++++++++++++- .../plugins/liquiditymanager/models/models.go | 5 +++++ .../ocr2/plugins/liquiditymanager/plugin.go | 13 +++++++------ .../plugins/liquiditymanager/plugin_validate.go | 4 ++-- 6 files changed, 42 insertions(+), 16 deletions(-) create mode 100644 .changeset/early-readers-work.md 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/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 From 969d44ad32058d75e60630664e131167acc944e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Evaldas=20Lato=C5=A1kinas?= <34982762+elatoskinas@users.noreply.github.com> Date: Fri, 21 Jun 2024 10:33:53 +0200 Subject: [PATCH 2/8] MultiOffRamp - size optimizations (#991) ## Motivation Optimizes the contract size for the merged MultiOffRamp + CommitStore to be able to fit the deployment size limits ## Solution Currently the margin is at -0.972KB with 3600 optimizer runs. The contract size fits the space with 1800 optimizer runs. The contract size can further be reduced, and the optimizer runs increased after the Nonce Manager is integrated into the MultiOffRamp Each optimization is split into a separate commit. Complete list: * Remove in-depth message validations -> these will be moved off-chain (ticket already created) * Move `isCursed` to shared internal function * Move forked chain check, curse check and source config enabled check to common internal function * ~~Move source chain config + curse check to single shared function (used in both exec & commit)~~ * ~~Move zero address check to internal lib~~ * Remove global pausing from the multi-offramp -> there are 4 alternative methods of achieving pausing: * Per-lane: using `IMessageValidator` (execution-only), disabling the source chain config, cursing the lane via RMN * Globally: implementing the global pause in the RMN * The savings are significant, at around ~0.8KB * Split StaticConfig and DynamicConfig set events * Get rid of `Any2EVMMessageRoute` and use 2 internal functions to solve stack depth (same as the OffRamp changes) * Other contract size golfing: variable caching, inlining * Compile with lower optimizer runs for the multi-offramp * **Update**: OCR3 no longer needs a `uniqueReports` distinction * **Other fix**: OCR3 now uses sequenceNumbers --- contracts/.changeset/gentle-spoons-vanish.md | 5 + contracts/gas-snapshots/ccip.gas-snapshot | 349 ++++---- .../scripts/native_solc_compile_all_ccip | 7 +- contracts/src/v0.8/ccip/ocr/MultiOCR3Base.sol | 30 +- .../v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol | 403 ++++----- .../v0.8/ccip/test/e2e/MultiRampsEnd2End.sol | 4 +- .../helpers/EVM2EVMMultiOffRampHelper.sol | 29 +- .../v0.8/ccip/test/ocr/MultiOCR3Base.t.sol | 84 +- .../ccip/test/ocr/MultiOCR3BaseSetup.t.sol | 14 +- .../test/offRamp/EVM2EVMMultiOffRamp.t.sol | 834 +++++++++--------- .../offRamp/EVM2EVMMultiOffRampSetup.t.sol | 25 +- .../evm_2_evm_multi_offramp.go | 490 +++------- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 13 files changed, 983 insertions(+), 1293 deletions(-) create mode 100644 contracts/.changeset/gentle-spoons-vanish.md 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..4af4b21269 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -66,152 +66,148 @@ 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: 330182) +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: 235451) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 91273) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 288058) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 95383) +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) @@ -574,38 +570,37 @@ 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: 1395580) 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/scripts/native_solc_compile_all_ccip b/contracts/scripts/native_solc_compile_all_ccip index 31c4bfff6d..2c209d69d6 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 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..1b6ed6eb21 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 ); @@ -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/test/e2e/MultiRampsEnd2End.sol b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol index 2db164eaf4..3ab36ab469 100644 --- a/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol +++ b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol @@ -138,10 +138,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/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/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/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..7dc439b6ce 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: "0x6101006040523480156200001257600080fd5b50604051620067e1380380620067e1833981016040819052620000359162000648565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001c1565b5050466080525060208201516001600160a01b03161580620000ec575060408201516001600160a01b0316155b156200010b576040516342bcdf7f60e11b815260040160405180910390fd5b81516001600160401b0316600003620001375760405163c656089560e01b815260040160405180910390fd5b81516001600160401b0390811660a052602080840180516001600160a01b0390811660c05260408087018051831660e052815188519096168652925182169385019390935290511682820152517f2f56698ec552a5d53d27d6f4b3dd8b6989f6426b6151a36aff61160c1d07efdf9181900360600190a1620001b9816200026c565b5050620007d0565b336001600160a01b038216036200021b5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b81518110156200051c576000828281518110620002905762000290620007ba565b60200260200101519050600081600001519050806001600160401b0316600003620002ce5760405163c656089560e01b815260040160405180910390fd5b60608201516001600160a01b0316620002fa576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b038116600090815260076020526040902060018101546001600160a01b031662000400576200035c8284606001517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b36200052060201b60201c565b600282015560608301516001820180546001600160a01b039283166001600160a01b03199091161790556040808501518354610100600160481b03199190931669010000000000000000000216610100600160e81b031990921691909117610100178255516001600160401b03831681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a16200046f565b606083015160018201546001600160a01b03908116911614158062000444575060408301518154690100000000000000000090046001600160a01b03908116911614155b156200046f5760405163c39a620560e01b81526001600160401b038316600482015260240162000083565b6020830151815490151560ff199091161781556040516001600160401b038316907fa73c588738263db34ef8c1942db8f99559bc6696f6a812d42e76bafb4c0e8d309062000505908490815460ff811615158252600881901c6001600160401b0316602083015260481c6001600160a01b0390811660408301526001830154166060820152600290910154608082015260a00190565b60405180910390a25050508060010190506200026f565b5050565b60a0805160408051602081018590526001600160401b0380881692820192909252911660608201526001600160a01b0384166080820152600091016040516020818303038152906040528051906020012090509392505050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b0381118282101715620005b557620005b56200057a565b60405290565b604051608081016001600160401b0381118282101715620005b557620005b56200057a565b604051601f8201601f191681016001600160401b03811182821017156200060b576200060b6200057a565b604052919050565b80516001600160401b03811681146200062b57600080fd5b919050565b80516001600160a01b03811681146200062b57600080fd5b6000808284036080808212156200065e57600080fd5b6060808312156200066e57600080fd5b6200067862000590565b9250620006858662000613565b835260206200069681880162000630565b818501526040620006aa6040890162000630565b604086015260608801519496506001600160401b0380861115620006cd57600080fd5b858901955089601f870112620006e257600080fd5b855181811115620006f757620006f76200057a565b62000707848260051b01620005e0565b818152848101925060079190911b87018401908b8211156200072857600080fd5b968401965b81881015620007a85786888d031215620007475760008081fd5b62000751620005bb565b6200075c8962000613565b8152858901518015158114620007725760008081fd5b818701526200078389860162000630565b8582015262000794878a0162000630565b81880152835296860196918401916200072d565b80985050505050505050509250929050565b634e487b7160e01b600052603260045260246000fd5b60805160a05160c05160e051615fb46200082d6000396000818161021e01526131fe0152600081816101ef015281816115fc01526116b30152600081816101bf0152613120015260008181611c4f0152611c9b0152615fb46000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c80637f63b711116100e3578063d2a15d351161008c578063f52121a511610066578063f52121a514610686578063f716f99f14610699578063ff888fb1146106ac57600080fd5b8063d2a15d3514610552578063e9d68a8e14610565578063f2fde38b1461067357600080fd5b80638da5cb5b116100bd5780638da5cb5b146104d2578063c673e584146104ed578063ccd37ba31461050d57600080fd5b80637f63b7111461049e57806385572ffb146104b15780638b364334146104bf57600080fd5b8063403b2d631161014557806369600bca1161011f57806369600bca1461036e5780637437ff9f1461038157806379ba50971461049657600080fd5b8063403b2d6314610328578063542625af1461033b5780635e36480c1461034e57600080fd5b80632d04ab76116101765780632d04ab76146102d9578063311cd513146102ee5780633f4b04aa1461030157600080fd5b806306285c6914610192578063181f5a7714610290575b600080fd5b61024e604080516060810182526000808252602082018190529181019190915260405180606001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b60408051825167ffffffffffffffff1681526020808401516001600160a01b039081169183019190915292820151909216908201526060015b60405180910390f35b6102cc6040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b604051610287919061423a565b6102ec6102e73660046142e5565b6106cf565b005b6102ec6102fc366004614398565b610a95565b600b5467ffffffffffffffff165b60405167ffffffffffffffff9091168152602001610287565b6102ec610336366004614545565b610afe565b6102ec610349366004614b69565b610cbb565b61036161035c366004614c94565b610e60565b6040516102879190614cf7565b6102ec61037c366004614d05565b610eb6565b61042d6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c0810182526004546001600160a01b03808216835263ffffffff74010000000000000000000000000000000000000000830481166020850152600160c01b8304811694840194909452600160e01b90910490921660608201526005548216608082015260065490911660a082015290565b6040516102879190600060c0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401528060a08501511660a08401525092915050565b6102ec610f21565b6102ec6104ac366004614d22565b610fdf565b6102ec61018d366004614e06565b61030f6104cd366004614e41565b610ff3565b6000546040516001600160a01b039091168152602001610287565b6105006104fb366004614e80565b611009565b6040516102879190614ee0565b61054461051b366004614f55565b67ffffffffffffffff919091166000908152600a60209081526040808320938352929052205490565b604051908152602001610287565b6102ec610560366004614f81565b611167565b610616610573366004614d05565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091525067ffffffffffffffff908116600090815260076020908152604091829020825160a081018452815460ff8116151582526101008104909516928101929092526001600160a01b0369010000000000000000009094048416928201929092526001820154909216606083015260020154608082015290565b6040516102879190600060a08201905082511515825267ffffffffffffffff602084015116602083015260408301516001600160a01b03808216604085015280606086015116606085015250506080830151608083015292915050565b6102ec610681366004614ff6565b611221565b6102ec610694366004615013565b611232565b6102ec6106a73660046150df565b611564565b6106bf6106ba36600461522a565b6115a6565b6040519015158152602001610287565b60006106dd878901896153bb565b805151519091501515806106f657508051602001515115155b156107f657600b5460208a01359067ffffffffffffffff808316911610156107b557600b805467ffffffffffffffff191667ffffffffffffffff831617905560065482516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921691633937306f9161077e916004016155f9565b600060405180830381600087803b15801561079857600080fd5b505af11580156107ac573d6000803e3d6000fd5b505050506107f4565b8160200151516000036107f4576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b8160200151518110156109de5760008260200151828151811061081e5761081e615526565b6020026020010151905060008160000151905061083a81611667565b600061084582611769565b602084015151815491925067ffffffffffffffff90811661010090920416141580610887575060208084015190810151905167ffffffffffffffff9182169116115b156108d057825160208401516040517feefb0cac0000000000000000000000000000000000000000000000000000000081526108c792919060040161560c565b60405180910390fd5b60408301518061090c576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff166000908152600a602090815260408083208484529091529020541561097f5783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602481018290526044016108c7565b6020808501510151610992906001615657565b825468ffffffffffffffff00191661010067ffffffffffffffff92831602179092559251166000908152600a6020908152604080832094835293905291909120429055506001016107f9565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d81604051610a0e919061567f565b60405180910390a1610a8a60008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b92506117c9915050565b505050505050505050565b610ad5610aa48284018461571c565b6040805160008082526020820190925290610acf565b6060815260200190600190039081610aba5790505b50611b40565b604080516000808252602082019092529050610af86001858585858660006117c9565b50505050565b610b06611bf0565b60a08101516001600160a01b03161580610b28575080516001600160a01b0316155b15610b5f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a177401000000000000000000000000000000000000000063ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff19908116928e1692909217905560a0808e01805160068054909416908f161790925586519a8b5297518716988a0198909852925185169388019390935251909216958501959095525185169383019390935251909216908201527f0da37fd00459f4f5f0b8210d31525e4910ae674b8bab34b561d146bb45773a4c9060c00160405180910390a150565b610cc3611c4c565b815181518114610cff576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610e50576000848281518110610d1e57610d1e615526565b60200260200101519050600081602001515190506000858481518110610d4657610d46615526565b6020026020010151905080518214610d8a576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610e41576000828281518110610da957610da9615526565b6020026020010151905080600014158015610de4575084602001518281518110610dd557610dd5615526565b60200260200101516080015181105b15610e385784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101839052604481018290526064016108c7565b50600101610d8d565b50505050806001019050610d02565b50610e5b8383611b40565b505050565b6000610e6e60016004615751565b6002610e7b60808561577a565b67ffffffffffffffff16610e8f91906157a1565b610e998585611ccd565b901c166003811115610ead57610ead614ccd565b90505b92915050565b610ebe611bf0565b600b805467ffffffffffffffff83811667ffffffffffffffff1983168117909355604080519190921680825260208201939093527f88ad9c61d6caf19a2af116a871802a03a31e680115a2dd20e8c08801d7c82f83910160405180910390a15050565b6001546001600160a01b03163314610f7b5760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108c7565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610fe7611bf0565b610ff081611d14565b50565b6000806110008484612025565b50949350505050565b61104c6040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c0820152948552918201805484518184028101840190955280855292938583019390928301828280156110f557602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116110d7575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561115757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611139575b5050505050815250509050919050565b61116f611bf0565b60005b81811015610e5b57600083838381811061118e5761118e615526565b9050604002018036038101906111a491906157b8565b90506111b381602001516115a6565b61121857805167ffffffffffffffff166000908152600a602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101611172565b611229611bf0565b610ff081612136565b33301461126b576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051600080825260208201909252816112a8565b60408051808201909152600080825260208201528152602001906001900390816112815790505b5061014084015151909150156113095761130683610140015184602001516040516020016112e591906001600160a01b0391909116815260200190565b60408051601f198184030181529181528601518651610160880151876121ec565b90505b60006113158483612299565b6005549091506001600160a01b03168015611402576040517fa219f6e50000000000000000000000000000000000000000000000000000000081526001600160a01b0382169063a219f6e59061136f9085906004016158a0565b600060405180830381600087803b15801561138957600080fd5b505af192505050801561139a575060015b611402573d8080156113c8576040519150601f19603f3d011682016040523d82523d6000602084013e6113cd565b606091505b50806040517f09c253250000000000000000000000000000000000000000000000000000000081526004016108c7919061423a565b6101208501515115801561141857506080850151155b8061142f575060408501516001600160a01b03163b155b8061146f5750604085015161146d906001600160a01b03167f85572ffb0000000000000000000000000000000000000000000000000000000061233c565b155b1561147b575050505050565b60048054608087015160408089015190517f3cf9798300000000000000000000000000000000000000000000000000000000815260009485946001600160a01b031693633cf97983936114d6938a93611388939291016158b3565b6000604051808303816000875af11580156114f5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261151d9190810190615934565b50915091508161155b57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016108c7919061423a565b50505050505050565b61156c611bf0565b60005b81518110156115a25761159a82828151811061158d5761158d615526565b6020026020010151612358565b60010161156f565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611643573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb0919061598e565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015611702573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611726919061598e565b15610ff0576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108c7565b67ffffffffffffffff81166000908152600760205260408120805460ff16610eb0576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108c7565b60ff878116600090815260026020908152604080832081516080810183528154815260019091015480861693820193909352610100830485169181019190915262010000909104909216151560608301528735906118288760a46159ab565b90508260600151156118705784516118419060206157a1565b865161184e9060206157a1565b6118599060a06159ab565b61186391906159ab565b61186d90826159ab565b90505b3681146118b2576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016108c7565b50815181146118fa5781516040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016108c7565b611902611c4c565b60ff808a166000908152600360209081526040808320338452825280832081518083019092528054808616835293949193909284019161010090910416600281111561195057611950614ccd565b600281111561196157611961614ccd565b905250905060028160200151600281111561197e5761197e614ccd565b1480156119d25750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff16815481106119ba576119ba615526565b6000918252602090912001546001600160a01b031633145b611a08576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611aea576020820151611a239060016159be565b60ff16855114611a5f576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611a9a576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611aac9291906159d7565b604051908190038120611ac3918b906020016159e7565b604051602081830303815290604052805190602001209050611ae88a82888888612663565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611b7a576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611be957611be1858281518110611baf57611baf615526565b602002602001015184611bdb57858381518110611bce57611bce615526565b602002602001015161287a565b8361287a565b600101611b91565b5050505050565b6000546001600160a01b03163314611c4a5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108c7565b565b467f000000000000000000000000000000000000000000000000000000000000000014611c4a576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016108c7565b67ffffffffffffffff8216600090815260096020526040812081611cf26080856159fb565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b60005b81518110156115a2576000828281518110611d3457611d34615526565b602002602001015190506000816000015190508067ffffffffffffffff16600003611d8b576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608201516001600160a01b0316611dcf576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8116600090815260076020526040902060018101546001600160a01b0316611ef257611e298284606001517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b361311a565b600282015560608301516001820180546001600160a01b0392831673ffffffffffffffffffffffffffffffffffffffff19909116179055604080850151835468ffffffffffffffff001991909316690100000000000000000002167fffffff00000000000000000000000000000000000000000000000000000000ff909216919091176101001782555167ffffffffffffffff831681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611f78565b606083015160018201546001600160a01b039081169116141580611f35575060408301518154690100000000000000000090046001600160a01b03908116911614155b15611f78576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff831660048201526024016108c7565b6020830151815490151560ff1990911617815560405167ffffffffffffffff8316907fa73c588738263db34ef8c1942db8f99559bc6696f6a812d42e76bafb4c0e8d309061200f908490815460ff811615158252600881901c67ffffffffffffffff16602083015260481c6001600160a01b0390811660408301526001830154166060820152600290910154608082015260a00190565b60405180910390a2505050806001019050611d17565b67ffffffffffffffff80831660009081526008602090815260408083206001600160a01b038616845290915281205490918291168082036121285767ffffffffffffffff8516600090815260076020526040902054690100000000000000000090046001600160a01b03168015612126576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b03868116600483015282169063856c824790602401602060405180830381865afa1580156120f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121199190615a22565b600193509350505061212f565b505b9150600090505b9250929050565b336001600160a01b0382160361218e5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108c7565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b8560005b875181101561228e5761226988828151811061220e5761220e615526565b60200260200101516020015188888888868151811061222f5761222f615526565b602002602001015180602001905181019061224a9190615a3f565b88878151811061225c5761225c615526565b602002602001015161319d565b82828151811061227b5761227b615526565b60209081029190910101526001016121f0565b509695505050505050565b6040805160a08101825260008082526020820152606091810182905281810182905260808101919091526040518060a001604052808461018001518152602001846000015167ffffffffffffffff168152602001846020015160405160200161231191906001600160a01b0391909116815260200190565b6040516020818303038152906040528152602001846101200151815260200183815250905092915050565b600061234783613516565b8015610ead5750610ead8383613562565b806040015160ff16600003612383576000604051631b3fab5160e11b81526004016108c79190615af4565b60208082015160ff808216600090815260029093526040832060018101549293909283921690036123d4576060840151600182018054911515620100000262ff000019909216919091179055612429565b6060840151600182015460ff6201000090910416151590151514612429576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff841660048201526024016108c7565b60a08401518051601f60ff82161115612458576001604051631b3fab5160e11b81526004016108c79190615af4565b6124be85856003018054806020026020016040519081016040528092919081815260200182805480156124b457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612496575b5050505050613604565b8560600151156125d05761252c85856002018054806020026020016040519081016040528092919081815260200182805480156124b4576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311612496575050505050613604565b608086015180516125469060028701906020840190614148565b50805160018501805461ff00191661010060ff841690810291909117909155601f1015612589576002604051631b3fab5160e11b81526004016108c79190615af4565b6040880151612599906003615b0e565b60ff168160ff16116125c1576003604051631b3fab5160e11b81526004016108c79190615af4565b6125cd8783600161366d565b50505b6125dc8583600261366d565b81516125f19060038601906020850190614148565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f5479361264a938a939260028b01929190615b2a565b60405180910390a161265b856137ed565b505050505050565b61266b6141b6565b835160005b8181101561287057600060018886846020811061268f5761268f615526565b61269c91901a601b6159be565b8985815181106126ae576126ae615526565b60200260200101518986815181106126c8576126c8615526565b602002602001015160405160008152602001604052604051612706949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612728573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b0385168352815285822085870190965285548084168652939750909550929392840191610100900416600281111561278957612789614ccd565b600281111561279a5761279a614ccd565b90525090506001816020015160028111156127b7576127b7614ccd565b146127ee576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061280557612805615526565b602002015115612841576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061285c5761285c615526565b911515602090920201525050600101612670565b5050505050505050565b815161288581611667565b600061289082611769565b60208501515190915060008190036128d3576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460400151518114612911576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561292c5761292c6143ec565b604051908082528060200260200182016040528015612955578160200160208202803683370190505b50905060005b82811015612a1a5760008760200151828151811061297b5761297b615526565b60200260200101519050612993818660020154613809565b8383815181106129a5576129a5615526565b6020026020010181815250508061018001518383815181106129c9576129c9615526565b602002602001015114612a11578061018001516040517f345039be0000000000000000000000000000000000000000000000000000000081526004016108c791815260200190565b5060010161295b565b506000612a31858389606001518a60800151613965565b905080600003612a79576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016108c7565b8551151560005b84811015610a8a57600089602001518281518110612aa057612aa0615526565b602002602001015190506000612aba898360600151610e60565b90506002816003811115612ad057612ad0614ccd565b03612b265760608201516040805167ffffffffffffffff808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c910160405180910390a15050613112565b6000816003811115612b3a57612b3a614ccd565b1480612b5757506003816003811115612b5557612b55614ccd565b145b612ba75760608201516040517f25507e7f00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808c16600483015290911660248201526044016108c7565b8315612c885760045460009074010000000000000000000000000000000000000000900463ffffffff16612bdb8742615751565b1190508080612bfb57506003826003811115612bf957612bf9614ccd565b145b612c3d576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8b1660048201526024016108c7565b8a8481518110612c4f57612c4f615526565b6020026020010151600014612c82578a8481518110612c7057612c70615526565b60200260200101518360800181815250505b50612ced565b6000816003811115612c9c57612c9c614ccd565b14612ced5760608201516040517f3ef2a99c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808c16600483015290911660248201526044016108c7565b600080612cfe8b8560200151612025565b915091508015612ded5760c084015167ffffffffffffffff16612d22836001615657565b67ffffffffffffffff1614612da55760c084015160208501516040517f5444a3301c7c42dd164cbf6ba4b72bf02504f86c049b06a27fc2b662e334bdbd92612d94928f9267ffffffffffffffff93841681529190921660208201526001600160a01b0391909116604082015260600190565b60405180910390a150505050613112565b67ffffffffffffffff8b81166000908152600860209081526040808320888301516001600160a01b031684529091529020805467ffffffffffffffff19169184169190911790555b6000836003811115612e0157612e01614ccd565b03612e925760c084015167ffffffffffffffff16612e20836001615657565b67ffffffffffffffff1614612e925760c084015160208501516040517f852dc8e405695593e311bd83991cf39b14a328f304935eac6d3d55617f911d8992612d94928f9267ffffffffffffffff93841681529190921660208201526001600160a01b0391909116604082015260600190565b60008d604001518681518110612eaa57612eaa615526565b6020026020010151905080518561014001515114612f0e5760608501516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808f16600483015290911660248201526044016108c7565b612f1e8c866060015160016139bb565b600080612f2b8784613a63565b91509150612f3e8e8860600151846139bb565b888015612f5c57506003826003811115612f5a57612f5a614ccd565b145b8015612f7a57506000866003811115612f7757612f77614ccd565b14155b15612fba57866101800151816040517f2b11b8d90000000000000000000000000000000000000000000000000000000081526004016108c7929190615bb0565b6003826003811115612fce57612fce614ccd565b14158015612fee57506002826003811115612feb57612feb614ccd565b14155b1561302f578d8760600151836040517f926c5a3e0000000000000000000000000000000000000000000000000000000081526004016108c793929190615bc9565b600086600381111561304357613043614ccd565b036130b15767ffffffffffffffff808f1660009081526008602090815260408083208b8301516001600160a01b0316845290915281208054909216919061308983615bef565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b866101800151876060015167ffffffffffffffff168f67ffffffffffffffff167f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df28585604051613102929190615c16565b60405180910390a4505050505050505b600101612a80565b600081847f00000000000000000000000000000000000000000000000000000000000000008560405160200161317d949392919093845267ffffffffffffffff9283166020850152911660408301526001600160a01b0316606082015260800190565b6040516020818303038152906040528051906020012090505b9392505050565b604080518082019091526000808252602082015260006131c08460200151613cad565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015613245573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132699190615c36565b90506001600160a01b03811615806132b157506132af6001600160a01b0382167faff2afbf0000000000000000000000000000000000000000000000000000000061233c565b155b156132f3576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016108c7565b6000806133be633907753760e01b6040518061010001604052808d81526020018b67ffffffffffffffff1681526020018c6001600160a01b031681526020018e8152602001876001600160a01b031681526020018a6000015181526020018a6040015181526020018981525060405160240161336f9190615c53565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152600454859063ffffffff600160e01b909104166113886084613cef565b5091509150816133e3578060405163e1cd550960e01b81526004016108c7919061423a565b805160201461342b5780516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016108c7565b6000818060200190518101906134419190615d2a565b604080516001600160a01b038d16602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b03167fa9059cbb000000000000000000000000000000000000000000000000000000001790526004549192506134c4918790600160c01b900463ffffffff166113886084613cef565b509093509150826134ea578160405163e1cd550960e01b81526004016108c7919061423a565b604080518082019091526001600160a01b03909516855260208501525091925050509695505050505050565b6000613542827f01ffc9a700000000000000000000000000000000000000000000000000000000613562565b8015610eb0575061355b826001600160e01b0319613562565b1592915050565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156135ed575060208210155b80156135f95750600081115b979650505050505050565b60005b8151811015610e5b5760ff83166000908152600360205260408120835190919084908490811061363957613639615526565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff19169055600101613607565b60005b82518160ff161015610af8576000838260ff168151811061369357613693615526565b60200260200101519050600060028111156136b0576136b0614ccd565b60ff80871660009081526003602090815260408083206001600160a01b038716845290915290205461010090041660028111156136ef576136ef614ccd565b14613710576004604051631b3fab5160e11b81526004016108c79190615af4565b6001600160a01b038116613750576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff16815260200184600281111561377657613776614ccd565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff1916176101008360028111156137d3576137d3614ccd565b021790555090505050806137e690615d43565b9050613670565b60ff8116610ff057600b805467ffffffffffffffff1916905550565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b610100015160405160200161389f9897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b60405160208183030381529060405280519060200120856101200151805190602001208661014001516040516020016138d89190615d62565b604051602081830303815290604052805190602001208761016001516040516020016139049190615e17565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e0015b60405160208183030381529060405280519060200120905092915050565b600080613973858585613e15565b905061397e816115a6565b61398c5760009150506139b3565b67ffffffffffffffff86166000908152600a60209081526040808320938352929052205490505b949350505050565b600060026139ca60808561577a565b67ffffffffffffffff166139de91906157a1565b905060006139ec8585611ccd565b9050816139fb60016004615751565b901b191681836003811115613a1257613a12614ccd565b67ffffffffffffffff871660009081526009602052604081209190921b92909217918291613a416080886159fb565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517ff52121a5000000000000000000000000000000000000000000000000000000008152600090606090309063f52121a590613aa79087908790600401615e2a565b600060405180830381600087803b158015613ac157600080fd5b505af1925050508015613ad2575060015b613c92573d808015613b00576040519150601f19603f3d011682016040523d82523d6000602084013e613b05565b606091505b506000613b1182615f6f565b90507f0a8d6e8c000000000000000000000000000000000000000000000000000000006001600160e01b031982161480613b5b575063e1cd550960e01b6001600160e01b03198216145b80613b76575063046b337b60e51b6001600160e01b03198216145b80613baa57507f78ef8024000000000000000000000000000000000000000000000000000000006001600160e01b03198216145b80613bde57507f0c3b563c000000000000000000000000000000000000000000000000000000006001600160e01b03198216145b80613c1257507fae9b4ce9000000000000000000000000000000000000000000000000000000006001600160e01b03198216145b80613c4657507f09c25325000000000000000000000000000000000000000000000000000000006001600160e01b03198216145b15613c57575060039250905061212f565b856101800151826040517f2b11b8d90000000000000000000000000000000000000000000000000000000081526004016108c7929190615bb0565b50506040805160208101909152600081526002909250929050565b60008151602014613cd3578160405163046b337b60e51b81526004016108c7919061423a565b610eb082806020019051810190613cea9190615d2a565b6140b3565b6000606060008361ffff1667ffffffffffffffff811115613d1257613d126143ec565b6040519080825280601f01601f191660200182016040528015613d3c576020820181803683370190505b509150863b613d6f577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613da2577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613ddb577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613dfe5750835b808352806000602085013e50955095509592505050565b8251825160009190818303613e56576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613e6a57506101018111155b613e87576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613eb1576040516309bde33960e01b815260040160405180910390fd5b80600003613ede5786600081518110613ecc57613ecc615526565b60200260200101519350505050613196565b60008167ffffffffffffffff811115613ef957613ef96143ec565b604051908082528060200260200182016040528015613f22578160200160208202803683370190505b50905060008080805b8581101561404c5760006001821b8b811603613f865788851015613f6f578c5160018601958e918110613f6057613f60615526565b60200260200101519050613fa8565b8551600185019487918110613f6057613f60615526565b8b5160018401938d918110613f9d57613f9d615526565b602002602001015190505b600089861015613fd8578d5160018701968f918110613fc957613fc9615526565b60200260200101519050613ffa565b8651600186019588918110613fef57613fef615526565b602002602001015190505b8285111561401b576040516309bde33960e01b815260040160405180910390fd5b6140258282614107565b87848151811061403757614037615526565b60209081029190910101525050600101613f2b565b50600185038214801561405e57508683145b801561406957508581145b614086576040516309bde33960e01b815260040160405180910390fd5b83600186038151811061409b5761409b615526565b60200260200101519750505050505050509392505050565b60006001600160a01b038211806140cb575061040082105b156141035760408051602081018490520160408051601f198184030181529082905263046b337b60e51b82526108c79160040161423a565b5090565b600081831061411f5761411a8284614125565b610ead565b610ead83835b604080516001602082015290810183905260608101829052600090608001613947565b8280548282559060005260206000209081019282156141aa579160200282015b828111156141aa578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190614168565b506141039291506141d5565b604051806103e00160405280601f906020820280368337509192915050565b5b8082111561410357600081556001016141d6565b60005b838110156142055781810151838201526020016141ed565b50506000910152565b600081518084526142268160208601602086016141ea565b601f01601f19169290920160200192915050565b602081526000610ead602083018461420e565b8060608101831015610eb057600080fd5b60008083601f84011261427057600080fd5b50813567ffffffffffffffff81111561428857600080fd5b60208301915083602082850101111561212f57600080fd5b60008083601f8401126142b257600080fd5b50813567ffffffffffffffff8111156142ca57600080fd5b6020830191508360208260051b850101111561212f57600080fd5b60008060008060008060008060e0898b03121561430157600080fd5b61430b8a8a61424d565b9750606089013567ffffffffffffffff8082111561432857600080fd5b6143348c838d0161425e565b909950975060808b013591508082111561434d57600080fd5b6143598c838d016142a0565b909750955060a08b013591508082111561437257600080fd5b5061437f8b828c016142a0565b999c989b50969995989497949560c00135949350505050565b6000806000608084860312156143ad57600080fd5b6143b7858561424d565b9250606084013567ffffffffffffffff8111156143d357600080fd5b6143df8682870161425e565b9497909650939450505050565b634e487b7160e01b600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715614425576144256143ec565b60405290565b6040805190810167ffffffffffffffff81118282101715614425576144256143ec565b6040516101a0810167ffffffffffffffff81118282101715614425576144256143ec565b60405160a0810167ffffffffffffffff81118282101715614425576144256143ec565b6040516080810167ffffffffffffffff81118282101715614425576144256143ec565b6040516060810167ffffffffffffffff81118282101715614425576144256143ec565b604051601f8201601f1916810167ffffffffffffffff81118282101715614504576145046143ec565b604052919050565b6001600160a01b0381168114610ff057600080fd5b803561452c8161450c565b919050565b803563ffffffff8116811461452c57600080fd5b600060c0828403121561455757600080fd5b61455f614402565b823561456a8161450c565b815261457860208401614531565b602082015261458960408401614531565b604082015261459a60608401614531565b606082015260808301356145ad8161450c565b608082015260a08301356145c08161450c565b60a08201529392505050565b600067ffffffffffffffff8211156145e6576145e66143ec565b5060051b60200190565b67ffffffffffffffff81168114610ff057600080fd5b803561452c816145f0565b8015158114610ff057600080fd5b803561452c81614611565b600067ffffffffffffffff821115614644576146446143ec565b50601f01601f191660200190565b600082601f83011261466357600080fd5b81356146766146718261462a565b6144db565b81815284602083860101111561468b57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f8301126146b957600080fd5b813560206146c9614671836145cc565b82815260069290921b840181019181810190868411156146e857600080fd5b8286015b8481101561228e57604081890312156147055760008081fd5b61470d61442b565b81356147188161450c565b815281850135858201528352918301916040016146ec565b600082601f83011261474157600080fd5b81356020614751614671836145cc565b82815260059290921b8401810191818101908684111561477057600080fd5b8286015b8481101561228e57803567ffffffffffffffff8111156147945760008081fd5b6147a28986838b0101614652565b845250918301918301614774565b60006101a082840312156147c357600080fd5b6147cb61444e565b90506147d682614606565b81526147e460208301614521565b60208201526147f560408301614521565b604082015261480660608301614606565b60608201526080820135608082015261482160a0830161461f565b60a082015261483260c08301614606565b60c082015261484360e08301614521565b60e082015261010082810135908201526101208083013567ffffffffffffffff8082111561487057600080fd5b61487c86838701614652565b8385015261014092508285013591508082111561489857600080fd5b6148a4868387016146a8565b838501526101609250828501359150808211156148c057600080fd5b506148cd85828601614730565b82840152505061018080830135818301525092915050565b600082601f8301126148f657600080fd5b81356020614906614671836145cc565b82815260059290921b8401810191818101908684111561492557600080fd5b8286015b8481101561228e57803567ffffffffffffffff8111156149495760008081fd5b6149578986838b01016147b0565b845250918301918301614929565b600082601f83011261497657600080fd5b81356020614986614671836145cc565b82815260059290921b840181019181810190868411156149a557600080fd5b8286015b8481101561228e57803567ffffffffffffffff8111156149c95760008081fd5b6149d78986838b0101614730565b8452509183019183016149a9565b600082601f8301126149f657600080fd5b81356020614a06614671836145cc565b8083825260208201915060208460051b870101935086841115614a2857600080fd5b602086015b8481101561228e5780358352918301918301614a2d565b600082601f830112614a5557600080fd5b81356020614a65614671836145cc565b82815260059290921b84018101918181019086841115614a8457600080fd5b8286015b8481101561228e57803567ffffffffffffffff80821115614aa95760008081fd5b9088019060a0828b03601f1901811315614ac35760008081fd5b614acb614472565b614ad6888501614606565b815260408085013584811115614aec5760008081fd5b614afa8e8b838901016148e5565b8a8401525060608086013585811115614b135760008081fd5b614b218f8c838a0101614965565b8385015250608091508186013585811115614b3c5760008081fd5b614b4a8f8c838a01016149e5565b9184019190915250919093013590830152508352918301918301614a88565b6000806040808486031215614b7d57600080fd5b833567ffffffffffffffff80821115614b9557600080fd5b614ba187838801614a44565b9450602091508186013581811115614bb857600080fd5b8601601f81018813614bc957600080fd5b8035614bd7614671826145cc565b81815260059190911b8201840190848101908a831115614bf657600080fd5b8584015b83811015614c8257803586811115614c125760008081fd5b8501603f81018d13614c245760008081fd5b87810135614c34614671826145cc565b81815260059190911b82018a0190898101908f831115614c545760008081fd5b928b01925b82841015614c725783358252928a0192908a0190614c59565b8652505050918601918601614bfa565b50809750505050505050509250929050565b60008060408385031215614ca757600080fd5b8235614cb2816145f0565b91506020830135614cc2816145f0565b809150509250929050565b634e487b7160e01b600052602160045260246000fd5b60048110614cf357614cf3614ccd565b9052565b60208101610eb08284614ce3565b600060208284031215614d1757600080fd5b8135613196816145f0565b60006020808385031215614d3557600080fd5b823567ffffffffffffffff811115614d4c57600080fd5b8301601f81018513614d5d57600080fd5b8035614d6b614671826145cc565b81815260079190911b82018301908381019087831115614d8a57600080fd5b928401925b828410156135f95760808489031215614da85760008081fd5b614db0614495565b8435614dbb816145f0565b815284860135614dca81614611565b81870152604085810135614ddd8161450c565b90820152606085810135614df08161450c565b9082015282526080939093019290840190614d8f565b600060208284031215614e1857600080fd5b813567ffffffffffffffff811115614e2f57600080fd5b820160a0818503121561319657600080fd5b60008060408385031215614e5457600080fd5b8235614e5f816145f0565b91506020830135614cc28161450c565b803560ff8116811461452c57600080fd5b600060208284031215614e9257600080fd5b610ead82614e6f565b60008151808452602080850194506020840160005b83811015614ed55781516001600160a01b031687529582019590820190600101614eb0565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614f2f60e0840182614e9b565b90506040840151601f198483030160c0850152614f4c8282614e9b565b95945050505050565b60008060408385031215614f6857600080fd5b8235614f73816145f0565b946020939093013593505050565b60008060208385031215614f9457600080fd5b823567ffffffffffffffff80821115614fac57600080fd5b818501915085601f830112614fc057600080fd5b813581811115614fcf57600080fd5b8660208260061b8501011115614fe457600080fd5b60209290920196919550909350505050565b60006020828403121561500857600080fd5b81356131968161450c565b6000806040838503121561502657600080fd5b823567ffffffffffffffff8082111561503e57600080fd5b61504a868387016147b0565b9350602085013591508082111561506057600080fd5b5061506d85828601614730565b9150509250929050565b600082601f83011261508857600080fd5b81356020615098614671836145cc565b8083825260208201915060208460051b8701019350868411156150ba57600080fd5b602086015b8481101561228e5780356150d28161450c565b83529183019183016150bf565b600060208083850312156150f257600080fd5b823567ffffffffffffffff8082111561510a57600080fd5b818501915085601f83011261511e57600080fd5b813561512c614671826145cc565b81815260059190911b8301840190848101908883111561514b57600080fd5b8585015b8381101561521d5780358581111561516657600080fd5b860160c0818c03601f1901121561517d5760008081fd5b615185614402565b8882013581526040615198818401614e6f565b8a83015260606151a9818501614e6f565b82840152608091506151bc82850161461f565b9083015260a083810135898111156151d45760008081fd5b6151e28f8d83880101615077565b838501525060c08401359150888211156151fc5760008081fd5b61520a8e8c84870101615077565b908301525084525091860191860161514f565b5098975050505050505050565b60006020828403121561523c57600080fd5b5035919050565b80356001600160e01b038116811461452c57600080fd5b600082601f83011261526b57600080fd5b8135602061527b614671836145cc565b82815260069290921b8401810191818101908684111561529a57600080fd5b8286015b8481101561228e57604081890312156152b75760008081fd5b6152bf61442b565b81356152ca816145f0565b81526152d7828601615243565b8186015283529183019160400161529e565b600082601f8301126152fa57600080fd5b8135602061530a614671836145cc565b82815260079290921b8401810191818101908684111561532957600080fd5b8286015b8481101561228e5780880360808112156153475760008081fd5b61534f6144b8565b823561535a816145f0565b81526040601f1983018113156153705760008081fd5b61537861442b565b925086840135615387816145f0565b835283810135615396816145f0565b838801528187019290925260608301359181019190915283529183019160800161532d565b600060208083850312156153ce57600080fd5b823567ffffffffffffffff808211156153e657600080fd5b818501915060408083880312156153fc57600080fd5b61540461442b565b83358381111561541357600080fd5b84016040818a03121561542557600080fd5b61542d61442b565b81358581111561543c57600080fd5b8201601f81018b1361544d57600080fd5b803561545b614671826145cc565b81815260069190911b8201890190898101908d83111561547a57600080fd5b928a01925b828410156154ca5787848f0312156154975760008081fd5b61549f61442b565b84356154aa8161450c565b81526154b7858d01615243565b818d0152825292870192908a019061547f565b8452505050818701359350848411156154e257600080fd5b6154ee8a85840161525a565b818801528252508385013591508282111561550857600080fd5b615514888386016152e9565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b8181101561559357835180516001600160a01b031684528501516001600160e01b031685840152928401929185019160010161555c565b50508583015187820388850152805180835290840192506000918401905b808310156155ed578351805167ffffffffffffffff1683528501516001600160e01b0316858301529284019260019290920191908501906155b1565b50979650505050505050565b602081526000610ead602083018461553c565b67ffffffffffffffff83168152606081016131966020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff81811683821601908082111561567857615678615641565b5092915050565b60006020808352606084516040808487015261569e606087018361553c565b87850151878203601f19016040890152805180835290860193506000918601905b8083101561521d57845167ffffffffffffffff8151168352878101516156fe89850182805167ffffffffffffffff908116835260209182015116910152565b508401518287015293860193600192909201916080909101906156bf565b60006020828403121561572e57600080fd5b813567ffffffffffffffff81111561574557600080fd5b6139b384828501614a44565b81810381811115610eb057610eb0615641565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff8084168061579557615795615764565b92169190910692915050565b8082028115828204841417610eb057610eb0615641565b6000604082840312156157ca57600080fd5b6157d261442b565b82356157dd816145f0565b81526020928301359281019290925250919050565b60008151808452602080850194506020840160005b83811015614ed557815180516001600160a01b031688526020908101519088015260408701965090820190600101615807565b8051825267ffffffffffffffff60208201511660208301526000604082015160a0604085015261586d60a085018261420e565b905060608301518482036060860152615886828261420e565b91505060808301518482036080860152614f4c82826157f2565b602081526000610ead602083018461583a565b6080815260006158c6608083018761583a565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b600082601f83011261590057600080fd5b815161590e6146718261462a565b81815284602083860101111561592357600080fd5b6139b38260208301602087016141ea565b60008060006060848603121561594957600080fd5b835161595481614611565b602085015190935067ffffffffffffffff81111561597157600080fd5b61597d868287016158ef565b925050604084015190509250925092565b6000602082840312156159a057600080fd5b815161319681614611565b80820180821115610eb057610eb0615641565b60ff8181168382160190811115610eb057610eb0615641565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff80841680615a1657615a16615764565b92169190910492915050565b600060208284031215615a3457600080fd5b8151613196816145f0565b600060208284031215615a5157600080fd5b815167ffffffffffffffff80821115615a6957600080fd5b9083019060608286031215615a7d57600080fd5b615a856144b8565b825182811115615a9457600080fd5b615aa0878286016158ef565b825250602083015182811115615ab557600080fd5b615ac1878286016158ef565b602083015250604083015182811115615ad957600080fd5b615ae5878286016158ef565b60408301525095945050505050565b6020810160058310615b0857615b08614ccd565b91905290565b60ff818116838216029081169081811461567857615678615641565b600060a0820160ff88168352602087602085015260a0604085015281875480845260c086019150886000526020600020935060005b81811015615b845784546001600160a01b031683526001948501949284019201615b5f565b50508481036060860152615b988188614e9b565b935050505060ff831660808301529695505050505050565b8281526040602082015260006139b3604083018461420e565b67ffffffffffffffff848116825283166020820152606081016139b36040830184614ce3565b600067ffffffffffffffff808316818103615c0c57615c0c615641565b6001019392505050565b615c208184614ce3565b6040602082015260006139b3604083018461420e565b600060208284031215615c4857600080fd5b81516131968161450c565b6020815260008251610100806020850152615c7261012085018361420e565b91506020850151615c8f604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615cc960a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615ce6848361420e565b935060c08701519150808685030160e0870152615d03848361420e565b935060e0870151915080868503018387015250615d20838261420e565b9695505050505050565b600060208284031215615d3c57600080fd5b5051919050565b600060ff821660ff8103615d5957615d59615641565b60010192915050565b6020808252825182820181905260009190848201906040850190845b81811015615db157835180516001600160a01b031684526020908101519084015260408301938501939250600101615d7e565b50909695505050505050565b60008282518085526020808601955060208260051b8401016020860160005b84811015615e0a57601f19868403018952615df883835161420e565b98840198925090830190600101615ddc565b5090979650505050505050565b602081526000610ead6020830184615dbd565b60408152615e4560408201845167ffffffffffffffff169052565b60006020840151615e6160608401826001600160a01b03169052565b5060408401516001600160a01b038116608084015250606084015167ffffffffffffffff811660a084015250608084015160c083015260a084015180151560e08401525060c0840151610100615ec28185018367ffffffffffffffff169052565b60e08601519150610120615ee0818601846001600160a01b03169052565b81870151925061014091508282860152808701519250506101a06101608181870152615f106101e087018561420e565b9350828801519250603f19610180818887030181890152615f3186866157f2565b9550828a01519450818887030184890152615f4c8686615dbd565b9550808a01516101c089015250505050508281036020840152614f4c8185615dbd565b6000815160208301516001600160e01b031980821693506004831015615f9f5780818460040360031b1b83161693505b50505091905056fea164736f6c6343000818000a", } 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/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index bd627364d8..de649f27e2 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 @@ -9,7 +9,7 @@ commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../ 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_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin 4c7bdddea3decee12887c5bd89648ed3b423bd31eefe586d5cb5c1bc8b883ffe 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_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 From e5057ce79dc8ef431ac87a858f083fd74c280b29 Mon Sep 17 00:00:00 2001 From: Amir Y <83904651+amirylm@users.noreply.github.com> Date: Fri, 21 Jun 2024 11:57:46 +0300 Subject: [PATCH 3/8] LM: increase transmit gas limit (#1061) ## Motivation The current value (`1e6`) might not be enough for extreme conditions ## Solution Increased gas limit to `5e6` #changed --- .changeset/wild-gifts-refuse.md | 5 +++++ core/services/relay/evm/liquidity_manager.go | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 .changeset/wild-gifts-refuse.md 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/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]{}, From 292ac452dd6aeac47f7e773ce81bd1944e63fa01 Mon Sep 17 00:00:00 2001 From: Makram Date: Fri, 21 Jun 2024 16:38:56 +0300 Subject: [PATCH 4/8] [feat] CCIP capability config contract (#858) ## Motivation The CCIP capability needs to fetch its configuration from somewhere - that somewhere is the CCIP capability configuration contract. ## Solution Implement the CCIP capability configuration contract in solidity. The solidity implementation almost matches the design doc exactly. --- contracts/gas-snapshots/ccip.gas-snapshot | 50 + .../scripts/native_solc_compile_all_ccip | 1 + .../CCIPCapabilityConfiguration.sol | 497 ++++++ .../interfaces/ICapabilityRegistry.sol | 23 + .../CCIPCapabilityConfiguration.t.sol | 1572 +++++++++++++++++ .../CCIPCapabilityConfigurationHelper.sol | 57 + .../ccip_capability_configuration.go | 1079 +++++++++++ ...rapper-dependency-versions-do-not-edit.txt | 2 +- core/gethwrappers/ccip/go_generate.go | 1 + 9 files changed, 3281 insertions(+), 1 deletion(-) create mode 100644 contracts/src/v0.8/ccip/capability/CCIPCapabilityConfiguration.sol create mode 100644 contracts/src/v0.8/ccip/capability/interfaces/ICapabilityRegistry.sol create mode 100644 contracts/src/v0.8/ccip/test/capability/CCIPCapabilityConfiguration.t.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/CCIPCapabilityConfigurationHelper.sol create mode 100644 core/gethwrappers/ccip/generated/ccip_capability_configuration/ccip_capability_configuration.go diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 4af4b21269..d70f3da3f0 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) diff --git a/contracts/scripts/native_solc_compile_all_ccip b/contracts/scripts/native_solc_compile_all_ccip index 2c209d69d6..661de2b842 100755 --- a/contracts/scripts/native_solc_compile_all_ccip +++ b/contracts/scripts/native_solc_compile_all_ccip @@ -75,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/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/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/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/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/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index de649f27e2..13aab261a8 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,9 +5,9 @@ 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 4c7bdddea3decee12887c5bd89648ed3b423bd31eefe586d5cb5c1bc8b883ffe evm_2_evm_multi_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.bin da3b401b00dae39a2851740d00f2ed81d498ad9287b7ab9276f8b10021743d20 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 From 84394c6cfcc93497e8964ea864dddd35b8ed8e54 Mon Sep 17 00:00:00 2001 From: Patrick Date: Fri, 21 Jun 2024 13:11:23 -0400 Subject: [PATCH 5/8] Adding setters to CommitStore for GasEstimator and SourceMaxGasPrice (#1047) ## Motivation CommitStore currently is constructed with dependencies from both a Source Chain Relayer and Dest Chain Relayer. This violates a key constraint of our system when moving to LOOPPs. This change is one step to separate the construction of a `CommitStore` from requiring the source max gas price and source gas price estimator. ## Solution Instead of setting `sourceMaxGasPrice` and `estimator` in the construction of a `CommitStore`, we now use explicit setter methods. This will be consumed in future PRs to add a provider based implementation of a gas estimator in the reporting plugin factory. --------- Co-authored-by: dimitris --- .github/workflows/ci-scripts.yml | 1 + .../plugins/ccip/ccipcommit/initializers.go | 15 ++++++- .../ocr2/plugins/ccip/ccipcommit/ocr2_test.go | 2 +- .../plugins/ccip/ccipexec/initializers.go | 14 +++++- .../internal/ccipdata/commit_store_reader.go | 6 +++ .../ccipdata/commit_store_reader_test.go | 14 ++++-- .../internal/ccipdata/factory/commit_store.go | 21 ++++----- .../ccipdata/factory/commit_store_test.go | 4 +- .../mocks/commit_store_reader_mock.go | 40 +++++++++++++++++ .../internal/ccipdata/v1_0_0/commit_store.go | 44 ++++++++++++++----- .../ccipdata/v1_0_0/commit_store_test.go | 2 +- .../internal/ccipdata/v1_2_0/commit_store.go | 43 +++++++++++++----- .../ccipdata/v1_2_0/commit_store_test.go | 2 +- .../internal/ccipdata/v1_5_0/commit_store.go | 6 +-- 14 files changed, 166 insertions(+), 48 deletions(-) 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/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 } From c7472e4704553ae83a1d3900b66a015d54c52927 Mon Sep 17 00:00:00 2001 From: Josh Weintraub Date: Fri, 21 Jun 2024 15:18:09 -0400 Subject: [PATCH 6/8] Additional Fuzz Tests for EVM2EVMOffRamp (#1068) ## Motivation Add additional fuzz tests in EVM2EVMOffRamp.t.sol to fill in fuzz-testing coverage gaps 2nd attempt at a PR after I messed up merging #919 ## Solution Added The following tests Stateless fuzzing: `getSenderNonce` with and without `i_prevOffRamp` `getAllRateLimitTokens` & `updateRateLimitTokens` `_trialExecute` with different messages and token data --- contracts/gas-snapshots/ccip.gas-snapshot | 52 ++--- .../ccip/test/offRamp/EVM2EVMOffRamp.t.sol | 177 ++++++++++++++++++ 2 files changed, 203 insertions(+), 26 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index d70f3da3f0..d3c64b3c8f 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -358,32 +358,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) 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 { From acb2d60d10f20d7ab2664108de7bedb2b6923d42 Mon Sep 17 00:00:00 2001 From: Anindita Ghosh <88458927+AnieeG@users.noreply.github.com> Date: Fri, 21 Jun 2024 14:34:43 -0700 Subject: [PATCH 7/8] fix panic in load test (#1069) --- .../ccip-tests/load/ccip_loadgen.go | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) 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)), From 20169bdf1d9173f3a7bc904ecd490ef60efebb24 Mon Sep 17 00:00:00 2001 From: Ryan <80392855+RayXpub@users.noreply.github.com> Date: Mon, 24 Jun 2024 16:10:12 +0400 Subject: [PATCH 8/8] NonceManager outbound nonces (#985) ## Motivation Implements the outbound nonce logic for the `NonceManager` contract. The goal of the `NonceManager` contract is to manage senders' nonces and extract that logic from the ramps. ## Solution - Onramp and offramp are listed as authorized callers by the owner - Contract owner sets previous onramp addresses - Previous ramps can only be set once - `EVM2EVMMultiOnRamp` calls `incrementOutboundNonce` which returns the new nonce - Handles upgradability logic to call `prevOnRamp` if necessary A shared `AuthorizedCallers` contract has been added and integrated to the following contracts: - `MultiAggregateRateLimiter` - `NonceManager` Out ouf scope: - Inbound nonce logic (next PR) --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- contracts/gas-snapshots/ccip.gas-snapshot | 110 +- contracts/gas-snapshots/shared.gas-snapshot | 9 + .../v0.8/ccip/MultiAggregateRateLimiter.sol | 116 +- contracts/src/v0.8/ccip/NonceManager.sol | 96 ++ .../ccip/interfaces/IEVM2AnyMultiOnRamp.sol | 17 - .../ccip/interfaces/IMessageInterceptor.sol | 4 +- .../v0.8/ccip/interfaces/INonceManager.sol | 11 + .../v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol | 2 +- .../v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol | 41 +- .../src/v0.8/ccip/test/NonceManager.t.sol | 227 ++++ .../v0.8/ccip/test/e2e/MultiRampsEnd2End.sol | 23 +- .../test/helpers/MessageInterceptorHelper.sol | 4 +- .../ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol | 209 +--- .../test/onRamp/EVM2EVMMultiOnRampSetup.t.sol | 19 +- .../MultiAggregateRateLimiter.t.sol | 248 +--- .../v0.8/shared/access/AuthorizedCallers.sol | 82 ++ .../test/access/AuthorizedCallers.t.sol | 186 +++ .../evm_2_evm_multi_offramp.go | 2 +- .../evm_2_evm_multi_onramp.go | 31 +- .../multi_aggregate_rate_limiter.go | 68 +- .../generated/nonce_manager/nonce_manager.go | 1064 +++++++++++++++++ ...rapper-dependency-versions-do-not-edit.txt | 7 +- 22 files changed, 1949 insertions(+), 627 deletions(-) create mode 100644 contracts/src/v0.8/ccip/NonceManager.sol delete mode 100644 contracts/src/v0.8/ccip/interfaces/IEVM2AnyMultiOnRamp.sol create mode 100644 contracts/src/v0.8/ccip/interfaces/INonceManager.sol create mode 100644 contracts/src/v0.8/ccip/test/NonceManager.t.sol create mode 100644 contracts/src/v0.8/shared/access/AuthorizedCallers.sol create mode 100644 contracts/src/v0.8/shared/test/access/AuthorizedCallers.t.sol create mode 100644 core/gethwrappers/ccip/generated/nonce_manager/nonce_manager.go diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index d3c64b3c8f..8d8d99b2a1 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -162,7 +162,7 @@ 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: 330182) +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) @@ -177,10 +177,10 @@ 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: 235451) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 91273) +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: 95383) +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) @@ -264,22 +264,24 @@ EVM2EVMMultiOnRamp_applyDestChainConfigUpdates:test_InvalidDestChainConfigNewPre 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) @@ -287,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) @@ -329,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) @@ -417,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) @@ -583,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) @@ -650,7 +641,16 @@ 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: 1395580) +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/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/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/offRamp/EVM2EVMMultiOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol index 1b6ed6eb21..a261c1fc65 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol @@ -564,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); } 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/e2e/MultiRampsEnd2End.sol b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol index 3ab36ab469..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); 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/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/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 7dc439b6ce..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 @@ -157,7 +157,7 @@ type MultiOCR3BaseOCRConfigArgs struct { 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\":\"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: "0x6101006040523480156200001257600080fd5b50604051620067e1380380620067e1833981016040819052620000359162000648565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001c1565b5050466080525060208201516001600160a01b03161580620000ec575060408201516001600160a01b0316155b156200010b576040516342bcdf7f60e11b815260040160405180910390fd5b81516001600160401b0316600003620001375760405163c656089560e01b815260040160405180910390fd5b81516001600160401b0390811660a052602080840180516001600160a01b0390811660c05260408087018051831660e052815188519096168652925182169385019390935290511682820152517f2f56698ec552a5d53d27d6f4b3dd8b6989f6426b6151a36aff61160c1d07efdf9181900360600190a1620001b9816200026c565b5050620007d0565b336001600160a01b038216036200021b5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b81518110156200051c576000828281518110620002905762000290620007ba565b60200260200101519050600081600001519050806001600160401b0316600003620002ce5760405163c656089560e01b815260040160405180910390fd5b60608201516001600160a01b0316620002fa576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b038116600090815260076020526040902060018101546001600160a01b031662000400576200035c8284606001517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b36200052060201b60201c565b600282015560608301516001820180546001600160a01b039283166001600160a01b03199091161790556040808501518354610100600160481b03199190931669010000000000000000000216610100600160e81b031990921691909117610100178255516001600160401b03831681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a16200046f565b606083015160018201546001600160a01b03908116911614158062000444575060408301518154690100000000000000000090046001600160a01b03908116911614155b156200046f5760405163c39a620560e01b81526001600160401b038316600482015260240162000083565b6020830151815490151560ff199091161781556040516001600160401b038316907fa73c588738263db34ef8c1942db8f99559bc6696f6a812d42e76bafb4c0e8d309062000505908490815460ff811615158252600881901c6001600160401b0316602083015260481c6001600160a01b0390811660408301526001830154166060820152600290910154608082015260a00190565b60405180910390a25050508060010190506200026f565b5050565b60a0805160408051602081018590526001600160401b0380881692820192909252911660608201526001600160a01b0384166080820152600091016040516020818303038152906040528051906020012090509392505050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b0381118282101715620005b557620005b56200057a565b60405290565b604051608081016001600160401b0381118282101715620005b557620005b56200057a565b604051601f8201601f191681016001600160401b03811182821017156200060b576200060b6200057a565b604052919050565b80516001600160401b03811681146200062b57600080fd5b919050565b80516001600160a01b03811681146200062b57600080fd5b6000808284036080808212156200065e57600080fd5b6060808312156200066e57600080fd5b6200067862000590565b9250620006858662000613565b835260206200069681880162000630565b818501526040620006aa6040890162000630565b604086015260608801519496506001600160401b0380861115620006cd57600080fd5b858901955089601f870112620006e257600080fd5b855181811115620006f757620006f76200057a565b62000707848260051b01620005e0565b818152848101925060079190911b87018401908b8211156200072857600080fd5b968401965b81881015620007a85786888d031215620007475760008081fd5b62000751620005bb565b6200075c8962000613565b8152858901518015158114620007725760008081fd5b818701526200078389860162000630565b8582015262000794878a0162000630565b81880152835296860196918401916200072d565b80985050505050505050509250929050565b634e487b7160e01b600052603260045260246000fd5b60805160a05160c05160e051615fb46200082d6000396000818161021e01526131fe0152600081816101ef015281816115fc01526116b30152600081816101bf0152613120015260008181611c4f0152611c9b0152615fb46000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c80637f63b711116100e3578063d2a15d351161008c578063f52121a511610066578063f52121a514610686578063f716f99f14610699578063ff888fb1146106ac57600080fd5b8063d2a15d3514610552578063e9d68a8e14610565578063f2fde38b1461067357600080fd5b80638da5cb5b116100bd5780638da5cb5b146104d2578063c673e584146104ed578063ccd37ba31461050d57600080fd5b80637f63b7111461049e57806385572ffb146104b15780638b364334146104bf57600080fd5b8063403b2d631161014557806369600bca1161011f57806369600bca1461036e5780637437ff9f1461038157806379ba50971461049657600080fd5b8063403b2d6314610328578063542625af1461033b5780635e36480c1461034e57600080fd5b80632d04ab76116101765780632d04ab76146102d9578063311cd513146102ee5780633f4b04aa1461030157600080fd5b806306285c6914610192578063181f5a7714610290575b600080fd5b61024e604080516060810182526000808252602082018190529181019190915260405180606001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b60408051825167ffffffffffffffff1681526020808401516001600160a01b039081169183019190915292820151909216908201526060015b60405180910390f35b6102cc6040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b604051610287919061423a565b6102ec6102e73660046142e5565b6106cf565b005b6102ec6102fc366004614398565b610a95565b600b5467ffffffffffffffff165b60405167ffffffffffffffff9091168152602001610287565b6102ec610336366004614545565b610afe565b6102ec610349366004614b69565b610cbb565b61036161035c366004614c94565b610e60565b6040516102879190614cf7565b6102ec61037c366004614d05565b610eb6565b61042d6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c0810182526004546001600160a01b03808216835263ffffffff74010000000000000000000000000000000000000000830481166020850152600160c01b8304811694840194909452600160e01b90910490921660608201526005548216608082015260065490911660a082015290565b6040516102879190600060c0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401528060a08501511660a08401525092915050565b6102ec610f21565b6102ec6104ac366004614d22565b610fdf565b6102ec61018d366004614e06565b61030f6104cd366004614e41565b610ff3565b6000546040516001600160a01b039091168152602001610287565b6105006104fb366004614e80565b611009565b6040516102879190614ee0565b61054461051b366004614f55565b67ffffffffffffffff919091166000908152600a60209081526040808320938352929052205490565b604051908152602001610287565b6102ec610560366004614f81565b611167565b610616610573366004614d05565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091525067ffffffffffffffff908116600090815260076020908152604091829020825160a081018452815460ff8116151582526101008104909516928101929092526001600160a01b0369010000000000000000009094048416928201929092526001820154909216606083015260020154608082015290565b6040516102879190600060a08201905082511515825267ffffffffffffffff602084015116602083015260408301516001600160a01b03808216604085015280606086015116606085015250506080830151608083015292915050565b6102ec610681366004614ff6565b611221565b6102ec610694366004615013565b611232565b6102ec6106a73660046150df565b611564565b6106bf6106ba36600461522a565b6115a6565b6040519015158152602001610287565b60006106dd878901896153bb565b805151519091501515806106f657508051602001515115155b156107f657600b5460208a01359067ffffffffffffffff808316911610156107b557600b805467ffffffffffffffff191667ffffffffffffffff831617905560065482516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921691633937306f9161077e916004016155f9565b600060405180830381600087803b15801561079857600080fd5b505af11580156107ac573d6000803e3d6000fd5b505050506107f4565b8160200151516000036107f4576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b8160200151518110156109de5760008260200151828151811061081e5761081e615526565b6020026020010151905060008160000151905061083a81611667565b600061084582611769565b602084015151815491925067ffffffffffffffff90811661010090920416141580610887575060208084015190810151905167ffffffffffffffff9182169116115b156108d057825160208401516040517feefb0cac0000000000000000000000000000000000000000000000000000000081526108c792919060040161560c565b60405180910390fd5b60408301518061090c576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff166000908152600a602090815260408083208484529091529020541561097f5783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602481018290526044016108c7565b6020808501510151610992906001615657565b825468ffffffffffffffff00191661010067ffffffffffffffff92831602179092559251166000908152600a6020908152604080832094835293905291909120429055506001016107f9565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d81604051610a0e919061567f565b60405180910390a1610a8a60008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b92506117c9915050565b505050505050505050565b610ad5610aa48284018461571c565b6040805160008082526020820190925290610acf565b6060815260200190600190039081610aba5790505b50611b40565b604080516000808252602082019092529050610af86001858585858660006117c9565b50505050565b610b06611bf0565b60a08101516001600160a01b03161580610b28575080516001600160a01b0316155b15610b5f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a177401000000000000000000000000000000000000000063ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff19908116928e1692909217905560a0808e01805160068054909416908f161790925586519a8b5297518716988a0198909852925185169388019390935251909216958501959095525185169383019390935251909216908201527f0da37fd00459f4f5f0b8210d31525e4910ae674b8bab34b561d146bb45773a4c9060c00160405180910390a150565b610cc3611c4c565b815181518114610cff576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610e50576000848281518110610d1e57610d1e615526565b60200260200101519050600081602001515190506000858481518110610d4657610d46615526565b6020026020010151905080518214610d8a576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610e41576000828281518110610da957610da9615526565b6020026020010151905080600014158015610de4575084602001518281518110610dd557610dd5615526565b60200260200101516080015181105b15610e385784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101839052604481018290526064016108c7565b50600101610d8d565b50505050806001019050610d02565b50610e5b8383611b40565b505050565b6000610e6e60016004615751565b6002610e7b60808561577a565b67ffffffffffffffff16610e8f91906157a1565b610e998585611ccd565b901c166003811115610ead57610ead614ccd565b90505b92915050565b610ebe611bf0565b600b805467ffffffffffffffff83811667ffffffffffffffff1983168117909355604080519190921680825260208201939093527f88ad9c61d6caf19a2af116a871802a03a31e680115a2dd20e8c08801d7c82f83910160405180910390a15050565b6001546001600160a01b03163314610f7b5760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108c7565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610fe7611bf0565b610ff081611d14565b50565b6000806110008484612025565b50949350505050565b61104c6040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c0820152948552918201805484518184028101840190955280855292938583019390928301828280156110f557602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116110d7575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561115757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611139575b5050505050815250509050919050565b61116f611bf0565b60005b81811015610e5b57600083838381811061118e5761118e615526565b9050604002018036038101906111a491906157b8565b90506111b381602001516115a6565b61121857805167ffffffffffffffff166000908152600a602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101611172565b611229611bf0565b610ff081612136565b33301461126b576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051600080825260208201909252816112a8565b60408051808201909152600080825260208201528152602001906001900390816112815790505b5061014084015151909150156113095761130683610140015184602001516040516020016112e591906001600160a01b0391909116815260200190565b60408051601f198184030181529181528601518651610160880151876121ec565b90505b60006113158483612299565b6005549091506001600160a01b03168015611402576040517fa219f6e50000000000000000000000000000000000000000000000000000000081526001600160a01b0382169063a219f6e59061136f9085906004016158a0565b600060405180830381600087803b15801561138957600080fd5b505af192505050801561139a575060015b611402573d8080156113c8576040519150601f19603f3d011682016040523d82523d6000602084013e6113cd565b606091505b50806040517f09c253250000000000000000000000000000000000000000000000000000000081526004016108c7919061423a565b6101208501515115801561141857506080850151155b8061142f575060408501516001600160a01b03163b155b8061146f5750604085015161146d906001600160a01b03167f85572ffb0000000000000000000000000000000000000000000000000000000061233c565b155b1561147b575050505050565b60048054608087015160408089015190517f3cf9798300000000000000000000000000000000000000000000000000000000815260009485946001600160a01b031693633cf97983936114d6938a93611388939291016158b3565b6000604051808303816000875af11580156114f5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261151d9190810190615934565b50915091508161155b57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016108c7919061423a565b50505050505050565b61156c611bf0565b60005b81518110156115a25761159a82828151811061158d5761158d615526565b6020026020010151612358565b60010161156f565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611643573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb0919061598e565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015611702573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611726919061598e565b15610ff0576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108c7565b67ffffffffffffffff81166000908152600760205260408120805460ff16610eb0576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108c7565b60ff878116600090815260026020908152604080832081516080810183528154815260019091015480861693820193909352610100830485169181019190915262010000909104909216151560608301528735906118288760a46159ab565b90508260600151156118705784516118419060206157a1565b865161184e9060206157a1565b6118599060a06159ab565b61186391906159ab565b61186d90826159ab565b90505b3681146118b2576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016108c7565b50815181146118fa5781516040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016108c7565b611902611c4c565b60ff808a166000908152600360209081526040808320338452825280832081518083019092528054808616835293949193909284019161010090910416600281111561195057611950614ccd565b600281111561196157611961614ccd565b905250905060028160200151600281111561197e5761197e614ccd565b1480156119d25750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff16815481106119ba576119ba615526565b6000918252602090912001546001600160a01b031633145b611a08576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611aea576020820151611a239060016159be565b60ff16855114611a5f576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611a9a576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611aac9291906159d7565b604051908190038120611ac3918b906020016159e7565b604051602081830303815290604052805190602001209050611ae88a82888888612663565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611b7a576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611be957611be1858281518110611baf57611baf615526565b602002602001015184611bdb57858381518110611bce57611bce615526565b602002602001015161287a565b8361287a565b600101611b91565b5050505050565b6000546001600160a01b03163314611c4a5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108c7565b565b467f000000000000000000000000000000000000000000000000000000000000000014611c4a576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016108c7565b67ffffffffffffffff8216600090815260096020526040812081611cf26080856159fb565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b60005b81518110156115a2576000828281518110611d3457611d34615526565b602002602001015190506000816000015190508067ffffffffffffffff16600003611d8b576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608201516001600160a01b0316611dcf576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8116600090815260076020526040902060018101546001600160a01b0316611ef257611e298284606001517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b361311a565b600282015560608301516001820180546001600160a01b0392831673ffffffffffffffffffffffffffffffffffffffff19909116179055604080850151835468ffffffffffffffff001991909316690100000000000000000002167fffffff00000000000000000000000000000000000000000000000000000000ff909216919091176101001782555167ffffffffffffffff831681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611f78565b606083015160018201546001600160a01b039081169116141580611f35575060408301518154690100000000000000000090046001600160a01b03908116911614155b15611f78576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff831660048201526024016108c7565b6020830151815490151560ff1990911617815560405167ffffffffffffffff8316907fa73c588738263db34ef8c1942db8f99559bc6696f6a812d42e76bafb4c0e8d309061200f908490815460ff811615158252600881901c67ffffffffffffffff16602083015260481c6001600160a01b0390811660408301526001830154166060820152600290910154608082015260a00190565b60405180910390a2505050806001019050611d17565b67ffffffffffffffff80831660009081526008602090815260408083206001600160a01b038616845290915281205490918291168082036121285767ffffffffffffffff8516600090815260076020526040902054690100000000000000000090046001600160a01b03168015612126576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b03868116600483015282169063856c824790602401602060405180830381865afa1580156120f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121199190615a22565b600193509350505061212f565b505b9150600090505b9250929050565b336001600160a01b0382160361218e5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108c7565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b8560005b875181101561228e5761226988828151811061220e5761220e615526565b60200260200101516020015188888888868151811061222f5761222f615526565b602002602001015180602001905181019061224a9190615a3f565b88878151811061225c5761225c615526565b602002602001015161319d565b82828151811061227b5761227b615526565b60209081029190910101526001016121f0565b509695505050505050565b6040805160a08101825260008082526020820152606091810182905281810182905260808101919091526040518060a001604052808461018001518152602001846000015167ffffffffffffffff168152602001846020015160405160200161231191906001600160a01b0391909116815260200190565b6040516020818303038152906040528152602001846101200151815260200183815250905092915050565b600061234783613516565b8015610ead5750610ead8383613562565b806040015160ff16600003612383576000604051631b3fab5160e11b81526004016108c79190615af4565b60208082015160ff808216600090815260029093526040832060018101549293909283921690036123d4576060840151600182018054911515620100000262ff000019909216919091179055612429565b6060840151600182015460ff6201000090910416151590151514612429576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff841660048201526024016108c7565b60a08401518051601f60ff82161115612458576001604051631b3fab5160e11b81526004016108c79190615af4565b6124be85856003018054806020026020016040519081016040528092919081815260200182805480156124b457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612496575b5050505050613604565b8560600151156125d05761252c85856002018054806020026020016040519081016040528092919081815260200182805480156124b4576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311612496575050505050613604565b608086015180516125469060028701906020840190614148565b50805160018501805461ff00191661010060ff841690810291909117909155601f1015612589576002604051631b3fab5160e11b81526004016108c79190615af4565b6040880151612599906003615b0e565b60ff168160ff16116125c1576003604051631b3fab5160e11b81526004016108c79190615af4565b6125cd8783600161366d565b50505b6125dc8583600261366d565b81516125f19060038601906020850190614148565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f5479361264a938a939260028b01929190615b2a565b60405180910390a161265b856137ed565b505050505050565b61266b6141b6565b835160005b8181101561287057600060018886846020811061268f5761268f615526565b61269c91901a601b6159be565b8985815181106126ae576126ae615526565b60200260200101518986815181106126c8576126c8615526565b602002602001015160405160008152602001604052604051612706949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612728573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b0385168352815285822085870190965285548084168652939750909550929392840191610100900416600281111561278957612789614ccd565b600281111561279a5761279a614ccd565b90525090506001816020015160028111156127b7576127b7614ccd565b146127ee576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061280557612805615526565b602002015115612841576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061285c5761285c615526565b911515602090920201525050600101612670565b5050505050505050565b815161288581611667565b600061289082611769565b60208501515190915060008190036128d3576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460400151518114612911576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561292c5761292c6143ec565b604051908082528060200260200182016040528015612955578160200160208202803683370190505b50905060005b82811015612a1a5760008760200151828151811061297b5761297b615526565b60200260200101519050612993818660020154613809565b8383815181106129a5576129a5615526565b6020026020010181815250508061018001518383815181106129c9576129c9615526565b602002602001015114612a11578061018001516040517f345039be0000000000000000000000000000000000000000000000000000000081526004016108c791815260200190565b5060010161295b565b506000612a31858389606001518a60800151613965565b905080600003612a79576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016108c7565b8551151560005b84811015610a8a57600089602001518281518110612aa057612aa0615526565b602002602001015190506000612aba898360600151610e60565b90506002816003811115612ad057612ad0614ccd565b03612b265760608201516040805167ffffffffffffffff808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c910160405180910390a15050613112565b6000816003811115612b3a57612b3a614ccd565b1480612b5757506003816003811115612b5557612b55614ccd565b145b612ba75760608201516040517f25507e7f00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808c16600483015290911660248201526044016108c7565b8315612c885760045460009074010000000000000000000000000000000000000000900463ffffffff16612bdb8742615751565b1190508080612bfb57506003826003811115612bf957612bf9614ccd565b145b612c3d576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8b1660048201526024016108c7565b8a8481518110612c4f57612c4f615526565b6020026020010151600014612c82578a8481518110612c7057612c70615526565b60200260200101518360800181815250505b50612ced565b6000816003811115612c9c57612c9c614ccd565b14612ced5760608201516040517f3ef2a99c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808c16600483015290911660248201526044016108c7565b600080612cfe8b8560200151612025565b915091508015612ded5760c084015167ffffffffffffffff16612d22836001615657565b67ffffffffffffffff1614612da55760c084015160208501516040517f5444a3301c7c42dd164cbf6ba4b72bf02504f86c049b06a27fc2b662e334bdbd92612d94928f9267ffffffffffffffff93841681529190921660208201526001600160a01b0391909116604082015260600190565b60405180910390a150505050613112565b67ffffffffffffffff8b81166000908152600860209081526040808320888301516001600160a01b031684529091529020805467ffffffffffffffff19169184169190911790555b6000836003811115612e0157612e01614ccd565b03612e925760c084015167ffffffffffffffff16612e20836001615657565b67ffffffffffffffff1614612e925760c084015160208501516040517f852dc8e405695593e311bd83991cf39b14a328f304935eac6d3d55617f911d8992612d94928f9267ffffffffffffffff93841681529190921660208201526001600160a01b0391909116604082015260600190565b60008d604001518681518110612eaa57612eaa615526565b6020026020010151905080518561014001515114612f0e5760608501516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808f16600483015290911660248201526044016108c7565b612f1e8c866060015160016139bb565b600080612f2b8784613a63565b91509150612f3e8e8860600151846139bb565b888015612f5c57506003826003811115612f5a57612f5a614ccd565b145b8015612f7a57506000866003811115612f7757612f77614ccd565b14155b15612fba57866101800151816040517f2b11b8d90000000000000000000000000000000000000000000000000000000081526004016108c7929190615bb0565b6003826003811115612fce57612fce614ccd565b14158015612fee57506002826003811115612feb57612feb614ccd565b14155b1561302f578d8760600151836040517f926c5a3e0000000000000000000000000000000000000000000000000000000081526004016108c793929190615bc9565b600086600381111561304357613043614ccd565b036130b15767ffffffffffffffff808f1660009081526008602090815260408083208b8301516001600160a01b0316845290915281208054909216919061308983615bef565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b866101800151876060015167ffffffffffffffff168f67ffffffffffffffff167f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df28585604051613102929190615c16565b60405180910390a4505050505050505b600101612a80565b600081847f00000000000000000000000000000000000000000000000000000000000000008560405160200161317d949392919093845267ffffffffffffffff9283166020850152911660408301526001600160a01b0316606082015260800190565b6040516020818303038152906040528051906020012090505b9392505050565b604080518082019091526000808252602082015260006131c08460200151613cad565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015613245573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132699190615c36565b90506001600160a01b03811615806132b157506132af6001600160a01b0382167faff2afbf0000000000000000000000000000000000000000000000000000000061233c565b155b156132f3576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016108c7565b6000806133be633907753760e01b6040518061010001604052808d81526020018b67ffffffffffffffff1681526020018c6001600160a01b031681526020018e8152602001876001600160a01b031681526020018a6000015181526020018a6040015181526020018981525060405160240161336f9190615c53565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152600454859063ffffffff600160e01b909104166113886084613cef565b5091509150816133e3578060405163e1cd550960e01b81526004016108c7919061423a565b805160201461342b5780516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016108c7565b6000818060200190518101906134419190615d2a565b604080516001600160a01b038d16602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b03167fa9059cbb000000000000000000000000000000000000000000000000000000001790526004549192506134c4918790600160c01b900463ffffffff166113886084613cef565b509093509150826134ea578160405163e1cd550960e01b81526004016108c7919061423a565b604080518082019091526001600160a01b03909516855260208501525091925050509695505050505050565b6000613542827f01ffc9a700000000000000000000000000000000000000000000000000000000613562565b8015610eb0575061355b826001600160e01b0319613562565b1592915050565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156135ed575060208210155b80156135f95750600081115b979650505050505050565b60005b8151811015610e5b5760ff83166000908152600360205260408120835190919084908490811061363957613639615526565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff19169055600101613607565b60005b82518160ff161015610af8576000838260ff168151811061369357613693615526565b60200260200101519050600060028111156136b0576136b0614ccd565b60ff80871660009081526003602090815260408083206001600160a01b038716845290915290205461010090041660028111156136ef576136ef614ccd565b14613710576004604051631b3fab5160e11b81526004016108c79190615af4565b6001600160a01b038116613750576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff16815260200184600281111561377657613776614ccd565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff1916176101008360028111156137d3576137d3614ccd565b021790555090505050806137e690615d43565b9050613670565b60ff8116610ff057600b805467ffffffffffffffff1916905550565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b610100015160405160200161389f9897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b60405160208183030381529060405280519060200120856101200151805190602001208661014001516040516020016138d89190615d62565b604051602081830303815290604052805190602001208761016001516040516020016139049190615e17565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e0015b60405160208183030381529060405280519060200120905092915050565b600080613973858585613e15565b905061397e816115a6565b61398c5760009150506139b3565b67ffffffffffffffff86166000908152600a60209081526040808320938352929052205490505b949350505050565b600060026139ca60808561577a565b67ffffffffffffffff166139de91906157a1565b905060006139ec8585611ccd565b9050816139fb60016004615751565b901b191681836003811115613a1257613a12614ccd565b67ffffffffffffffff871660009081526009602052604081209190921b92909217918291613a416080886159fb565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517ff52121a5000000000000000000000000000000000000000000000000000000008152600090606090309063f52121a590613aa79087908790600401615e2a565b600060405180830381600087803b158015613ac157600080fd5b505af1925050508015613ad2575060015b613c92573d808015613b00576040519150601f19603f3d011682016040523d82523d6000602084013e613b05565b606091505b506000613b1182615f6f565b90507f0a8d6e8c000000000000000000000000000000000000000000000000000000006001600160e01b031982161480613b5b575063e1cd550960e01b6001600160e01b03198216145b80613b76575063046b337b60e51b6001600160e01b03198216145b80613baa57507f78ef8024000000000000000000000000000000000000000000000000000000006001600160e01b03198216145b80613bde57507f0c3b563c000000000000000000000000000000000000000000000000000000006001600160e01b03198216145b80613c1257507fae9b4ce9000000000000000000000000000000000000000000000000000000006001600160e01b03198216145b80613c4657507f09c25325000000000000000000000000000000000000000000000000000000006001600160e01b03198216145b15613c57575060039250905061212f565b856101800151826040517f2b11b8d90000000000000000000000000000000000000000000000000000000081526004016108c7929190615bb0565b50506040805160208101909152600081526002909250929050565b60008151602014613cd3578160405163046b337b60e51b81526004016108c7919061423a565b610eb082806020019051810190613cea9190615d2a565b6140b3565b6000606060008361ffff1667ffffffffffffffff811115613d1257613d126143ec565b6040519080825280601f01601f191660200182016040528015613d3c576020820181803683370190505b509150863b613d6f577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613da2577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613ddb577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613dfe5750835b808352806000602085013e50955095509592505050565b8251825160009190818303613e56576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613e6a57506101018111155b613e87576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613eb1576040516309bde33960e01b815260040160405180910390fd5b80600003613ede5786600081518110613ecc57613ecc615526565b60200260200101519350505050613196565b60008167ffffffffffffffff811115613ef957613ef96143ec565b604051908082528060200260200182016040528015613f22578160200160208202803683370190505b50905060008080805b8581101561404c5760006001821b8b811603613f865788851015613f6f578c5160018601958e918110613f6057613f60615526565b60200260200101519050613fa8565b8551600185019487918110613f6057613f60615526565b8b5160018401938d918110613f9d57613f9d615526565b602002602001015190505b600089861015613fd8578d5160018701968f918110613fc957613fc9615526565b60200260200101519050613ffa565b8651600186019588918110613fef57613fef615526565b602002602001015190505b8285111561401b576040516309bde33960e01b815260040160405180910390fd5b6140258282614107565b87848151811061403757614037615526565b60209081029190910101525050600101613f2b565b50600185038214801561405e57508683145b801561406957508581145b614086576040516309bde33960e01b815260040160405180910390fd5b83600186038151811061409b5761409b615526565b60200260200101519750505050505050509392505050565b60006001600160a01b038211806140cb575061040082105b156141035760408051602081018490520160408051601f198184030181529082905263046b337b60e51b82526108c79160040161423a565b5090565b600081831061411f5761411a8284614125565b610ead565b610ead83835b604080516001602082015290810183905260608101829052600090608001613947565b8280548282559060005260206000209081019282156141aa579160200282015b828111156141aa578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190614168565b506141039291506141d5565b604051806103e00160405280601f906020820280368337509192915050565b5b8082111561410357600081556001016141d6565b60005b838110156142055781810151838201526020016141ed565b50506000910152565b600081518084526142268160208601602086016141ea565b601f01601f19169290920160200192915050565b602081526000610ead602083018461420e565b8060608101831015610eb057600080fd5b60008083601f84011261427057600080fd5b50813567ffffffffffffffff81111561428857600080fd5b60208301915083602082850101111561212f57600080fd5b60008083601f8401126142b257600080fd5b50813567ffffffffffffffff8111156142ca57600080fd5b6020830191508360208260051b850101111561212f57600080fd5b60008060008060008060008060e0898b03121561430157600080fd5b61430b8a8a61424d565b9750606089013567ffffffffffffffff8082111561432857600080fd5b6143348c838d0161425e565b909950975060808b013591508082111561434d57600080fd5b6143598c838d016142a0565b909750955060a08b013591508082111561437257600080fd5b5061437f8b828c016142a0565b999c989b50969995989497949560c00135949350505050565b6000806000608084860312156143ad57600080fd5b6143b7858561424d565b9250606084013567ffffffffffffffff8111156143d357600080fd5b6143df8682870161425e565b9497909650939450505050565b634e487b7160e01b600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715614425576144256143ec565b60405290565b6040805190810167ffffffffffffffff81118282101715614425576144256143ec565b6040516101a0810167ffffffffffffffff81118282101715614425576144256143ec565b60405160a0810167ffffffffffffffff81118282101715614425576144256143ec565b6040516080810167ffffffffffffffff81118282101715614425576144256143ec565b6040516060810167ffffffffffffffff81118282101715614425576144256143ec565b604051601f8201601f1916810167ffffffffffffffff81118282101715614504576145046143ec565b604052919050565b6001600160a01b0381168114610ff057600080fd5b803561452c8161450c565b919050565b803563ffffffff8116811461452c57600080fd5b600060c0828403121561455757600080fd5b61455f614402565b823561456a8161450c565b815261457860208401614531565b602082015261458960408401614531565b604082015261459a60608401614531565b606082015260808301356145ad8161450c565b608082015260a08301356145c08161450c565b60a08201529392505050565b600067ffffffffffffffff8211156145e6576145e66143ec565b5060051b60200190565b67ffffffffffffffff81168114610ff057600080fd5b803561452c816145f0565b8015158114610ff057600080fd5b803561452c81614611565b600067ffffffffffffffff821115614644576146446143ec565b50601f01601f191660200190565b600082601f83011261466357600080fd5b81356146766146718261462a565b6144db565b81815284602083860101111561468b57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f8301126146b957600080fd5b813560206146c9614671836145cc565b82815260069290921b840181019181810190868411156146e857600080fd5b8286015b8481101561228e57604081890312156147055760008081fd5b61470d61442b565b81356147188161450c565b815281850135858201528352918301916040016146ec565b600082601f83011261474157600080fd5b81356020614751614671836145cc565b82815260059290921b8401810191818101908684111561477057600080fd5b8286015b8481101561228e57803567ffffffffffffffff8111156147945760008081fd5b6147a28986838b0101614652565b845250918301918301614774565b60006101a082840312156147c357600080fd5b6147cb61444e565b90506147d682614606565b81526147e460208301614521565b60208201526147f560408301614521565b604082015261480660608301614606565b60608201526080820135608082015261482160a0830161461f565b60a082015261483260c08301614606565b60c082015261484360e08301614521565b60e082015261010082810135908201526101208083013567ffffffffffffffff8082111561487057600080fd5b61487c86838701614652565b8385015261014092508285013591508082111561489857600080fd5b6148a4868387016146a8565b838501526101609250828501359150808211156148c057600080fd5b506148cd85828601614730565b82840152505061018080830135818301525092915050565b600082601f8301126148f657600080fd5b81356020614906614671836145cc565b82815260059290921b8401810191818101908684111561492557600080fd5b8286015b8481101561228e57803567ffffffffffffffff8111156149495760008081fd5b6149578986838b01016147b0565b845250918301918301614929565b600082601f83011261497657600080fd5b81356020614986614671836145cc565b82815260059290921b840181019181810190868411156149a557600080fd5b8286015b8481101561228e57803567ffffffffffffffff8111156149c95760008081fd5b6149d78986838b0101614730565b8452509183019183016149a9565b600082601f8301126149f657600080fd5b81356020614a06614671836145cc565b8083825260208201915060208460051b870101935086841115614a2857600080fd5b602086015b8481101561228e5780358352918301918301614a2d565b600082601f830112614a5557600080fd5b81356020614a65614671836145cc565b82815260059290921b84018101918181019086841115614a8457600080fd5b8286015b8481101561228e57803567ffffffffffffffff80821115614aa95760008081fd5b9088019060a0828b03601f1901811315614ac35760008081fd5b614acb614472565b614ad6888501614606565b815260408085013584811115614aec5760008081fd5b614afa8e8b838901016148e5565b8a8401525060608086013585811115614b135760008081fd5b614b218f8c838a0101614965565b8385015250608091508186013585811115614b3c5760008081fd5b614b4a8f8c838a01016149e5565b9184019190915250919093013590830152508352918301918301614a88565b6000806040808486031215614b7d57600080fd5b833567ffffffffffffffff80821115614b9557600080fd5b614ba187838801614a44565b9450602091508186013581811115614bb857600080fd5b8601601f81018813614bc957600080fd5b8035614bd7614671826145cc565b81815260059190911b8201840190848101908a831115614bf657600080fd5b8584015b83811015614c8257803586811115614c125760008081fd5b8501603f81018d13614c245760008081fd5b87810135614c34614671826145cc565b81815260059190911b82018a0190898101908f831115614c545760008081fd5b928b01925b82841015614c725783358252928a0192908a0190614c59565b8652505050918601918601614bfa565b50809750505050505050509250929050565b60008060408385031215614ca757600080fd5b8235614cb2816145f0565b91506020830135614cc2816145f0565b809150509250929050565b634e487b7160e01b600052602160045260246000fd5b60048110614cf357614cf3614ccd565b9052565b60208101610eb08284614ce3565b600060208284031215614d1757600080fd5b8135613196816145f0565b60006020808385031215614d3557600080fd5b823567ffffffffffffffff811115614d4c57600080fd5b8301601f81018513614d5d57600080fd5b8035614d6b614671826145cc565b81815260079190911b82018301908381019087831115614d8a57600080fd5b928401925b828410156135f95760808489031215614da85760008081fd5b614db0614495565b8435614dbb816145f0565b815284860135614dca81614611565b81870152604085810135614ddd8161450c565b90820152606085810135614df08161450c565b9082015282526080939093019290840190614d8f565b600060208284031215614e1857600080fd5b813567ffffffffffffffff811115614e2f57600080fd5b820160a0818503121561319657600080fd5b60008060408385031215614e5457600080fd5b8235614e5f816145f0565b91506020830135614cc28161450c565b803560ff8116811461452c57600080fd5b600060208284031215614e9257600080fd5b610ead82614e6f565b60008151808452602080850194506020840160005b83811015614ed55781516001600160a01b031687529582019590820190600101614eb0565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614f2f60e0840182614e9b565b90506040840151601f198483030160c0850152614f4c8282614e9b565b95945050505050565b60008060408385031215614f6857600080fd5b8235614f73816145f0565b946020939093013593505050565b60008060208385031215614f9457600080fd5b823567ffffffffffffffff80821115614fac57600080fd5b818501915085601f830112614fc057600080fd5b813581811115614fcf57600080fd5b8660208260061b8501011115614fe457600080fd5b60209290920196919550909350505050565b60006020828403121561500857600080fd5b81356131968161450c565b6000806040838503121561502657600080fd5b823567ffffffffffffffff8082111561503e57600080fd5b61504a868387016147b0565b9350602085013591508082111561506057600080fd5b5061506d85828601614730565b9150509250929050565b600082601f83011261508857600080fd5b81356020615098614671836145cc565b8083825260208201915060208460051b8701019350868411156150ba57600080fd5b602086015b8481101561228e5780356150d28161450c565b83529183019183016150bf565b600060208083850312156150f257600080fd5b823567ffffffffffffffff8082111561510a57600080fd5b818501915085601f83011261511e57600080fd5b813561512c614671826145cc565b81815260059190911b8301840190848101908883111561514b57600080fd5b8585015b8381101561521d5780358581111561516657600080fd5b860160c0818c03601f1901121561517d5760008081fd5b615185614402565b8882013581526040615198818401614e6f565b8a83015260606151a9818501614e6f565b82840152608091506151bc82850161461f565b9083015260a083810135898111156151d45760008081fd5b6151e28f8d83880101615077565b838501525060c08401359150888211156151fc5760008081fd5b61520a8e8c84870101615077565b908301525084525091860191860161514f565b5098975050505050505050565b60006020828403121561523c57600080fd5b5035919050565b80356001600160e01b038116811461452c57600080fd5b600082601f83011261526b57600080fd5b8135602061527b614671836145cc565b82815260069290921b8401810191818101908684111561529a57600080fd5b8286015b8481101561228e57604081890312156152b75760008081fd5b6152bf61442b565b81356152ca816145f0565b81526152d7828601615243565b8186015283529183019160400161529e565b600082601f8301126152fa57600080fd5b8135602061530a614671836145cc565b82815260079290921b8401810191818101908684111561532957600080fd5b8286015b8481101561228e5780880360808112156153475760008081fd5b61534f6144b8565b823561535a816145f0565b81526040601f1983018113156153705760008081fd5b61537861442b565b925086840135615387816145f0565b835283810135615396816145f0565b838801528187019290925260608301359181019190915283529183019160800161532d565b600060208083850312156153ce57600080fd5b823567ffffffffffffffff808211156153e657600080fd5b818501915060408083880312156153fc57600080fd5b61540461442b565b83358381111561541357600080fd5b84016040818a03121561542557600080fd5b61542d61442b565b81358581111561543c57600080fd5b8201601f81018b1361544d57600080fd5b803561545b614671826145cc565b81815260069190911b8201890190898101908d83111561547a57600080fd5b928a01925b828410156154ca5787848f0312156154975760008081fd5b61549f61442b565b84356154aa8161450c565b81526154b7858d01615243565b818d0152825292870192908a019061547f565b8452505050818701359350848411156154e257600080fd5b6154ee8a85840161525a565b818801528252508385013591508282111561550857600080fd5b615514888386016152e9565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b8181101561559357835180516001600160a01b031684528501516001600160e01b031685840152928401929185019160010161555c565b50508583015187820388850152805180835290840192506000918401905b808310156155ed578351805167ffffffffffffffff1683528501516001600160e01b0316858301529284019260019290920191908501906155b1565b50979650505050505050565b602081526000610ead602083018461553c565b67ffffffffffffffff83168152606081016131966020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff81811683821601908082111561567857615678615641565b5092915050565b60006020808352606084516040808487015261569e606087018361553c565b87850151878203601f19016040890152805180835290860193506000918601905b8083101561521d57845167ffffffffffffffff8151168352878101516156fe89850182805167ffffffffffffffff908116835260209182015116910152565b508401518287015293860193600192909201916080909101906156bf565b60006020828403121561572e57600080fd5b813567ffffffffffffffff81111561574557600080fd5b6139b384828501614a44565b81810381811115610eb057610eb0615641565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff8084168061579557615795615764565b92169190910692915050565b8082028115828204841417610eb057610eb0615641565b6000604082840312156157ca57600080fd5b6157d261442b565b82356157dd816145f0565b81526020928301359281019290925250919050565b60008151808452602080850194506020840160005b83811015614ed557815180516001600160a01b031688526020908101519088015260408701965090820190600101615807565b8051825267ffffffffffffffff60208201511660208301526000604082015160a0604085015261586d60a085018261420e565b905060608301518482036060860152615886828261420e565b91505060808301518482036080860152614f4c82826157f2565b602081526000610ead602083018461583a565b6080815260006158c6608083018761583a565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b600082601f83011261590057600080fd5b815161590e6146718261462a565b81815284602083860101111561592357600080fd5b6139b38260208301602087016141ea565b60008060006060848603121561594957600080fd5b835161595481614611565b602085015190935067ffffffffffffffff81111561597157600080fd5b61597d868287016158ef565b925050604084015190509250925092565b6000602082840312156159a057600080fd5b815161319681614611565b80820180821115610eb057610eb0615641565b60ff8181168382160190811115610eb057610eb0615641565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff80841680615a1657615a16615764565b92169190910492915050565b600060208284031215615a3457600080fd5b8151613196816145f0565b600060208284031215615a5157600080fd5b815167ffffffffffffffff80821115615a6957600080fd5b9083019060608286031215615a7d57600080fd5b615a856144b8565b825182811115615a9457600080fd5b615aa0878286016158ef565b825250602083015182811115615ab557600080fd5b615ac1878286016158ef565b602083015250604083015182811115615ad957600080fd5b615ae5878286016158ef565b60408301525095945050505050565b6020810160058310615b0857615b08614ccd565b91905290565b60ff818116838216029081169081811461567857615678615641565b600060a0820160ff88168352602087602085015260a0604085015281875480845260c086019150886000526020600020935060005b81811015615b845784546001600160a01b031683526001948501949284019201615b5f565b50508481036060860152615b988188614e9b565b935050505060ff831660808301529695505050505050565b8281526040602082015260006139b3604083018461420e565b67ffffffffffffffff848116825283166020820152606081016139b36040830184614ce3565b600067ffffffffffffffff808316818103615c0c57615c0c615641565b6001019392505050565b615c208184614ce3565b6040602082015260006139b3604083018461420e565b600060208284031215615c4857600080fd5b81516131968161450c565b6020815260008251610100806020850152615c7261012085018361420e565b91506020850151615c8f604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615cc960a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615ce6848361420e565b935060c08701519150808685030160e0870152615d03848361420e565b935060e0870151915080868503018387015250615d20838261420e565b9695505050505050565b600060208284031215615d3c57600080fd5b5051919050565b600060ff821660ff8103615d5957615d59615641565b60010192915050565b6020808252825182820181905260009190848201906040850190845b81811015615db157835180516001600160a01b031684526020908101519084015260408301938501939250600101615d7e565b50909695505050505050565b60008282518085526020808601955060208260051b8401016020860160005b84811015615e0a57601f19868403018952615df883835161420e565b98840198925090830190600101615ddc565b5090979650505050505050565b602081526000610ead6020830184615dbd565b60408152615e4560408201845167ffffffffffffffff169052565b60006020840151615e6160608401826001600160a01b03169052565b5060408401516001600160a01b038116608084015250606084015167ffffffffffffffff811660a084015250608084015160c083015260a084015180151560e08401525060c0840151610100615ec28185018367ffffffffffffffff169052565b60e08601519150610120615ee0818601846001600160a01b03169052565b81870151925061014091508282860152808701519250506101a06101608181870152615f106101e087018561420e565b9350828801519250603f19610180818887030181890152615f3186866157f2565b9550828a01519450818887030184890152615f4c8686615dbd565b9550808a01516101c089015250505050508281036020840152614f4c8185615dbd565b6000815160208301516001600160e01b031980821693506004831015615f9f5780818460040360031b1b83161693505b50505091905056fea164736f6c6343000818000a", + Bin: "0x6101006040523480156200001257600080fd5b50604051620067e1380380620067e1833981016040819052620000359162000648565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001c1565b5050466080525060208201516001600160a01b03161580620000ec575060408201516001600160a01b0316155b156200010b576040516342bcdf7f60e11b815260040160405180910390fd5b81516001600160401b0316600003620001375760405163c656089560e01b815260040160405180910390fd5b81516001600160401b0390811660a052602080840180516001600160a01b0390811660c05260408087018051831660e052815188519096168652925182169385019390935290511682820152517f2f56698ec552a5d53d27d6f4b3dd8b6989f6426b6151a36aff61160c1d07efdf9181900360600190a1620001b9816200026c565b5050620007d0565b336001600160a01b038216036200021b5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b81518110156200051c576000828281518110620002905762000290620007ba565b60200260200101519050600081600001519050806001600160401b0316600003620002ce5760405163c656089560e01b815260040160405180910390fd5b60608201516001600160a01b0316620002fa576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b038116600090815260076020526040902060018101546001600160a01b031662000400576200035c8284606001517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b36200052060201b60201c565b600282015560608301516001820180546001600160a01b039283166001600160a01b03199091161790556040808501518354610100600160481b03199190931669010000000000000000000216610100600160e81b031990921691909117610100178255516001600160401b03831681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a16200046f565b606083015160018201546001600160a01b03908116911614158062000444575060408301518154690100000000000000000090046001600160a01b03908116911614155b156200046f5760405163c39a620560e01b81526001600160401b038316600482015260240162000083565b6020830151815490151560ff199091161781556040516001600160401b038316907fa73c588738263db34ef8c1942db8f99559bc6696f6a812d42e76bafb4c0e8d309062000505908490815460ff811615158252600881901c6001600160401b0316602083015260481c6001600160a01b0390811660408301526001830154166060820152600290910154608082015260a00190565b60405180910390a25050508060010190506200026f565b5050565b60a0805160408051602081018590526001600160401b0380881692820192909252911660608201526001600160a01b0384166080820152600091016040516020818303038152906040528051906020012090509392505050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b0381118282101715620005b557620005b56200057a565b60405290565b604051608081016001600160401b0381118282101715620005b557620005b56200057a565b604051601f8201601f191681016001600160401b03811182821017156200060b576200060b6200057a565b604052919050565b80516001600160401b03811681146200062b57600080fd5b919050565b80516001600160a01b03811681146200062b57600080fd5b6000808284036080808212156200065e57600080fd5b6060808312156200066e57600080fd5b6200067862000590565b9250620006858662000613565b835260206200069681880162000630565b818501526040620006aa6040890162000630565b604086015260608801519496506001600160401b0380861115620006cd57600080fd5b858901955089601f870112620006e257600080fd5b855181811115620006f757620006f76200057a565b62000707848260051b01620005e0565b818152848101925060079190911b87018401908b8211156200072857600080fd5b968401965b81881015620007a85786888d031215620007475760008081fd5b62000751620005bb565b6200075c8962000613565b8152858901518015158114620007725760008081fd5b818701526200078389860162000630565b8582015262000794878a0162000630565b81880152835296860196918401916200072d565b80985050505050505050509250929050565b634e487b7160e01b600052603260045260246000fd5b60805160a05160c05160e051615fb46200082d6000396000818161021e01526131fe0152600081816101ef015281816115fc01526116b30152600081816101bf0152613120015260008181611c4f0152611c9b0152615fb46000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c80637f63b711116100e3578063d2a15d351161008c578063f52121a511610066578063f52121a514610686578063f716f99f14610699578063ff888fb1146106ac57600080fd5b8063d2a15d3514610552578063e9d68a8e14610565578063f2fde38b1461067357600080fd5b80638da5cb5b116100bd5780638da5cb5b146104d2578063c673e584146104ed578063ccd37ba31461050d57600080fd5b80637f63b7111461049e57806385572ffb146104b15780638b364334146104bf57600080fd5b8063403b2d631161014557806369600bca1161011f57806369600bca1461036e5780637437ff9f1461038157806379ba50971461049657600080fd5b8063403b2d6314610328578063542625af1461033b5780635e36480c1461034e57600080fd5b80632d04ab76116101765780632d04ab76146102d9578063311cd513146102ee5780633f4b04aa1461030157600080fd5b806306285c6914610192578063181f5a7714610290575b600080fd5b61024e604080516060810182526000808252602082018190529181019190915260405180606001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b60408051825167ffffffffffffffff1681526020808401516001600160a01b039081169183019190915292820151909216908201526060015b60405180910390f35b6102cc6040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b604051610287919061423a565b6102ec6102e73660046142e5565b6106cf565b005b6102ec6102fc366004614398565b610a95565b600b5467ffffffffffffffff165b60405167ffffffffffffffff9091168152602001610287565b6102ec610336366004614545565b610afe565b6102ec610349366004614b69565b610cbb565b61036161035c366004614c94565b610e60565b6040516102879190614cf7565b6102ec61037c366004614d05565b610eb6565b61042d6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c0810182526004546001600160a01b03808216835263ffffffff74010000000000000000000000000000000000000000830481166020850152600160c01b8304811694840194909452600160e01b90910490921660608201526005548216608082015260065490911660a082015290565b6040516102879190600060c0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401528060a08501511660a08401525092915050565b6102ec610f21565b6102ec6104ac366004614d22565b610fdf565b6102ec61018d366004614e06565b61030f6104cd366004614e41565b610ff3565b6000546040516001600160a01b039091168152602001610287565b6105006104fb366004614e80565b611009565b6040516102879190614ee0565b61054461051b366004614f55565b67ffffffffffffffff919091166000908152600a60209081526040808320938352929052205490565b604051908152602001610287565b6102ec610560366004614f81565b611167565b610616610573366004614d05565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091525067ffffffffffffffff908116600090815260076020908152604091829020825160a081018452815460ff8116151582526101008104909516928101929092526001600160a01b0369010000000000000000009094048416928201929092526001820154909216606083015260020154608082015290565b6040516102879190600060a08201905082511515825267ffffffffffffffff602084015116602083015260408301516001600160a01b03808216604085015280606086015116606085015250506080830151608083015292915050565b6102ec610681366004614ff6565b611221565b6102ec610694366004615013565b611232565b6102ec6106a73660046150df565b611564565b6106bf6106ba36600461522a565b6115a6565b6040519015158152602001610287565b60006106dd878901896153bb565b805151519091501515806106f657508051602001515115155b156107f657600b5460208a01359067ffffffffffffffff808316911610156107b557600b805467ffffffffffffffff191667ffffffffffffffff831617905560065482516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921691633937306f9161077e916004016155f9565b600060405180830381600087803b15801561079857600080fd5b505af11580156107ac573d6000803e3d6000fd5b505050506107f4565b8160200151516000036107f4576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b8160200151518110156109de5760008260200151828151811061081e5761081e615526565b6020026020010151905060008160000151905061083a81611667565b600061084582611769565b602084015151815491925067ffffffffffffffff90811661010090920416141580610887575060208084015190810151905167ffffffffffffffff9182169116115b156108d057825160208401516040517feefb0cac0000000000000000000000000000000000000000000000000000000081526108c792919060040161560c565b60405180910390fd5b60408301518061090c576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff166000908152600a602090815260408083208484529091529020541561097f5783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602481018290526044016108c7565b6020808501510151610992906001615657565b825468ffffffffffffffff00191661010067ffffffffffffffff92831602179092559251166000908152600a6020908152604080832094835293905291909120429055506001016107f9565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d81604051610a0e919061567f565b60405180910390a1610a8a60008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b92506117c9915050565b505050505050505050565b610ad5610aa48284018461571c565b6040805160008082526020820190925290610acf565b6060815260200190600190039081610aba5790505b50611b40565b604080516000808252602082019092529050610af86001858585858660006117c9565b50505050565b610b06611bf0565b60a08101516001600160a01b03161580610b28575080516001600160a01b0316155b15610b5f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a177401000000000000000000000000000000000000000063ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff19908116928e1692909217905560a0808e01805160068054909416908f161790925586519a8b5297518716988a0198909852925185169388019390935251909216958501959095525185169383019390935251909216908201527f0da37fd00459f4f5f0b8210d31525e4910ae674b8bab34b561d146bb45773a4c9060c00160405180910390a150565b610cc3611c4c565b815181518114610cff576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610e50576000848281518110610d1e57610d1e615526565b60200260200101519050600081602001515190506000858481518110610d4657610d46615526565b6020026020010151905080518214610d8a576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610e41576000828281518110610da957610da9615526565b6020026020010151905080600014158015610de4575084602001518281518110610dd557610dd5615526565b60200260200101516080015181105b15610e385784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101839052604481018290526064016108c7565b50600101610d8d565b50505050806001019050610d02565b50610e5b8383611b40565b505050565b6000610e6e60016004615751565b6002610e7b60808561577a565b67ffffffffffffffff16610e8f91906157a1565b610e998585611ccd565b901c166003811115610ead57610ead614ccd565b90505b92915050565b610ebe611bf0565b600b805467ffffffffffffffff83811667ffffffffffffffff1983168117909355604080519190921680825260208201939093527f88ad9c61d6caf19a2af116a871802a03a31e680115a2dd20e8c08801d7c82f83910160405180910390a15050565b6001546001600160a01b03163314610f7b5760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108c7565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610fe7611bf0565b610ff081611d14565b50565b6000806110008484612025565b50949350505050565b61104c6040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c0820152948552918201805484518184028101840190955280855292938583019390928301828280156110f557602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116110d7575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561115757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611139575b5050505050815250509050919050565b61116f611bf0565b60005b81811015610e5b57600083838381811061118e5761118e615526565b9050604002018036038101906111a491906157b8565b90506111b381602001516115a6565b61121857805167ffffffffffffffff166000908152600a602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101611172565b611229611bf0565b610ff081612136565b33301461126b576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051600080825260208201909252816112a8565b60408051808201909152600080825260208201528152602001906001900390816112815790505b5061014084015151909150156113095761130683610140015184602001516040516020016112e591906001600160a01b0391909116815260200190565b60408051601f198184030181529181528601518651610160880151876121ec565b90505b60006113158483612299565b6005549091506001600160a01b03168015611402576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a19061136f9085906004016158a0565b600060405180830381600087803b15801561138957600080fd5b505af192505050801561139a575060015b611402573d8080156113c8576040519150601f19603f3d011682016040523d82523d6000602084013e6113cd565b606091505b50806040517f09c253250000000000000000000000000000000000000000000000000000000081526004016108c7919061423a565b6101208501515115801561141857506080850151155b8061142f575060408501516001600160a01b03163b155b8061146f5750604085015161146d906001600160a01b03167f85572ffb0000000000000000000000000000000000000000000000000000000061233c565b155b1561147b575050505050565b60048054608087015160408089015190517f3cf9798300000000000000000000000000000000000000000000000000000000815260009485946001600160a01b031693633cf97983936114d6938a93611388939291016158b3565b6000604051808303816000875af11580156114f5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261151d9190810190615934565b50915091508161155b57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016108c7919061423a565b50505050505050565b61156c611bf0565b60005b81518110156115a25761159a82828151811061158d5761158d615526565b6020026020010151612358565b60010161156f565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611643573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb0919061598e565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015611702573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611726919061598e565b15610ff0576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108c7565b67ffffffffffffffff81166000908152600760205260408120805460ff16610eb0576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108c7565b60ff878116600090815260026020908152604080832081516080810183528154815260019091015480861693820193909352610100830485169181019190915262010000909104909216151560608301528735906118288760a46159ab565b90508260600151156118705784516118419060206157a1565b865161184e9060206157a1565b6118599060a06159ab565b61186391906159ab565b61186d90826159ab565b90505b3681146118b2576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016108c7565b50815181146118fa5781516040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016108c7565b611902611c4c565b60ff808a166000908152600360209081526040808320338452825280832081518083019092528054808616835293949193909284019161010090910416600281111561195057611950614ccd565b600281111561196157611961614ccd565b905250905060028160200151600281111561197e5761197e614ccd565b1480156119d25750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff16815481106119ba576119ba615526565b6000918252602090912001546001600160a01b031633145b611a08576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611aea576020820151611a239060016159be565b60ff16855114611a5f576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611a9a576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611aac9291906159d7565b604051908190038120611ac3918b906020016159e7565b604051602081830303815290604052805190602001209050611ae88a82888888612663565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611b7a576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611be957611be1858281518110611baf57611baf615526565b602002602001015184611bdb57858381518110611bce57611bce615526565b602002602001015161287a565b8361287a565b600101611b91565b5050505050565b6000546001600160a01b03163314611c4a5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108c7565b565b467f000000000000000000000000000000000000000000000000000000000000000014611c4a576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016108c7565b67ffffffffffffffff8216600090815260096020526040812081611cf26080856159fb565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b60005b81518110156115a2576000828281518110611d3457611d34615526565b602002602001015190506000816000015190508067ffffffffffffffff16600003611d8b576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608201516001600160a01b0316611dcf576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8116600090815260076020526040902060018101546001600160a01b0316611ef257611e298284606001517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b361311a565b600282015560608301516001820180546001600160a01b0392831673ffffffffffffffffffffffffffffffffffffffff19909116179055604080850151835468ffffffffffffffff001991909316690100000000000000000002167fffffff00000000000000000000000000000000000000000000000000000000ff909216919091176101001782555167ffffffffffffffff831681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611f78565b606083015160018201546001600160a01b039081169116141580611f35575060408301518154690100000000000000000090046001600160a01b03908116911614155b15611f78576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff831660048201526024016108c7565b6020830151815490151560ff1990911617815560405167ffffffffffffffff8316907fa73c588738263db34ef8c1942db8f99559bc6696f6a812d42e76bafb4c0e8d309061200f908490815460ff811615158252600881901c67ffffffffffffffff16602083015260481c6001600160a01b0390811660408301526001830154166060820152600290910154608082015260a00190565b60405180910390a2505050806001019050611d17565b67ffffffffffffffff80831660009081526008602090815260408083206001600160a01b038616845290915281205490918291168082036121285767ffffffffffffffff8516600090815260076020526040902054690100000000000000000090046001600160a01b03168015612126576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b03868116600483015282169063856c824790602401602060405180830381865afa1580156120f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121199190615a22565b600193509350505061212f565b505b9150600090505b9250929050565b336001600160a01b0382160361218e5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108c7565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b8560005b875181101561228e5761226988828151811061220e5761220e615526565b60200260200101516020015188888888868151811061222f5761222f615526565b602002602001015180602001905181019061224a9190615a3f565b88878151811061225c5761225c615526565b602002602001015161319d565b82828151811061227b5761227b615526565b60209081029190910101526001016121f0565b509695505050505050565b6040805160a08101825260008082526020820152606091810182905281810182905260808101919091526040518060a001604052808461018001518152602001846000015167ffffffffffffffff168152602001846020015160405160200161231191906001600160a01b0391909116815260200190565b6040516020818303038152906040528152602001846101200151815260200183815250905092915050565b600061234783613516565b8015610ead5750610ead8383613562565b806040015160ff16600003612383576000604051631b3fab5160e11b81526004016108c79190615af4565b60208082015160ff808216600090815260029093526040832060018101549293909283921690036123d4576060840151600182018054911515620100000262ff000019909216919091179055612429565b6060840151600182015460ff6201000090910416151590151514612429576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff841660048201526024016108c7565b60a08401518051601f60ff82161115612458576001604051631b3fab5160e11b81526004016108c79190615af4565b6124be85856003018054806020026020016040519081016040528092919081815260200182805480156124b457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612496575b5050505050613604565b8560600151156125d05761252c85856002018054806020026020016040519081016040528092919081815260200182805480156124b4576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311612496575050505050613604565b608086015180516125469060028701906020840190614148565b50805160018501805461ff00191661010060ff841690810291909117909155601f1015612589576002604051631b3fab5160e11b81526004016108c79190615af4565b6040880151612599906003615b0e565b60ff168160ff16116125c1576003604051631b3fab5160e11b81526004016108c79190615af4565b6125cd8783600161366d565b50505b6125dc8583600261366d565b81516125f19060038601906020850190614148565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f5479361264a938a939260028b01929190615b2a565b60405180910390a161265b856137ed565b505050505050565b61266b6141b6565b835160005b8181101561287057600060018886846020811061268f5761268f615526565b61269c91901a601b6159be565b8985815181106126ae576126ae615526565b60200260200101518986815181106126c8576126c8615526565b602002602001015160405160008152602001604052604051612706949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612728573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b0385168352815285822085870190965285548084168652939750909550929392840191610100900416600281111561278957612789614ccd565b600281111561279a5761279a614ccd565b90525090506001816020015160028111156127b7576127b7614ccd565b146127ee576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061280557612805615526565b602002015115612841576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061285c5761285c615526565b911515602090920201525050600101612670565b5050505050505050565b815161288581611667565b600061289082611769565b60208501515190915060008190036128d3576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460400151518114612911576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561292c5761292c6143ec565b604051908082528060200260200182016040528015612955578160200160208202803683370190505b50905060005b82811015612a1a5760008760200151828151811061297b5761297b615526565b60200260200101519050612993818660020154613809565b8383815181106129a5576129a5615526565b6020026020010181815250508061018001518383815181106129c9576129c9615526565b602002602001015114612a11578061018001516040517f345039be0000000000000000000000000000000000000000000000000000000081526004016108c791815260200190565b5060010161295b565b506000612a31858389606001518a60800151613965565b905080600003612a79576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016108c7565b8551151560005b84811015610a8a57600089602001518281518110612aa057612aa0615526565b602002602001015190506000612aba898360600151610e60565b90506002816003811115612ad057612ad0614ccd565b03612b265760608201516040805167ffffffffffffffff808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c910160405180910390a15050613112565b6000816003811115612b3a57612b3a614ccd565b1480612b5757506003816003811115612b5557612b55614ccd565b145b612ba75760608201516040517f25507e7f00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808c16600483015290911660248201526044016108c7565b8315612c885760045460009074010000000000000000000000000000000000000000900463ffffffff16612bdb8742615751565b1190508080612bfb57506003826003811115612bf957612bf9614ccd565b145b612c3d576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8b1660048201526024016108c7565b8a8481518110612c4f57612c4f615526565b6020026020010151600014612c82578a8481518110612c7057612c70615526565b60200260200101518360800181815250505b50612ced565b6000816003811115612c9c57612c9c614ccd565b14612ced5760608201516040517f3ef2a99c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808c16600483015290911660248201526044016108c7565b600080612cfe8b8560200151612025565b915091508015612ded5760c084015167ffffffffffffffff16612d22836001615657565b67ffffffffffffffff1614612da55760c084015160208501516040517f5444a3301c7c42dd164cbf6ba4b72bf02504f86c049b06a27fc2b662e334bdbd92612d94928f9267ffffffffffffffff93841681529190921660208201526001600160a01b0391909116604082015260600190565b60405180910390a150505050613112565b67ffffffffffffffff8b81166000908152600860209081526040808320888301516001600160a01b031684529091529020805467ffffffffffffffff19169184169190911790555b6000836003811115612e0157612e01614ccd565b03612e925760c084015167ffffffffffffffff16612e20836001615657565b67ffffffffffffffff1614612e925760c084015160208501516040517f852dc8e405695593e311bd83991cf39b14a328f304935eac6d3d55617f911d8992612d94928f9267ffffffffffffffff93841681529190921660208201526001600160a01b0391909116604082015260600190565b60008d604001518681518110612eaa57612eaa615526565b6020026020010151905080518561014001515114612f0e5760608501516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808f16600483015290911660248201526044016108c7565b612f1e8c866060015160016139bb565b600080612f2b8784613a63565b91509150612f3e8e8860600151846139bb565b888015612f5c57506003826003811115612f5a57612f5a614ccd565b145b8015612f7a57506000866003811115612f7757612f77614ccd565b14155b15612fba57866101800151816040517f2b11b8d90000000000000000000000000000000000000000000000000000000081526004016108c7929190615bb0565b6003826003811115612fce57612fce614ccd565b14158015612fee57506002826003811115612feb57612feb614ccd565b14155b1561302f578d8760600151836040517f926c5a3e0000000000000000000000000000000000000000000000000000000081526004016108c793929190615bc9565b600086600381111561304357613043614ccd565b036130b15767ffffffffffffffff808f1660009081526008602090815260408083208b8301516001600160a01b0316845290915281208054909216919061308983615bef565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b866101800151876060015167ffffffffffffffff168f67ffffffffffffffff167f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df28585604051613102929190615c16565b60405180910390a4505050505050505b600101612a80565b600081847f00000000000000000000000000000000000000000000000000000000000000008560405160200161317d949392919093845267ffffffffffffffff9283166020850152911660408301526001600160a01b0316606082015260800190565b6040516020818303038152906040528051906020012090505b9392505050565b604080518082019091526000808252602082015260006131c08460200151613cad565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015613245573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132699190615c36565b90506001600160a01b03811615806132b157506132af6001600160a01b0382167faff2afbf0000000000000000000000000000000000000000000000000000000061233c565b155b156132f3576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016108c7565b6000806133be633907753760e01b6040518061010001604052808d81526020018b67ffffffffffffffff1681526020018c6001600160a01b031681526020018e8152602001876001600160a01b031681526020018a6000015181526020018a6040015181526020018981525060405160240161336f9190615c53565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152600454859063ffffffff600160e01b909104166113886084613cef565b5091509150816133e3578060405163e1cd550960e01b81526004016108c7919061423a565b805160201461342b5780516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016108c7565b6000818060200190518101906134419190615d2a565b604080516001600160a01b038d16602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b03167fa9059cbb000000000000000000000000000000000000000000000000000000001790526004549192506134c4918790600160c01b900463ffffffff166113886084613cef565b509093509150826134ea578160405163e1cd550960e01b81526004016108c7919061423a565b604080518082019091526001600160a01b03909516855260208501525091925050509695505050505050565b6000613542827f01ffc9a700000000000000000000000000000000000000000000000000000000613562565b8015610eb0575061355b826001600160e01b0319613562565b1592915050565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156135ed575060208210155b80156135f95750600081115b979650505050505050565b60005b8151811015610e5b5760ff83166000908152600360205260408120835190919084908490811061363957613639615526565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff19169055600101613607565b60005b82518160ff161015610af8576000838260ff168151811061369357613693615526565b60200260200101519050600060028111156136b0576136b0614ccd565b60ff80871660009081526003602090815260408083206001600160a01b038716845290915290205461010090041660028111156136ef576136ef614ccd565b14613710576004604051631b3fab5160e11b81526004016108c79190615af4565b6001600160a01b038116613750576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff16815260200184600281111561377657613776614ccd565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff1916176101008360028111156137d3576137d3614ccd565b021790555090505050806137e690615d43565b9050613670565b60ff8116610ff057600b805467ffffffffffffffff1916905550565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b610100015160405160200161389f9897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b60405160208183030381529060405280519060200120856101200151805190602001208661014001516040516020016138d89190615d62565b604051602081830303815290604052805190602001208761016001516040516020016139049190615e17565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e0015b60405160208183030381529060405280519060200120905092915050565b600080613973858585613e15565b905061397e816115a6565b61398c5760009150506139b3565b67ffffffffffffffff86166000908152600a60209081526040808320938352929052205490505b949350505050565b600060026139ca60808561577a565b67ffffffffffffffff166139de91906157a1565b905060006139ec8585611ccd565b9050816139fb60016004615751565b901b191681836003811115613a1257613a12614ccd565b67ffffffffffffffff871660009081526009602052604081209190921b92909217918291613a416080886159fb565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517ff52121a5000000000000000000000000000000000000000000000000000000008152600090606090309063f52121a590613aa79087908790600401615e2a565b600060405180830381600087803b158015613ac157600080fd5b505af1925050508015613ad2575060015b613c92573d808015613b00576040519150601f19603f3d011682016040523d82523d6000602084013e613b05565b606091505b506000613b1182615f6f565b90507f0a8d6e8c000000000000000000000000000000000000000000000000000000006001600160e01b031982161480613b5b575063e1cd550960e01b6001600160e01b03198216145b80613b76575063046b337b60e51b6001600160e01b03198216145b80613baa57507f78ef8024000000000000000000000000000000000000000000000000000000006001600160e01b03198216145b80613bde57507f0c3b563c000000000000000000000000000000000000000000000000000000006001600160e01b03198216145b80613c1257507fae9b4ce9000000000000000000000000000000000000000000000000000000006001600160e01b03198216145b80613c4657507f09c25325000000000000000000000000000000000000000000000000000000006001600160e01b03198216145b15613c57575060039250905061212f565b856101800151826040517f2b11b8d90000000000000000000000000000000000000000000000000000000081526004016108c7929190615bb0565b50506040805160208101909152600081526002909250929050565b60008151602014613cd3578160405163046b337b60e51b81526004016108c7919061423a565b610eb082806020019051810190613cea9190615d2a565b6140b3565b6000606060008361ffff1667ffffffffffffffff811115613d1257613d126143ec565b6040519080825280601f01601f191660200182016040528015613d3c576020820181803683370190505b509150863b613d6f577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613da2577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613ddb577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613dfe5750835b808352806000602085013e50955095509592505050565b8251825160009190818303613e56576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613e6a57506101018111155b613e87576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613eb1576040516309bde33960e01b815260040160405180910390fd5b80600003613ede5786600081518110613ecc57613ecc615526565b60200260200101519350505050613196565b60008167ffffffffffffffff811115613ef957613ef96143ec565b604051908082528060200260200182016040528015613f22578160200160208202803683370190505b50905060008080805b8581101561404c5760006001821b8b811603613f865788851015613f6f578c5160018601958e918110613f6057613f60615526565b60200260200101519050613fa8565b8551600185019487918110613f6057613f60615526565b8b5160018401938d918110613f9d57613f9d615526565b602002602001015190505b600089861015613fd8578d5160018701968f918110613fc957613fc9615526565b60200260200101519050613ffa565b8651600186019588918110613fef57613fef615526565b602002602001015190505b8285111561401b576040516309bde33960e01b815260040160405180910390fd5b6140258282614107565b87848151811061403757614037615526565b60209081029190910101525050600101613f2b565b50600185038214801561405e57508683145b801561406957508581145b614086576040516309bde33960e01b815260040160405180910390fd5b83600186038151811061409b5761409b615526565b60200260200101519750505050505050509392505050565b60006001600160a01b038211806140cb575061040082105b156141035760408051602081018490520160408051601f198184030181529082905263046b337b60e51b82526108c79160040161423a565b5090565b600081831061411f5761411a8284614125565b610ead565b610ead83835b604080516001602082015290810183905260608101829052600090608001613947565b8280548282559060005260206000209081019282156141aa579160200282015b828111156141aa578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190614168565b506141039291506141d5565b604051806103e00160405280601f906020820280368337509192915050565b5b8082111561410357600081556001016141d6565b60005b838110156142055781810151838201526020016141ed565b50506000910152565b600081518084526142268160208601602086016141ea565b601f01601f19169290920160200192915050565b602081526000610ead602083018461420e565b8060608101831015610eb057600080fd5b60008083601f84011261427057600080fd5b50813567ffffffffffffffff81111561428857600080fd5b60208301915083602082850101111561212f57600080fd5b60008083601f8401126142b257600080fd5b50813567ffffffffffffffff8111156142ca57600080fd5b6020830191508360208260051b850101111561212f57600080fd5b60008060008060008060008060e0898b03121561430157600080fd5b61430b8a8a61424d565b9750606089013567ffffffffffffffff8082111561432857600080fd5b6143348c838d0161425e565b909950975060808b013591508082111561434d57600080fd5b6143598c838d016142a0565b909750955060a08b013591508082111561437257600080fd5b5061437f8b828c016142a0565b999c989b50969995989497949560c00135949350505050565b6000806000608084860312156143ad57600080fd5b6143b7858561424d565b9250606084013567ffffffffffffffff8111156143d357600080fd5b6143df8682870161425e565b9497909650939450505050565b634e487b7160e01b600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715614425576144256143ec565b60405290565b6040805190810167ffffffffffffffff81118282101715614425576144256143ec565b6040516101a0810167ffffffffffffffff81118282101715614425576144256143ec565b60405160a0810167ffffffffffffffff81118282101715614425576144256143ec565b6040516080810167ffffffffffffffff81118282101715614425576144256143ec565b6040516060810167ffffffffffffffff81118282101715614425576144256143ec565b604051601f8201601f1916810167ffffffffffffffff81118282101715614504576145046143ec565b604052919050565b6001600160a01b0381168114610ff057600080fd5b803561452c8161450c565b919050565b803563ffffffff8116811461452c57600080fd5b600060c0828403121561455757600080fd5b61455f614402565b823561456a8161450c565b815261457860208401614531565b602082015261458960408401614531565b604082015261459a60608401614531565b606082015260808301356145ad8161450c565b608082015260a08301356145c08161450c565b60a08201529392505050565b600067ffffffffffffffff8211156145e6576145e66143ec565b5060051b60200190565b67ffffffffffffffff81168114610ff057600080fd5b803561452c816145f0565b8015158114610ff057600080fd5b803561452c81614611565b600067ffffffffffffffff821115614644576146446143ec565b50601f01601f191660200190565b600082601f83011261466357600080fd5b81356146766146718261462a565b6144db565b81815284602083860101111561468b57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f8301126146b957600080fd5b813560206146c9614671836145cc565b82815260069290921b840181019181810190868411156146e857600080fd5b8286015b8481101561228e57604081890312156147055760008081fd5b61470d61442b565b81356147188161450c565b815281850135858201528352918301916040016146ec565b600082601f83011261474157600080fd5b81356020614751614671836145cc565b82815260059290921b8401810191818101908684111561477057600080fd5b8286015b8481101561228e57803567ffffffffffffffff8111156147945760008081fd5b6147a28986838b0101614652565b845250918301918301614774565b60006101a082840312156147c357600080fd5b6147cb61444e565b90506147d682614606565b81526147e460208301614521565b60208201526147f560408301614521565b604082015261480660608301614606565b60608201526080820135608082015261482160a0830161461f565b60a082015261483260c08301614606565b60c082015261484360e08301614521565b60e082015261010082810135908201526101208083013567ffffffffffffffff8082111561487057600080fd5b61487c86838701614652565b8385015261014092508285013591508082111561489857600080fd5b6148a4868387016146a8565b838501526101609250828501359150808211156148c057600080fd5b506148cd85828601614730565b82840152505061018080830135818301525092915050565b600082601f8301126148f657600080fd5b81356020614906614671836145cc565b82815260059290921b8401810191818101908684111561492557600080fd5b8286015b8481101561228e57803567ffffffffffffffff8111156149495760008081fd5b6149578986838b01016147b0565b845250918301918301614929565b600082601f83011261497657600080fd5b81356020614986614671836145cc565b82815260059290921b840181019181810190868411156149a557600080fd5b8286015b8481101561228e57803567ffffffffffffffff8111156149c95760008081fd5b6149d78986838b0101614730565b8452509183019183016149a9565b600082601f8301126149f657600080fd5b81356020614a06614671836145cc565b8083825260208201915060208460051b870101935086841115614a2857600080fd5b602086015b8481101561228e5780358352918301918301614a2d565b600082601f830112614a5557600080fd5b81356020614a65614671836145cc565b82815260059290921b84018101918181019086841115614a8457600080fd5b8286015b8481101561228e57803567ffffffffffffffff80821115614aa95760008081fd5b9088019060a0828b03601f1901811315614ac35760008081fd5b614acb614472565b614ad6888501614606565b815260408085013584811115614aec5760008081fd5b614afa8e8b838901016148e5565b8a8401525060608086013585811115614b135760008081fd5b614b218f8c838a0101614965565b8385015250608091508186013585811115614b3c5760008081fd5b614b4a8f8c838a01016149e5565b9184019190915250919093013590830152508352918301918301614a88565b6000806040808486031215614b7d57600080fd5b833567ffffffffffffffff80821115614b9557600080fd5b614ba187838801614a44565b9450602091508186013581811115614bb857600080fd5b8601601f81018813614bc957600080fd5b8035614bd7614671826145cc565b81815260059190911b8201840190848101908a831115614bf657600080fd5b8584015b83811015614c8257803586811115614c125760008081fd5b8501603f81018d13614c245760008081fd5b87810135614c34614671826145cc565b81815260059190911b82018a0190898101908f831115614c545760008081fd5b928b01925b82841015614c725783358252928a0192908a0190614c59565b8652505050918601918601614bfa565b50809750505050505050509250929050565b60008060408385031215614ca757600080fd5b8235614cb2816145f0565b91506020830135614cc2816145f0565b809150509250929050565b634e487b7160e01b600052602160045260246000fd5b60048110614cf357614cf3614ccd565b9052565b60208101610eb08284614ce3565b600060208284031215614d1757600080fd5b8135613196816145f0565b60006020808385031215614d3557600080fd5b823567ffffffffffffffff811115614d4c57600080fd5b8301601f81018513614d5d57600080fd5b8035614d6b614671826145cc565b81815260079190911b82018301908381019087831115614d8a57600080fd5b928401925b828410156135f95760808489031215614da85760008081fd5b614db0614495565b8435614dbb816145f0565b815284860135614dca81614611565b81870152604085810135614ddd8161450c565b90820152606085810135614df08161450c565b9082015282526080939093019290840190614d8f565b600060208284031215614e1857600080fd5b813567ffffffffffffffff811115614e2f57600080fd5b820160a0818503121561319657600080fd5b60008060408385031215614e5457600080fd5b8235614e5f816145f0565b91506020830135614cc28161450c565b803560ff8116811461452c57600080fd5b600060208284031215614e9257600080fd5b610ead82614e6f565b60008151808452602080850194506020840160005b83811015614ed55781516001600160a01b031687529582019590820190600101614eb0565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614f2f60e0840182614e9b565b90506040840151601f198483030160c0850152614f4c8282614e9b565b95945050505050565b60008060408385031215614f6857600080fd5b8235614f73816145f0565b946020939093013593505050565b60008060208385031215614f9457600080fd5b823567ffffffffffffffff80821115614fac57600080fd5b818501915085601f830112614fc057600080fd5b813581811115614fcf57600080fd5b8660208260061b8501011115614fe457600080fd5b60209290920196919550909350505050565b60006020828403121561500857600080fd5b81356131968161450c565b6000806040838503121561502657600080fd5b823567ffffffffffffffff8082111561503e57600080fd5b61504a868387016147b0565b9350602085013591508082111561506057600080fd5b5061506d85828601614730565b9150509250929050565b600082601f83011261508857600080fd5b81356020615098614671836145cc565b8083825260208201915060208460051b8701019350868411156150ba57600080fd5b602086015b8481101561228e5780356150d28161450c565b83529183019183016150bf565b600060208083850312156150f257600080fd5b823567ffffffffffffffff8082111561510a57600080fd5b818501915085601f83011261511e57600080fd5b813561512c614671826145cc565b81815260059190911b8301840190848101908883111561514b57600080fd5b8585015b8381101561521d5780358581111561516657600080fd5b860160c0818c03601f1901121561517d5760008081fd5b615185614402565b8882013581526040615198818401614e6f565b8a83015260606151a9818501614e6f565b82840152608091506151bc82850161461f565b9083015260a083810135898111156151d45760008081fd5b6151e28f8d83880101615077565b838501525060c08401359150888211156151fc5760008081fd5b61520a8e8c84870101615077565b908301525084525091860191860161514f565b5098975050505050505050565b60006020828403121561523c57600080fd5b5035919050565b80356001600160e01b038116811461452c57600080fd5b600082601f83011261526b57600080fd5b8135602061527b614671836145cc565b82815260069290921b8401810191818101908684111561529a57600080fd5b8286015b8481101561228e57604081890312156152b75760008081fd5b6152bf61442b565b81356152ca816145f0565b81526152d7828601615243565b8186015283529183019160400161529e565b600082601f8301126152fa57600080fd5b8135602061530a614671836145cc565b82815260079290921b8401810191818101908684111561532957600080fd5b8286015b8481101561228e5780880360808112156153475760008081fd5b61534f6144b8565b823561535a816145f0565b81526040601f1983018113156153705760008081fd5b61537861442b565b925086840135615387816145f0565b835283810135615396816145f0565b838801528187019290925260608301359181019190915283529183019160800161532d565b600060208083850312156153ce57600080fd5b823567ffffffffffffffff808211156153e657600080fd5b818501915060408083880312156153fc57600080fd5b61540461442b565b83358381111561541357600080fd5b84016040818a03121561542557600080fd5b61542d61442b565b81358581111561543c57600080fd5b8201601f81018b1361544d57600080fd5b803561545b614671826145cc565b81815260069190911b8201890190898101908d83111561547a57600080fd5b928a01925b828410156154ca5787848f0312156154975760008081fd5b61549f61442b565b84356154aa8161450c565b81526154b7858d01615243565b818d0152825292870192908a019061547f565b8452505050818701359350848411156154e257600080fd5b6154ee8a85840161525a565b818801528252508385013591508282111561550857600080fd5b615514888386016152e9565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b8181101561559357835180516001600160a01b031684528501516001600160e01b031685840152928401929185019160010161555c565b50508583015187820388850152805180835290840192506000918401905b808310156155ed578351805167ffffffffffffffff1683528501516001600160e01b0316858301529284019260019290920191908501906155b1565b50979650505050505050565b602081526000610ead602083018461553c565b67ffffffffffffffff83168152606081016131966020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff81811683821601908082111561567857615678615641565b5092915050565b60006020808352606084516040808487015261569e606087018361553c565b87850151878203601f19016040890152805180835290860193506000918601905b8083101561521d57845167ffffffffffffffff8151168352878101516156fe89850182805167ffffffffffffffff908116835260209182015116910152565b508401518287015293860193600192909201916080909101906156bf565b60006020828403121561572e57600080fd5b813567ffffffffffffffff81111561574557600080fd5b6139b384828501614a44565b81810381811115610eb057610eb0615641565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff8084168061579557615795615764565b92169190910692915050565b8082028115828204841417610eb057610eb0615641565b6000604082840312156157ca57600080fd5b6157d261442b565b82356157dd816145f0565b81526020928301359281019290925250919050565b60008151808452602080850194506020840160005b83811015614ed557815180516001600160a01b031688526020908101519088015260408701965090820190600101615807565b8051825267ffffffffffffffff60208201511660208301526000604082015160a0604085015261586d60a085018261420e565b905060608301518482036060860152615886828261420e565b91505060808301518482036080860152614f4c82826157f2565b602081526000610ead602083018461583a565b6080815260006158c6608083018761583a565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b600082601f83011261590057600080fd5b815161590e6146718261462a565b81815284602083860101111561592357600080fd5b6139b38260208301602087016141ea565b60008060006060848603121561594957600080fd5b835161595481614611565b602085015190935067ffffffffffffffff81111561597157600080fd5b61597d868287016158ef565b925050604084015190509250925092565b6000602082840312156159a057600080fd5b815161319681614611565b80820180821115610eb057610eb0615641565b60ff8181168382160190811115610eb057610eb0615641565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff80841680615a1657615a16615764565b92169190910492915050565b600060208284031215615a3457600080fd5b8151613196816145f0565b600060208284031215615a5157600080fd5b815167ffffffffffffffff80821115615a6957600080fd5b9083019060608286031215615a7d57600080fd5b615a856144b8565b825182811115615a9457600080fd5b615aa0878286016158ef565b825250602083015182811115615ab557600080fd5b615ac1878286016158ef565b602083015250604083015182811115615ad957600080fd5b615ae5878286016158ef565b60408301525095945050505050565b6020810160058310615b0857615b08614ccd565b91905290565b60ff818116838216029081169081811461567857615678615641565b600060a0820160ff88168352602087602085015260a0604085015281875480845260c086019150886000526020600020935060005b81811015615b845784546001600160a01b031683526001948501949284019201615b5f565b50508481036060860152615b988188614e9b565b935050505060ff831660808301529695505050505050565b8281526040602082015260006139b3604083018461420e565b67ffffffffffffffff848116825283166020820152606081016139b36040830184614ce3565b600067ffffffffffffffff808316818103615c0c57615c0c615641565b6001019392505050565b615c208184614ce3565b6040602082015260006139b3604083018461420e565b600060208284031215615c4857600080fd5b81516131968161450c565b6020815260008251610100806020850152615c7261012085018361420e565b91506020850151615c8f604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615cc960a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615ce6848361420e565b935060c08701519150808685030160e0870152615d03848361420e565b935060e0870151915080868503018387015250615d20838261420e565b9695505050505050565b600060208284031215615d3c57600080fd5b5051919050565b600060ff821660ff8103615d5957615d59615641565b60010192915050565b6020808252825182820181905260009190848201906040850190845b81811015615db157835180516001600160a01b031684526020908101519084015260408301938501939250600101615d7e565b50909695505050505050565b60008282518085526020808601955060208260051b8401016020860160005b84811015615e0a57601f19868403018952615df883835161420e565b98840198925090830190600101615ddc565b5090979650505050505050565b602081526000610ead6020830184615dbd565b60408152615e4560408201845167ffffffffffffffff169052565b60006020840151615e6160608401826001600160a01b03169052565b5060408401516001600160a01b038116608084015250606084015167ffffffffffffffff811660a084015250608084015160c083015260a084015180151560e08401525060c0840151610100615ec28185018367ffffffffffffffff169052565b60e08601519150610120615ee0818601846001600160a01b03169052565b81870151925061014091508282860152808701519250506101a06101608181870152615f106101e087018561420e565b9350828801519250603f19610180818887030181890152615f3186866157f2565b9550828a01519450818887030184890152615f4c8686615dbd565b9550808a01516101c089015250505050508281036020840152614f4c8185615dbd565b6000815160208301516001600160e01b031980821693506004831015615f9f5780818460040360031b1b83161693505b50505091905056fea164736f6c6343000818000a", } var EVM2EVMMultiOffRampABI = EVM2EVMMultiOffRampMetaData.ABI 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 13aab261a8..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 @@ -9,8 +9,8 @@ ccip_capability_configuration: ../../../contracts/solc/v0.8.24/CCIPCapabilityCon 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 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 4c7bdddea3decee12887c5bd89648ed3b423bd31eefe586d5cb5c1bc8b883ffe -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