From 074c1f2c3fe089d9ae5a223e5fb33ce710a35d4d Mon Sep 17 00:00:00 2001 From: Connor Stein Date: Fri, 6 Dec 2024 18:04:54 -0500 Subject: [PATCH 01/29] Fix multiclient (#15557) --- deployment/multiclient.go | 18 ++++++++---------- deployment/multiclient_test.go | 24 +++++++++++++++++++----- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/deployment/multiclient.go b/deployment/multiclient.go index 914c1fbd9e3..f1ac2f3c310 100644 --- a/deployment/multiclient.go +++ b/deployment/multiclient.go @@ -61,17 +61,15 @@ func NewMultiClient(lggr logger.Logger, rpcs []RPC, opts ...func(client *MultiCl if err != nil { return nil, fmt.Errorf("failed to dial ws url '%s': %w", rpc.WSURL, err) } - // fetch chain name if not set - if mc.chainName == "" { - id, err := client.ChainID(context.Background()) - if err == nil { - details, err := chainselectors.GetChainDetailsByChainIDAndFamily(id.String(), chainselectors.FamilyEVM) - if err == nil { - return nil, err - } - mc.chainName = details.ChainName - } + id, err := client.ChainID(context.Background()) + if err != nil { + return nil, fmt.Errorf("failed to get chain id: %w", err) + } + details, err := chainselectors.GetChainDetailsByChainIDAndFamily(id.String(), chainselectors.FamilyEVM) + if err != nil { + return nil, fmt.Errorf("failed to lookup chain details %w", err) } + mc.chainName = details.ChainName clients = append(clients, client) } mc.Client = clients[0] diff --git a/deployment/multiclient_test.go b/deployment/multiclient_test.go index 0dbebbe3a6a..2e10c46e33f 100644 --- a/deployment/multiclient_test.go +++ b/deployment/multiclient_test.go @@ -1,6 +1,7 @@ package deployment import ( + "io/ioutil" "net/http" "net/http/httptest" "testing" @@ -15,20 +16,33 @@ func TestMultiClient(t *testing.T) { lggr := logger.TestLogger(t) // Expect an error if no RPCs supplied. s := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { - writer.WriteHeader(http.StatusOK) - _, err := writer.Write([]byte(`{"jsonrpc":"2.0","id":1,"result":true}`)) + b, err := ioutil.ReadAll(request.Body) require.NoError(t, err) + // TODO: Helper struct somewhere for this? + if string(b) == "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_chainId\"}" { + writer.WriteHeader(http.StatusOK) + // Respond with 1337 + _, err = writer.Write([]byte(`{"jsonrpc":"2.0","id":1,"result":"0x539"}`)) + require.NoError(t, err) + return + } else { + // Dial + writer.WriteHeader(http.StatusOK) + _, err = writer.Write([]byte(`{"jsonrpc":"2.0","id":1,"result":true}`)) + require.NoError(t, err) + } })) defer s.Close() - _, err := NewMultiClient(lggr, []RPC{}) - require.Error(t, err) - // Expect defaults to be set if not provided. mc, err := NewMultiClient(lggr, []RPC{{WSURL: s.URL}}) require.NoError(t, err) + require.NotNil(t, mc) assert.Equal(t, mc.RetryConfig.Attempts, uint(RPC_DEFAULT_RETRY_ATTEMPTS)) assert.Equal(t, mc.RetryConfig.Delay, RPC_DEFAULT_RETRY_DELAY) + _, err = NewMultiClient(lggr, []RPC{}) + require.Error(t, err) + // Expect second client to be set as backup. mc, err = NewMultiClient(lggr, []RPC{ {WSURL: s.URL}, From ddd012ec2969730b15019bc8373e0783eb13428b Mon Sep 17 00:00:00 2001 From: Connor Stein Date: Fri, 6 Dec 2024 18:19:27 -0500 Subject: [PATCH 02/29] Skip ccip transfer tests (#15558) * Skip * Skip USDC * Leave USDC actually --- integration-tests/smoke/ccip/ccip_token_transfer_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/integration-tests/smoke/ccip/ccip_token_transfer_test.go b/integration-tests/smoke/ccip/ccip_token_transfer_test.go index 81920246bed..979a6b13695 100644 --- a/integration-tests/smoke/ccip/ccip_token_transfer_test.go +++ b/integration-tests/smoke/ccip/ccip_token_transfer_test.go @@ -25,6 +25,7 @@ import ( ) func TestTokenTransfer(t *testing.T) { + t.Skip("need to deflake and optimize") lggr := logger.TestLogger(t) ctx := tests.Context(t) config := &changeset.TestConfigs{} From 49b77048d1b5480a07b9f77b32b005379c679c44 Mon Sep 17 00:00:00 2001 From: Mateusz Sekara Date: Mon, 9 Dec 2024 09:18:27 +0100 Subject: [PATCH 03/29] CCIP-4447 Llo promwrapper (#15539) * Adding OCR3 metrics promwrapper to LLO * Changeset bump * Added some logging * Added some logging * Added some logging --- .changeset/clean-files-beg.md | 5 +++++ .../capabilities/ccip/oraclecreator/plugin.go | 4 ++-- core/services/llo/delegate.go | 19 +++++++++++++++++-- core/services/ocr2/delegate.go | 1 + core/services/ocr3/promwrapper/factory.go | 9 +++++++++ .../services/ocr3/promwrapper/factory_test.go | 6 ++++-- 6 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 .changeset/clean-files-beg.md diff --git a/.changeset/clean-files-beg.md b/.changeset/clean-files-beg.md new file mode 100644 index 00000000000..1357a044cb0 --- /dev/null +++ b/.changeset/clean-files-beg.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Adding OCR3 promwrapper to LLO #internal diff --git a/core/capabilities/ccip/oraclecreator/plugin.go b/core/capabilities/ccip/oraclecreator/plugin.go index 1b8c6344349..a716d96418a 100644 --- a/core/capabilities/ccip/oraclecreator/plugin.go +++ b/core/capabilities/ccip/oraclecreator/plugin.go @@ -270,7 +270,7 @@ func (i *pluginOracleCreator) createFactoryAndTransmitter( rmnPeerClient, rmnCrypto, ) - factory = promwrapper.NewReportingPluginFactory[[]byte](factory, chainID, "CCIPCommit") + factory = promwrapper.NewReportingPluginFactory[[]byte](factory, i.lggr, chainID, "CCIPCommit") transmitter = ocrimpls.NewCommitContractTransmitter[[]byte](destChainWriter, ocrtypes.Account(destFromAccounts[0]), hexutil.Encode(config.Config.OfframpAddress), // TODO: this works for evm only, how about non-evm? @@ -291,7 +291,7 @@ func (i *pluginOracleCreator) createFactoryAndTransmitter( contractReaders, chainWriters, ) - factory = promwrapper.NewReportingPluginFactory[[]byte](factory, chainID, "CCIPExec") + factory = promwrapper.NewReportingPluginFactory[[]byte](factory, i.lggr, chainID, "CCIPExec") transmitter = ocrimpls.NewExecContractTransmitter[[]byte](destChainWriter, ocrtypes.Account(destFromAccounts[0]), hexutil.Encode(config.Config.OfframpAddress), // TODO: this works for evm only, how about non-evm? diff --git a/core/services/llo/delegate.go b/core/services/llo/delegate.go index d305fe0e948..ba4ddbb8fb0 100644 --- a/core/services/llo/delegate.go +++ b/core/services/llo/delegate.go @@ -21,6 +21,7 @@ import ( corelogger "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr3/promwrapper" "github.com/smartcontractkit/chainlink/v2/core/services/streams" ) @@ -59,6 +60,7 @@ type DelegateConfig struct { ShouldRetireCache datastreamsllo.ShouldRetireCache EAMonitoringEndpoint ocrcommontypes.MonitoringEndpoint DonID uint32 + ChainID string // OCR3 TraceLogging bool @@ -151,8 +153,21 @@ func (d *delegate) Start(ctx context.Context) error { OffchainConfigDigester: d.cfg.OffchainConfigDigester, OffchainKeyring: d.cfg.OffchainKeyring, OnchainKeyring: d.cfg.OnchainKeyring, - ReportingPluginFactory: datastreamsllo.NewPluginFactory( - d.cfg.ReportingPluginConfig, psrrc, d.src, d.cfg.RetirementReportCodec, d.cfg.ChannelDefinitionCache, d.ds, logger.Named(lggr, "ReportingPlugin"), llo.EVMOnchainConfigCodec{}, d.reportCodecs, + ReportingPluginFactory: promwrapper.NewReportingPluginFactory( + datastreamsllo.NewPluginFactory( + d.cfg.ReportingPluginConfig, + psrrc, + d.src, + d.cfg.RetirementReportCodec, + d.cfg.ChannelDefinitionCache, + d.ds, + logger.Named(lggr, "ReportingPlugin"), + llo.EVMOnchainConfigCodec{}, + d.reportCodecs, + ), + lggr, + d.cfg.ChainID, + "llo", ), MetricsRegisterer: prometheus.WrapRegistererWith(map[string]string{"job_name": d.cfg.JobName.ValueOrZero()}, prometheus.DefaultRegisterer), }) diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index e7a5a1c3a92..edcc816bf04 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -1048,6 +1048,7 @@ func (d *Delegate) newServicesLLO( RetirementReportCodec: datastreamsllo.StandardRetirementReportCodec{}, EAMonitoringEndpoint: d.monitoringEndpointGen.GenMonitoringEndpoint(rid.Network, rid.ChainID, telemetryContractID, synchronization.EnhancedEAMercury), DonID: pluginCfg.DonID, + ChainID: rid.ChainID, TraceLogging: d.cfg.OCR2().TraceLogging(), BinaryNetworkEndpointFactory: d.peerWrapper.Peer2, diff --git a/core/services/ocr3/promwrapper/factory.go b/core/services/ocr3/promwrapper/factory.go index 0dabd346112..84269cf3779 100644 --- a/core/services/ocr3/promwrapper/factory.go +++ b/core/services/ocr3/promwrapper/factory.go @@ -3,6 +3,8 @@ package promwrapper import ( "context" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" ) @@ -10,17 +12,20 @@ var _ ocr3types.ReportingPluginFactory[any] = &ReportingPluginFactory[any]{} type ReportingPluginFactory[RI any] struct { origin ocr3types.ReportingPluginFactory[RI] + lggr logger.Logger chainID string plugin string } func NewReportingPluginFactory[RI any]( origin ocr3types.ReportingPluginFactory[RI], + lggr logger.Logger, chainID string, plugin string, ) *ReportingPluginFactory[RI] { return &ReportingPluginFactory[RI]{ origin: origin, + lggr: lggr, chainID: chainID, plugin: plugin, } @@ -31,6 +36,10 @@ func (r ReportingPluginFactory[RI]) NewReportingPlugin(ctx context.Context, conf if err != nil { return nil, ocr3types.ReportingPluginInfo{}, err } + r.lggr.Infow("Wrapping ReportingPlugin with prometheus metrics reporter", + "configDigest", config.ConfigDigest, + "oracleID", config.OracleID, + ) wrapped := newReportingPlugin( plugin, r.chainID, diff --git a/core/services/ocr3/promwrapper/factory_test.go b/core/services/ocr3/promwrapper/factory_test.go index 72f35aad172..fb68c039b78 100644 --- a/core/services/ocr3/promwrapper/factory_test.go +++ b/core/services/ocr3/promwrapper/factory_test.go @@ -10,11 +10,13 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + + "github.com/smartcontractkit/chainlink/v2/core/logger" ) func Test_WrapperFactory(t *testing.T) { - validFactory := NewReportingPluginFactory(fakeFactory[uint]{}, "solana", "plugin") - failingFactory := NewReportingPluginFactory(fakeFactory[uint]{err: errors.New("error")}, "123", "plugin") + validFactory := NewReportingPluginFactory(fakeFactory[uint]{}, logger.TestLogger(t), "solana", "plugin") + failingFactory := NewReportingPluginFactory(fakeFactory[uint]{err: errors.New("error")}, logger.TestLogger(t), "123", "plugin") plugin, _, err := validFactory.NewReportingPlugin(tests.Context(t), ocr3types.ReportingPluginConfig{}) require.NoError(t, err) From 036cb20d43b8f2d3cdb4de79d11f97ff63831025 Mon Sep 17 00:00:00 2001 From: Mateusz Sekara Date: Mon, 9 Dec 2024 12:18:32 +0100 Subject: [PATCH 04/29] CCIP-4447 Publishing status of the OCR3 plugin (based on the config digest) (#15544) * Publishing status of the OCR3 plugin (based on the config digest) * Publishing status of the OCR3 plugin (based on the config digest) --- .changeset/dull-readers-rush.md | 5 ++++ core/services/ocr3/promwrapper/factory.go | 2 ++ core/services/ocr3/promwrapper/plugin.go | 28 +++++++++++++++---- core/services/ocr3/promwrapper/plugin_test.go | 19 +++++++++---- core/services/ocr3/promwrapper/types.go | 7 +++++ 5 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 .changeset/dull-readers-rush.md diff --git a/.changeset/dull-readers-rush.md b/.changeset/dull-readers-rush.md new file mode 100644 index 00000000000..3b6f2ae8758 --- /dev/null +++ b/.changeset/dull-readers-rush.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Reporting number of OCR3 instances running using promwrapper #internal diff --git a/core/services/ocr3/promwrapper/factory.go b/core/services/ocr3/promwrapper/factory.go index 84269cf3779..6518cea3c0d 100644 --- a/core/services/ocr3/promwrapper/factory.go +++ b/core/services/ocr3/promwrapper/factory.go @@ -44,8 +44,10 @@ func (r ReportingPluginFactory[RI]) NewReportingPlugin(ctx context.Context, conf plugin, r.chainID, r.plugin, + config.ConfigDigest.String(), promOCR3ReportsGenerated, promOCR3Durations, + promOCR3PluginStatus, ) return wrapped, info, err } diff --git a/core/services/ocr3/promwrapper/plugin.go b/core/services/ocr3/promwrapper/plugin.go index e4e0c3d35d5..dcee5050d1e 100644 --- a/core/services/ocr3/promwrapper/plugin.go +++ b/core/services/ocr3/promwrapper/plugin.go @@ -14,27 +14,33 @@ var _ ocr3types.ReportingPlugin[any] = &reportingPlugin[any]{} type reportingPlugin[RI any] struct { ocr3types.ReportingPlugin[RI] - chainID string - plugin string + chainID string + plugin string + configDigest string // Prometheus components for tracking metrics reportsGenerated *prometheus.CounterVec durations *prometheus.HistogramVec + status *prometheus.GaugeVec } func newReportingPlugin[RI any]( origin ocr3types.ReportingPlugin[RI], chainID string, plugin string, + configDigest string, reportsGenerated *prometheus.CounterVec, durations *prometheus.HistogramVec, + status *prometheus.GaugeVec, ) *reportingPlugin[RI] { return &reportingPlugin[RI]{ ReportingPlugin: origin, chainID: chainID, plugin: plugin, + configDigest: configDigest, reportsGenerated: reportsGenerated, durations: durations, + status: status, } } @@ -88,15 +94,23 @@ func (p *reportingPlugin[RI]) ShouldTransmitAcceptedReport(ctx context.Context, return result, err } -func (p *reportingPlugin[RI]) trackReports( - function functionType, - count int, -) { +func (p *reportingPlugin[RI]) Close() error { + p.updateStatus(false) + return p.ReportingPlugin.Close() +} + +func (p *reportingPlugin[RI]) trackReports(function functionType, count int) { p.reportsGenerated. WithLabelValues(p.chainID, p.plugin, string(function)). Add(float64(count)) } +func (p *reportingPlugin[RI]) updateStatus(status bool) { + p.status. + WithLabelValues(p.chainID, p.plugin, p.configDigest). + Set(float64(boolToInt(status))) +} + func boolToInt(arg bool) int { if arg { return 1 @@ -118,5 +132,7 @@ func withObservedExecution[RI, R any]( WithLabelValues(p.chainID, p.plugin, string(function), strconv.FormatBool(success)). Observe(float64(time.Since(start))) + p.updateStatus(true) + return result, err } diff --git a/core/services/ocr3/promwrapper/plugin_test.go b/core/services/ocr3/promwrapper/plugin_test.go index 35a97d109aa..9a7b6f2e648 100644 --- a/core/services/ocr3/promwrapper/plugin_test.go +++ b/core/services/ocr3/promwrapper/plugin_test.go @@ -19,15 +19,15 @@ import ( func Test_ReportsGeneratedGauge(t *testing.T) { plugin1 := newReportingPlugin( fakePlugin[uint]{reports: make([]ocr3types.ReportPlus[uint], 2)}, - "123", "empty", promOCR3ReportsGenerated, promOCR3Durations, + "123", "empty", "abc", promOCR3ReportsGenerated, promOCR3Durations, promOCR3PluginStatus, ) plugin2 := newReportingPlugin( fakePlugin[bool]{reports: make([]ocr3types.ReportPlus[bool], 10)}, - "solana", "different_plugin", promOCR3ReportsGenerated, promOCR3Durations, + "solana", "different_plugin", "abc", promOCR3ReportsGenerated, promOCR3Durations, promOCR3PluginStatus, ) plugin3 := newReportingPlugin( fakePlugin[string]{err: errors.New("error")}, - "1234", "empty", promOCR3ReportsGenerated, promOCR3Durations, + "1234", "empty", "abc", promOCR3ReportsGenerated, promOCR3Durations, promOCR3PluginStatus, ) r1, err := plugin1.Reports(tests.Context(t), 1, nil) @@ -57,20 +57,27 @@ func Test_ReportsGeneratedGauge(t *testing.T) { g4 := testutil.ToFloat64(promOCR3ReportsGenerated.WithLabelValues("1234", "empty", "reports")) require.Equal(t, 0, int(g4)) + + pluginHealth := testutil.ToFloat64(promOCR3PluginStatus.WithLabelValues("123", "empty", "abc")) + require.Equal(t, 1, int(pluginHealth)) + + require.NoError(t, plugin1.Close()) + pluginHealth = testutil.ToFloat64(promOCR3PluginStatus.WithLabelValues("123", "empty", "abc")) + require.Equal(t, 0, int(pluginHealth)) } func Test_DurationHistograms(t *testing.T) { plugin1 := newReportingPlugin( fakePlugin[uint]{}, - "123", "empty", promOCR3ReportsGenerated, promOCR3Durations, + "123", "empty", "abc", promOCR3ReportsGenerated, promOCR3Durations, promOCR3PluginStatus, ) plugin2 := newReportingPlugin( fakePlugin[uint]{err: errors.New("error")}, - "123", "empty", promOCR3ReportsGenerated, promOCR3Durations, + "123", "empty", "abc", promOCR3ReportsGenerated, promOCR3Durations, promOCR3PluginStatus, ) plugin3 := newReportingPlugin( fakePlugin[uint]{}, - "solana", "commit", promOCR3ReportsGenerated, promOCR3Durations, + "solana", "commit", "abc", promOCR3ReportsGenerated, promOCR3Durations, promOCR3PluginStatus, ) for _, p := range []*reportingPlugin[uint]{plugin1, plugin2, plugin3} { diff --git a/core/services/ocr3/promwrapper/types.go b/core/services/ocr3/promwrapper/types.go index bf6a1b2a39c..2fa29dcdf20 100644 --- a/core/services/ocr3/promwrapper/types.go +++ b/core/services/ocr3/promwrapper/types.go @@ -48,4 +48,11 @@ var ( }, []string{"chainID", "plugin", "function", "success"}, ) + promOCR3PluginStatus = promauto.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "ocr3_reporting_plugin_status", + Help: "Gauge indicating whether plugin is up and running or not", + }, + []string{"chainID", "plugin", "configDigest"}, + ) ) From a4b0c1914697e56ef05f12b97bf423b58c31ff04 Mon Sep 17 00:00:00 2001 From: Anindita Ghosh <88458927+AnieeG@users.noreply.github.com> Date: Mon, 9 Dec 2024 04:15:12 -0800 Subject: [PATCH 05/29] Upgrade chain selectors (#15561) * chain-selector upgrade * more --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- deployment/go.mod | 2 +- deployment/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 10 files changed, 15 insertions(+), 15 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 0caacb11c28..8f9e458b8e2 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -297,7 +297,7 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 // indirect - github.com/smartcontractkit/chain-selectors v1.0.31 // indirect + github.com/smartcontractkit/chain-selectors v1.0.34 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e // indirect github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e // indirect github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 42378db36de..3b8c5987c00 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1136,8 +1136,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 h1:qQH6fZZe31nBAG6INHph3z5ysDTPptyu0TR9uoJ1+ok= github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86/go.mod h1:WtWOoVQQEHxRHL2hNmuRrvDfYfQG/CioFNoa9Rr2mBE= -github.com/smartcontractkit/chain-selectors v1.0.31 h1:oRHyK88KnsCh4OdU2hr0u70pm3KUgyMDyK0v0aOtUk4= -github.com/smartcontractkit/chain-selectors v1.0.31/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= +github.com/smartcontractkit/chain-selectors v1.0.34 h1:MJ17OGu8+jjl426pcKrJkCf3fePb3eCreuAnUA3RBj4= +github.com/smartcontractkit/chain-selectors v1.0.34/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e h1:GnM6ZWV6vlk2+n6c6o+v/R1LtXzBGVVx7r37nt/h6Uc= diff --git a/deployment/go.mod b/deployment/go.mod index d8f1d6a3bf3..b9a2fdb255f 100644 --- a/deployment/go.mod +++ b/deployment/go.mod @@ -23,7 +23,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/sethvargo/go-retry v0.2.4 github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 - github.com/smartcontractkit/chain-selectors v1.0.31 + github.com/smartcontractkit/chain-selectors v1.0.34 github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 diff --git a/deployment/go.sum b/deployment/go.sum index a1e44825328..7513309dddf 100644 --- a/deployment/go.sum +++ b/deployment/go.sum @@ -1405,8 +1405,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 h1:qQH6fZZe31nBAG6INHph3z5ysDTPptyu0TR9uoJ1+ok= github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86/go.mod h1:WtWOoVQQEHxRHL2hNmuRrvDfYfQG/CioFNoa9Rr2mBE= -github.com/smartcontractkit/chain-selectors v1.0.31 h1:oRHyK88KnsCh4OdU2hr0u70pm3KUgyMDyK0v0aOtUk4= -github.com/smartcontractkit/chain-selectors v1.0.31/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= +github.com/smartcontractkit/chain-selectors v1.0.34 h1:MJ17OGu8+jjl426pcKrJkCf3fePb3eCreuAnUA3RBj4= +github.com/smartcontractkit/chain-selectors v1.0.34/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e h1:GnM6ZWV6vlk2+n6c6o+v/R1LtXzBGVVx7r37nt/h6Uc= diff --git a/go.mod b/go.mod index 63e11a3f3fe..35069d38bbf 100644 --- a/go.mod +++ b/go.mod @@ -76,7 +76,7 @@ require ( github.com/scylladb/go-reflectx v1.0.1 github.com/shirou/gopsutil/v3 v3.24.3 github.com/shopspring/decimal v1.4.0 - github.com/smartcontractkit/chain-selectors v1.0.31 + github.com/smartcontractkit/chain-selectors v1.0.34 github.com/smartcontractkit/chainlink-automation v0.8.1 github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f diff --git a/go.sum b/go.sum index bb0201fd3c9..caa877d66fa 100644 --- a/go.sum +++ b/go.sum @@ -1119,8 +1119,8 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartcontractkit/chain-selectors v1.0.31 h1:oRHyK88KnsCh4OdU2hr0u70pm3KUgyMDyK0v0aOtUk4= -github.com/smartcontractkit/chain-selectors v1.0.31/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= +github.com/smartcontractkit/chain-selectors v1.0.34 h1:MJ17OGu8+jjl426pcKrJkCf3fePb3eCreuAnUA3RBj4= +github.com/smartcontractkit/chain-selectors v1.0.34/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e h1:GnM6ZWV6vlk2+n6c6o+v/R1LtXzBGVVx7r37nt/h6Uc= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 4f598a368da..f4e6a9720e8 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -38,7 +38,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/slack-go/slack v0.15.0 github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 - github.com/smartcontractkit/chain-selectors v1.0.31 + github.com/smartcontractkit/chain-selectors v1.0.34 github.com/smartcontractkit/chainlink-automation v0.8.1 github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 02fc189da83..9e0e176190d 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1426,8 +1426,8 @@ github.com/slack-go/slack v0.15.0 h1:LE2lj2y9vqqiOf+qIIy0GvEoxgF1N5yLGZffmEZykt0 github.com/slack-go/slack v0.15.0/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 h1:qQH6fZZe31nBAG6INHph3z5ysDTPptyu0TR9uoJ1+ok= github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86/go.mod h1:WtWOoVQQEHxRHL2hNmuRrvDfYfQG/CioFNoa9Rr2mBE= -github.com/smartcontractkit/chain-selectors v1.0.31 h1:oRHyK88KnsCh4OdU2hr0u70pm3KUgyMDyK0v0aOtUk4= -github.com/smartcontractkit/chain-selectors v1.0.31/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= +github.com/smartcontractkit/chain-selectors v1.0.34 h1:MJ17OGu8+jjl426pcKrJkCf3fePb3eCreuAnUA3RBj4= +github.com/smartcontractkit/chain-selectors v1.0.34/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e h1:GnM6ZWV6vlk2+n6c6o+v/R1LtXzBGVVx7r37nt/h6Uc= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 0da60336039..23f840a67f3 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -399,7 +399,7 @@ require ( github.com/shoenig/test v0.6.6 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/smartcontractkit/chain-selectors v1.0.31 // indirect + github.com/smartcontractkit/chain-selectors v1.0.34 // indirect github.com/smartcontractkit/chainlink-automation v0.8.1 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e // indirect github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index d2aad258e23..e9eaaf81dad 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1417,8 +1417,8 @@ github.com/slack-go/slack v0.15.0 h1:LE2lj2y9vqqiOf+qIIy0GvEoxgF1N5yLGZffmEZykt0 github.com/slack-go/slack v0.15.0/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 h1:qQH6fZZe31nBAG6INHph3z5ysDTPptyu0TR9uoJ1+ok= github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86/go.mod h1:WtWOoVQQEHxRHL2hNmuRrvDfYfQG/CioFNoa9Rr2mBE= -github.com/smartcontractkit/chain-selectors v1.0.31 h1:oRHyK88KnsCh4OdU2hr0u70pm3KUgyMDyK0v0aOtUk4= -github.com/smartcontractkit/chain-selectors v1.0.31/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= +github.com/smartcontractkit/chain-selectors v1.0.34 h1:MJ17OGu8+jjl426pcKrJkCf3fePb3eCreuAnUA3RBj4= +github.com/smartcontractkit/chain-selectors v1.0.34/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e h1:GnM6ZWV6vlk2+n6c6o+v/R1LtXzBGVVx7r37nt/h6Uc= From 077971ef1ab19e15b066722cbb7b774dea4d225d Mon Sep 17 00:00:00 2001 From: Mateusz Sekara Date: Mon, 9 Dec 2024 13:53:42 +0100 Subject: [PATCH 06/29] Memorize longer tests (#15566) --- .github/e2e-tests.yml | 39 --------- .github/integration-in-memory-tests.yml | 24 ++++++ .../smoke/ccip/ccip_ooo_execution_test.go | 11 ++- .../smoke/ccip/ccip_token_transfer_test.go | 82 +++---------------- .../smoke/ccip/ccip_usdc_test.go | 15 ++-- 5 files changed, 51 insertions(+), 120 deletions(-) diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index 3b394293378..d40d375f860 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -948,45 +948,6 @@ runner-test-matrix: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 E2E_JD_VERSION: 0.6.0 - - id: smoke/ccip/ccip_token_transfer_test.go:* - path: integration-tests/smoke/ccip/ccip_token_transfer_test.go - test_env_type: docker - runs_on: ubuntu-latest - triggers: - - PR E2E Core Tests - - Nightly E2E Tests - test_cmd: cd integration-tests/ && go test smoke/ccip/ccip_token_transfer_test.go -timeout 16m -test.parallel=1 -count=1 -json - pyroscope_env: ci-smoke-ccipv1_6-evm-simulated - test_env_vars: - E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 - E2E_JD_VERSION: 0.6.0 - - - id: smoke/ccip/ccip_ooo_execution_test.go:* - path: integration-tests/smoke/ccip/ccip_ooo_execution_test.go - test_env_type: docker - runs_on: ubuntu-latest - triggers: - - PR E2E Core Tests - - Nightly E2E Tests - test_cmd: cd integration-tests/ && go test smoke/ccip/ccip_ooo_execution_test.go -timeout 16m -test.parallel=1 -count=1 -json - pyroscope_env: ci-smoke-ccipv1_6-evm-simulated - test_env_vars: - E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 - E2E_JD_VERSION: 0.6.0 - - - id: smoke/ccip/ccip_usdc_test.go:* - path: integration-tests/smoke/ccip/ccip_usdc_test.go - test_env_type: docker - runs_on: ubuntu-latest - triggers: - - PR E2E Core Tests - - Nightly E2E Tests - test_cmd: cd integration-tests/smoke/ccip && go test ccip_usdc_test.go -timeout 18m -test.parallel=1 -count=1 -json - pyroscope_env: ci-smoke-ccipv1_6-evm-simulated - test_env_vars: - E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2,SIMULATED_3 - E2E_JD_VERSION: 0.6.0 - - id: smoke/ccip/ccip_message_limitations_test.go:* path: integration-tests/smoke/ccip/ccip_message_limitations_test.go test_env_type: docker diff --git a/.github/integration-in-memory-tests.yml b/.github/integration-in-memory-tests.yml index 4b4fd71258d..b7522274d85 100644 --- a/.github/integration-in-memory-tests.yml +++ b/.github/integration-in-memory-tests.yml @@ -48,4 +48,28 @@ runner-test-matrix: - PR Integration CCIP Tests test_cmd: cd integration-tests/contracts && go test ccipreader_test.go -timeout 5m -test.parallel=1 -count=1 -json + - id: smoke/ccip/ccip_usdc_test.go:* + path: integration-tests/smoke/ccip/ccip_usdc_test.go + test_env_type: in-memory + runs_on: ubuntu-latest + triggers: + - PR Integration CCIP Tests + test_cmd: cd integration-tests/smoke/ccip && go test ccip_usdc_test.go -timeout 18m -test.parallel=1 -count=1 -json + + - id: smoke/ccip/ccip_ooo_execution_test.go:* + path: integration-tests/smoke/ccip/ccip_ooo_execution_test.go + test_env_type: in-memory + runs_on: ubuntu-latest + triggers: + - PR Integration CCIP Tests + test_cmd: cd integration-tests/ && go test smoke/ccip/ccip_ooo_execution_test.go -timeout 16m -test.parallel=1 -count=1 -json + + - id: smoke/ccip/ccip_token_transfer_test.go:* + path: integration-tests/smoke/ccip/ccip_token_transfer_test.go + test_env_type: in-memory + runs_on: ubuntu-latest + triggers: + - PR Integration CCIP Tests + test_cmd: cd integration-tests/ && go test smoke/ccip/ccip_token_transfer_test.go -timeout 16m -test.parallel=1 -count=1 -json + # END: CCIP tests diff --git a/integration-tests/smoke/ccip/ccip_ooo_execution_test.go b/integration-tests/smoke/ccip/ccip_ooo_execution_test.go index 6a3a6b869cd..86ddd07ec85 100644 --- a/integration-tests/smoke/ccip/ccip_ooo_execution_test.go +++ b/integration-tests/smoke/ccip/ccip_ooo_execution_test.go @@ -14,7 +14,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" - testsetups "github.com/smartcontractkit/chainlink/integration-tests/testsetups/ccip" + "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -36,9 +36,12 @@ func Test_OutOfOrderExecution(t *testing.T) { IsUSDC: true, IsUSDCAttestationMissing: true, } - tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr, config) - // Inmemory setup used for debugging and development, use instead of docker when needed - //tenv := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 2, 4, config) + tenv := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), memory.MemoryEnvironmentConfig{ + Chains: 2, + Nodes: 4, + Bootstraps: 1, + NumOfUsersPerChain: 2, + }, config) e := tenv.Env state, err := changeset.LoadOnchainState(e) diff --git a/integration-tests/smoke/ccip/ccip_token_transfer_test.go b/integration-tests/smoke/ccip/ccip_token_transfer_test.go index 979a6b13695..13abe33fe7c 100644 --- a/integration-tests/smoke/ccip/ccip_token_transfer_test.go +++ b/integration-tests/smoke/ccip/ccip_token_transfer_test.go @@ -1,56 +1,50 @@ package smoke import ( - "context" "math/big" "testing" "golang.org/x/exp/maps" - "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/crypto" "github.com/stretchr/testify/require" - sel "github.com/smartcontractkit/chain-selectors" - "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" - "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" - testsetups "github.com/smartcontractkit/chainlink/integration-tests/testsetups/ccip" + "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/logger" ) func TestTokenTransfer(t *testing.T) { - t.Skip("need to deflake and optimize") lggr := logger.TestLogger(t) ctx := tests.Context(t) config := &changeset.TestConfigs{} - tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr, config) - inMemoryEnv := false - // use this if you are testing locally in memory - // tenv := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 2, 4, config) - // inMemoryEnv := true + tenv := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), memory.MemoryEnvironmentConfig{ + Chains: 2, + Nodes: 4, + Bootstraps: 1, + NumOfUsersPerChain: 3, + }, config) e := tenv.Env state, err := changeset.LoadOnchainState(e) require.NoError(t, err) + require.GreaterOrEqual(t, len(e.Chains), 2) allChainSelectors := maps.Keys(e.Chains) sourceChain, destChain := allChainSelectors[0], allChainSelectors[1] ownerSourceChain := e.Chains[sourceChain].DeployerKey ownerDestChain := e.Chains[destChain].DeployerKey - oneE18 := new(big.Int).SetUint64(1e18) - funds := new(big.Int).Mul(oneE18, new(big.Int).SetUint64(10)) + require.GreaterOrEqual(t, len(tenv.Users[sourceChain]), 2) + require.GreaterOrEqual(t, len(tenv.Users[destChain]), 2) + selfServeSrcTokenPoolDeployer := tenv.Users[sourceChain][1] + selfServeDestTokenPoolDeployer := tenv.Users[destChain][1] - // Deploy and fund self-serve actors - selfServeSrcTokenPoolDeployer := createAndFundSelfServeActor(ctx, t, ownerSourceChain, e.Chains[sourceChain], funds, inMemoryEnv) - selfServeDestTokenPoolDeployer := createAndFundSelfServeActor(ctx, t, ownerDestChain, e.Chains[destChain], funds, inMemoryEnv) + oneE18 := new(big.Int).SetUint64(1e18) // Deploy tokens and pool by CCIP Owner srcToken, _, destToken, _, err := changeset.DeployTransferableToken( @@ -227,53 +221,3 @@ func TestTokenTransfer(t *testing.T) { changeset.WaitForTokenBalances(ctx, t, e.Chains, expectedTokenBalances) } - -func createAndFundSelfServeActor( - ctx context.Context, - t *testing.T, - deployer *bind.TransactOpts, - chain deployment.Chain, - amountToFund *big.Int, - isInMemory bool, -) *bind.TransactOpts { - key, err := crypto.GenerateKey() - require.NoError(t, err) - - // Simulated backend sets chainID to 1337 always - chainID := big.NewInt(1337) - if !isInMemory { - // Docker environment runs real geth so chainID has to be set accordingly - stringChainID, err1 := sel.GetChainIDFromSelector(chain.Selector) - require.NoError(t, err1) - chainID, _ = new(big.Int).SetString(stringChainID, 10) - } - - actor, err := bind.NewKeyedTransactorWithChainID(key, chainID) - require.NoError(t, err) - - nonce, err := chain.Client.PendingNonceAt(ctx, deployer.From) - require.NoError(t, err) - - gasPrice, err := chain.Client.SuggestGasPrice(ctx) - require.NoError(t, err) - - tx := types.NewTx(&types.LegacyTx{ - Nonce: nonce, - To: &actor.From, - Value: amountToFund, - Gas: uint64(21000), - GasPrice: gasPrice, - Data: nil, - }) - - signedTx, err := deployer.Signer(deployer.From, tx) - require.NoError(t, err) - - err = chain.Client.SendTransaction(ctx, signedTx) - require.NoError(t, err) - - _, err = chain.Confirm(signedTx) - require.NoError(t, err) - - return actor -} diff --git a/integration-tests/smoke/ccip/ccip_usdc_test.go b/integration-tests/smoke/ccip/ccip_usdc_test.go index eacf03df926..2dae3f3c48e 100644 --- a/integration-tests/smoke/ccip/ccip_usdc_test.go +++ b/integration-tests/smoke/ccip/ccip_usdc_test.go @@ -13,7 +13,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" - testsetups "github.com/smartcontractkit/chainlink/integration-tests/testsetups/ccip" + "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" @@ -34,13 +34,12 @@ func TestUSDCTokenTransfer(t *testing.T) { config := &changeset.TestConfigs{ IsUSDC: true, } - tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr, config) - //tenv := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, lggr, memory.MemoryEnvironmentConfig{ - // Chains: 3, - // NumOfUsersPerChain: 3, - // Nodes: 5, - // Bootstraps: 1, - //}, config) + tenv := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, lggr, memory.MemoryEnvironmentConfig{ + Chains: 3, + NumOfUsersPerChain: 3, + Nodes: 4, + Bootstraps: 1, + }, config) e := tenv.Env state, err := changeset.LoadOnchainState(e) From 54938d4ad2b430d4941eaae711abe5e1e6a7686a Mon Sep 17 00:00:00 2001 From: Graham Goh Date: Tue, 10 Dec 2024 01:20:04 +1100 Subject: [PATCH 07/29] fix: include OCR secrets as part of deployment.Environment (#15470) There are many cases where a changeset requires access to the OCR secrets and because it is not accessible via `deployment.Environment`, users are left no choice but to pass secrets as config in a changesets. By plumbing OCR secrets in `deployment.Environment`, user will no longer need to do the workaround. Update code to use OCR secrets from the env instead of from requests. JIRA: https://smartcontract-it.atlassian.net/browse/DPA-1357 --- .changeset/hot-islands-dress.md | 5 ++++ .../keystone/src/88_gen_ocr3_config.go | 3 +- .../ccip/changeset/cs_active_candidate.go | 2 +- .../changeset/cs_active_candidate_test.go | 2 +- deployment/ccip/changeset/cs_add_chain.go | 6 ++-- .../ccip/changeset/cs_add_chain_test.go | 3 -- .../ccip/changeset/cs_initial_add_chain.go | 8 ++--- deployment/ccip/changeset/test_helpers.go | 1 - deployment/common/changeset/test_helpers.go | 1 + deployment/environment.go | 3 ++ deployment/environment/devenv/environment.go | 1 + deployment/environment/memory/environment.go | 2 ++ .../keystone/changeset/configure_contracts.go | 3 +- deployment/keystone/changeset/deploy_ocr3.go | 3 +- .../keystone/changeset/deploy_ocr3_test.go | 11 +++---- deployment/keystone/changeset/helpers_test.go | 17 +++++------ deployment/keystone/deploy.go | 10 ++++--- deployment/keystone/deploy_test.go | 8 ++--- deployment/keystone/ocr3config.go | 29 +++++++++---------- deployment/keystone/ocr3config_test.go | 3 +- .../testsetups/ccip/test_helpers.go | 1 - 21 files changed, 60 insertions(+), 62 deletions(-) create mode 100644 .changeset/hot-islands-dress.md diff --git a/.changeset/hot-islands-dress.md b/.changeset/hot-islands-dress.md new file mode 100644 index 00000000000..82e34ecf42b --- /dev/null +++ b/.changeset/hot-islands-dress.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal refactor: inject ocr secrets via env instead of config diff --git a/core/scripts/keystone/src/88_gen_ocr3_config.go b/core/scripts/keystone/src/88_gen_ocr3_config.go index f4292e9a1d4..707616b833b 100644 --- a/core/scripts/keystone/src/88_gen_ocr3_config.go +++ b/core/scripts/keystone/src/88_gen_ocr3_config.go @@ -13,9 +13,8 @@ func mustReadConfig(fileName string) (output ksdeploy.TopLevelConfigSource) { func generateOCR3Config(nodeList string, configFile string, chainID int64, pubKeysPath string) ksdeploy.OCR2OracleConfig { topLevelCfg := mustReadConfig(configFile) cfg := topLevelCfg.OracleConfig - cfg.OCRSecrets = deployment.XXXGenerateTestOCRSecrets() nca := downloadNodePubKeys(nodeList, chainID, pubKeysPath) - c, err := ksdeploy.GenerateOCR3Config(cfg, nca) + c, err := ksdeploy.GenerateOCR3Config(cfg, nca, deployment.XXXGenerateTestOCRSecrets()) helpers.PanicErr(err) return c } diff --git a/deployment/ccip/changeset/cs_active_candidate.go b/deployment/ccip/changeset/cs_active_candidate.go index b2aad3889ec..ecd87e2d399 100644 --- a/deployment/ccip/changeset/cs_active_candidate.go +++ b/deployment/ccip/changeset/cs_active_candidate.go @@ -137,7 +137,7 @@ func SetCandidatePluginChangeset( } newDONArgs, err := internal.BuildOCR3ConfigForCCIPHome( - cfg.OCRSecrets, + e.OCRSecrets, state.Chains[cfg.NewChainSelector].OffRamp, e.Chains[cfg.NewChainSelector], nodes.NonBootstraps(), diff --git a/deployment/ccip/changeset/cs_active_candidate_test.go b/deployment/ccip/changeset/cs_active_candidate_test.go index 4bd0c9fd7a4..0fb29242794 100644 --- a/deployment/ccip/changeset/cs_active_candidate_test.go +++ b/deployment/ccip/changeset/cs_active_candidate_test.go @@ -144,7 +144,7 @@ func TestActiveCandidate(t *testing.T) { nil, ) ocr3ConfigMap, err := internal.BuildOCR3ConfigForCCIPHome( - deployment.XXXGenerateTestOCRSecrets(), + e.OCRSecrets, state.Chains[tenv.FeedChainSel].OffRamp, e.Chains[tenv.FeedChainSel], nodes.NonBootstraps(), diff --git a/deployment/ccip/changeset/cs_add_chain.go b/deployment/ccip/changeset/cs_add_chain.go index 9c19517260f..d589d16b779 100644 --- a/deployment/ccip/changeset/cs_add_chain.go +++ b/deployment/ccip/changeset/cs_add_chain.go @@ -8,6 +8,7 @@ import ( "github.com/smartcontractkit/chainlink-ccip/chainconfig" "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" @@ -142,7 +143,6 @@ type AddDonAndSetCandidateChangesetConfig struct { PluginType types.PluginType NodeIDs []string CCIPOCRParams CCIPOCRParams - OCRSecrets deployment.OCRSecrets } func (a AddDonAndSetCandidateChangesetConfig) Validate(e deployment.Environment, state CCIPOnChainState) (deployment.Nodes, error) { @@ -191,7 +191,7 @@ func (a AddDonAndSetCandidateChangesetConfig) Validate(e deployment.Environment, return nil, fmt.Errorf("invalid ccip ocr params: %w", err) } - if a.OCRSecrets.IsEmpty() { + if e.OCRSecrets.IsEmpty() { return nil, fmt.Errorf("OCR secrets must be set") } @@ -215,7 +215,7 @@ func AddDonAndSetCandidateChangeset( } newDONArgs, err := internal.BuildOCR3ConfigForCCIPHome( - cfg.OCRSecrets, + e.OCRSecrets, state.Chains[cfg.NewChainSelector].OffRamp, e.Chains[cfg.NewChainSelector], nodes.NonBootstraps(), diff --git a/deployment/ccip/changeset/cs_add_chain_test.go b/deployment/ccip/changeset/cs_add_chain_test.go index f6e1c04c469..c8d872236c2 100644 --- a/deployment/ccip/changeset/cs_add_chain_test.go +++ b/deployment/ccip/changeset/cs_add_chain_test.go @@ -84,7 +84,6 @@ func TestAddChainInbound(t *testing.T) { HomeChainSel: e.HomeChainSel, FeedChainSel: e.FeedChainSel, ChainConfigByChain: chainConfig, - OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), }) require.NoError(t, err) @@ -191,7 +190,6 @@ func TestAddChainInbound(t *testing.T) { NewChainSelector: newChain, PluginType: types.PluginTypeCCIPCommit, NodeIDs: nodeIDs, - OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), CCIPOCRParams: DefaultOCRParams( e.FeedChainSel, tokenConfig.GetTokenInfo(logger.TestLogger(t), state.Chains[newChain].LinkToken, state.Chains[newChain].Weth9), @@ -207,7 +205,6 @@ func TestAddChainInbound(t *testing.T) { NewChainSelector: newChain, PluginType: types.PluginTypeCCIPExec, NodeIDs: nodeIDs, - OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), CCIPOCRParams: DefaultOCRParams( e.FeedChainSel, tokenConfig.GetTokenInfo(logger.TestLogger(t), state.Chains[newChain].LinkToken, state.Chains[newChain].Weth9), diff --git a/deployment/ccip/changeset/cs_initial_add_chain.go b/deployment/ccip/changeset/cs_initial_add_chain.go index d18116b8a74..13aee106e5a 100644 --- a/deployment/ccip/changeset/cs_initial_add_chain.go +++ b/deployment/ccip/changeset/cs_initial_add_chain.go @@ -76,7 +76,6 @@ type NewChainsConfig struct { // Common to all chains HomeChainSel uint64 FeedChainSel uint64 - OCRSecrets deployment.OCRSecrets // Per chain config ChainConfigByChain map[uint64]CCIPOCRParams } @@ -96,9 +95,6 @@ func (c NewChainsConfig) Validate() error { if err := deployment.IsValidChainSelector(c.FeedChainSel); err != nil { return fmt.Errorf("invalid feed chain selector: %d - %w", c.FeedChainSel, err) } - if c.OCRSecrets.IsEmpty() { - return fmt.Errorf("no OCR secrets provided") - } // Validate chain config for chain, cfg := range c.ChainConfigByChain { if err := cfg.Validate(); err != nil { @@ -166,7 +162,7 @@ func configureChain( e deployment.Environment, c NewChainsConfig, ) error { - if c.OCRSecrets.IsEmpty() { + if e.OCRSecrets.IsEmpty() { return fmt.Errorf("OCR secrets are empty") } nodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain) @@ -217,7 +213,7 @@ func configureChain( // For each chain, we create a DON on the home chain (2 OCR instances) if err := addDON( e.Logger, - c.OCRSecrets, + e.OCRSecrets, capReg, ccipHome, rmnHome.Address(), diff --git a/deployment/ccip/changeset/test_helpers.go b/deployment/ccip/changeset/test_helpers.go index 1ee8b0d0e42..49edb275526 100644 --- a/deployment/ccip/changeset/test_helpers.go +++ b/deployment/ccip/changeset/test_helpers.go @@ -379,7 +379,6 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, Config: NewChainsConfig{ HomeChainSel: e.HomeChainSel, FeedChainSel: e.FeedChainSel, - OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), ChainConfigByChain: chainConfigs, }, }, diff --git a/deployment/common/changeset/test_helpers.go b/deployment/common/changeset/test_helpers.go index 913b4544f30..2d5295282f5 100644 --- a/deployment/common/changeset/test_helpers.go +++ b/deployment/common/changeset/test_helpers.go @@ -90,6 +90,7 @@ func ApplyChangesets(t *testing.T, e deployment.Environment, timelocksPerChain m Chains: e.Chains, NodeIDs: e.NodeIDs, Offchain: e.Offchain, + OCRSecrets: e.OCRSecrets, } } return currentEnv, nil diff --git a/deployment/environment.go b/deployment/environment.go index b4ac3a4f3f0..3d120adbbf1 100644 --- a/deployment/environment.go +++ b/deployment/environment.go @@ -98,6 +98,7 @@ type Environment struct { NodeIDs []string Offchain OffchainClient GetContext func() context.Context + OCRSecrets OCRSecrets } func NewEnvironment( @@ -108,6 +109,7 @@ func NewEnvironment( nodeIDs []string, offchain OffchainClient, ctx func() context.Context, + secrets OCRSecrets, ) *Environment { return &Environment{ Name: name, @@ -117,6 +119,7 @@ func NewEnvironment( NodeIDs: nodeIDs, Offchain: offchain, GetContext: ctx, + OCRSecrets: secrets, } } diff --git a/deployment/environment/devenv/environment.go b/deployment/environment/devenv/environment.go index 094eba99adf..121caea43bb 100644 --- a/deployment/environment/devenv/environment.go +++ b/deployment/environment/devenv/environment.go @@ -52,5 +52,6 @@ func NewEnvironment(ctx func() context.Context, lggr logger.Logger, config Envir nodeIDs, offChain, ctx, + deployment.XXXGenerateTestOCRSecrets(), ), jd.don, nil } diff --git a/deployment/environment/memory/environment.go b/deployment/environment/memory/environment.go index 1693834c572..d6c80a92a44 100644 --- a/deployment/environment/memory/environment.go +++ b/deployment/environment/memory/environment.go @@ -142,6 +142,7 @@ func NewMemoryEnvironmentFromChainsNodes( nodeIDs, // Note these have the p2p_ prefix. NewMemoryJobClient(nodes), ctx, + deployment.XXXGenerateTestOCRSecrets(), ) } @@ -161,5 +162,6 @@ func NewMemoryEnvironment(t *testing.T, lggr logger.Logger, logLevel zapcore.Lev nodeIDs, NewMemoryJobClient(nodes), func() context.Context { return tests.Context(t) }, + deployment.XXXGenerateTestOCRSecrets(), ) } diff --git a/deployment/keystone/changeset/configure_contracts.go b/deployment/keystone/changeset/configure_contracts.go index 17635a42ed1..3a92782e12b 100644 --- a/deployment/keystone/changeset/configure_contracts.go +++ b/deployment/keystone/changeset/configure_contracts.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/deployment" kslib "github.com/smartcontractkit/chainlink/deployment/keystone" ) @@ -14,7 +15,7 @@ var _ deployment.ChangeSet[InitialContractsCfg] = ConfigureInitialContractsChang type InitialContractsCfg struct { RegistryChainSel uint64 Dons []kslib.DonCapabilities - OCR3Config *kslib.OracleConfigWithSecrets + OCR3Config *kslib.OracleConfig } func ConfigureInitialContractsChangeset(e deployment.Environment, cfg InitialContractsCfg) (deployment.ChangesetOutput, error) { diff --git a/deployment/keystone/changeset/deploy_ocr3.go b/deployment/keystone/changeset/deploy_ocr3.go index fdf51e644be..0ce3d02844b 100644 --- a/deployment/keystone/changeset/deploy_ocr3.go +++ b/deployment/keystone/changeset/deploy_ocr3.go @@ -6,6 +6,7 @@ import ( "io" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" + "github.com/smartcontractkit/chainlink/deployment" kslib "github.com/smartcontractkit/chainlink/deployment/keystone" ) @@ -33,7 +34,7 @@ var _ deployment.ChangeSet[ConfigureOCR3Config] = ConfigureOCR3Contract type ConfigureOCR3Config struct { ChainSel uint64 NodeIDs []string - OCR3Config *kslib.OracleConfigWithSecrets + OCR3Config *kslib.OracleConfig DryRun bool WriteGeneratedConfig io.Writer // if not nil, write the generated config to this writer as JSON [OCR2OracleConfig] diff --git a/deployment/keystone/changeset/deploy_ocr3_test.go b/deployment/keystone/changeset/deploy_ocr3_test.go index 0d49af68823..0e5fea6b7c6 100644 --- a/deployment/keystone/changeset/deploy_ocr3_test.go +++ b/deployment/keystone/changeset/deploy_ocr3_test.go @@ -12,7 +12,7 @@ import ( "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/chainlink-common/pkg/logger" - "github.com/smartcontractkit/chainlink/deployment" + commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" "github.com/smartcontractkit/chainlink/deployment/environment/memory" kslib "github.com/smartcontractkit/chainlink/deployment/keystone" @@ -48,12 +48,9 @@ func TestConfigureOCR3(t *testing.T) { t.Parallel() lggr := logger.Test(t) - c := kslib.OracleConfigWithSecrets{ - OracleConfig: kslib.OracleConfig{ - MaxFaultyOracles: 1, - DeltaProgressMillis: 12345, - }, - OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), + c := kslib.OracleConfig{ + MaxFaultyOracles: 1, + DeltaProgressMillis: 12345, } t.Run("no mcms", func(t *testing.T) { diff --git a/deployment/keystone/changeset/helpers_test.go b/deployment/keystone/changeset/helpers_test.go index d4435d8f7a6..faf112867ce 100644 --- a/deployment/keystone/changeset/helpers_test.go +++ b/deployment/keystone/changeset/helpers_test.go @@ -7,16 +7,19 @@ import ( "encoding/hex" "errors" "fmt" + "math" "math/big" "sort" - - "math" "testing" "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + "golang.org/x/exp/maps" + "github.com/smartcontractkit/chainlink/deployment" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" @@ -26,9 +29,6 @@ import ( kschangeset "github.com/smartcontractkit/chainlink/deployment/keystone/changeset" kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" - "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" - "golang.org/x/exp/maps" ) func TestSetupTestEnv(t *testing.T) { @@ -215,11 +215,8 @@ func SetupTestEnv(t *testing.T, c TestConfig) TestEnv { err = env.ExistingAddresses.Merge(e.ExistingAddresses) require.NoError(t, err) - var ocr3Config = keystone.OracleConfigWithSecrets{ - OracleConfig: keystone.OracleConfig{ - MaxFaultyOracles: len(wfNodes) / 3, - }, - OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), + var ocr3Config = keystone.OracleConfig{ + MaxFaultyOracles: len(wfNodes) / 3, } var allDons = []keystone.DonCapabilities{wfDon, cwDon, assetDon} diff --git a/deployment/keystone/deploy.go b/deployment/keystone/deploy.go index da277bc3497..9bd291e9c1e 100644 --- a/deployment/keystone/deploy.go +++ b/deployment/keystone/deploy.go @@ -44,8 +44,8 @@ type ConfigureContractsRequest struct { RegistryChainSel uint64 Env *deployment.Environment - Dons []DonCapabilities // externally sourced based on the environment - OCR3Config *OracleConfigWithSecrets // TODO: probably should be a map of don to config; but currently we only have one wf don therefore one config + Dons []DonCapabilities // externally sourced based on the environment + OCR3Config *OracleConfig // TODO: probably should be a map of don to config; but currently we only have one wf don therefore one config // TODO rm this option; unused DoContractDeploy bool // if false, the contracts are assumed to be deployed and the address book is used @@ -304,7 +304,7 @@ func ConfigureRegistry(ctx context.Context, lggr logger.Logger, req ConfigureCon // Depreciated: use changeset.ConfigureOCR3Contract instead // ocr3 contract on the registry chain for the wf dons -func ConfigureOCR3Contract(env *deployment.Environment, chainSel uint64, dons []RegisteredDon, cfg *OracleConfigWithSecrets) error { +func ConfigureOCR3Contract(env *deployment.Environment, chainSel uint64, dons []RegisteredDon, cfg *OracleConfig) error { registryChain, ok := env.Chains[chainSel] if !ok { return fmt.Errorf("chain %d not found in environment", chainSel) @@ -338,6 +338,7 @@ func ConfigureOCR3Contract(env *deployment.Environment, chainSel uint64, dons [] contract: contract, nodes: don.Nodes, contractSet: &contracts, + ocrSecrets: env.OCRSecrets, }) if err != nil { return fmt.Errorf("failed to configure OCR3 contract for don %s: %w", don.Name, err) @@ -354,7 +355,7 @@ type ConfigureOCR3Resp struct { type ConfigureOCR3Config struct { ChainSel uint64 NodeIDs []string - OCR3Config *OracleConfigWithSecrets + OCR3Config *OracleConfig DryRun bool UseMCMS bool @@ -398,6 +399,7 @@ func ConfigureOCR3ContractFromJD(env *deployment.Environment, cfg ConfigureOCR3C dryRun: cfg.DryRun, contractSet: &contracts, useMCMS: cfg.UseMCMS, + ocrSecrets: env.OCRSecrets, }) if err != nil { return nil, err diff --git a/deployment/keystone/deploy_test.go b/deployment/keystone/deploy_test.go index 715f8b7aba7..eb167ed60fb 100644 --- a/deployment/keystone/deploy_test.go +++ b/deployment/keystone/deploy_test.go @@ -107,6 +107,7 @@ func TestDeployCLO(t *testing.T) { Offchain: clo.NewJobClient(lggr, clo.JobClientConfig{Nops: allNops}), Chains: allChains, Logger: lggr, + OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), } // assume that all the nodes in the provided input nops are part of the don for _, nop := range allNops { @@ -119,11 +120,8 @@ func TestDeployCLO(t *testing.T) { registryChainSel, err := chainsel.SelectorFromChainId(11155111) require.NoError(t, err) - var ocr3Config = keystone.OracleConfigWithSecrets{ - OracleConfig: keystone.OracleConfig{ - MaxFaultyOracles: len(wfNops) / 3, - }, - OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), + var ocr3Config = keystone.OracleConfig{ + MaxFaultyOracles: len(wfNops) / 3, } ctx := tests.Context(t) diff --git a/deployment/keystone/ocr3config.go b/deployment/keystone/ocr3config.go index c4f8714b113..ccd738636ed 100644 --- a/deployment/keystone/ocr3config.go +++ b/deployment/keystone/ocr3config.go @@ -21,6 +21,7 @@ import ( "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" + "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" kocr3 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/ocr3_capability" @@ -30,12 +31,9 @@ import ( ) type TopLevelConfigSource struct { - OracleConfig OracleConfigWithSecrets -} -type OracleConfigWithSecrets struct { - OracleConfig - deployment.OCRSecrets `json:"-" toml:"-"` // don't spill secrets + OracleConfig OracleConfig } + type OracleConfig struct { MaxQueryLengthBytes uint32 MaxObservationLengthBytes uint32 @@ -151,10 +149,10 @@ func (c *OCR2OracleConfig) UnmarshalJSON(data []byte) error { return nil } -func GenerateOCR3Config(cfg OracleConfigWithSecrets, nca []NodeKeys) (OCR2OracleConfig, error) { +func GenerateOCR3Config(cfg OracleConfig, nca []NodeKeys, secrets deployment.OCRSecrets) (OCR2OracleConfig, error) { onchainPubKeys := [][]byte{} allPubKeys := map[string]any{} - if cfg.OCRSecrets.IsEmpty() { + if secrets.IsEmpty() { return OCR2OracleConfig{}, errors.New("OCRSecrets is required") } for _, n := range nca { @@ -236,8 +234,8 @@ func GenerateOCR3Config(cfg OracleConfigWithSecrets, nca []NodeKeys) (OCR2Oracle } signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsDeterministic( - cfg.EphemeralSk, - cfg.SharedSecret, + secrets.EphemeralSk, + secrets.SharedSecret, time.Duration(cfg.DeltaProgressMillis)*time.Millisecond, time.Duration(cfg.DeltaResendMillis)*time.Millisecond, time.Duration(cfg.DeltaInitialMillis)*time.Millisecond, @@ -284,11 +282,12 @@ func GenerateOCR3Config(cfg OracleConfigWithSecrets, nca []NodeKeys) (OCR2Oracle } type configureOCR3Request struct { - cfg *OracleConfigWithSecrets - chain deployment.Chain - contract *kocr3.OCR3Capability - nodes []deployment.Node - dryRun bool + cfg *OracleConfig + chain deployment.Chain + contract *kocr3.OCR3Capability + nodes []deployment.Node + dryRun bool + ocrSecrets deployment.OCRSecrets useMCMS bool contractSet *ContractSet @@ -296,7 +295,7 @@ type configureOCR3Request struct { func (r configureOCR3Request) generateOCR3Config() (OCR2OracleConfig, error) { nks := makeNodeKeysSlice(r.nodes, r.chain.Selector) - return GenerateOCR3Config(*r.cfg, nks) + return GenerateOCR3Config(*r.cfg, nks, r.ocrSecrets) } type configureOCR3Response struct { diff --git a/deployment/keystone/ocr3config_test.go b/deployment/keystone/ocr3config_test.go index daf869d77e0..55fa16af68c 100644 --- a/deployment/keystone/ocr3config_test.go +++ b/deployment/keystone/ocr3config_test.go @@ -85,11 +85,12 @@ func Test_configureOCR3Request_generateOCR3Config(t *testing.T) { err := json.Unmarshal([]byte(ocr3Cfg), &cfg) require.NoError(t, err) r := configureOCR3Request{ - cfg: &OracleConfigWithSecrets{OracleConfig: cfg, OCRSecrets: deployment.XXXGenerateTestOCRSecrets()}, + cfg: &cfg, nodes: nodes, chain: deployment.Chain{ Selector: chain_selectors.ETHEREUM_TESTNET_SEPOLIA.Selector, }, + ocrSecrets: deployment.XXXGenerateTestOCRSecrets(), } got, err := r.generateOCR3Config() require.NoError(t, err) diff --git a/integration-tests/testsetups/ccip/test_helpers.go b/integration-tests/testsetups/ccip/test_helpers.go index 4d51093d419..3112d738869 100644 --- a/integration-tests/testsetups/ccip/test_helpers.go +++ b/integration-tests/testsetups/ccip/test_helpers.go @@ -244,7 +244,6 @@ func NewLocalDevEnvironment( Config: changeset.NewChainsConfig{ HomeChainSel: homeChainSel, FeedChainSel: feedSel, - OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), ChainConfigByChain: chainConfigs, }, }, From 398e5834cbdbb1258c854d397599501cf803361f Mon Sep 17 00:00:00 2001 From: Makram Date: Mon, 9 Dec 2024 17:04:17 +0200 Subject: [PATCH 08/29] deployment/ccip/changeset: rm TestInitialDeploy (#15568) This test is now a relic as we have more granular test cases in other test files. --- .github/e2e-tests.yml | 13 --- .../ccip/changeset/initial_deploy_test.go | 82 ------------------ deployment/environment/devenv/README.md | 12 +-- integration-tests/smoke/ccip/ccip_test.go | 83 ------------------- 4 files changed, 6 insertions(+), 184 deletions(-) delete mode 100644 deployment/ccip/changeset/initial_deploy_test.go delete mode 100644 integration-tests/smoke/ccip/ccip_test.go diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index d40d375f860..ebe5b62a709 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -935,19 +935,6 @@ runner-test-matrix: # START: CCIPv1.6 tests - - id: smoke/ccip/ccip_test.go:* - path: integration-tests/smoke/ccip/ccip_test.go - test_env_type: docker - runs_on: ubuntu-latest - triggers: - - PR E2E Core Tests - - Nightly E2E Tests - test_cmd: cd integration-tests/smoke/ccip && go test ccip_test.go -timeout 25m -test.parallel=2 -count=1 -json - pyroscope_env: ci-smoke-ccipv1_6-evm-simulated - test_env_vars: - E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 - E2E_JD_VERSION: 0.6.0 - - id: smoke/ccip/ccip_message_limitations_test.go:* path: integration-tests/smoke/ccip/ccip_message_limitations_test.go test_env_type: docker diff --git a/deployment/ccip/changeset/initial_deploy_test.go b/deployment/ccip/changeset/initial_deploy_test.go deleted file mode 100644 index 97e516c8f94..00000000000 --- a/deployment/ccip/changeset/initial_deploy_test.go +++ /dev/null @@ -1,82 +0,0 @@ -package changeset - -import ( - "testing" - - "github.com/ethereum/go-ethereum/common" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" - - "github.com/smartcontractkit/chainlink/deployment/environment/memory" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/logger" - - "github.com/stretchr/testify/require" -) - -func TestInitialDeploy(t *testing.T) { - lggr := logger.TestLogger(t) - tenv := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, memory.MemoryEnvironmentConfig{ - Chains: 3, - Nodes: 4, - Bootstraps: 1, - NumOfUsersPerChain: 1, - }, nil) - e := tenv.Env - state, err := LoadOnchainState(e) - require.NoError(t, err) - // Add all lanes - require.NoError(t, AddLanesForAll(e, state)) - // Need to keep track of the block number for each chain so that event subscription can be done from that block. - startBlocks := make(map[uint64]*uint64) - // Send a message from each chain to every other chain. - expectedSeqNum := make(map[SourceDestPair]uint64) - expectedSeqNumExec := make(map[SourceDestPair][]uint64) - - for src := range e.Chains { - for dest, destChain := range e.Chains { - if src == dest { - continue - } - latesthdr, err := destChain.Client.HeaderByNumber(testcontext.Get(t), nil) - require.NoError(t, err) - block := latesthdr.Number.Uint64() - startBlocks[dest] = &block - require.GreaterOrEqual(t, len(tenv.Users[src]), 1) - msgSentEvent, err := DoSendRequest(t, e, state, - WithTestRouter(false), - WithSourceChain(src), - WithDestChain(dest), - WithEvm2AnyMessage(router.ClientEVM2AnyMessage{ - Receiver: common.LeftPadBytes(state.Chains[dest].Receiver.Address().Bytes(), 32), - Data: []byte("hello"), - TokenAmounts: nil, - FeeToken: common.HexToAddress("0x0"), - ExtraArgs: nil, - }), - WithSender(tenv.Users[src][0]), - ) - require.NoError(t, err) - expectedSeqNum[SourceDestPair{ - SourceChainSelector: src, - DestChainSelector: dest, - }] = msgSentEvent.SequenceNumber - expectedSeqNumExec[SourceDestPair{ - SourceChainSelector: src, - DestChainSelector: dest, - }] = []uint64{msgSentEvent.SequenceNumber} - } - } - - // Wait for all commit reports to land. - ConfirmCommitForAllWithExpectedSeqNums(t, e, state, expectedSeqNum, startBlocks) - - // Confirm token and gas prices are updated - ConfirmTokenPriceUpdatedForAll(t, e, state, startBlocks, - DefaultInitialPrices.LinkPrice, DefaultInitialPrices.WethPrice) - // TODO: Fix gas prices? - //ConfirmGasPriceUpdatedForAll(t, e, state, startBlocks) - // - //// Wait for all exec reports to land - ConfirmExecWithSeqNrsForAll(t, e, state, expectedSeqNumExec, startBlocks) -} diff --git a/deployment/environment/devenv/README.md b/deployment/environment/devenv/README.md index f5e11f0475e..e6f5bc1b5ac 100644 --- a/deployment/environment/devenv/README.md +++ b/deployment/environment/devenv/README.md @@ -14,11 +14,11 @@ Pre-requisites: #### Setting Up Testconfig with Simulated Private Ethereum Network -To run tests (e.g., [ccip-test](../../integration-tests/smoke/ccip_test.go)), -you need to set up the testconfig following the [testconfig setup instructions](../../integration-tests/testconfig/README.md). +To run tests (e.g., [ccip-test](../../../integration-tests/ccip-tests/smoke/ccip_test.go)), +you need to set up the testconfig following the [testconfig setup instructions](../../../integration-tests/testconfig/README.md). The testconfig specifies the details of the different configurations to set up the environment and run the tests. -Generally, tests are run with the [default](../../integration-tests/testconfig/default.toml) config unless overridden by product-specific config. -For example, the [ccip-test](../../integration-tests/smoke/ccip_test.go) uses [ccip.toml](../../integration-tests/testconfig/ccip/ccip.toml) to specify +Generally, tests are run with the [default](../../../integration-tests/testconfig/default.toml) config unless overridden by product-specific config. +For example, the [ccip-test](../../../integration-tests/ccip-tests/smoke/ccip_test.go) uses [ccip.toml](../../../integration-tests/testconfig/ccip/ccip.toml) to specify CCIP-specific test environment details. There are additional secret configuration parameters required by the `devenv` environment that are not stored in the testconfig. @@ -37,7 +37,7 @@ By default, tests are run with private Ethereum network containers set up in the the Chainlink nodes and job distributor. To run tests against existing testnet/mainnet, set the `selected_network` field in the testconfig with the specific network names. -For example, if running [ccip-smoke](../../integration-tests/smoke/ccip_test.go) tests with Sepolia, Avax, and Binance testnets, +For example, if running [ccip-smoke](../../../integration-tests/ccip-tests/smoke/ccip_test.go) tests with Sepolia, Avax, and Binance testnets, copy the contents of [sepolia_avax_binance.toml](../../integration-tests/testconfig/ccip/overrides/sepolia_avax_binance.toml) to the `overrides.toml` file. @@ -48,4 +48,4 @@ provide necessary secrets applicable to the network you are running the tests ag - `E2E_TEST__RPC_HTTP_URL_` - `E2E_TEST__RPC_WS_URL_` -Now you are all set to run the tests with the existing testnet/mainnet. \ No newline at end of file +Now you are all set to run the tests with the existing testnet/mainnet. diff --git a/integration-tests/smoke/ccip/ccip_test.go b/integration-tests/smoke/ccip/ccip_test.go deleted file mode 100644 index ca30c9281c4..00000000000 --- a/integration-tests/smoke/ccip/ccip_test.go +++ /dev/null @@ -1,83 +0,0 @@ -package smoke - -import ( - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" - - "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" - testsetups "github.com/smartcontractkit/chainlink/integration-tests/testsetups/ccip" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/logger" -) - -func TestInitialDeployOnLocal(t *testing.T) { - t.Parallel() - lggr := logger.TestLogger(t) - config := &changeset.TestConfigs{} - tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr, config) - e := tenv.Env - state, err := changeset.LoadOnchainState(e) - require.NoError(t, err) - - // Add all lanes - require.NoError(t, changeset.AddLanesForAll(e, state)) - // Need to keep track of the block number for each chain so that event subscription can be done from that block. - startBlocks := make(map[uint64]*uint64) - // Send a message from each chain to every other chain. - expectedSeqNum := make(map[changeset.SourceDestPair]uint64) - expectedSeqNumExec := make(map[changeset.SourceDestPair][]uint64) - for src := range e.Chains { - for dest, destChain := range e.Chains { - if src == dest { - continue - } - latesthdr, err := destChain.Client.HeaderByNumber(testcontext.Get(t), nil) - require.NoError(t, err) - block := latesthdr.Number.Uint64() - startBlocks[dest] = &block - require.GreaterOrEqual(t, len(tenv.Users[src]), 2) - msgSentEvent, err := changeset.DoSendRequest(t, e, state, - changeset.WithSender(tenv.Users[src][1]), - changeset.WithSourceChain(src), - changeset.WithDestChain(dest), - changeset.WithTestRouter(false), - changeset.WithEvm2AnyMessage(router.ClientEVM2AnyMessage{ - Receiver: common.LeftPadBytes(state.Chains[dest].Receiver.Address().Bytes(), 32), - Data: []byte("hello world"), - TokenAmounts: nil, - FeeToken: common.HexToAddress("0x0"), - ExtraArgs: nil, - })) - require.NoError(t, err) - expectedSeqNum[changeset.SourceDestPair{ - SourceChainSelector: src, - DestChainSelector: dest, - }] = msgSentEvent.SequenceNumber - expectedSeqNumExec[changeset.SourceDestPair{ - SourceChainSelector: src, - DestChainSelector: dest, - }] = []uint64{msgSentEvent.SequenceNumber} - } - } - - // Wait for all commit reports to land. - changeset.ConfirmCommitForAllWithExpectedSeqNums(t, e, state, expectedSeqNum, startBlocks) - - // After commit is reported on all chains, token prices should be updated in FeeQuoter. - for dest := range e.Chains { - linkAddress := state.Chains[dest].LinkToken.Address() - feeQuoter := state.Chains[dest].FeeQuoter - timestampedPrice, err := feeQuoter.GetTokenPrice(nil, linkAddress) - require.NoError(t, err) - require.Equal(t, changeset.MockLinkPrice, timestampedPrice.Value) - } - - // Wait for all exec reports to land - changeset.ConfirmExecWithSeqNrsForAll(t, e, state, expectedSeqNumExec, startBlocks) - - // TODO: Apply the proposal. -} From b6bf8f2bdd4d6613ec7e29748f42fa229fdd065c Mon Sep 17 00:00:00 2001 From: Makram Date: Mon, 9 Dec 2024 17:51:53 +0200 Subject: [PATCH 09/29] core/services/ocr2/plugins/ccip: skip racey TestIntegration_CCIP (#15569) Also delete TestIntegration_legacy_CCIP since v1.5 has been live for a bit. --- .../plugins/ccip/integration_legacy_test.go | 594 ------------------ .../ocr2/plugins/ccip/integration_test.go | 2 + 2 files changed, 2 insertions(+), 594 deletions(-) delete mode 100644 core/services/ocr2/plugins/ccip/integration_legacy_test.go diff --git a/core/services/ocr2/plugins/ccip/integration_legacy_test.go b/core/services/ocr2/plugins/ccip/integration_legacy_test.go deleted file mode 100644 index 12a117d47c4..00000000000 --- a/core/services/ocr2/plugins/ccip/integration_legacy_test.go +++ /dev/null @@ -1,594 +0,0 @@ -package ccip_test - -import ( - "context" - "encoding/json" - "fmt" - "math/big" - "sync" - "testing" - "time" - - "github.com/ethereum/go-ethereum/common" - gethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - evm_2_evm_onramp "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_v3_aggregator_contract" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" - testhelpers_new "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" - testhelpers "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0" -) - -func TestIntegration_legacy_CCIP(t *testing.T) { - // Run the batches of tests for both pipeline and dynamic price getter setups. - // We will remove the pipeline batch once the feature is deleted from the code. - tests := []struct { - name string - withPipeline bool - }{ - { - name: "with pipeline", - withPipeline: true, - }, - { - name: "with dynamic price getter", - withPipeline: false, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - ccipTH := testhelpers.SetupCCIPIntegrationTH(t, testhelpers.SourceChainID, testhelpers.SourceChainSelector, testhelpers.DestChainID, testhelpers.DestChainSelector) - - tokenPricesUSDPipeline := "" - priceGetterConfigJson := "" - - if test.withPipeline { - // Set up a test pipeline. - testPricePipeline, linkUSD, ethUSD := ccipTH.CreatePricesPipeline(t) - defer linkUSD.Close() - defer ethUSD.Close() - tokenPricesUSDPipeline = testPricePipeline - } else { - // Set up a test price getter. - // Set up the aggregators here to avoid modifying ccipTH. - aggSrcNatAddr, _, aggSrcNat, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(ccipTH.Source.User, ccipTH.Source.Chain.Client(), 18, big.NewInt(2e18)) - require.NoError(t, err) - _, err = aggSrcNat.UpdateRoundData(ccipTH.Source.User, big.NewInt(50), big.NewInt(17000000), big.NewInt(1000), big.NewInt(1000)) - require.NoError(t, err) - ccipTH.Source.Chain.Commit() - - aggDstLnkAddr, _, aggDstLnk, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(ccipTH.Dest.User, ccipTH.Dest.Chain.Client(), 18, big.NewInt(3e18)) - require.NoError(t, err) - ccipTH.Dest.Chain.Commit() - _, err = aggDstLnk.UpdateRoundData(ccipTH.Dest.User, big.NewInt(50), big.NewInt(8000000), big.NewInt(1000), big.NewInt(1000)) - require.NoError(t, err) - ccipTH.Dest.Chain.Commit() - - priceGetterConfig := config.DynamicPriceGetterConfig{ - AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ - ccipTH.Source.WrappedNative.Address(): { - ChainID: ccipTH.Source.ChainID, - AggregatorContractAddress: aggSrcNatAddr, - }, - ccipTH.Dest.LinkToken.Address(): { - ChainID: ccipTH.Dest.ChainID, - AggregatorContractAddress: aggDstLnkAddr, - }, - ccipTH.Dest.WrappedNative.Address(): { - ChainID: ccipTH.Dest.ChainID, - AggregatorContractAddress: aggDstLnkAddr, - }, - }, - StaticPrices: map[common.Address]config.StaticPriceConfig{}, - } - priceGetterConfigBytes, err := json.MarshalIndent(priceGetterConfig, "", " ") - require.NoError(t, err) - priceGetterConfigJson = string(priceGetterConfigBytes) - } - - jobParams := ccipTH.SetUpNodesAndJobs(t, tokenPricesUSDPipeline, priceGetterConfigJson, "") - - currentSeqNum := 1 - - t.Run("single", func(t *testing.T) { - tokenAmount := big.NewInt(500000003) // prime number - gasLimit := big.NewInt(200_003) // prime number - - extraArgs, err2 := testhelpers.GetEVMExtraArgsV1(gasLimit, false) - require.NoError(t, err2) - - sourceBalances, err2 := testhelpers.GetBalances(t, []testhelpers.BalanceReq{ - {Name: testhelpers.SourcePool, Addr: ccipTH.Source.LinkTokenPool.Address(), Getter: ccipTH.GetSourceLinkBalance}, - {Name: testhelpers.OnRamp, Addr: ccipTH.Source.OnRamp.Address(), Getter: ccipTH.GetSourceLinkBalance}, - {Name: testhelpers.SourceRouter, Addr: ccipTH.Source.Router.Address(), Getter: ccipTH.GetSourceLinkBalance}, - {Name: testhelpers.SourcePriceRegistry, Addr: ccipTH.Source.PriceRegistry.Address(), Getter: ccipTH.GetSourceLinkBalance}, - }) - require.NoError(t, err2) - destBalances, err2 := testhelpers.GetBalances(t, []testhelpers.BalanceReq{ - {Name: testhelpers.Receiver, Addr: ccipTH.Dest.Receivers[0].Receiver.Address(), Getter: ccipTH.GetDestLinkBalance}, - {Name: testhelpers.DestPool, Addr: ccipTH.Dest.LinkTokenPool.Address(), Getter: ccipTH.GetDestLinkBalance}, - {Name: testhelpers.OffRamp, Addr: ccipTH.Dest.OffRamp.Address(), Getter: ccipTH.GetDestLinkBalance}, - }) - require.NoError(t, err2) - - ccipTH.Source.User.Value = tokenAmount - _, err2 = ccipTH.Source.WrappedNative.Deposit(ccipTH.Source.User) - require.NoError(t, err2) - ccipTH.Source.Chain.Commit() - ccipTH.Source.User.Value = nil - - msg := router.ClientEVM2AnyMessage{ - Receiver: testhelpers.MustEncodeAddress(t, ccipTH.Dest.Receivers[0].Receiver.Address()), - Data: []byte("hello"), - TokenAmounts: []router.ClientEVMTokenAmount{ - { - Token: ccipTH.Source.LinkToken.Address(), - Amount: tokenAmount, - }, - { - Token: ccipTH.Source.WrappedNative.Address(), - Amount: tokenAmount, - }, - }, - FeeToken: ccipTH.Source.LinkToken.Address(), - ExtraArgs: extraArgs, - } - fee, err2 := ccipTH.Source.Router.GetFee(nil, testhelpers.DestChainSelector, msg) - require.NoError(t, err2) - // Currently no overhead and 10gwei dest gas price. So fee is simply (gasLimit * gasPrice)* link/native - // require.Equal(t, new(big.Int).Mul(gasLimit, gasPrice).String(), fee.String()) - // Approve the fee amount + the token amount - _, err2 = ccipTH.Source.LinkToken.Approve(ccipTH.Source.User, ccipTH.Source.Router.Address(), new(big.Int).Add(fee, tokenAmount)) - require.NoError(t, err2) - ccipTH.Source.Chain.Commit() - _, err2 = ccipTH.Source.WrappedNative.Approve(ccipTH.Source.User, ccipTH.Source.Router.Address(), tokenAmount) - require.NoError(t, err2) - ccipTH.Source.Chain.Commit() - - ccipTH.SendRequest(t, msg) - // Should eventually see this executed. - ccipTH.AllNodesHaveReqSeqNum(t, currentSeqNum) - ccipTH.EventuallyReportCommitted(t, currentSeqNum) - - executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum) - assert.Len(t, executionLogs, 1) - ccipTH.AssertExecState(t, executionLogs[0], testhelpers.ExecutionStateSuccess) - - // Asserts - // 1) The total pool input == total pool output - // 2) Pool flow equals tokens sent - // 3) Sent tokens arrive at the receiver - ccipTH.AssertBalances(t, []testhelpers.BalanceAssertion{ - { - Name: testhelpers.SourcePool, - Address: ccipTH.Source.LinkTokenPool.Address(), - Expected: testhelpers.MustAddBigInt(sourceBalances[testhelpers.SourcePool], tokenAmount.String()).String(), - Getter: ccipTH.GetSourceLinkBalance, - }, - { - Name: testhelpers.SourcePriceRegistry, - Address: ccipTH.Source.PriceRegistry.Address(), - Expected: sourceBalances[testhelpers.SourcePriceRegistry].String(), - Getter: ccipTH.GetSourceLinkBalance, - }, - { - // Fees end up in the onramp. - Name: testhelpers.OnRamp, - Address: ccipTH.Source.OnRamp.Address(), - Expected: testhelpers.MustAddBigInt(sourceBalances[testhelpers.SourcePriceRegistry], fee.String()).String(), - Getter: ccipTH.GetSourceLinkBalance, - }, - { - Name: testhelpers.SourceRouter, - Address: ccipTH.Source.Router.Address(), - Expected: sourceBalances[testhelpers.SourceRouter].String(), - Getter: ccipTH.GetSourceLinkBalance, - }, - { - Name: testhelpers.Receiver, - Address: ccipTH.Dest.Receivers[0].Receiver.Address(), - Expected: testhelpers.MustAddBigInt(destBalances[testhelpers.Receiver], tokenAmount.String()).String(), - Getter: ccipTH.GetDestLinkBalance, - }, - { - Name: testhelpers.DestPool, - Address: ccipTH.Dest.LinkTokenPool.Address(), - Expected: testhelpers.MustSubBigInt(destBalances[testhelpers.DestPool], tokenAmount.String()).String(), - Getter: ccipTH.GetDestLinkBalance, - }, - { - Name: testhelpers.OffRamp, - Address: ccipTH.Dest.OffRamp.Address(), - Expected: destBalances[testhelpers.OffRamp].String(), - Getter: ccipTH.GetDestLinkBalance, - }, - }) - currentSeqNum++ - }) - - t.Run("multiple batches", func(t *testing.T) { - tokenAmount := big.NewInt(500000003) - gasLimit := big.NewInt(250_000) - - var txs []*gethtypes.Transaction - // Enough to require batched executions as gasLimit per tx is 250k -> 500k -> 750k .... - // The actual gas usage of executing 15 messages is higher than the gas limit for - // a single tx. This means that when batching is turned off, and we simply include - // all txs without checking gas, this also fails. - n := 15 - for i := 0; i < n; i++ { - txGasLimit := new(big.Int).Mul(gasLimit, big.NewInt(int64(i+1))) - extraArgs, err2 := testhelpers.GetEVMExtraArgsV1(txGasLimit, false) - require.NoError(t, err2) - msg := router.ClientEVM2AnyMessage{ - Receiver: testhelpers.MustEncodeAddress(t, ccipTH.Dest.Receivers[0].Receiver.Address()), - Data: []byte("hello"), - TokenAmounts: []router.ClientEVMTokenAmount{ - { - Token: ccipTH.Source.LinkToken.Address(), - Amount: tokenAmount, - }, - }, - FeeToken: ccipTH.Source.LinkToken.Address(), - ExtraArgs: extraArgs, - } - fee, err2 := ccipTH.Source.Router.GetFee(nil, testhelpers.DestChainSelector, msg) - require.NoError(t, err2) - // Currently no overhead and 1gwei dest gas price. So fee is simply gasLimit * gasPrice. - // require.Equal(t, new(big.Int).Mul(txGasLimit, gasPrice).String(), fee.String()) - // Approve the fee amount + the token amount - _, err2 = ccipTH.Source.LinkToken.Approve(ccipTH.Source.User, ccipTH.Source.Router.Address(), new(big.Int).Add(fee, tokenAmount)) - require.NoError(t, err2) - ccipTH.Source.Chain.Commit() - tx, err2 := ccipTH.Source.Router.CcipSend(ccipTH.Source.User, ccipTH.Dest.ChainSelector, msg) - require.NoError(t, err2) - ccipTH.Source.Chain.Commit() - txs = append(txs, tx) - } - - // Send a batch of requests in a single block - testhelpers_new.ConfirmTxs(t, txs, ccipTH.Source.Chain) - for i := 0; i < n; i++ { - ccipTH.AllNodesHaveReqSeqNum(t, currentSeqNum+i) - } - // Should see a report with the full range - ccipTH.EventuallyReportCommitted(t, currentSeqNum+n-1) - // Should all be executed - executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum+n-1) - for _, execLog := range executionLogs { - ccipTH.AssertExecState(t, execLog, testhelpers.ExecutionStateSuccess) - } - - currentSeqNum += n - }) - - // Deploy new on ramp,Commit store,off ramp - // Delete v1 jobs - // Send a number of requests - // Upgrade the router with new contracts - // create new jobs - // Verify all pending requests are sent after the contracts are upgraded - t.Run("upgrade contracts and verify requests can be sent with upgraded contract", func(t *testing.T) { - ctx := testutils.Context(t) - gasLimit := big.NewInt(200_003) // prime number - tokenAmount := big.NewInt(100) - commitStoreV1 := ccipTH.Dest.CommitStore - offRampV1 := ccipTH.Dest.OffRamp - onRampV1 := ccipTH.Source.OnRamp - // deploy v2 contracts - ccipTH.DeployNewOnRamp(t) - ccipTH.DeployNewCommitStore(t) - ccipTH.DeployNewOffRamp(t) - - // send a request as the v2 contracts are not enabled in router it should route through the v1 contracts - t.Logf("sending request for seqnum %d", currentSeqNum) - ccipTH.SendMessage(t, gasLimit, tokenAmount, ccipTH.Dest.Receivers[0].Receiver.Address()) - ccipTH.Source.Chain.Commit() - ccipTH.Dest.Chain.Commit() - t.Logf("verifying seqnum %d on previous onRamp %s", currentSeqNum, onRampV1.Address().Hex()) - ccipTH.AllNodesHaveReqSeqNum(t, currentSeqNum, onRampV1.Address()) - ccipTH.EventuallyReportCommitted(t, currentSeqNum, commitStoreV1.Address()) - executionLog := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum, offRampV1.Address()) - ccipTH.AssertExecState(t, executionLog[0], testhelpers.ExecutionStateSuccess, offRampV1.Address()) - - nonceAtOnRampV1, err := onRampV1.GetSenderNonce(nil, ccipTH.Source.User.From) - require.NoError(t, err, "getting nonce from onRamp") - require.Equal(t, currentSeqNum, int(nonceAtOnRampV1)) - nonceAtOffRampV1, err := offRampV1.GetSenderNonce(nil, ccipTH.Source.User.From) - require.NoError(t, err, "getting nonce from offRamp") - require.Equal(t, currentSeqNum, int(nonceAtOffRampV1)) - - // enable the newly deployed contracts - newConfigBlock, err := ccipTH.Dest.Chain.Client().BlockNumber(ctx) - require.NoError(t, err) - ccipTH.EnableOnRamp(t) - ccipTH.EnableCommitStore(t) - ccipTH.EnableOffRamp(t) - srcStartBlock, err := ccipTH.Source.Chain.Client().BlockNumber(ctx) - require.NoError(t, err) - - // send a number of requests, the requests should not be delivered yet as the previous contracts are not configured - // with the router anymore - startSeq := 1 - noOfRequests := 5 - endSeqNum := startSeq + noOfRequests - for i := startSeq; i <= endSeqNum; i++ { - t.Logf("sending request for seqnum %d", i) - ccipTH.SendMessage(t, gasLimit, tokenAmount, ccipTH.Dest.Receivers[0].Receiver.Address()) - ccipTH.Source.Chain.Commit() - ccipTH.Dest.Chain.Commit() - ccipTH.EventuallySendRequested(t, uint64(i)) - } - - // delete v1 jobs - for _, node := range ccipTH.Nodes { - id := node.FindJobIDForContract(t, commitStoreV1.Address()) - require.Greater(t, id, int32(0)) - t.Logf("deleting job %d", id) - err = node.App.DeleteJob(context.Background(), id) - require.NoError(t, err) - id = node.FindJobIDForContract(t, offRampV1.Address()) - require.Greater(t, id, int32(0)) - t.Logf("deleting job %d", id) - err = node.App.DeleteJob(context.Background(), id) - require.NoError(t, err) - } - - // Commit on both chains to reach Finality - ccipTH.Source.Chain.Commit() - ccipTH.Dest.Chain.Commit() - - // create new jobs - jobParams = ccipTH.NewCCIPJobSpecParams(tokenPricesUSDPipeline, priceGetterConfigJson, newConfigBlock, "") - jobParams.Version = "v2" - jobParams.SourceStartBlock = srcStartBlock - ccipTH.AddAllJobs(t, jobParams) - committedSeqNum := uint64(0) - // Now the requests should be delivered - for i := startSeq; i <= endSeqNum; i++ { - t.Logf("verifying seqnum %d", i) - ccipTH.AllNodesHaveReqSeqNum(t, i) - if committedSeqNum < uint64(i+1) { - committedSeqNum = ccipTH.EventuallyReportCommitted(t, i) - } - ccipTH.EventuallyExecutionStateChangedToSuccess(t, []uint64{uint64(i)}, uint64(newConfigBlock)) - } - - // nonces should be correctly synced from v1 contracts for the sender - nonceAtOnRampV2, err := ccipTH.Source.OnRamp.GetSenderNonce(nil, ccipTH.Source.User.From) - require.NoError(t, err, "getting nonce from onRamp") - nonceAtOffRampV2, err := ccipTH.Dest.OffRamp.GetSenderNonce(nil, ccipTH.Source.User.From) - require.NoError(t, err, "getting nonce from offRamp") - require.Equal(t, nonceAtOnRampV1+uint64(noOfRequests)+1, nonceAtOnRampV2, "nonce should be synced from v1 onRamps") - require.Equal(t, nonceAtOffRampV1+uint64(noOfRequests)+1, nonceAtOffRampV2, "nonce should be synced from v1 offRamps") - currentSeqNum = endSeqNum + 1 - }) - - t.Run("pay nops", func(t *testing.T) { - linkToTransferToOnRamp := big.NewInt(1e18) - - // transfer some link to onramp to pay the nops - _, err := ccipTH.Source.LinkToken.Transfer(ccipTH.Source.User, ccipTH.Source.OnRamp.Address(), linkToTransferToOnRamp) - require.NoError(t, err) - ccipTH.Source.Chain.Commit() - - srcBalReq := []testhelpers.BalanceReq{ - { - Name: testhelpers.Sender, - Addr: ccipTH.Source.User.From, - Getter: ccipTH.GetSourceWrappedTokenBalance, - }, - { - Name: testhelpers.OnRampNative, - Addr: ccipTH.Source.OnRamp.Address(), - Getter: ccipTH.GetSourceWrappedTokenBalance, - }, - { - Name: testhelpers.OnRamp, - Addr: ccipTH.Source.OnRamp.Address(), - Getter: ccipTH.GetSourceLinkBalance, - }, - { - Name: testhelpers.SourceRouter, - Addr: ccipTH.Source.Router.Address(), - Getter: ccipTH.GetSourceWrappedTokenBalance, - }, - } - - var nopsAndWeights []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight - var totalWeight uint16 - nodes := ccipTH.Nodes - for i := range nodes { - // For now set the transmitter addresses to be the same as the payee addresses - nodes[i].PaymentReceiver = nodes[i].Transmitter - nopsAndWeights = append(nopsAndWeights, evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight{ - Nop: nodes[i].PaymentReceiver, - Weight: 5, - }) - totalWeight += 5 - srcBalReq = append(srcBalReq, testhelpers.BalanceReq{ - Name: fmt.Sprintf("node %d", i), - Addr: nodes[i].PaymentReceiver, - Getter: ccipTH.GetSourceLinkBalance, - }) - } - srcBalances, err := testhelpers.GetBalances(t, srcBalReq) - require.NoError(t, err) - - // set nops on the onramp - ccipTH.SetNopsOnRamp(t, nopsAndWeights) - - // send a message - extraArgs, err := testhelpers.GetEVMExtraArgsV1(big.NewInt(200_000), true) - require.NoError(t, err) - - // FeeToken is empty, indicating it should use native token - msg := router.ClientEVM2AnyMessage{ - Receiver: testhelpers.MustEncodeAddress(t, ccipTH.Dest.Receivers[1].Receiver.Address()), - Data: []byte("hello"), - TokenAmounts: []router.ClientEVMTokenAmount{}, - ExtraArgs: extraArgs, - FeeToken: common.Address{}, - } - fee, err := ccipTH.Source.Router.GetFee(nil, testhelpers.DestChainSelector, msg) - require.NoError(t, err) - - // verify message is sent - ccipTH.Source.User.Value = fee - ccipTH.SendRequest(t, msg) - ccipTH.Source.User.Value = nil - ccipTH.AllNodesHaveReqSeqNum(t, currentSeqNum) - ccipTH.EventuallyReportCommitted(t, currentSeqNum) - - executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum) - assert.Len(t, executionLogs, 1) - ccipTH.AssertExecState(t, executionLogs[0], testhelpers.ExecutionStateSuccess) - currentSeqNum++ - - // get the nop fee - nopFee, err := ccipTH.Source.OnRamp.GetNopFeesJuels(nil) - require.NoError(t, err) - t.Log("nopFee", nopFee) - - // withdraw fees and verify there is still fund left for nop payment - _, err = ccipTH.Source.OnRamp.WithdrawNonLinkFees( - ccipTH.Source.User, - ccipTH.Source.WrappedNative.Address(), - ccipTH.Source.User.From, - ) - require.NoError(t, err) - ccipTH.Source.Chain.Commit() - - // pay nops - _, err = ccipTH.Source.OnRamp.PayNops(ccipTH.Source.User) - require.NoError(t, err) - ccipTH.Source.Chain.Commit() - - srcBalanceAssertions := []testhelpers.BalanceAssertion{ - { - // Onramp should not have any balance left in wrapped native - Name: testhelpers.OnRampNative, - Address: ccipTH.Source.OnRamp.Address(), - Expected: big.NewInt(0).String(), - Getter: ccipTH.GetSourceWrappedTokenBalance, - }, - { - // Onramp should have the remaining link after paying nops - Name: testhelpers.OnRamp, - Address: ccipTH.Source.OnRamp.Address(), - Expected: new(big.Int).Sub(srcBalances[testhelpers.OnRamp], nopFee).String(), - Getter: ccipTH.GetSourceLinkBalance, - }, - { - Name: testhelpers.SourceRouter, - Address: ccipTH.Source.Router.Address(), - Expected: srcBalances[testhelpers.SourceRouter].String(), - Getter: ccipTH.GetSourceWrappedTokenBalance, - }, - // onRamp's balance (of previously sent fee during message sending) should have been transferred to - // the owner as a result of WithdrawNonLinkFees - { - Name: testhelpers.Sender, - Address: ccipTH.Source.User.From, - Expected: fee.String(), - Getter: ccipTH.GetSourceWrappedTokenBalance, - }, - } - - // the nodes should be paid according to the weights assigned - for i, node := range nodes { - paymentWeight := float64(nopsAndWeights[i].Weight) / float64(totalWeight) - paidInFloat := paymentWeight * float64(nopFee.Int64()) - paid, _ := new(big.Float).SetFloat64(paidInFloat).Int64() - bal := new(big.Int).Add( - new(big.Int).SetInt64(paid), - srcBalances[fmt.Sprintf("node %d", i)]).String() - srcBalanceAssertions = append(srcBalanceAssertions, testhelpers.BalanceAssertion{ - Name: fmt.Sprintf("node %d", i), - Address: node.PaymentReceiver, - Expected: bal, - Getter: ccipTH.GetSourceLinkBalance, - }) - } - ccipTH.AssertBalances(t, srcBalanceAssertions) - }) - - // Keep on sending a bunch of messages - // In the meantime update onchainConfig with new price registry address - // Verify if the jobs can pick up updated config - // Verify if all the messages are sent - t.Run("config change or price registry update while requests are inflight", func(t *testing.T) { - gasLimit := big.NewInt(200_003) // prime number - tokenAmount := big.NewInt(100) - msgWg := &sync.WaitGroup{} - msgWg.Add(1) - ticker := time.NewTicker(100 * time.Millisecond) - defer ticker.Stop() - startSeq := currentSeqNum - endSeq := currentSeqNum + 20 - - // send message with the old configs - ccipTH.SendMessage(t, gasLimit, tokenAmount, ccipTH.Dest.Receivers[0].Receiver.Address()) - ccipTH.Source.Chain.Commit() - - go func(ccipContracts testhelpers.CCIPContracts, currentSeqNum int) { - seqNumber := currentSeqNum + 1 - defer msgWg.Done() - for { - <-ticker.C // wait for ticker - t.Logf("sending request for seqnum %d", seqNumber) - ccipContracts.SendMessage(t, gasLimit, tokenAmount, ccipTH.Dest.Receivers[0].Receiver.Address()) - ccipContracts.Source.Chain.Commit() - seqNumber++ - if seqNumber == endSeq { - return - } - } - }(ccipTH.CCIPContracts, currentSeqNum) - - ccipTH.DeployNewPriceRegistry(t) - commitOnchainConfig := ccipTH.CreateDefaultCommitOnchainConfig(t) - commitOffchainConfig := ccipTH.CreateDefaultCommitOffchainConfig(t) - execOnchainConfig := ccipTH.CreateDefaultExecOnchainConfig(t) - execOffchainConfig := ccipTH.CreateDefaultExecOffchainConfig(t) - - ccipTH.SetupOnchainConfig(t, commitOnchainConfig, commitOffchainConfig, execOnchainConfig, execOffchainConfig) - - // wait for all requests to be complete - msgWg.Wait() - for i := startSeq; i < endSeq; i++ { - ccipTH.AllNodesHaveReqSeqNum(t, i) - ccipTH.EventuallyReportCommitted(t, i) - - executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, i, i) - assert.Len(t, executionLogs, 1) - ccipTH.AssertExecState(t, executionLogs[0], testhelpers.ExecutionStateSuccess) - } - - for i, node := range ccipTH.Nodes { - t.Logf("verifying node %d", i) - node.EventuallyNodeUsesNewCommitConfig(t, ccipTH, ccipdata.CommitOnchainConfig{ - PriceRegistry: ccipTH.Dest.PriceRegistry.Address(), - }) - node.EventuallyNodeUsesNewExecConfig(t, ccipTH, v1_2_0.ExecOnchainConfig{ - PermissionLessExecutionThresholdSeconds: testhelpers.PermissionLessExecutionThresholdSeconds, - Router: ccipTH.Dest.Router.Address(), - PriceRegistry: ccipTH.Dest.PriceRegistry.Address(), - MaxDataBytes: 1e5, - MaxNumberOfTokensPerMsg: 5, - MaxPoolReleaseOrMintGas: 200_000, - }) - node.EventuallyNodeUsesUpdatedPriceRegistry(t, ccipTH) - } - currentSeqNum = endSeq - }) - }) - } -} diff --git a/core/services/ocr2/plugins/ccip/integration_test.go b/core/services/ocr2/plugins/ccip/integration_test.go index e644a3e6f4a..15934a261c5 100644 --- a/core/services/ocr2/plugins/ccip/integration_test.go +++ b/core/services/ocr2/plugins/ccip/integration_test.go @@ -29,6 +29,8 @@ import ( ) func TestIntegration_CCIP(t *testing.T) { + t.Skip("racey test, need to sync backend.Commit() calls") + // Run tke batches of tests for both pipeline and dynamic price getter setups. // We will remove the pipeline batch once the feature is deleted from the code. tests := []struct { From 7b7815e9746562f6def8a2306f2a15572242f52c Mon Sep 17 00:00:00 2001 From: Matthew Pendrey Date: Mon, 9 Dec 2024 17:16:02 +0000 Subject: [PATCH 10/29] evm implementation of contract reader query keys API (#15336) * evm implementation of query keys api * lint * test fix * review --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- core/services/relay/evm/chain_reader.go | 36 +++ .../evm/evmtesting/bindings_test_adapter.go | 7 + core/services/relay/evm/read/errors.go | 52 +++++ .../services/relay/evm/read/multieventtype.go | 216 ++++++++++++++++++ .../relay/evm/read/multieventtype_test.go | 119 ++++++++++ deployment/go.mod | 2 +- deployment/go.sum | 4 +- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 15 files changed, 445 insertions(+), 15 deletions(-) create mode 100644 core/services/relay/evm/read/multieventtype.go create mode 100644 core/services/relay/evm/read/multieventtype_test.go diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 8f9e458b8e2..8f57442c8a1 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -26,7 +26,7 @@ require ( github.com/prometheus/client_golang v1.20.5 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v0.8.1 - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241209151352-70300ddcc776 github.com/smartcontractkit/chainlink/deployment v0.0.0-00010101000000-000000000000 github.com/smartcontractkit/chainlink/v2 v2.14.0-mercury-20240807.0.20241106193309-5560cd76211a github.com/smartcontractkit/libocr v0.0.0-20241007185508-adbe57025f12 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 3b8c5987c00..2a777f569b1 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1142,8 +1142,8 @@ github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgB github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e h1:GnM6ZWV6vlk2+n6c6o+v/R1LtXzBGVVx7r37nt/h6Uc= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e/go.mod h1:80vGBbOfertJig0xFKsRfm+i17FkjdKkk1dAaGE45Os= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f h1:hH+cAG2zt+WK4I2m572LXAnAJg3wtGEAwzBKR8FiXo8= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241209151352-70300ddcc776 h1:NATQA1LfrEPXCdtEed9/G4SxaVuF8EZp5O2ucOK5C98= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241209151352-70300ddcc776/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e/go.mod h1:mUh5/woemsVaHgTorA080hrYmO3syBCmPdnWc/5dOqk= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db h1:N1RH1hSr2ACzOFc9hkCcjE8pRBTdcU3p8nsTJByaLes= diff --git a/core/services/relay/evm/chain_reader.go b/core/services/relay/evm/chain_reader.go index 4de739a44b4..99be89eae17 100644 --- a/core/services/relay/evm/chain_reader.go +++ b/core/services/relay/evm/chain_reader.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "iter" "maps" "slices" "strings" @@ -298,6 +299,41 @@ func (cr *chainReader) QueryKey( return sequenceOfValues, nil } +func (cr *chainReader) QueryKeys(ctx context.Context, filters []commontypes.ContractKeyFilter, + limitAndSort query.LimitAndSort) (iter.Seq2[string, commontypes.Sequence], error) { + eventQueries := make([]read.EventQuery, 0, len(filters)) + for _, filter := range filters { + binding, address, err := cr.bindings.GetReader(filter.Contract.ReadIdentifier(filter.KeyFilter.Key)) + if err != nil { + return nil, err + } + + sequenceDataType := filter.SequenceDataType + _, isValuePtr := filter.SequenceDataType.(*values.Value) + if isValuePtr { + sequenceDataType, err = cr.CreateContractType(filter.Contract.ReadIdentifier(filter.Key), false) + if err != nil { + return nil, err + } + } + + eventBinding, ok := binding.(*read.EventBinding) + if !ok { + return nil, fmt.Errorf("query key %s is not an event", filter.KeyFilter.Key) + } + + eventQueries = append(eventQueries, read.EventQuery{ + Filter: filter.KeyFilter, + SequenceDataType: sequenceDataType, + IsValuePtr: isValuePtr, + EventBinding: eventBinding, + Address: common.HexToAddress(address), + }) + } + + return read.MultiEventTypeQuery(ctx, cr.lp, eventQueries, limitAndSort) +} + func (cr *chainReader) CreateContractType(readIdentifier string, forEncoding bool) (any, error) { return cr.codec.CreateType(cr.bindings.ReadTypeIdentifier(readIdentifier, forEncoding), forEncoding) } diff --git a/core/services/relay/evm/evmtesting/bindings_test_adapter.go b/core/services/relay/evm/evmtesting/bindings_test_adapter.go index 6c391aa0a7f..408acb0d5a8 100644 --- a/core/services/relay/evm/evmtesting/bindings_test_adapter.go +++ b/core/services/relay/evm/evmtesting/bindings_test_adapter.go @@ -36,6 +36,8 @@ func WrapContractReaderTesterWithBindings(t *testing.T, wrapped *EVMChainCompone interfacetests.ContractReaderBatchGetLatestValueSetsErrorsProperly, interfacetests.ContractReaderBatchGetLatestValueNoArgumentsWithSliceReturn, interfacetests.ContractReaderBatchGetLatestValueWithModifiersOwnMapstructureOverride, interfacetests.ContractReaderQueryKeyNotFound, interfacetests.ContractReaderQueryKeyReturnsData, interfacetests.ContractReaderQueryKeyReturnsDataAsValuesDotValue, interfacetests.ContractReaderQueryKeyReturnsDataAsValuesDotValue, interfacetests.ContractReaderQueryKeyCanFilterWithValueComparator, interfacetests.ContractReaderQueryKeyCanLimitResultsWithCursor, + interfacetests.ContractReaderQueryKeysNotFound, interfacetests.ContractReaderQueryKeysReturnsData, interfacetests.ContractReaderQueryKeysReturnsDataTwoEventTypes, interfacetests.ContractReaderQueryKeysReturnsDataAsValuesDotValue, + interfacetests.ContractReaderQueryKeysCanFilterWithValueComparator, interfacetests.ContractReaderQueryKeysCanLimitResultsWithCursor, ContractReaderQueryKeyFilterOnDataWordsWithValueComparator, ContractReaderQueryKeyOnDataWordsWithValueComparatorOnNestedField, ContractReaderQueryKeyFilterOnDataWordsWithValueComparatorOnDynamicField, ContractReaderQueryKeyFilteringOnDataWordsUsingValueComparatorsOnFieldsWithManualIndex, // TODO BCFR-1073 - Fix flaky tests @@ -71,6 +73,7 @@ func newBindingsMapping() bindingsMapping { interfacetests.MethodSettingStruct: "AddTestStruct", interfacetests.MethodSettingUint64: "SetAlterablePrimitiveValue", interfacetests.MethodTriggeringEvent: "TriggerEvent", + interfacetests.MethodTriggeringEventWithDynamicTopic: "TriggerEventWithDynamicTopic", } methodNameMappingByContract[interfacetests.AnySecondContractName] = map[string]string{ interfacetests.MethodReturningUint64: "GetDifferentPrimitiveValue", @@ -249,6 +252,10 @@ func (b bindingChainWriterProxy) SubmitTransaction(ctx context.Context, contract bindingsInput := bindings.TriggerEventInput{} _ = convertStruct(args, &bindingsInput) return chainReaderTesters.TriggerEvent(ctx, bindingsInput, transactionID, toAddress, meta) + case interfacetests.MethodTriggeringEventWithDynamicTopic: + bindingsInput := bindings.TriggerEventWithDynamicTopicInput{} + _ = convertStruct(args, &bindingsInput) + return chainReaderTesters.TriggerEventWithDynamicTopic(ctx, bindingsInput, transactionID, toAddress, meta) default: return errors.New("No logic implemented for method: " + method) } diff --git a/core/services/relay/evm/read/errors.go b/core/services/relay/evm/read/errors.go index 422b7ded1d8..e767da495e7 100644 --- a/core/services/relay/evm/read/errors.go +++ b/core/services/relay/evm/read/errors.go @@ -75,6 +75,58 @@ func (e Error) Unwrap() error { return e.Err } +type MultiCallError struct { + Err error + Type readType + Detail *callsReadDetail + Result *string +} + +type callsReadDetail struct { + Calls []Call + Block string +} + +func newErrorFromCalls(err error, calls []Call, block string, tp readType) MultiCallError { + return MultiCallError{ + Err: err, + Type: tp, + Detail: &callsReadDetail{ + Calls: calls, + Block: block, + }, + } +} + +func (e MultiCallError) Error() string { + var builder strings.Builder + + builder.WriteString("[read error]") + builder.WriteString(fmt.Sprintf(" err: %s;", e.Err.Error())) + builder.WriteString(fmt.Sprintf(" type: %s;", e.Type)) + + if e.Detail != nil { + builder.WriteString(fmt.Sprintf(" block: %s;", e.Detail.Block)) + for _, call := range e.Detail.Calls { + builder.WriteString(fmt.Sprintf(" address: %s;", call.ContractAddress.Hex())) + builder.WriteString(fmt.Sprintf(" contract-name: %s;", call.ContractName)) + builder.WriteString(fmt.Sprintf(" read-name: %s;", call.ReadName)) + builder.WriteString(fmt.Sprintf(" params: %+v;", call.Params)) + builder.WriteString(fmt.Sprintf(" expected return type: %s;", reflect.TypeOf(call.ReturnVal))) + } + + if e.Result != nil { + builder.WriteString(fmt.Sprintf("encoded result: %s;", *e.Result)) + } + } + + return builder.String() +} + +func (e MultiCallError) Unwrap() error { + return e.Err +} + type ConfigError struct { Msg string } diff --git a/core/services/relay/evm/read/multieventtype.go b/core/services/relay/evm/read/multieventtype.go new file mode 100644 index 00000000000..1b561912d18 --- /dev/null +++ b/core/services/relay/evm/read/multieventtype.go @@ -0,0 +1,216 @@ +package read + +import ( + "context" + "errors" + "fmt" + "iter" + "reflect" + "sort" + "strconv" + "strings" + + "github.com/ethereum/go-ethereum/common" + + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/query" + "github.com/smartcontractkit/chainlink-common/pkg/values" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" +) + +type EventQuery struct { + Filter query.KeyFilter + EventBinding *EventBinding + SequenceDataType any + IsValuePtr bool + Address common.Address +} + +func MultiEventTypeQuery(ctx context.Context, lp logpoller.LogPoller, eventQueries []EventQuery, limitAndSort query.LimitAndSort) (iter.Seq2[string, commontypes.Sequence], error) { + seqIter, err := multiEventTypeQueryWithoutErrorWrapping(ctx, lp, eventQueries, limitAndSort) + if err != nil { + if len(eventQueries) > 0 { + var calls []Call + for _, eq := range eventQueries { + calls = append(calls, Call{ + ContractAddress: eq.Address, + ContractName: eq.EventBinding.contractName, + ReadName: eq.EventBinding.eventName, + ReturnVal: eq.SequenceDataType, + }) + } + + err = newErrorFromCalls(err, calls, "", eventReadType) + } else { + err = fmt.Errorf("no event queries provided: %w", err) + } + } + + return seqIter, err +} + +func multiEventTypeQueryWithoutErrorWrapping(ctx context.Context, lp logpoller.LogPoller, eventQueries []EventQuery, limitAndSort query.LimitAndSort) (iter.Seq2[string, commontypes.Sequence], error) { + if err := validateEventQueries(eventQueries); err != nil { + return nil, fmt.Errorf("error validating event queries: %w", err) + } + + for _, eq := range eventQueries { + if err := eq.EventBinding.validateBound(eq.Address); err != nil { + return nil, err + } + } + + allFilterExpressions := make([]query.Expression, 0, len(eventQueries)) + for _, eq := range eventQueries { + var expressions []query.Expression + + defaultExpressions := []query.Expression{ + logpoller.NewAddressFilter(eq.Address), + logpoller.NewEventSigFilter(eq.EventBinding.hash), + } + expressions = append(expressions, defaultExpressions...) + + remapped, remapErr := eq.EventBinding.remap(eq.Filter) + if remapErr != nil { + return nil, fmt.Errorf("error remapping filter: %w", remapErr) + } + expressions = append(expressions, remapped.Expressions...) + + filterExpression := query.And(expressions...) + + allFilterExpressions = append(allFilterExpressions, filterExpression) + } + + eventQuery := query.Or(allFilterExpressions...) + + queryName := createQueryName(eventQueries) + + logs, err := lp.FilteredLogs(ctx, []query.Expression{eventQuery}, limitAndSort, queryName) + if err != nil { + return nil, wrapInternalErr(err) + } + + seqIter, err := decodeMultiEventTypeLogsIntoSequences(ctx, logs, eventQueries) + if err != nil { + return nil, wrapInternalErr(err) + } + + return seqIter, nil +} + +func createQueryName(eventQueries []EventQuery) string { + queryName := "" + contractToEvents := map[string][]string{} + for _, eq := range eventQueries { + contractName := eq.EventBinding.contractName + "-" + eq.Address.String() + + if _, exists := contractToEvents[contractName]; !exists { + contractToEvents[contractName] = []string{} + } + contractToEvents[contractName] = append(contractToEvents[contractName], eq.EventBinding.eventName) + } + + contractNames := make([]string, 0, len(contractToEvents)) + for contractName := range contractToEvents { + contractNames = append(contractNames, contractName) + } + + sort.Strings(contractNames) + + for _, contractName := range contractNames { + queryName += contractName + "-" + for _, event := range contractToEvents[contractName] { + queryName += event + "-" + } + } + + queryName = strings.TrimSuffix(queryName, "-") + return queryName +} + +func validateEventQueries(eventQueries []EventQuery) error { + duplicateCheck := map[common.Hash]EventQuery{} + for _, eq := range eventQueries { + if eq.EventBinding == nil { + return errors.New("event binding is nil") + } + + if eq.SequenceDataType == nil { + return errors.New("sequence data type is nil") + } + + // TODO support queries with the same event signature but different filters + if _, exists := duplicateCheck[eq.EventBinding.hash]; exists { + return fmt.Errorf("duplicate event query for event signature %s, event name %s", eq.EventBinding.hash, eq.EventBinding.eventName) + } + duplicateCheck[eq.EventBinding.hash] = eq + } + return nil +} + +func decodeMultiEventTypeLogsIntoSequences(ctx context.Context, logs []logpoller.Log, eventQueries []EventQuery) (iter.Seq2[string, commontypes.Sequence], error) { + type sequenceWithKey struct { + Key string + Sequence commontypes.Sequence + } + sequenceWithKeys := make([]sequenceWithKey, 0, len(logs)) + eventSigToEventQuery := map[common.Hash]EventQuery{} + for _, eq := range eventQueries { + eventSigToEventQuery[eq.EventBinding.hash] = eq + } + + for _, logEntry := range logs { + eventSignatureHash := logEntry.EventSig + + eq, exists := eventSigToEventQuery[eventSignatureHash] + if !exists { + return nil, fmt.Errorf("no event query found for log with event signature %s", eventSignatureHash) + } + + seqWithKey := sequenceWithKey{ + Key: eq.Filter.Key, + Sequence: commontypes.Sequence{ + Cursor: logpoller.FormatContractReaderCursor(logEntry), + Head: commontypes.Head{ + Height: strconv.FormatInt(logEntry.BlockNumber, 10), + Hash: logEntry.BlockHash.Bytes(), + Timestamp: uint64(logEntry.BlockTimestamp.Unix()), //nolint:gosec // G115 false positive + }, + }, + } + + var typeVal reflect.Value + + typeInto := reflect.TypeOf(eq.SequenceDataType) + if typeInto.Kind() == reflect.Pointer { + typeVal = reflect.New(typeInto.Elem()) + } else { + typeVal = reflect.Indirect(reflect.New(typeInto)) + } + + // create a new value of the same type as 'into' for the data to be extracted to + seqWithKey.Sequence.Data = typeVal.Interface() + + if err := eq.EventBinding.decodeLog(ctx, &logEntry, seqWithKey.Sequence.Data); err != nil { + return nil, err + } + + if eq.IsValuePtr { + wrappedValue, err := values.Wrap(seqWithKey.Sequence.Data) + if err != nil { + return nil, err + } + seqWithKey.Sequence.Data = &wrappedValue + } + + sequenceWithKeys = append(sequenceWithKeys, seqWithKey) + } + + return func(yield func(string, commontypes.Sequence) bool) { + for _, s := range sequenceWithKeys { + if !yield(s.Key, s.Sequence) { + return + } + } + }, nil +} diff --git a/core/services/relay/evm/read/multieventtype_test.go b/core/services/relay/evm/read/multieventtype_test.go new file mode 100644 index 00000000000..8fb39ecc526 --- /dev/null +++ b/core/services/relay/evm/read/multieventtype_test.go @@ -0,0 +1,119 @@ +package read + +import ( + "github.com/ethereum/go-ethereum/common" + + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink-common/pkg/types/query" +) + +func TestCreateQueryName(t *testing.T) { + eventQueries := []EventQuery{ + { + Filter: query.KeyFilter{Key: "key1"}, + EventBinding: &EventBinding{ + contractName: "ContractA", + eventName: "EventA", + hash: common.HexToHash("0x1"), + }, + SequenceDataType: "dataType1", + Address: common.HexToAddress("0x123"), + }, + { + Filter: query.KeyFilter{Key: "key2"}, + EventBinding: &EventBinding{ + contractName: "ContractB", + eventName: "EventB", + hash: common.HexToHash("0x2"), + }, + SequenceDataType: "dataType2", + Address: common.HexToAddress("0x456"), + }, + { + Filter: query.KeyFilter{Key: "key1"}, + EventBinding: &EventBinding{ + contractName: "ContractA", + eventName: "EventA1", + hash: common.HexToHash("0x1"), + }, + SequenceDataType: "dataType1", + Address: common.HexToAddress("0x123"), + }, + } + + expectedQueryName := "ContractA-0x0000000000000000000000000000000000000123-EventA-EventA1-ContractB-0x0000000000000000000000000000000000000456-EventB" + queryName := createQueryName(eventQueries) + + assert.Equal(t, expectedQueryName, queryName) +} + +func TestValidateEventQueries(t *testing.T) { + tests := []struct { + name string + eventQueries []EventQuery + expectedError string + }{ + { + name: "valid event queries", + eventQueries: []EventQuery{ + { + EventBinding: &EventBinding{hash: common.HexToHash("0x1")}, + SequenceDataType: "dataType1", + }, + { + EventBinding: &EventBinding{hash: common.HexToHash("0x2")}, + SequenceDataType: "dataType2", + }, + }, + expectedError: "", + }, + { + name: "nil event binding", + eventQueries: []EventQuery{ + { + EventBinding: nil, + SequenceDataType: "dataType1", + }, + }, + expectedError: "event binding is nil", + }, + { + name: "nil sequence data type", + eventQueries: []EventQuery{ + { + EventBinding: &EventBinding{hash: common.HexToHash("0x1")}, + SequenceDataType: nil, + }, + }, + expectedError: "sequence data type is nil", + }, + { + name: "duplicate event query", + eventQueries: []EventQuery{ + { + EventBinding: &EventBinding{hash: common.HexToHash("0x1")}, + SequenceDataType: "dataType1", + }, + { + EventBinding: &EventBinding{hash: common.HexToHash("0x1")}, + SequenceDataType: "dataType2", + }, + }, + expectedError: "duplicate event query for event signature 0x0000000000000000000000000000000000000000000000000000000000000001, event name ", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := validateEventQueries(tt.eventQueries) + if tt.expectedError == "" { + assert.NoError(t, err) + } else { + assert.EqualError(t, err, tt.expectedError) + } + }) + } +} diff --git a/deployment/go.mod b/deployment/go.mod index b9a2fdb255f..058df5d2a29 100644 --- a/deployment/go.mod +++ b/deployment/go.mod @@ -25,7 +25,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 github.com/smartcontractkit/chain-selectors v1.0.34 github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241209151352-70300ddcc776 github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.13 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/deployment/go.sum b/deployment/go.sum index 7513309dddf..00e0aab077b 100644 --- a/deployment/go.sum +++ b/deployment/go.sum @@ -1411,8 +1411,8 @@ github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgB github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e h1:GnM6ZWV6vlk2+n6c6o+v/R1LtXzBGVVx7r37nt/h6Uc= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e/go.mod h1:80vGBbOfertJig0xFKsRfm+i17FkjdKkk1dAaGE45Os= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f h1:hH+cAG2zt+WK4I2m572LXAnAJg3wtGEAwzBKR8FiXo8= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241209151352-70300ddcc776 h1:NATQA1LfrEPXCdtEed9/G4SxaVuF8EZp5O2ucOK5C98= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241209151352-70300ddcc776/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e/go.mod h1:mUh5/woemsVaHgTorA080hrYmO3syBCmPdnWc/5dOqk= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db h1:N1RH1hSr2ACzOFc9hkCcjE8pRBTdcU3p8nsTJByaLes= diff --git a/go.mod b/go.mod index 35069d38bbf..2dd7d3fcfe5 100644 --- a/go.mod +++ b/go.mod @@ -79,7 +79,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.34 github.com/smartcontractkit/chainlink-automation v0.8.1 github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241209151352-70300ddcc776 github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db github.com/smartcontractkit/chainlink-feeds v0.1.1 diff --git a/go.sum b/go.sum index caa877d66fa..b8941bc7d01 100644 --- a/go.sum +++ b/go.sum @@ -1125,8 +1125,8 @@ github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgB github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e h1:GnM6ZWV6vlk2+n6c6o+v/R1LtXzBGVVx7r37nt/h6Uc= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e/go.mod h1:80vGBbOfertJig0xFKsRfm+i17FkjdKkk1dAaGE45Os= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f h1:hH+cAG2zt+WK4I2m572LXAnAJg3wtGEAwzBKR8FiXo8= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241209151352-70300ddcc776 h1:NATQA1LfrEPXCdtEed9/G4SxaVuF8EZp5O2ucOK5C98= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241209151352-70300ddcc776/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e/go.mod h1:mUh5/woemsVaHgTorA080hrYmO3syBCmPdnWc/5dOqk= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db h1:N1RH1hSr2ACzOFc9hkCcjE8pRBTdcU3p8nsTJByaLes= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index f4e6a9720e8..58b2a6fa1c4 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -41,7 +41,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.34 github.com/smartcontractkit/chainlink-automation v0.8.1 github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241209151352-70300ddcc776 github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.2 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.18 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 9e0e176190d..4f31dd61871 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1432,8 +1432,8 @@ github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgB github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e h1:GnM6ZWV6vlk2+n6c6o+v/R1LtXzBGVVx7r37nt/h6Uc= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e/go.mod h1:80vGBbOfertJig0xFKsRfm+i17FkjdKkk1dAaGE45Os= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f h1:hH+cAG2zt+WK4I2m572LXAnAJg3wtGEAwzBKR8FiXo8= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241209151352-70300ddcc776 h1:NATQA1LfrEPXCdtEed9/G4SxaVuF8EZp5O2ucOK5C98= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241209151352-70300ddcc776/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e/go.mod h1:mUh5/woemsVaHgTorA080hrYmO3syBCmPdnWc/5dOqk= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db h1:N1RH1hSr2ACzOFc9hkCcjE8pRBTdcU3p8nsTJByaLes= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 23f840a67f3..47b128c7f60 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -19,7 +19,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.15.0 - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241209151352-70300ddcc776 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.18 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.9 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.2 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index e9eaaf81dad..59a4e9e64ad 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1423,8 +1423,8 @@ github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgB github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e h1:GnM6ZWV6vlk2+n6c6o+v/R1LtXzBGVVx7r37nt/h6Uc= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e/go.mod h1:80vGBbOfertJig0xFKsRfm+i17FkjdKkk1dAaGE45Os= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f h1:hH+cAG2zt+WK4I2m572LXAnAJg3wtGEAwzBKR8FiXo8= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241209151352-70300ddcc776 h1:NATQA1LfrEPXCdtEed9/G4SxaVuF8EZp5O2ucOK5C98= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241209151352-70300ddcc776/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e/go.mod h1:mUh5/woemsVaHgTorA080hrYmO3syBCmPdnWc/5dOqk= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db h1:N1RH1hSr2ACzOFc9hkCcjE8pRBTdcU3p8nsTJByaLes= From a7074338e708ee79b9a8d5baa2223b84ccc70347 Mon Sep 17 00:00:00 2001 From: Makram Date: Mon, 9 Dec 2024 20:01:08 +0200 Subject: [PATCH 11/29] core/services/ocr2/plugins/ccip: fix racey TestIntegration_CCIP (#15572) Wrap simulated backend with an object that synchronizes Commit() calls --- .../ocr2/plugins/ccip/integration_test.go | 2 - .../ccip/testhelpers/ccip_contracts.go | 28 +- .../ccip/testhelpers/integration/chainlink.go | 3 +- .../ccip/testhelpers/simulated_backend.go | 2 +- .../testhelpers_1_4_0/ccip_contracts_1_4_0.go | 1620 ----------------- .../testhelpers_1_4_0/chainlink.go | 1053 ----------- .../testhelpers_1_4_0/config_1_4_0.go | 75 - .../ccip-tests/contracts/contract_deployer.go | 31 - 8 files changed, 27 insertions(+), 2787 deletions(-) delete mode 100644 core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go delete mode 100644 core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go delete mode 100644 core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/config_1_4_0.go diff --git a/core/services/ocr2/plugins/ccip/integration_test.go b/core/services/ocr2/plugins/ccip/integration_test.go index 15934a261c5..e644a3e6f4a 100644 --- a/core/services/ocr2/plugins/ccip/integration_test.go +++ b/core/services/ocr2/plugins/ccip/integration_test.go @@ -29,8 +29,6 @@ import ( ) func TestIntegration_CCIP(t *testing.T) { - t.Skip("racey test, need to sync backend.Commit() calls") - // Run tke batches of tests for both pipeline and dynamic price getter setups. // We will remove the pipeline batch once the feature is deleted from the code. tests := []struct { diff --git a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go index 6a220ececf7..c2fec2903e8 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go @@ -5,6 +5,7 @@ import ( "fmt" "math" "math/big" + "sync" "testing" "time" @@ -168,11 +169,32 @@ type MaybeRevertReceiver struct { Strict bool } +// Backend wraps a simulated backend with a mutex to make it safe for concurrent use +// Commit() in particular has caused races. +type Backend struct { + mu sync.Mutex + *simulated.Backend +} + +func NewBackend(sim *simulated.Backend) *Backend { + return &Backend{ + mu: sync.Mutex{}, + Backend: sim, + } +} + +func (b *Backend) Commit() common.Hash { + b.mu.Lock() + defer b.mu.Unlock() + + return b.Backend.Commit() +} + type Common struct { ChainID uint64 ChainSelector uint64 User *bind.TransactOpts - Chain *simulated.Backend + Chain *Backend LinkToken *link_token_interface.LinkToken LinkTokenPool *lock_release_token_pool.LockReleaseTokenPool CustomToken *link_token_interface.LinkToken @@ -1194,7 +1216,7 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh ChainID: sourceChainID, ChainSelector: sourceChainSelector, User: sourceUser, - Chain: sourceChain, + Chain: NewBackend(sourceChain), LinkToken: sourceLinkToken, LinkTokenPool: sourceLinkPool, CustomToken: sourceCustomToken, @@ -1214,7 +1236,7 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh ChainID: destChainID, ChainSelector: destChainSelector, User: destUser, - Chain: destChain, + Chain: NewBackend(destChain), LinkToken: destLinkToken, LinkTokenPool: destLinkPool, CustomToken: destCustomToken, diff --git a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go index ddae5241883..d21c5b12513 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go @@ -17,7 +17,6 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" types3 "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethclient/simulated" "github.com/google/uuid" "github.com/hashicorp/consul/sdk/freeport" "github.com/jmoiron/sqlx" @@ -369,7 +368,7 @@ func setupNodeCCIP( owner *bind.TransactOpts, port int64, dbName string, - sourceChain *simulated.Backend, destChain *simulated.Backend, + sourceChain *testhelpers.Backend, destChain *testhelpers.Backend, sourceChainID *big.Int, destChainID *big.Int, bootstrapPeerID string, bootstrapPort int64, diff --git a/core/services/ocr2/plugins/ccip/testhelpers/simulated_backend.go b/core/services/ocr2/plugins/ccip/testhelpers/simulated_backend.go index 58206d37427..699af7e14dc 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/simulated_backend.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/simulated_backend.go @@ -56,7 +56,7 @@ func (ks EthKeyStoreSim) Eth() keystore.Eth { var _ keystore.Eth = EthKeyStoreSim{}.ETHKS -func ConfirmTxs(t *testing.T, txs []*ethtypes.Transaction, chain *simulated.Backend) { +func ConfirmTxs(t *testing.T, txs []*ethtypes.Transaction, chain *Backend) { chain.Commit() ctx := tests.Context(t) for _, tx := range txs { diff --git a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go deleted file mode 100644 index 5ed20875498..00000000000 --- a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go +++ /dev/null @@ -1,1620 +0,0 @@ -package testhelpers_1_4_0 - -import ( - "context" - "fmt" - "math" - "math/big" - "testing" - "time" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethclient/simulated" - "github.com/pkg/errors" - "github.com/rs/zerolog/log" - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" - ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - - "github.com/smartcontractkit/chainlink-common/pkg/config" - "github.com/smartcontractkit/chainlink-common/pkg/hashutil" - "github.com/smartcontractkit/chainlink-common/pkg/merklemulti" - cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" - - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - burn_mint_token_pool "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/burn_mint_token_pool_1_4_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_2_0" - evm_2_evm_offramp "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" - evm_2_evm_onramp "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool_1_0_0" - lock_release_token_pool "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool_1_4_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" - "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" - ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" -) - -var ( - // Source - SourcePool = "source Link pool" - SourcePriceRegistry = "source PriceRegistry" - OnRamp = "onramp" - OnRampNative = "onramp-native" - SourceRouter = "source router" - - // Dest - OffRamp = "offramp" - DestPool = "dest Link pool" - - Receiver = "receiver" - Sender = "sender" - Link = func(amount int64) *big.Int { return new(big.Int).Mul(big.NewInt(1e18), big.NewInt(amount)) } - HundredLink = Link(100) - LinkUSDValue = func(amount int64) *big.Int { return new(big.Int).Mul(big.NewInt(1e18), big.NewInt(amount)) } - SourceChainID = uint64(1000) - SourceChainSelector = uint64(11787463284727550157) - DestChainID = uint64(1337) - DestChainSelector = uint64(3379446385462418246) -) - -// Backwards compat, in principle these statuses are version dependent -// TODO: Adjust integration tests to be version agnostic using readers -var ( - ExecutionStateSuccess = MessageExecutionState(cciptypes.ExecutionStateSuccess) - ExecutionStateFailure = MessageExecutionState(cciptypes.ExecutionStateFailure) -) - -type MessageExecutionState cciptypes.MessageExecutionState -type CommitOffchainConfig struct { - v1_2_0.JSONCommitOffchainConfig -} - -func (c CommitOffchainConfig) Encode() ([]byte, error) { - return ccipconfig.EncodeOffchainConfig(c.JSONCommitOffchainConfig) -} - -func NewCommitOffchainConfig( - GasPriceHeartBeat config.Duration, - DAGasPriceDeviationPPB uint32, - ExecGasPriceDeviationPPB uint32, - TokenPriceHeartBeat config.Duration, - TokenPriceDeviationPPB uint32, - InflightCacheExpiry config.Duration, - priceReportingDisabled bool) CommitOffchainConfig { - return CommitOffchainConfig{v1_2_0.JSONCommitOffchainConfig{ - GasPriceHeartBeat: GasPriceHeartBeat, - DAGasPriceDeviationPPB: DAGasPriceDeviationPPB, - ExecGasPriceDeviationPPB: ExecGasPriceDeviationPPB, - TokenPriceHeartBeat: TokenPriceHeartBeat, - TokenPriceDeviationPPB: TokenPriceDeviationPPB, - InflightCacheExpiry: InflightCacheExpiry, - PriceReportingDisabled: priceReportingDisabled, - }} -} - -type CommitOnchainConfig struct { - ccipdata.CommitOnchainConfig -} - -func NewCommitOnchainConfig( - PriceRegistry common.Address, -) CommitOnchainConfig { - return CommitOnchainConfig{ccipdata.CommitOnchainConfig{ - PriceRegistry: PriceRegistry, - }} -} - -type ExecOnchainConfig struct { - v1_2_0.ExecOnchainConfig -} - -func NewExecOnchainConfig( - PermissionLessExecutionThresholdSeconds uint32, - Router common.Address, - PriceRegistry common.Address, - MaxNumberOfTokensPerMsg uint16, - MaxDataBytes uint32, - MaxPoolReleaseOrMintGas uint32, -) ExecOnchainConfig { - return ExecOnchainConfig{v1_2_0.ExecOnchainConfig{ - PermissionLessExecutionThresholdSeconds: PermissionLessExecutionThresholdSeconds, - Router: Router, - PriceRegistry: PriceRegistry, - MaxNumberOfTokensPerMsg: MaxNumberOfTokensPerMsg, - MaxDataBytes: MaxDataBytes, - MaxPoolReleaseOrMintGas: MaxPoolReleaseOrMintGas, - }} -} - -type ExecOffchainConfig struct { - v1_2_0.JSONExecOffchainConfig -} - -func (c ExecOffchainConfig) Encode() ([]byte, error) { - return ccipconfig.EncodeOffchainConfig(c.JSONExecOffchainConfig) -} - -func NewExecOffchainConfig( - DestOptimisticConfirmations uint32, - BatchGasLimit uint32, - RelativeBoostPerWaitHour float64, - InflightCacheExpiry config.Duration, - RootSnoozeTime config.Duration, - BatchingStrategyID uint32, -) ExecOffchainConfig { - return ExecOffchainConfig{v1_2_0.JSONExecOffchainConfig{ - DestOptimisticConfirmations: DestOptimisticConfirmations, - BatchGasLimit: BatchGasLimit, - RelativeBoostPerWaitHour: RelativeBoostPerWaitHour, - InflightCacheExpiry: InflightCacheExpiry, - RootSnoozeTime: RootSnoozeTime, - BatchingStrategyID: BatchingStrategyID, - }} -} - -type MaybeRevertReceiver struct { - Receiver *maybe_revert_message_receiver.MaybeRevertMessageReceiver - Strict bool -} - -type Common struct { - ChainID uint64 - ChainSelector uint64 - User *bind.TransactOpts - Chain *simulated.Backend - LinkToken *link_token_interface.LinkToken - LinkTokenPool *lock_release_token_pool.LockReleaseTokenPool - CustomToken *link_token_interface.LinkToken - WrappedNative *weth9.WETH9 - WrappedNativePool *lock_release_token_pool_1_0_0.LockReleaseTokenPool - ARM *mock_rmn_contract.MockRMNContract - ARMProxy *rmn_proxy_contract.RMNProxyContract - PriceRegistry *price_registry_1_2_0.PriceRegistry -} - -type SourceChain struct { - Common - Router *router.Router - OnRamp *evm_2_evm_onramp.EVM2EVMOnRamp -} - -type DestinationChain struct { - Common - - CommitStore *commit_store_1_2_0.CommitStore - Router *router.Router - OffRamp *evm_2_evm_offramp.EVM2EVMOffRamp - Receivers []MaybeRevertReceiver -} - -type OCR2Config struct { - Signers []common.Address - Transmitters []common.Address - F uint8 - OnchainConfig []byte - OffchainConfigVersion uint64 - OffchainConfig []byte -} - -type BalanceAssertion struct { - Name string - Address common.Address - Expected string - Getter func(t *testing.T, addr common.Address) *big.Int - Within string -} - -type BalanceReq struct { - Name string - Addr common.Address - Getter func(t *testing.T, addr common.Address) *big.Int -} - -type CCIPContracts struct { - Source SourceChain - Dest DestinationChain - Oracles []confighelper.OracleIdentityExtra - - commitOCRConfig, execOCRConfig *OCR2Config -} - -func (c *CCIPContracts) DeployNewOffRamp(t *testing.T) { - prevOffRamp := common.HexToAddress("") - if c.Dest.OffRamp != nil { - prevOffRamp = c.Dest.OffRamp.Address() - } - offRampAddress, _, _, err := evm_2_evm_offramp.DeployEVM2EVMOffRamp( - c.Dest.User, - c.Dest.Chain.Client(), - evm_2_evm_offramp.EVM2EVMOffRampStaticConfig{ - CommitStore: c.Dest.CommitStore.Address(), - ChainSelector: c.Dest.ChainSelector, - SourceChainSelector: c.Source.ChainSelector, - OnRamp: c.Source.OnRamp.Address(), - PrevOffRamp: prevOffRamp, - ArmProxy: c.Dest.ARMProxy.Address(), - }, - []common.Address{c.Source.LinkToken.Address()}, // source tokens - []common.Address{c.Dest.LinkTokenPool.Address()}, // pools - evm_2_evm_offramp.RateLimiterConfig{ - IsEnabled: true, - Capacity: LinkUSDValue(100), - Rate: LinkUSDValue(1), - }, - ) - require.NoError(t, err) - c.Dest.Chain.Commit() - - c.Dest.OffRamp, err = evm_2_evm_offramp.NewEVM2EVMOffRamp(offRampAddress, c.Dest.Chain.Client()) - require.NoError(t, err) - - c.Dest.Chain.Commit() - c.Source.Chain.Commit() -} - -func (c *CCIPContracts) EnableOffRamp(t *testing.T) { - _, err := c.Dest.Router.ApplyRampUpdates(c.Dest.User, nil, nil, []router.RouterOffRamp{{SourceChainSelector: SourceChainSelector, OffRamp: c.Dest.OffRamp.Address()}}) - require.NoError(t, err) - c.Dest.Chain.Commit() - - onChainConfig := c.CreateDefaultExecOnchainConfig(t) - offChainConfig := c.CreateDefaultExecOffchainConfig(t) - - c.SetupExecOCR2Config(t, onChainConfig, offChainConfig) -} - -func (c *CCIPContracts) EnableCommitStore(t *testing.T) { - onChainConfig := c.CreateDefaultCommitOnchainConfig(t) - offChainConfig := c.CreateDefaultCommitOffchainConfig(t) - - c.SetupCommitOCR2Config(t, onChainConfig, offChainConfig) - - _, err := c.Dest.PriceRegistry.ApplyPriceUpdatersUpdates(c.Dest.User, []common.Address{c.Dest.CommitStore.Address()}, []common.Address{}) - require.NoError(t, err) - c.Dest.Chain.Commit() -} - -func (c *CCIPContracts) DeployNewOnRamp(t *testing.T) { - t.Log("Deploying new onRamp") - // find the last onRamp - prevOnRamp := common.HexToAddress("") - if c.Source.OnRamp != nil { - prevOnRamp = c.Source.OnRamp.Address() - } - onRampAddress, _, _, err := evm_2_evm_onramp.DeployEVM2EVMOnRamp( - c.Source.User, // user - c.Source.Chain.Client(), // client - evm_2_evm_onramp.EVM2EVMOnRampStaticConfig{ - LinkToken: c.Source.LinkToken.Address(), - ChainSelector: c.Source.ChainSelector, - DestChainSelector: c.Dest.ChainSelector, - DefaultTxGasLimit: 200_000, - MaxNopFeesJuels: big.NewInt(0).Mul(big.NewInt(100_000_000), big.NewInt(1e18)), - PrevOnRamp: prevOnRamp, - ArmProxy: c.Source.ARM.Address(), // ARM - }, - evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{ - Router: c.Source.Router.Address(), - MaxNumberOfTokensPerMsg: 5, - DestGasOverhead: 350_000, - DestGasPerPayloadByte: 16, - DestDataAvailabilityOverheadGas: 33_596, - DestGasPerDataAvailabilityByte: 16, - DestDataAvailabilityMultiplierBps: 6840, // 0.684 - PriceRegistry: c.Source.PriceRegistry.Address(), - MaxDataBytes: 1e5, - MaxPerMsgGasLimit: 4_000_000, - }, - []evm_2_evm_onramp.InternalPoolUpdate{ - { - Token: c.Source.LinkToken.Address(), - Pool: c.Source.LinkTokenPool.Address(), - }, - }, - evm_2_evm_onramp.RateLimiterConfig{ - IsEnabled: true, - Capacity: LinkUSDValue(100), - Rate: LinkUSDValue(1), - }, - []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs{ - { - Token: c.Source.LinkToken.Address(), - NetworkFeeUSDCents: 1_00, - GasMultiplierWeiPerEth: 1e18, - PremiumMultiplierWeiPerEth: 9e17, - Enabled: true, - }, - { - Token: c.Source.WrappedNative.Address(), - NetworkFeeUSDCents: 1_00, - GasMultiplierWeiPerEth: 1e18, - PremiumMultiplierWeiPerEth: 1e18, - Enabled: true, - }, - }, - []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs{ - { - Token: c.Source.LinkToken.Address(), - MinFeeUSDCents: 50, // $0.5 - MaxFeeUSDCents: 1_000_000_00, // $ 1 million - DeciBps: 5_0, // 5 bps - DestGasOverhead: 34_000, - DestBytesOverhead: 32, - }, - }, - []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight{}, - ) - - require.NoError(t, err) - c.Source.Chain.Commit() - c.Dest.Chain.Commit() - c.Source.OnRamp, err = evm_2_evm_onramp.NewEVM2EVMOnRamp(onRampAddress, c.Source.Chain.Client()) - require.NoError(t, err) - c.Source.Chain.Commit() - c.Dest.Chain.Commit() -} - -func (c *CCIPContracts) EnableOnRamp(t *testing.T) { - t.Log("Setting onRamp on source router") - _, err := c.Source.Router.ApplyRampUpdates(c.Source.User, []router.RouterOnRamp{{DestChainSelector: c.Dest.ChainSelector, OnRamp: c.Source.OnRamp.Address()}}, nil, nil) - require.NoError(t, err) - c.Source.Chain.Commit() - c.Dest.Chain.Commit() -} - -func (c *CCIPContracts) DeployNewCommitStore(t *testing.T) { - commitStoreAddress, _, _, err := commit_store_1_2_0.DeployCommitStore( - c.Dest.User, // user - c.Dest.Chain.Client(), // client - commit_store_1_2_0.CommitStoreStaticConfig{ - ChainSelector: c.Dest.ChainSelector, - SourceChainSelector: c.Source.ChainSelector, - OnRamp: c.Source.OnRamp.Address(), - ArmProxy: c.Dest.ARMProxy.Address(), - }, - ) - require.NoError(t, err) - c.Dest.Chain.Commit() - // since CommitStoreHelper derives from CommitStore, it's safe to instantiate both on same address - c.Dest.CommitStore, err = commit_store_1_2_0.NewCommitStore(commitStoreAddress, c.Dest.Chain.Client()) - require.NoError(t, err) -} - -func (c *CCIPContracts) DeployNewPriceRegistry(t *testing.T) { - t.Log("Deploying new Price Registry") - destPricesAddress, _, _, err := price_registry_1_2_0.DeployPriceRegistry( - c.Dest.User, - c.Dest.Chain.Client(), - []common.Address{c.Dest.CommitStore.Address()}, - []common.Address{c.Dest.LinkToken.Address()}, - 60*60*24*14, // two weeks - ) - require.NoError(t, err) - c.Source.Chain.Commit() - c.Dest.Chain.Commit() - c.Dest.PriceRegistry, err = price_registry_1_2_0.NewPriceRegistry(destPricesAddress, c.Dest.Chain.Client()) - require.NoError(t, err) - - priceUpdates := price_registry_1_2_0.InternalPriceUpdates{ - TokenPriceUpdates: []price_registry_1_2_0.InternalTokenPriceUpdate{ - { - SourceToken: c.Dest.LinkToken.Address(), - UsdPerToken: big.NewInt(8e18), // 8usd - }, - { - SourceToken: c.Dest.WrappedNative.Address(), - UsdPerToken: big.NewInt(1e18), // 1usd - }, - }, - GasPriceUpdates: []price_registry_1_2_0.InternalGasPriceUpdate{ - { - DestChainSelector: c.Source.ChainSelector, - UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 - }, - }, - } - _, err = c.Dest.PriceRegistry.UpdatePrices(c.Dest.User, priceUpdates) - require.NoError(t, err) - - c.Source.Chain.Commit() - c.Dest.Chain.Commit() - - t.Logf("New Price Registry deployed at %s", destPricesAddress.String()) -} - -func (c *CCIPContracts) SetNopsOnRamp(t *testing.T, nopsAndWeights []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight) { - tx, err := c.Source.OnRamp.SetNops(c.Source.User, nopsAndWeights) - require.NoError(t, err) - c.Source.Chain.Commit() - _, err = bind.WaitMined(tests.Context(t), c.Source.Chain.Client(), tx) - require.NoError(t, err) -} - -func (c *CCIPContracts) GetSourceLinkBalance(t *testing.T, addr common.Address) *big.Int { - return GetBalance(t, c.Source.Chain.Client(), c.Source.LinkToken.Address(), addr) -} - -func (c *CCIPContracts) GetDestLinkBalance(t *testing.T, addr common.Address) *big.Int { - return GetBalance(t, c.Dest.Chain.Client(), c.Dest.LinkToken.Address(), addr) -} - -func (c *CCIPContracts) GetSourceWrappedTokenBalance(t *testing.T, addr common.Address) *big.Int { - return GetBalance(t, c.Source.Chain.Client(), c.Source.WrappedNative.Address(), addr) -} - -func (c *CCIPContracts) GetDestWrappedTokenBalance(t *testing.T, addr common.Address) *big.Int { - return GetBalance(t, c.Dest.Chain.Client(), c.Dest.WrappedNative.Address(), addr) -} - -func (c *CCIPContracts) AssertBalances(t *testing.T, bas []BalanceAssertion) { - for _, b := range bas { - actual := b.Getter(t, b.Address) - t.Log("Checking balance for", b.Name, "at", b.Address.Hex(), "got", actual) - require.NotNil(t, actual, "%v getter return nil", b.Name) - if b.Within == "" { - require.Equal(t, b.Expected, actual.String(), "wrong balance for %s got %s want %s", b.Name, actual, b.Expected) - } else { - bi, _ := big.NewInt(0).SetString(b.Expected, 10) - withinI, _ := big.NewInt(0).SetString(b.Within, 10) - high := big.NewInt(0).Add(bi, withinI) - low := big.NewInt(0).Sub(bi, withinI) - require.Equal(t, -1, actual.Cmp(high), "wrong balance for %s got %s outside expected range [%s, %s]", b.Name, actual, low, high) - require.Equal(t, 1, actual.Cmp(low), "wrong balance for %s got %s outside expected range [%s, %s]", b.Name, actual, low, high) - } - } -} - -func AccountToAddress(accounts []ocr2types.Account) (addresses []common.Address, err error) { - for _, signer := range accounts { - bytes, err := hexutil.Decode(string(signer)) - if err != nil { - return []common.Address{}, errors.Wrap(err, fmt.Sprintf("given address is not valid %s", signer)) - } - if len(bytes) != 20 { - return []common.Address{}, errors.Errorf("address is not 20 bytes %s", signer) - } - addresses = append(addresses, common.BytesToAddress(bytes)) - } - return addresses, nil -} - -func OnchainPublicKeyToAddress(publicKeys []ocrtypes.OnchainPublicKey) (addresses []common.Address, err error) { - for _, signer := range publicKeys { - if len(signer) != 20 { - return []common.Address{}, errors.Errorf("address is not 20 bytes %s", signer) - } - addresses = append(addresses, common.BytesToAddress(signer)) - } - return addresses, nil -} - -func (c *CCIPContracts) DeriveOCR2Config(t *testing.T, oracles []confighelper.OracleIdentityExtra, rawOnchainConfig []byte, rawOffchainConfig []byte) *OCR2Config { - signers, transmitters, threshold, onchainConfig, offchainConfigVersion, offchainConfig, err := confighelper.ContractSetConfigArgsForTests( - 2*time.Second, // deltaProgress - 1*time.Second, // deltaResend - 1*time.Second, // deltaRound - 500*time.Millisecond, // deltaGrace - 2*time.Second, // deltaStage - 3, - []int{1, 1, 1, 1}, - oracles, - rawOffchainConfig, - nil, - 50*time.Millisecond, // Max duration query - 1*time.Second, // Max duration observation - 100*time.Millisecond, - 100*time.Millisecond, - 100*time.Millisecond, - 1, // faults - rawOnchainConfig, - ) - require.NoError(t, err) - lggr := logger.TestLogger(t) - lggr.Infow("Setting Config on Oracle Contract", - "signers", signers, - "transmitters", transmitters, - "threshold", threshold, - "onchainConfig", onchainConfig, - "encodedConfigVersion", offchainConfigVersion, - ) - signerAddresses, err := OnchainPublicKeyToAddress(signers) - require.NoError(t, err) - transmitterAddresses, err := AccountToAddress(transmitters) - require.NoError(t, err) - - return &OCR2Config{ - Signers: signerAddresses, - Transmitters: transmitterAddresses, - F: threshold, - OnchainConfig: onchainConfig, - OffchainConfigVersion: offchainConfigVersion, - OffchainConfig: offchainConfig, - } -} - -func (c *CCIPContracts) SetupCommitOCR2Config(t *testing.T, commitOnchainConfig, commitOffchainConfig []byte) { - c.commitOCRConfig = c.DeriveOCR2Config(t, c.Oracles, commitOnchainConfig, commitOffchainConfig) - // Set the DON on the commit store - _, err := c.Dest.CommitStore.SetOCR2Config( - c.Dest.User, - c.commitOCRConfig.Signers, - c.commitOCRConfig.Transmitters, - c.commitOCRConfig.F, - c.commitOCRConfig.OnchainConfig, - c.commitOCRConfig.OffchainConfigVersion, - c.commitOCRConfig.OffchainConfig, - ) - require.NoError(t, err) - c.Dest.Chain.Commit() -} - -func (c *CCIPContracts) SetupExecOCR2Config(t *testing.T, execOnchainConfig, execOffchainConfig []byte) { - c.execOCRConfig = c.DeriveOCR2Config(t, c.Oracles, execOnchainConfig, execOffchainConfig) - // Same DON on the offramp - _, err := c.Dest.OffRamp.SetOCR2Config( - c.Dest.User, - c.execOCRConfig.Signers, - c.execOCRConfig.Transmitters, - c.execOCRConfig.F, - c.execOCRConfig.OnchainConfig, - c.execOCRConfig.OffchainConfigVersion, - c.execOCRConfig.OffchainConfig, - ) - require.NoError(t, err) - c.Dest.Chain.Commit() -} - -func (c *CCIPContracts) SetupOnchainConfig(t *testing.T, commitOnchainConfig, commitOffchainConfig, execOnchainConfig, execOffchainConfig []byte) int64 { - // Note We do NOT set the payees, payment is done in the OCR2Base implementation - blockBeforeConfig, err := c.Dest.Chain.Client().BlockByNumber(tests.Context(t), nil) - require.NoError(t, err) - - c.SetupCommitOCR2Config(t, commitOnchainConfig, commitOffchainConfig) - c.SetupExecOCR2Config(t, execOnchainConfig, execOffchainConfig) - - return blockBeforeConfig.Number().Int64() -} - -func (c *CCIPContracts) SetupLockAndMintTokenPool( - sourceTokenAddress common.Address, - wrappedTokenName, - wrappedTokenSymbol string) (common.Address, *burn_mint_erc677.BurnMintERC677, error) { - // Deploy dest token & pool - destTokenAddress, _, _, err := burn_mint_erc677.DeployBurnMintERC677(c.Dest.User, c.Dest.Chain.Client(), wrappedTokenName, wrappedTokenSymbol, 18, big.NewInt(0)) - if err != nil { - return [20]byte{}, nil, err - } - c.Dest.Chain.Commit() - - destToken, err := burn_mint_erc677.NewBurnMintERC677(destTokenAddress, c.Dest.Chain.Client()) - if err != nil { - return [20]byte{}, nil, err - } - - destPoolAddress, _, destPool, err := burn_mint_token_pool.DeployBurnMintTokenPool( - c.Dest.User, - c.Dest.Chain.Client(), - destTokenAddress, - []common.Address{}, // pool originalSender allowList - c.Dest.ARMProxy.Address(), - c.Dest.Router.Address(), - ) - if err != nil { - return [20]byte{}, nil, err - } - c.Dest.Chain.Commit() - - _, err = destToken.GrantMintAndBurnRoles(c.Dest.User, destPoolAddress) - if err != nil { - return [20]byte{}, nil, err - } - - _, err = destPool.ApplyChainUpdates(c.Dest.User, - []burn_mint_token_pool.TokenPoolChainUpdate{ - { - RemoteChainSelector: c.Source.ChainSelector, - Allowed: true, - OutboundRateLimiterConfig: burn_mint_token_pool.RateLimiterConfig{ - IsEnabled: true, - Capacity: HundredLink, - Rate: big.NewInt(1e18), - }, - InboundRateLimiterConfig: burn_mint_token_pool.RateLimiterConfig{ - IsEnabled: true, - Capacity: HundredLink, - Rate: big.NewInt(1e18), - }, - }, - }) - if err != nil { - return [20]byte{}, nil, err - } - c.Dest.Chain.Commit() - - sourcePoolAddress, _, sourcePool, err := lock_release_token_pool.DeployLockReleaseTokenPool( - c.Source.User, - c.Source.Chain.Client(), - sourceTokenAddress, - []common.Address{}, // empty allowList at deploy time indicates pool has no original sender restrictions - c.Source.ARMProxy.Address(), - true, - c.Source.Router.Address(), - ) - if err != nil { - return [20]byte{}, nil, err - } - c.Source.Chain.Commit() - - // set onRamp as valid caller for source pool - _, err = sourcePool.ApplyChainUpdates(c.Source.User, []lock_release_token_pool.TokenPoolChainUpdate{ - { - RemoteChainSelector: c.Dest.ChainSelector, - Allowed: true, - OutboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ - IsEnabled: true, - Capacity: HundredLink, - Rate: big.NewInt(1e18), - }, - InboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ - IsEnabled: true, - Capacity: HundredLink, - Rate: big.NewInt(1e18), - }, - }, - }) - if err != nil { - return [20]byte{}, nil, err - } - c.Source.Chain.Commit() - - wrappedNativeAddress, err := c.Source.Router.GetWrappedNative(nil) - if err != nil { - return [20]byte{}, nil, err - } - - // native token is used as fee token - _, err = c.Source.PriceRegistry.UpdatePrices(c.Source.User, price_registry_1_2_0.InternalPriceUpdates{ - TokenPriceUpdates: []price_registry_1_2_0.InternalTokenPriceUpdate{ - { - SourceToken: sourceTokenAddress, - UsdPerToken: big.NewInt(5), - }, - }, - GasPriceUpdates: []price_registry_1_2_0.InternalGasPriceUpdate{}, - }) - if err != nil { - return [20]byte{}, nil, err - } - c.Source.Chain.Commit() - - _, err = c.Source.PriceRegistry.ApplyFeeTokensUpdates(c.Source.User, []common.Address{wrappedNativeAddress}, nil) - if err != nil { - return [20]byte{}, nil, err - } - c.Source.Chain.Commit() - - // add new token pool created above - _, err = c.Source.OnRamp.ApplyPoolUpdates(c.Source.User, nil, []evm_2_evm_onramp.InternalPoolUpdate{ - { - Token: sourceTokenAddress, - Pool: sourcePoolAddress, - }, - }) - if err != nil { - return [20]byte{}, nil, err - } - - _, err = c.Dest.OffRamp.ApplyPoolUpdates(c.Dest.User, nil, []evm_2_evm_offramp.InternalPoolUpdate{ - { - Token: sourceTokenAddress, - Pool: destPoolAddress, - }, - }) - if err != nil { - return [20]byte{}, nil, err - } - c.Dest.Chain.Commit() - - return sourcePoolAddress, destToken, err -} - -func (c *CCIPContracts) SendMessage(t *testing.T, gasLimit, tokenAmount *big.Int, receiverAddr common.Address) { - extraArgs, err := GetEVMExtraArgsV1(gasLimit, false) - require.NoError(t, err) - msg := router.ClientEVM2AnyMessage{ - Receiver: MustEncodeAddress(t, receiverAddr), - Data: []byte("hello"), - TokenAmounts: []router.ClientEVMTokenAmount{ - { - Token: c.Source.LinkToken.Address(), - Amount: tokenAmount, - }, - }, - FeeToken: c.Source.LinkToken.Address(), - ExtraArgs: extraArgs, - } - fee, err := c.Source.Router.GetFee(nil, c.Dest.ChainSelector, msg) - require.NoError(t, err) - // Currently no overhead and 1gwei dest gas price. So fee is simply gasLimit * gasPrice. - // require.Equal(t, new(big.Int).Mul(gasLimit, gasPrice).String(), fee.String()) - // Approve the fee amount + the token amount - _, err = c.Source.LinkToken.Approve(c.Source.User, c.Source.Router.Address(), new(big.Int).Add(fee, tokenAmount)) - require.NoError(t, err) - c.Source.Chain.Commit() - c.SendRequest(t, msg) -} - -func GetBalances(t *testing.T, brs []BalanceReq) (map[string]*big.Int, error) { - m := make(map[string]*big.Int) - for _, br := range brs { - m[br.Name] = br.Getter(t, br.Addr) - if m[br.Name] == nil { - return nil, fmt.Errorf("%v getter return nil", br.Name) - } - } - return m, nil -} - -func MustAddBigInt(a *big.Int, b string) *big.Int { - bi, _ := big.NewInt(0).SetString(b, 10) - return big.NewInt(0).Add(a, bi) -} - -func MustSubBigInt(a *big.Int, b string) *big.Int { - bi, _ := big.NewInt(0).SetString(b, 10) - return big.NewInt(0).Sub(a, bi) -} - -func MustEncodeAddress(t *testing.T, address common.Address) []byte { - bts, err := utils.ABIEncode(`[{"type":"address"}]`, address) - require.NoError(t, err) - return bts -} - -func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destChainID, destChainSelector uint64) CCIPContracts { - sourceChain, sourceUser := testhelpers.SetupChain(t) - destChain, destUser := testhelpers.SetupChain(t) - - sourceChain.Commit() - destChain.Commit() - - armSourceAddress, _, _, err := mock_rmn_contract.DeployMockRMNContract( - sourceUser, - sourceChain.Client(), - ) - require.NoError(t, err) - sourceChain.Commit() - - sourceARM, err := mock_rmn_contract.NewMockRMNContract(armSourceAddress, sourceChain.Client()) - require.NoError(t, err) - armProxySourceAddress, _, _, err := rmn_proxy_contract.DeployRMNProxyContract( - sourceUser, - sourceChain.Client(), - armSourceAddress, - ) - require.NoError(t, err) - sourceChain.Commit() - - sourceARMProxy, err := rmn_proxy_contract.NewRMNProxyContract(armProxySourceAddress, sourceChain.Client()) - require.NoError(t, err) - - armDestAddress, _, _, err := mock_rmn_contract.DeployMockRMNContract( - destUser, - destChain.Client(), - ) - require.NoError(t, err) - destChain.Commit() - - armProxyDestAddress, _, _, err := rmn_proxy_contract.DeployRMNProxyContract( - destUser, - destChain.Client(), - armDestAddress, - ) - require.NoError(t, err) - destChain.Commit() - - destARM, err := mock_rmn_contract.NewMockRMNContract(armDestAddress, destChain.Client()) - require.NoError(t, err) - destARMProxy, err := rmn_proxy_contract.NewRMNProxyContract(armProxyDestAddress, destChain.Client()) - require.NoError(t, err) - - // Deploy link token and pool on source chain - sourceLinkTokenAddress, _, _, err := link_token_interface.DeployLinkToken(sourceUser, sourceChain.Client()) - require.NoError(t, err) - sourceChain.Commit() - sourceLinkToken, err := link_token_interface.NewLinkToken(sourceLinkTokenAddress, sourceChain.Client()) - require.NoError(t, err) - - // Create router - sourceWeth9addr, _, _, err := weth9.DeployWETH9(sourceUser, sourceChain.Client()) - require.NoError(t, err) - sourceChain.Commit() - - sourceWrapped, err := weth9.NewWETH9(sourceWeth9addr, sourceChain.Client()) - require.NoError(t, err) - - sourceRouterAddress, _, _, err := router.DeployRouter(sourceUser, sourceChain.Client(), sourceWeth9addr, armProxySourceAddress) - require.NoError(t, err) - sourceChain.Commit() - - sourceRouter, err := router.NewRouter(sourceRouterAddress, sourceChain.Client()) - require.NoError(t, err) - - sourceWeth9PoolAddress, _, _, err := lock_release_token_pool_1_0_0.DeployLockReleaseTokenPool( - sourceUser, - sourceChain.Client(), - sourceWeth9addr, - []common.Address{}, - armProxySourceAddress, - ) - require.NoError(t, err) - sourceChain.Commit() - - sourceWeth9Pool, err := lock_release_token_pool_1_0_0.NewLockReleaseTokenPool(sourceWeth9PoolAddress, sourceChain.Client()) - require.NoError(t, err) - - sourcePoolAddress, _, _, err := lock_release_token_pool.DeployLockReleaseTokenPool( - sourceUser, - sourceChain.Client(), - sourceLinkTokenAddress, - []common.Address{}, - armProxySourceAddress, - true, - sourceRouterAddress, - ) - require.NoError(t, err) - sourceChain.Commit() - sourcePool, err := lock_release_token_pool.NewLockReleaseTokenPool(sourcePoolAddress, sourceChain.Client()) - require.NoError(t, err) - - // Deploy custom token pool source - sourceCustomTokenAddress, _, _, err := link_token_interface.DeployLinkToken(sourceUser, sourceChain.Client()) // Just re-use this, it's an ERC20. - require.NoError(t, err) - sourceCustomToken, err := link_token_interface.NewLinkToken(sourceCustomTokenAddress, sourceChain.Client()) - require.NoError(t, err) - destChain.Commit() - - // Deploy custom token pool dest - destCustomTokenAddress, _, _, err := link_token_interface.DeployLinkToken(destUser, destChain.Client()) // Just re-use this, it's an ERC20. - require.NoError(t, err) - destCustomToken, err := link_token_interface.NewLinkToken(destCustomTokenAddress, destChain.Client()) - require.NoError(t, err) - destChain.Commit() - - // Deploy and configure onramp - sourcePricesAddress, _, _, err := price_registry_1_2_0.DeployPriceRegistry( - sourceUser, - sourceChain.Client(), - nil, - []common.Address{sourceLinkTokenAddress, sourceWeth9addr}, - 60*60*24*14, // two weeks - ) - require.NoError(t, err) - sourceChain.Commit() - - srcPriceRegistry, err := price_registry_1_2_0.NewPriceRegistry(sourcePricesAddress, sourceChain.Client()) - require.NoError(t, err) - - _, err = srcPriceRegistry.UpdatePrices(sourceUser, price_registry_1_2_0.InternalPriceUpdates{ - TokenPriceUpdates: []price_registry_1_2_0.InternalTokenPriceUpdate{ - { - SourceToken: sourceLinkTokenAddress, - UsdPerToken: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(20)), - }, - { - SourceToken: sourceWeth9addr, - UsdPerToken: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(2000)), - }, - }, - GasPriceUpdates: []price_registry_1_2_0.InternalGasPriceUpdate{ - { - DestChainSelector: destChainSelector, - UsdPerUnitGas: big.NewInt(20000e9), - }, - }, - }) - require.NoError(t, err) - sourceChain.Commit() - - onRampAddress, _, _, err := evm_2_evm_onramp.DeployEVM2EVMOnRamp( - sourceUser, // user - sourceChain.Client(), // client - evm_2_evm_onramp.EVM2EVMOnRampStaticConfig{ - LinkToken: sourceLinkTokenAddress, - ChainSelector: sourceChainSelector, - DestChainSelector: destChainSelector, - DefaultTxGasLimit: 200_000, - MaxNopFeesJuels: big.NewInt(0).Mul(big.NewInt(100_000_000), big.NewInt(1e18)), - PrevOnRamp: common.HexToAddress(""), - ArmProxy: armProxySourceAddress, // ARM - }, - evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{ - Router: sourceRouterAddress, - MaxNumberOfTokensPerMsg: 5, - DestGasOverhead: 350_000, - DestGasPerPayloadByte: 16, - DestDataAvailabilityOverheadGas: 33_596, - DestGasPerDataAvailabilityByte: 16, - DestDataAvailabilityMultiplierBps: 6840, // 0.684 - PriceRegistry: sourcePricesAddress, - MaxDataBytes: 1e5, - MaxPerMsgGasLimit: 4_000_000, - }, - []evm_2_evm_onramp.InternalPoolUpdate{ - { - Token: sourceLinkTokenAddress, - Pool: sourcePoolAddress, - }, - { - Token: sourceWeth9addr, - Pool: sourceWeth9PoolAddress, - }, - }, - evm_2_evm_onramp.RateLimiterConfig{ - IsEnabled: true, - Capacity: LinkUSDValue(100), - Rate: LinkUSDValue(1), - }, - []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs{ - { - Token: sourceLinkTokenAddress, - NetworkFeeUSDCents: 1_00, - GasMultiplierWeiPerEth: 1e18, - PremiumMultiplierWeiPerEth: 9e17, - Enabled: true, - }, - { - Token: sourceWeth9addr, - NetworkFeeUSDCents: 1_00, - GasMultiplierWeiPerEth: 1e18, - PremiumMultiplierWeiPerEth: 1e18, - Enabled: true, - }, - }, - []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs{ - { - Token: sourceLinkTokenAddress, - MinFeeUSDCents: 50, // $0.5 - MaxFeeUSDCents: 1_000_000_00, // $ 1 million - DeciBps: 5_0, // 5 bps - DestGasOverhead: 34_000, - DestBytesOverhead: 32, - }, - }, - []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight{}, - ) - require.NoError(t, err) - sourceChain.Commit() - - onRamp, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(onRampAddress, sourceChain.Client()) - require.NoError(t, err) - _, err = sourcePool.ApplyChainUpdates( - sourceUser, - []lock_release_token_pool.TokenPoolChainUpdate{{ - RemoteChainSelector: DestChainSelector, - Allowed: true, - OutboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ - IsEnabled: true, - Capacity: HundredLink, - Rate: big.NewInt(1e18), - }, - InboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ - IsEnabled: true, - Capacity: HundredLink, - Rate: big.NewInt(1e18), - }, - }}, - ) - require.NoError(t, err) - _, err = sourceWeth9Pool.ApplyRampUpdates(sourceUser, - []lock_release_token_pool_1_0_0.TokenPoolRampUpdate{{Ramp: onRampAddress, Allowed: true, - RateLimiterConfig: lock_release_token_pool_1_0_0.RateLimiterConfig{ - IsEnabled: true, - Capacity: HundredLink, - Rate: big.NewInt(1e18), - }, - }}, - []lock_release_token_pool_1_0_0.TokenPoolRampUpdate{}, - ) - require.NoError(t, err) - sourceChain.Commit() - _, err = sourceRouter.ApplyRampUpdates(sourceUser, []router.RouterOnRamp{{DestChainSelector: destChainSelector, OnRamp: onRampAddress}}, nil, nil) - require.NoError(t, err) - sourceChain.Commit() - - destWethaddr, _, _, err := weth9.DeployWETH9(destUser, destChain.Client()) - require.NoError(t, err) - destChain.Commit() - destWrapped, err := weth9.NewWETH9(destWethaddr, destChain.Client()) - require.NoError(t, err) - - // Create dest router - destRouterAddress, _, _, err := router.DeployRouter(destUser, destChain.Client(), destWethaddr, armProxyDestAddress) - require.NoError(t, err) - destChain.Commit() - destRouter, err := router.NewRouter(destRouterAddress, destChain.Client()) - require.NoError(t, err) - - // Deploy link token and pool on destination chain - destLinkTokenAddress, _, _, err := link_token_interface.DeployLinkToken(destUser, destChain.Client()) - require.NoError(t, err) - destChain.Commit() - destLinkToken, err := link_token_interface.NewLinkToken(destLinkTokenAddress, destChain.Client()) - require.NoError(t, err) - destPoolAddress, _, _, err := lock_release_token_pool.DeployLockReleaseTokenPool( - destUser, - destChain.Client(), - destLinkTokenAddress, - []common.Address{}, - armProxyDestAddress, - true, - destRouterAddress, - ) - require.NoError(t, err) - destChain.Commit() - destPool, err := lock_release_token_pool.NewLockReleaseTokenPool(destPoolAddress, destChain.Client()) - require.NoError(t, err) - destChain.Commit() - - // Float the offramp pool - o, err := destPool.Owner(nil) - require.NoError(t, err) - require.Equal(t, destUser.From.String(), o.String()) - _, err = destPool.SetRebalancer(destUser, destUser.From) - require.NoError(t, err) - _, err = destLinkToken.Approve(destUser, destPoolAddress, Link(200)) - require.NoError(t, err) - destChain.Commit() - _, err = destPool.ProvideLiquidity(destUser, Link(200)) - require.NoError(t, err) - destChain.Commit() - - destWrappedPoolAddress, _, _, err := lock_release_token_pool_1_0_0.DeployLockReleaseTokenPool( - destUser, - destChain.Client(), - destWethaddr, - []common.Address{}, - armProxyDestAddress, - ) - require.NoError(t, err) - destChain.Commit() - destWrappedPool, err := lock_release_token_pool_1_0_0.NewLockReleaseTokenPool(destWrappedPoolAddress, destChain.Client()) - require.NoError(t, err) - - poolFloatValue := big.NewInt(1e18) - - destUser.Value = poolFloatValue - _, err = destWrapped.Deposit(destUser) - require.NoError(t, err) - destChain.Commit() - destUser.Value = nil - - _, err = destWrapped.Transfer(destUser, destWrappedPool.Address(), poolFloatValue) - require.NoError(t, err) - destChain.Commit() - - // Deploy and configure ge offramp. - destPricesAddress, _, _, err := price_registry_1_2_0.DeployPriceRegistry( - destUser, - destChain.Client(), - nil, - []common.Address{destLinkTokenAddress}, - 60*60*24*14, // two weeks - ) - require.NoError(t, err) - destChain.Commit() - - destPriceRegistry, err := price_registry_1_2_0.NewPriceRegistry(destPricesAddress, destChain.Client()) - require.NoError(t, err) - - // Deploy commit store. - commitStoreAddress, _, _, err := commit_store_1_2_0.DeployCommitStore( - destUser, // user - destChain.Client(), // client - commit_store_1_2_0.CommitStoreStaticConfig{ - ChainSelector: destChainSelector, - SourceChainSelector: sourceChainSelector, - OnRamp: onRamp.Address(), - ArmProxy: destARMProxy.Address(), - }, - ) - require.NoError(t, err) - destChain.Commit() - commitStore, err := commit_store_1_2_0.NewCommitStore(commitStoreAddress, destChain.Client()) - require.NoError(t, err) - - offRampAddress, _, _, err := evm_2_evm_offramp.DeployEVM2EVMOffRamp( - destUser, - destChain.Client(), - evm_2_evm_offramp.EVM2EVMOffRampStaticConfig{ - CommitStore: commitStore.Address(), - ChainSelector: destChainSelector, - SourceChainSelector: sourceChainSelector, - OnRamp: onRampAddress, - PrevOffRamp: common.HexToAddress(""), - ArmProxy: armProxyDestAddress, - }, - []common.Address{sourceLinkTokenAddress, sourceWeth9addr}, - []common.Address{destPoolAddress, destWrappedPool.Address()}, - evm_2_evm_offramp.RateLimiterConfig{ - IsEnabled: true, - Capacity: LinkUSDValue(100), - Rate: LinkUSDValue(1), - }, - ) - require.NoError(t, err) - destChain.Commit() - - offRamp, err := evm_2_evm_offramp.NewEVM2EVMOffRamp(offRampAddress, destChain.Client()) - require.NoError(t, err) - _, err = destPool.ApplyChainUpdates(destUser, - []lock_release_token_pool.TokenPoolChainUpdate{{ - RemoteChainSelector: sourceChainSelector, - Allowed: true, - OutboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ - IsEnabled: true, - Capacity: HundredLink, - Rate: big.NewInt(1e18), - }, - InboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ - IsEnabled: true, - Capacity: HundredLink, - Rate: big.NewInt(1e18), - }, - }}, - ) - require.NoError(t, err) - - _, err = destWrappedPool.ApplyRampUpdates(destUser, - []lock_release_token_pool_1_0_0.TokenPoolRampUpdate{}, - []lock_release_token_pool_1_0_0.TokenPoolRampUpdate{{ - Ramp: offRampAddress, - Allowed: true, - RateLimiterConfig: lock_release_token_pool_1_0_0.RateLimiterConfig{ - IsEnabled: true, - Capacity: HundredLink, - Rate: big.NewInt(1e18), - }, - }}, - ) - require.NoError(t, err) - - destChain.Commit() - _, err = destPriceRegistry.ApplyPriceUpdatersUpdates(destUser, []common.Address{commitStoreAddress}, []common.Address{}) - require.NoError(t, err) - destChain.Commit() - - _, err = destRouter.ApplyRampUpdates(destUser, nil, - nil, []router.RouterOffRamp{{SourceChainSelector: sourceChainSelector, OffRamp: offRampAddress}}) - require.NoError(t, err) - destChain.Commit() - - // Deploy 2 revertable (one SS one non-SS) - revertingMessageReceiver1Address, _, _, err := maybe_revert_message_receiver.DeployMaybeRevertMessageReceiver(destUser, destChain.Client(), false) - require.NoError(t, err) - revertingMessageReceiver1, _ := maybe_revert_message_receiver.NewMaybeRevertMessageReceiver(revertingMessageReceiver1Address, destChain.Client()) - revertingMessageReceiver2Address, _, _, err := maybe_revert_message_receiver.DeployMaybeRevertMessageReceiver(destUser, destChain.Client(), false) - require.NoError(t, err) - revertingMessageReceiver2, _ := maybe_revert_message_receiver.NewMaybeRevertMessageReceiver(revertingMessageReceiver2Address, destChain.Client()) - // Need to commit here, or we will hit the block gas limit when deploying the executor - sourceChain.Commit() - destChain.Commit() - - // Ensure we have at least finality blocks. - for i := 0; i < 50; i++ { - sourceChain.Commit() - destChain.Commit() - } - - source := SourceChain{ - Common: Common{ - ChainID: sourceChainID, - ChainSelector: sourceChainSelector, - User: sourceUser, - Chain: sourceChain, - LinkToken: sourceLinkToken, - LinkTokenPool: sourcePool, - CustomToken: sourceCustomToken, - ARM: sourceARM, - ARMProxy: sourceARMProxy, - PriceRegistry: srcPriceRegistry, - WrappedNative: sourceWrapped, - WrappedNativePool: sourceWeth9Pool, - }, - Router: sourceRouter, - OnRamp: onRamp, - } - dest := DestinationChain{ - Common: Common{ - ChainID: destChainID, - ChainSelector: destChainSelector, - User: destUser, - Chain: destChain, - LinkToken: destLinkToken, - LinkTokenPool: destPool, - CustomToken: destCustomToken, - ARM: destARM, - ARMProxy: destARMProxy, - PriceRegistry: destPriceRegistry, - WrappedNative: destWrapped, - WrappedNativePool: destWrappedPool, - }, - CommitStore: commitStore, - Router: destRouter, - OffRamp: offRamp, - Receivers: []MaybeRevertReceiver{{Receiver: revertingMessageReceiver1, Strict: false}, {Receiver: revertingMessageReceiver2, Strict: true}}, - } - - return CCIPContracts{ - Source: source, - Dest: dest, - } -} - -func (c *CCIPContracts) SendRequest(t *testing.T, msg router.ClientEVM2AnyMessage) *types.Transaction { - tx, err := c.Source.Router.CcipSend(c.Source.User, c.Dest.ChainSelector, msg) - require.NoError(t, err) - testhelpers.ConfirmTxs(t, []*types.Transaction{tx}, c.Source.Chain) - return tx -} - -func (c *CCIPContracts) AssertExecState(t *testing.T, log logpoller.Log, state MessageExecutionState, offRampOpts ...common.Address) { - var offRamp *evm_2_evm_offramp.EVM2EVMOffRamp - var err error - if len(offRampOpts) > 0 { - offRamp, err = evm_2_evm_offramp.NewEVM2EVMOffRamp(offRampOpts[0], c.Dest.Chain.Client()) - require.NoError(t, err) - } else { - require.NotNil(t, c.Dest.OffRamp, "no offRamp configured") - offRamp = c.Dest.OffRamp - } - executionStateChanged, err := offRamp.ParseExecutionStateChanged(log.ToGethLog()) - require.NoError(t, err) - if MessageExecutionState(executionStateChanged.State) != state { - t.Log("Execution failed", hexutil.Encode(executionStateChanged.ReturnData)) - t.Fail() - } -} - -func GetEVMExtraArgsV1(gasLimit *big.Int, strict bool) ([]byte, error) { - EVMV1Tag := []byte{0x97, 0xa6, 0x57, 0xc9} - - encodedArgs, err := utils.ABIEncode(`[{"type":"uint256"},{"type":"bool"}]`, gasLimit, strict) - if err != nil { - return nil, err - } - - return append(EVMV1Tag, encodedArgs...), nil -} - -type ManualExecArgs struct { - SourceChainID, DestChainID uint64 - DestUser *bind.TransactOpts - SourceChain, DestChain bind.ContractBackend - SourceStartBlock *big.Int // the block in/after which failed ccip-send transaction was triggered - DestStartBlock uint64 // the start block for filtering ReportAccepted event (including the failed seq num) - // in destination chain. if not provided to be derived by ApproxDestStartBlock method - DestLatestBlockNum uint64 // current block number in destination - DestDeployedAt uint64 // destination block number for the initial destination contract deployment. - // Can be any number before the tx was reverted in destination chain. Preferably this needs to be set up with - // a value greater than zero to avoid performance issue in locating approximate destination block - SendReqLogIndex uint // log index of the CCIPSendRequested log in source chain - SendReqTxHash string // tx hash of the ccip-send transaction for which execution was reverted - CommitStore string - OnRamp string - OffRamp string - SeqNr uint64 - GasLimit *big.Int -} - -// ApproxDestStartBlock attempts to locate a block in destination chain with timestamp closest to the timestamp of the block -// in source chain in which ccip-send transaction was included -// it uses binary search to locate the block with the closest timestamp -// if the block located has a timestamp greater than the timestamp of mentioned source block -// it just returns the first block found with lesser timestamp of the source block -// providing a value of args.DestDeployedAt ensures better performance by reducing the range of block numbers to be traversed -func (args *ManualExecArgs) ApproxDestStartBlock(ctx context.Context) error { - sourceBlockHdr, err := args.SourceChain.HeaderByNumber(ctx, args.SourceStartBlock) - if err != nil { - return err - } - sendTxTime := sourceBlockHdr.Time - maxBlockNum := args.DestLatestBlockNum - // setting this to an approx value of 1000 considering destination chain would have at least 1000 blocks before the transaction started - minBlockNum := args.DestDeployedAt - closestBlockNum := uint64(math.Floor((float64(maxBlockNum) + float64(minBlockNum)) / 2)) - var closestBlockHdr *types.Header - closestBlockHdr, err = args.DestChain.HeaderByNumber(ctx, new(big.Int).SetUint64(closestBlockNum)) - if err != nil { - return err - } - // to reduce the number of RPC calls increase the value of blockOffset - blockOffset := uint64(10) - for { - blockNum := closestBlockHdr.Number.Uint64() - if minBlockNum > maxBlockNum { - break - } - timeDiff := math.Abs(float64(closestBlockHdr.Time - sendTxTime)) - // break if the difference in timestamp is lesser than 1 minute - if timeDiff < 60 { - break - } else if closestBlockHdr.Time > sendTxTime { - maxBlockNum = blockNum - 1 - } else { - minBlockNum = blockNum + 1 - } - closestBlockNum = uint64(math.Floor((float64(maxBlockNum) + float64(minBlockNum)) / 2)) - closestBlockHdr, err = args.DestChain.HeaderByNumber(ctx, new(big.Int).SetUint64(closestBlockNum)) - if err != nil { - return err - } - } - - for closestBlockHdr.Time > sendTxTime { - closestBlockNum = closestBlockNum - blockOffset - if closestBlockNum <= 0 { - return fmt.Errorf("approx destination blocknumber not found") - } - closestBlockHdr, err = args.DestChain.HeaderByNumber(ctx, new(big.Int).SetUint64(closestBlockNum)) - if err != nil { - return err - } - } - args.DestStartBlock = closestBlockHdr.Number.Uint64() - fmt.Println("using approx destination start block number", args.DestStartBlock) - return nil -} - -func (args *ManualExecArgs) FindSeqNrFromCCIPSendRequested() (uint64, error) { - var seqNr uint64 - onRampContract, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(common.HexToAddress(args.OnRamp), args.SourceChain) - if err != nil { - return seqNr, err - } - iterator, err := onRampContract.FilterCCIPSendRequested(&bind.FilterOpts{ - Start: args.SourceStartBlock.Uint64(), - }) - if err != nil { - return seqNr, err - } - for iterator.Next() { - if iterator.Event.Raw.Index == args.SendReqLogIndex && - iterator.Event.Raw.TxHash.Hex() == args.SendReqTxHash { - seqNr = iterator.Event.Message.SequenceNumber - break - } - } - if seqNr == 0 { - return seqNr, - fmt.Errorf("no CCIPSendRequested logs found for logIndex %d starting from block number %d", args.SendReqLogIndex, args.SourceStartBlock) - } - return seqNr, nil -} - -func (args *ManualExecArgs) ExecuteManually(ctx context.Context) (*types.Transaction, error) { - if args.SourceChainID == 0 || - args.DestChainID == 0 || - args.DestUser == nil { - return nil, fmt.Errorf("chain ids and owners are mandatory for source and dest chain") - } - if !common.IsHexAddress(args.CommitStore) || - !common.IsHexAddress(args.OffRamp) || - !common.IsHexAddress(args.OnRamp) { - return nil, fmt.Errorf("contract addresses must be valid hex address") - } - if args.SendReqTxHash == "" { - return nil, fmt.Errorf("tx hash of ccip-send request are required") - } - if args.SourceStartBlock == nil { - return nil, fmt.Errorf("must provide the value of source block in/after which ccip-send tx was included") - } - if args.SeqNr == 0 { - if args.SendReqLogIndex == 0 { - return nil, fmt.Errorf("must provide the value of log index of ccip-send request") - } - // locate seq nr from CCIPSendRequested log - seqNr, err := args.FindSeqNrFromCCIPSendRequested() - if err != nil { - return nil, err - } - args.SeqNr = seqNr - } - commitStore, err := commit_store_1_2_0.NewCommitStore(common.HexToAddress(args.CommitStore), args.DestChain) - if err != nil { - return nil, err - } - if args.DestStartBlock < 1 { - err = args.ApproxDestStartBlock(ctx) - if err != nil { - return nil, err - } - } - iterator, err := commitStore.FilterReportAccepted(&bind.FilterOpts{Start: args.DestStartBlock}) - if err != nil { - return nil, err - } - - var commitReport *commit_store_1_2_0.CommitStoreCommitReport - for iterator.Next() { - if iterator.Event.Report.Interval.Min <= args.SeqNr && iterator.Event.Report.Interval.Max >= args.SeqNr { - commitReport = &iterator.Event.Report - fmt.Println("Found root") - break - } - } - if commitReport == nil { - return nil, fmt.Errorf("unable to find seq num %d in commit report", args.SeqNr) - } - - return args.execute(commitReport) -} - -func (args *ManualExecArgs) execute(report *commit_store_1_2_0.CommitStoreCommitReport) (*types.Transaction, error) { - log.Info().Msg("Executing request manually") - seqNr := args.SeqNr - // Build a merkle tree for the report - mctx := hashutil.NewKeccak() - onRampContract, err := evm_2_evm_onramp_1_2_0.NewEVM2EVMOnRamp(common.HexToAddress(args.OnRamp), args.SourceChain) - if err != nil { - return nil, err - } - leafHasher := v1_2_0.NewLeafHasher(args.SourceChainID, args.DestChainID, common.HexToAddress(args.OnRamp), mctx, onRampContract) - if leafHasher == nil { - return nil, fmt.Errorf("unable to create leaf hasher") - } - - var leaves [][32]byte - var curr, prove int - var msgs []evm_2_evm_offramp.InternalEVM2EVMMessage - var manualExecGasLimits []*big.Int - var tokenData [][][]byte - sendRequestedIterator, err := onRampContract.FilterCCIPSendRequested(&bind.FilterOpts{ - Start: args.SourceStartBlock.Uint64(), - }) - if err != nil { - return nil, err - } - for sendRequestedIterator.Next() { - if sendRequestedIterator.Event.Message.SequenceNumber <= report.Interval.Max && - sendRequestedIterator.Event.Message.SequenceNumber >= report.Interval.Min { - fmt.Println("Found seq num", sendRequestedIterator.Event.Message.SequenceNumber, report.Interval) - hash, err2 := leafHasher.HashLeaf(sendRequestedIterator.Event.Raw) - if err2 != nil { - return nil, err2 - } - leaves = append(leaves, hash) - if sendRequestedIterator.Event.Message.SequenceNumber == seqNr { - fmt.Printf("Found proving %d %+v\n", curr, sendRequestedIterator.Event.Message) - var tokensAndAmounts []evm_2_evm_offramp.ClientEVMTokenAmount - for _, tokenAndAmount := range sendRequestedIterator.Event.Message.TokenAmounts { - tokensAndAmounts = append(tokensAndAmounts, evm_2_evm_offramp.ClientEVMTokenAmount{ - Token: tokenAndAmount.Token, - Amount: tokenAndAmount.Amount, - }) - } - msg := evm_2_evm_offramp.InternalEVM2EVMMessage{ - SourceChainSelector: sendRequestedIterator.Event.Message.SourceChainSelector, - Sender: sendRequestedIterator.Event.Message.Sender, - Receiver: sendRequestedIterator.Event.Message.Receiver, - SequenceNumber: sendRequestedIterator.Event.Message.SequenceNumber, - GasLimit: sendRequestedIterator.Event.Message.GasLimit, - Strict: sendRequestedIterator.Event.Message.Strict, - Nonce: sendRequestedIterator.Event.Message.Nonce, - FeeToken: sendRequestedIterator.Event.Message.FeeToken, - FeeTokenAmount: sendRequestedIterator.Event.Message.FeeTokenAmount, - Data: sendRequestedIterator.Event.Message.Data, - TokenAmounts: tokensAndAmounts, - SourceTokenData: sendRequestedIterator.Event.Message.SourceTokenData, - MessageId: sendRequestedIterator.Event.Message.MessageId, - } - msgs = append(msgs, msg) - if args.GasLimit != nil { - msg.GasLimit = args.GasLimit - } - manualExecGasLimits = append(manualExecGasLimits, msg.GasLimit) - var msgTokenData [][]byte - for range sendRequestedIterator.Event.Message.TokenAmounts { - msgTokenData = append(msgTokenData, []byte{}) - } - - tokenData = append(tokenData, msgTokenData) - prove = curr - } - curr++ - } - } - sendRequestedIterator.Close() - if msgs == nil { - return nil, fmt.Errorf("unable to find msg with seqNr %d", seqNr) - } - tree, err := merklemulti.NewTree(mctx, leaves) - if err != nil { - return nil, err - } - if tree.Root() != report.MerkleRoot { - return nil, fmt.Errorf("root doesn't match") - } - - proof, err := tree.Prove([]int{prove}) - if err != nil { - return nil, err - } - - offRampProof := evm_2_evm_offramp.InternalExecutionReport{ - Messages: msgs, - OffchainTokenData: tokenData, - Proofs: proof.Hashes, - ProofFlagBits: abihelpers.ProofFlagsToBits(proof.SourceFlags), - } - offRamp, err := evm_2_evm_offramp.NewEVM2EVMOffRamp(common.HexToAddress(args.OffRamp), args.DestChain) - if err != nil { - return nil, err - } - // Execute. - return offRamp.ManuallyExecute(args.DestUser, offRampProof, manualExecGasLimits) -} - -func (c *CCIPContracts) ExecuteMessage( - t *testing.T, - req logpoller.Log, - txHash common.Hash, - destStartBlock uint64, -) uint64 { - t.Log("Executing request manually") - ctx := tests.Context(t) - sendReqReceipt, err := c.Source.Chain.Client().TransactionReceipt(ctx, txHash) - require.NoError(t, err) - destLatest, err := c.Dest.Chain.Client().BlockByNumber(context.Background(), nil) - require.NoError(t, err) - args := ManualExecArgs{ - SourceChainID: c.Source.ChainID, - DestChainID: c.Dest.ChainID, - DestUser: c.Dest.User, - SourceChain: c.Source.Chain.Client(), - DestChain: c.Dest.Chain.Client(), - SourceStartBlock: sendReqReceipt.BlockNumber, - DestStartBlock: destStartBlock, - DestLatestBlockNum: destLatest.NumberU64(), - SendReqLogIndex: uint(req.LogIndex), - SendReqTxHash: txHash.String(), - CommitStore: c.Dest.CommitStore.Address().String(), - OnRamp: c.Source.OnRamp.Address().String(), - OffRamp: c.Dest.OffRamp.Address().String(), - } - tx, err := args.ExecuteManually(ctx) - require.NoError(t, err) - c.Dest.Chain.Commit() - c.Source.Chain.Commit() - rec, err := c.Dest.Chain.Client().TransactionReceipt(tests.Context(t), tx.Hash()) - require.NoError(t, err) - require.Equal(t, uint64(1), rec.Status, "manual execution failed") - t.Logf("Manual Execution completed for seqNum %d", args.SeqNr) - return args.SeqNr -} - -func GetBalance(t *testing.T, chain bind.ContractBackend, tokenAddr common.Address, addr common.Address) *big.Int { - token, err := link_token_interface.NewLinkToken(tokenAddr, chain) - require.NoError(t, err) - bal, err := token.BalanceOf(nil, addr) - require.NoError(t, err) - return bal -} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go deleted file mode 100644 index 30aaebd4e9e..00000000000 --- a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go +++ /dev/null @@ -1,1053 +0,0 @@ -package testhelpers_1_4_0 - -import ( - "context" - "encoding/hex" - "fmt" - "math" - "math/big" - "net/http" - "net/http/httptest" - "strconv" - "strings" - "testing" - "time" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - types3 "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethclient/simulated" - "github.com/google/uuid" - "github.com/hashicorp/consul/sdk/freeport" - "github.com/jmoiron/sqlx" - "github.com/onsi/gomega" - "github.com/pkg/errors" - "k8s.io/utils/ptr" - - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "go.uber.org/zap" - - "github.com/smartcontractkit/libocr/commontypes" - "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" - types4 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - - "github.com/smartcontractkit/chainlink-common/pkg/config" - "github.com/smartcontractkit/chainlink-common/pkg/loop" - "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" - "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" - - cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - coretypes "github.com/smartcontractkit/chainlink-common/pkg/types/core/mocks" - - pb "github.com/smartcontractkit/chainlink-protos/orchestrator/feedsmanager" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" - v2 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - evmUtils "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" - "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - configv2 "github.com/smartcontractkit/chainlink/v2/core/config/toml" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/logger/audit" - "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - feeds2 "github.com/smartcontractkit/chainlink/v2/core/services/feeds" - feedsMocks "github.com/smartcontractkit/chainlink/v2/core/services/feeds/mocks" - "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/csakey" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" - ksMocks "github.com/smartcontractkit/chainlink/v2/core/services/keystore/mocks" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" - integrationtesthelpers "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers/integration" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" - "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" - evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" - clutils "github.com/smartcontractkit/chainlink/v2/core/utils" - "github.com/smartcontractkit/chainlink/v2/core/utils/crypto" - "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" - "github.com/smartcontractkit/chainlink/v2/plugins" -) - -const ( - execSpecTemplate = ` - type = "offchainreporting2" - schemaVersion = 1 - name = "ccip-exec-1" - externalJobID = "67ffad71-d90f-4fe3-b4e4-494924b707fb" - forwardingAllowed = false - maxTaskDuration = "0s" - contractID = "%s" - contractConfigConfirmations = 1 - contractConfigTrackerPollInterval = "20s" - ocrKeyBundleID = "%s" - relay = "evm" - pluginType = "ccip-execution" - transmitterID = "%s" - - [relayConfig] - chainID = 1_337 - - [pluginConfig] - destStartBlock = 50 - - [pluginConfig.USDCConfig] - AttestationAPI = "http://blah.com" - SourceMessageTransmitterAddress = "%s" - SourceTokenAddress = "%s" - AttestationAPITimeoutSeconds = 10 - ` - commitSpecTemplatePipeline = ` - type = "offchainreporting2" - schemaVersion = 1 - name = "ccip-commit-1" - externalJobID = "13c997cf-1a14-4ab7-9068-07ee6d2afa55" - forwardingAllowed = false - maxTaskDuration = "0s" - contractID = "%s" - contractConfigConfirmations = 1 - contractConfigTrackerPollInterval = "20s" - ocrKeyBundleID = "%s" - relay = "evm" - pluginType = "ccip-commit" - transmitterID = "%s" - - [relayConfig] - chainID = 1_337 - - [pluginConfig] - destStartBlock = 50 - offRamp = "%s" - tokenPricesUSDPipeline = """ - %s - """ - ` - commitSpecTemplateDynamicPriceGetter = ` - type = "offchainreporting2" - schemaVersion = 1 - name = "ccip-commit-1" - externalJobID = "13c997cf-1a14-4ab7-9068-07ee6d2afa55" - forwardingAllowed = false - maxTaskDuration = "0s" - contractID = "%s" - contractConfigConfirmations = 1 - contractConfigTrackerPollInterval = "20s" - ocrKeyBundleID = "%s" - relay = "evm" - pluginType = "ccip-commit" - transmitterID = "%s" - - [relayConfig] - chainID = 1_337 - - [pluginConfig] - destStartBlock = 50 - offRamp = "%s" - priceGetterConfig = """ - %s - """ - ` -) - -type Node struct { - App chainlink.Application - Transmitter common.Address - PaymentReceiver common.Address - KeyBundle ocr2key.KeyBundle -} - -func (node *Node) FindJobIDForContract(t *testing.T, addr common.Address) int32 { - jobs := node.App.JobSpawner().ActiveJobs() - for _, j := range jobs { - if j.Type == job.OffchainReporting2 && j.OCR2OracleSpec.ContractID == addr.Hex() { - return j.ID - } - } - t.Fatalf("Could not find job for contract %s", addr.Hex()) - return 0 -} - -func (node *Node) EventuallyNodeUsesUpdatedPriceRegistry(t *testing.T, ccipContracts CCIPIntegrationTestHarness) logpoller.Log { - c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) - require.NoError(t, err) - var log logpoller.Log - gomega.NewGomegaWithT(t).Eventually(func() bool { - ccipContracts.Source.Chain.Commit() - ccipContracts.Dest.Chain.Commit() - log, err := c.LogPoller().LatestLogByEventSigWithConfs( - testutils.Context(t), - v1_2_0.UsdPerUnitGasUpdated, - ccipContracts.Dest.PriceRegistry.Address(), - 0, - ) - // err can be transient errors such as sql row set empty - if err != nil { - return false - } - return log != nil - }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "node is not using updated price registry %s", ccipContracts.Dest.PriceRegistry.Address().Hex()) - return log -} - -func (node *Node) EventuallyNodeUsesNewCommitConfig(t *testing.T, ccipContracts CCIPIntegrationTestHarness, commitCfg ccipdata.CommitOnchainConfig) logpoller.Log { - c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) - require.NoError(t, err) - var log logpoller.Log - gomega.NewGomegaWithT(t).Eventually(func() bool { - ccipContracts.Source.Chain.Commit() - ccipContracts.Dest.Chain.Commit() - log, err := c.LogPoller().LatestLogByEventSigWithConfs( - testutils.Context(t), - evmrelay.OCR2AggregatorLogDecoder.EventSig(), - ccipContracts.Dest.CommitStore.Address(), - 0, - ) - require.NoError(t, err) - var latestCfg ccipdata.CommitOnchainConfig - if log != nil { - latestCfg, err = DecodeCommitOnChainConfig(log.Data) - require.NoError(t, err) - return latestCfg == commitCfg - } - return false - }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "node is using old cfg") - return log -} - -func (node *Node) EventuallyNodeUsesNewExecConfig(t *testing.T, ccipContracts CCIPIntegrationTestHarness, execCfg v1_2_0.ExecOnchainConfig) logpoller.Log { - c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) - require.NoError(t, err) - var log logpoller.Log - gomega.NewGomegaWithT(t).Eventually(func() bool { - ccipContracts.Source.Chain.Commit() - ccipContracts.Dest.Chain.Commit() - log, err := c.LogPoller().LatestLogByEventSigWithConfs( - testutils.Context(t), - evmrelay.OCR2AggregatorLogDecoder.EventSig(), - ccipContracts.Dest.OffRamp.Address(), - 0, - ) - require.NoError(t, err) - var latestCfg v1_2_0.ExecOnchainConfig - if log != nil { - latestCfg, err = DecodeExecOnChainConfig(log.Data) - require.NoError(t, err) - return latestCfg == execCfg - } - return false - }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "node is using old cfg") - return log -} - -func (node *Node) EventuallyHasReqSeqNum(t *testing.T, ccipContracts *CCIPIntegrationTestHarness, onRamp common.Address, seqNum int) logpoller.Log { - c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Source.ChainID, 10)) - require.NoError(t, err) - var log logpoller.Log - gomega.NewGomegaWithT(t).Eventually(func() bool { - ccipContracts.Source.Chain.Commit() - ccipContracts.Dest.Chain.Commit() - lgs, err := c.LogPoller().LogsDataWordRange( - testutils.Context(t), - v1_2_0.CCIPSendRequestEventSig, - onRamp, - v1_2_0.CCIPSendRequestSeqNumIndex, - abihelpers.EvmWord(uint64(seqNum)), - abihelpers.EvmWord(uint64(seqNum)), - 1, - ) - require.NoError(t, err) - t.Log("Send requested", len(lgs)) - if len(lgs) == 1 { - log = lgs[0] - return true - } - return false - }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "eventually has seq num") - return log -} - -func (node *Node) EventuallyHasExecutedSeqNums(t *testing.T, ccipContracts *CCIPIntegrationTestHarness, offRamp common.Address, minSeqNum int, maxSeqNum int) []logpoller.Log { - c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) - require.NoError(t, err) - var logs []logpoller.Log - gomega.NewGomegaWithT(t).Eventually(func() bool { - ccipContracts.Source.Chain.Commit() - ccipContracts.Dest.Chain.Commit() - lgs, err := c.LogPoller().IndexedLogsTopicRange( - testutils.Context(t), - v1_2_0.ExecutionStateChangedEvent, - offRamp, - v1_2_0.ExecutionStateChangedSeqNrIndex, - abihelpers.EvmWord(uint64(minSeqNum)), - abihelpers.EvmWord(uint64(maxSeqNum)), - 1, - ) - require.NoError(t, err) - t.Logf("Have executed logs %d want %d", len(lgs), maxSeqNum-minSeqNum+1) - if len(lgs) == maxSeqNum-minSeqNum+1 { - logs = lgs - t.Logf("Seq Num %d-%d executed", minSeqNum, maxSeqNum) - return true - } - return false - }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "eventually has not executed seq num") - return logs -} - -func (node *Node) ConsistentlySeqNumHasNotBeenExecuted(t *testing.T, ccipContracts *CCIPIntegrationTestHarness, offRamp common.Address, seqNum int) logpoller.Log { - c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) - require.NoError(t, err) - var log logpoller.Log - gomega.NewGomegaWithT(t).Consistently(func() bool { - ccipContracts.Source.Chain.Commit() - ccipContracts.Dest.Chain.Commit() - lgs, err := c.LogPoller().IndexedLogsTopicRange( - testutils.Context(t), - v1_2_0.ExecutionStateChangedEvent, - offRamp, - v1_2_0.ExecutionStateChangedSeqNrIndex, - abihelpers.EvmWord(uint64(seqNum)), - abihelpers.EvmWord(uint64(seqNum)), - 1, - ) - require.NoError(t, err) - t.Log("Executed logs", lgs) - if len(lgs) == 1 { - log = lgs[0] - return true - } - return false - }, 10*time.Second, 1*time.Second).Should(gomega.BeFalse(), "seq number got executed") - return log -} - -func (node *Node) AddJob(t *testing.T, spec *integrationtesthelpers.OCR2TaskJobSpec) { - specString, err := spec.String() - require.NoError(t, err) - ccipJob, err := validate.ValidatedOracleSpecToml( - testutils.Context(t), - node.App.GetConfig().OCR2(), - node.App.GetConfig().Insecure(), - specString, - // FIXME Ani - nil, - ) - require.NoError(t, err) - err = node.App.AddJobV2(tests.Context(t), &ccipJob) - require.NoError(t, err) -} - -func (node *Node) AddBootstrapJob(t *testing.T, spec *integrationtesthelpers.OCR2TaskJobSpec) { - specString, err := spec.String() - require.NoError(t, err) - ccipJob, err := ocrbootstrap.ValidatedBootstrapSpecToml(specString) - require.NoError(t, err) - err = node.App.AddJobV2(tests.Context(t), &ccipJob) - require.NoError(t, err) -} - -func (node *Node) AddJobsWithSpec(t *testing.T, jobSpec *integrationtesthelpers.OCR2TaskJobSpec) { - // set node specific values - jobSpec.OCR2OracleSpec.OCRKeyBundleID.SetValid(node.KeyBundle.ID()) - jobSpec.OCR2OracleSpec.TransmitterID.SetValid(node.Transmitter.Hex()) - node.AddJob(t, jobSpec) -} - -func setupNodeCCIP( - t *testing.T, - owner *bind.TransactOpts, - port int64, - dbName string, - sourceChain *simulated.Backend, destChain *simulated.Backend, - sourceChainID *big.Int, destChainID *big.Int, - bootstrapPeerID string, - bootstrapPort int64, -) (chainlink.Application, string, common.Address, ocr2key.KeyBundle) { - trueRef, falseRef := true, false - - // Do not want to load fixtures as they contain a dummy chainID. - loglevel := configv2.LogLevel(zap.DebugLevel) - config, db := heavyweight.FullTestDBNoFixturesV2(t, func(c *chainlink.Config, _ *chainlink.Secrets) { - p2pAddresses := []string{ - fmt.Sprintf("127.0.0.1:%d", port), - } - c.Log.Level = &loglevel - c.Feature.UICSAKeys = &trueRef - c.Feature.FeedsManager = &trueRef - c.OCR.Enabled = &falseRef - c.OCR.DefaultTransactionQueueDepth = ptr.To[uint32](200) - c.OCR2.Enabled = &trueRef - c.Feature.LogPoller = &trueRef - c.P2P.V2.Enabled = &trueRef - - dur, err := config.NewDuration(500 * time.Millisecond) - if err != nil { - panic(err) - } - c.P2P.V2.DeltaDial = &dur - - dur2, err := config.NewDuration(5 * time.Second) - if err != nil { - panic(err) - } - - c.P2P.V2.DeltaReconcile = &dur2 - c.P2P.V2.ListenAddresses = &p2pAddresses - c.P2P.V2.AnnounceAddresses = &p2pAddresses - - c.EVM = []*v2.EVMConfig{createConfigV2Chain(sourceChainID), createConfigV2Chain(destChainID)} - - if bootstrapPeerID != "" { - // Supply the bootstrap IP and port as a V2 peer address - c.P2P.V2.DefaultBootstrappers = &[]commontypes.BootstrapperLocator{ - { - PeerID: bootstrapPeerID, Addrs: []string{ - fmt.Sprintf("127.0.0.1:%d", bootstrapPort), - }, - }, - } - } - }) - - lggr := logger.TestLogger(t) - - // The in-memory geth sim does not let you create a custom ChainID, it will always be 1337. - // In particular this means that if you sign an eip155 tx, the chainID used MUST be 1337 - // and the CHAINID op code will always emit 1337. To work around this to simulate a "multichain" - // test, we fake different chainIDs using the wrapped sim cltest.SimulatedBackend so the RPC - // appears to operate on different chainIDs and we use an EthKeyStoreSim wrapper which always - // signs 1337 see https://github.com/smartcontractkit/chainlink-ccip/blob/a24dd436810250a458d27d8bb3fb78096afeb79c/core/services/ocr2/plugins/ccip/testhelpers/simulated_backend.go#L35 - sourceClient := client.NewSimulatedBackendClient(t, sourceChain, sourceChainID) - destClient := client.NewSimulatedBackendClient(t, destChain, destChainID) - csaKeyStore := ksMocks.NewCSA(t) - - key, err := csakey.NewV2() - require.NoError(t, err) - csaKeyStore.On("GetAll").Return([]csakey.KeyV2{key}, nil) - keyStore := NewKsa(db, lggr, csaKeyStore) - - simEthKeyStore := testhelpers.EthKeyStoreSim{ - ETHKS: keyStore.Eth(), - CSAKS: keyStore.CSA(), - } - mailMon := mailbox.NewMonitor("CCIP", lggr.Named("Mailbox")) - evmOpts := chainlink.EVMFactoryConfig{ - ChainOpts: legacyevm.ChainOpts{ - AppConfig: config, - GenEthClient: func(chainID *big.Int) client.Client { - if chainID.String() == sourceChainID.String() { - return sourceClient - } else if chainID.String() == destChainID.String() { - return destClient - } - t.Fatalf("invalid chain ID %v", chainID.String()) - return nil - }, - MailMon: mailMon, - DS: db, - }, - CSAETHKeystore: simEthKeyStore, - } - - beholderAuthHeaders, csaPubKeyHex, err := keystore.BuildBeholderAuth(keyStore) - require.NoError(t, err) - - loopRegistry := plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), config.Tracing(), config.Telemetry(), beholderAuthHeaders, csaPubKeyHex) - relayerFactory := chainlink.RelayerFactory{ - Logger: lggr, - LoopRegistry: loopRegistry, - GRPCOpts: loop.GRPCOpts{}, - CapabilitiesRegistry: coretypes.NewCapabilitiesRegistry(t), - } - testCtx := testutils.Context(t) - // evm alway enabled for backward compatibility - initOps := []chainlink.CoreRelayerChainInitFunc{ - chainlink.InitEVM(testCtx, relayerFactory, evmOpts), - } - - relayChainInterops, err := chainlink.NewCoreRelayerChainInteroperators(initOps...) - if err != nil { - t.Fatal(err) - } - - app, err := chainlink.NewApplication(chainlink.ApplicationOpts{ - Config: config, - DS: db, - KeyStore: keyStore, - RelayerChainInteroperators: relayChainInterops, - Logger: lggr, - ExternalInitiatorManager: nil, - CloseLogger: lggr.Sync, - UnrestrictedHTTPClient: &http.Client{}, - RestrictedHTTPClient: &http.Client{}, - AuditLogger: audit.NoopLogger, - MailMon: mailMon, - LoopRegistry: plugins.NewLoopRegistry(lggr, config.Tracing(), config.Telemetry(), beholderAuthHeaders, csaPubKeyHex), - }) - ctx := testutils.Context(t) - require.NoError(t, err) - require.NoError(t, app.GetKeyStore().Unlock(ctx, "password")) - _, err = app.GetKeyStore().P2P().Create(ctx) - require.NoError(t, err) - - p2pIDs, err := app.GetKeyStore().P2P().GetAll() - require.NoError(t, err) - require.Len(t, p2pIDs, 1) - peerID := p2pIDs[0].PeerID() - - _, err = app.GetKeyStore().Eth().Create(testCtx, destChainID) - require.NoError(t, err) - sendingKeys, err := app.GetKeyStore().Eth().EnabledKeysForChain(testCtx, destChainID) - require.NoError(t, err) - require.Len(t, sendingKeys, 1) - transmitter := sendingKeys[0].Address - s, err := app.GetKeyStore().Eth().GetState(testCtx, sendingKeys[0].ID(), destChainID) - require.NoError(t, err) - lggr.Debug(fmt.Sprintf("Transmitter address %s chainID %s", transmitter, s.EVMChainID.String())) - - // Fund the commitTransmitter address with some ETH - destChain.Commit() - n, err := destChain.Client().NonceAt(tests.Context(t), owner.From, nil) - require.NoError(t, err) - tx := types3.NewTransaction(n, transmitter, big.NewInt(1000000000000000000), 21000, big.NewInt(1000000000), nil) - signedTx, err := owner.Signer(owner.From, tx) - require.NoError(t, err) - err = destChain.Client().SendTransaction(tests.Context(t), signedTx) - require.NoError(t, err) - destChain.Commit() - - kb, err := app.GetKeyStore().OCR2().Create(ctx, chaintype.EVM) - require.NoError(t, err) - return app, peerID.Raw(), transmitter, kb -} - -func createConfigV2Chain(chainId *big.Int) *v2.EVMConfig { - // NOTE: For the executor jobs, the default of 500k is insufficient for a 3 message batch - defaultGasLimit := uint64(5000000) - tr := true - - sourceC := v2.Defaults((*evmUtils.Big)(chainId)) - sourceC.GasEstimator.LimitDefault = &defaultGasLimit - fixedPrice := "FixedPrice" - sourceC.GasEstimator.Mode = &fixedPrice - d, _ := config.NewDuration(100 * time.Millisecond) - sourceC.LogPollInterval = &d - fd := uint32(2) - sourceC.FinalityDepth = &fd - return &v2.EVMConfig{ - ChainID: (*evmUtils.Big)(chainId), - Enabled: &tr, - Chain: sourceC, - Nodes: v2.EVMNodes{&v2.Node{}}, - } -} - -type CCIPIntegrationTestHarness struct { - CCIPContracts - Nodes []Node - Bootstrap Node -} - -func SetupCCIPIntegrationTH(t *testing.T, sourceChainID, sourceChainSelector, destChainId, destChainSelector uint64) CCIPIntegrationTestHarness { - return CCIPIntegrationTestHarness{ - CCIPContracts: SetupCCIPContracts(t, sourceChainID, sourceChainSelector, destChainId, destChainSelector), - } -} - -func (c *CCIPIntegrationTestHarness) CreatePricesPipeline(t *testing.T) (string, *httptest.Server, *httptest.Server) { - linkUSD := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { - _, err := w.Write([]byte(`{"UsdPerLink": "8000000000000000000"}`)) - require.NoError(t, err) - })) - ethUSD := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { - _, err := w.Write([]byte(`{"UsdPerETH": "1700000000000000000000"}`)) - require.NoError(t, err) - })) - sourceWrappedNative, err := c.Source.Router.GetWrappedNative(nil) - require.NoError(t, err) - destWrappedNative, err := c.Dest.Router.GetWrappedNative(nil) - require.NoError(t, err) - tokenPricesUSDPipeline := fmt.Sprintf(` -// Price 1 -link [type=http method=GET url="%s"]; -link_parse [type=jsonparse path="UsdPerLink"]; -link->link_parse; -eth [type=http method=GET url="%s"]; -eth_parse [type=jsonparse path="UsdPerETH"]; -eth->eth_parse; -merge [type=merge left="{}" right="{\\\"%s\\\":$(link_parse), \\\"%s\\\":$(eth_parse), \\\"%s\\\":$(eth_parse)}"];`, - linkUSD.URL, ethUSD.URL, c.Dest.LinkToken.Address(), sourceWrappedNative, destWrappedNative) - - return tokenPricesUSDPipeline, linkUSD, ethUSD -} - -func (c *CCIPIntegrationTestHarness) AddAllJobs(t *testing.T, jobParams integrationtesthelpers.CCIPJobSpecParams) { - jobParams.OffRamp = c.Dest.OffRamp.Address() - - commitSpec, err := jobParams.CommitJobSpec() - require.NoError(t, err) - geExecutionSpec, err := jobParams.ExecutionJobSpec() - require.NoError(t, err) - nodes := c.Nodes - for _, node := range nodes { - node.AddJobsWithSpec(t, commitSpec) - node.AddJobsWithSpec(t, geExecutionSpec) - } -} - -func (c *CCIPIntegrationTestHarness) jobSpecProposal(t *testing.T, specTemplate string, f func() (*integrationtesthelpers.OCR2TaskJobSpec, error), feedsManagerId int64, version int32, opts ...any) feeds2.ProposeJobArgs { - spec, err := f() - require.NoError(t, err) - - args := []any{spec.OCR2OracleSpec.ContractID} - args = append(args, opts...) - - return feeds2.ProposeJobArgs{ - FeedsManagerID: feedsManagerId, - RemoteUUID: uuid.New(), - Multiaddrs: nil, - Version: version, - Spec: fmt.Sprintf(specTemplate, args...), - } -} - -func (c *CCIPIntegrationTestHarness) SetupFeedsManager(t *testing.T) { - ctx := testutils.Context(t) - for _, node := range c.Nodes { - f := node.App.GetFeedsService() - - managers, err := f.ListManagers(ctx) - require.NoError(t, err) - if len(managers) > 0 { - // Use at most one feeds manager, don't register if one already exists - continue - } - - secret := utils.RandomBytes32() - pkey, err := crypto.PublicKeyFromHex(hex.EncodeToString(secret[:])) - require.NoError(t, err) - - m := feeds2.RegisterManagerParams{ - Name: "CCIP", - URI: "http://localhost:8080", - PublicKey: *pkey, - } - - _, err = f.RegisterManager(testutils.Context(t), m) - require.NoError(t, err) - - connManager := feedsMocks.NewConnectionsManager(t) - connManager.On("GetClient", mock.Anything).Maybe().Return(NoopFeedsClient{}, nil) - connManager.On("Close").Maybe().Return() - connManager.On("IsConnected", mock.Anything).Maybe().Return(true) - f.Unsafe_SetConnectionsManager(connManager) - } -} - -func (c *CCIPIntegrationTestHarness) ApproveJobSpecs(t *testing.T, jobParams integrationtesthelpers.CCIPJobSpecParams) { - ctx := testutils.Context(t) - - for _, node := range c.Nodes { - f := node.App.GetFeedsService() - managers, err := f.ListManagers(ctx) - require.NoError(t, err) - require.Len(t, managers, 1, "expected exactly one feeds manager") - - execSpec := c.jobSpecProposal( - t, - execSpecTemplate, - jobParams.ExecutionJobSpec, - managers[0].ID, - 1, - node.KeyBundle.ID(), - node.Transmitter.Hex(), - utils.RandomAddress().String(), - utils.RandomAddress().String(), - ) - execId, err := f.ProposeJob(ctx, &execSpec) - require.NoError(t, err) - - err = f.ApproveSpec(ctx, execId, true) - require.NoError(t, err) - - var commitSpec feeds2.ProposeJobArgs - if jobParams.TokenPricesUSDPipeline != "" { - commitSpec = c.jobSpecProposal( - t, - commitSpecTemplatePipeline, - jobParams.CommitJobSpec, - managers[0].ID, - 2, - node.KeyBundle.ID(), - node.Transmitter.Hex(), - jobParams.OffRamp.String(), - jobParams.TokenPricesUSDPipeline, - ) - } else { - commitSpec = c.jobSpecProposal( - t, - commitSpecTemplateDynamicPriceGetter, - jobParams.CommitJobSpec, - managers[0].ID, - 2, - node.KeyBundle.ID(), - node.Transmitter.Hex(), - jobParams.OffRamp.String(), - jobParams.PriceGetterConfig, - ) - } - - commitId, err := f.ProposeJob(ctx, &commitSpec) - require.NoError(t, err) - - err = f.ApproveSpec(ctx, commitId, true) - require.NoError(t, err) - } -} - -func (c *CCIPIntegrationTestHarness) AllNodesHaveReqSeqNum(t *testing.T, seqNum int, onRampOpts ...common.Address) logpoller.Log { - var log logpoller.Log - nodes := c.Nodes - var onRamp common.Address - if len(onRampOpts) > 0 { - onRamp = onRampOpts[0] - } else { - require.NotNil(t, c.Source.OnRamp, "no onramp configured") - onRamp = c.Source.OnRamp.Address() - } - for _, node := range nodes { - log = node.EventuallyHasReqSeqNum(t, c, onRamp, seqNum) - } - return log -} - -func (c *CCIPIntegrationTestHarness) AllNodesHaveExecutedSeqNums(t *testing.T, minSeqNum int, maxSeqNum int, offRampOpts ...common.Address) []logpoller.Log { - var logs []logpoller.Log - nodes := c.Nodes - var offRamp common.Address - - if len(offRampOpts) > 0 { - offRamp = offRampOpts[0] - } else { - require.NotNil(t, c.Dest.OffRamp, "no offramp configured") - offRamp = c.Dest.OffRamp.Address() - } - for _, node := range nodes { - logs = node.EventuallyHasExecutedSeqNums(t, c, offRamp, minSeqNum, maxSeqNum) - } - return logs -} - -func (c *CCIPIntegrationTestHarness) NoNodesHaveExecutedSeqNum(t *testing.T, seqNum int, offRampOpts ...common.Address) logpoller.Log { - var log logpoller.Log - nodes := c.Nodes - var offRamp common.Address - if len(offRampOpts) > 0 { - offRamp = offRampOpts[0] - } else { - require.NotNil(t, c.Dest.OffRamp, "no offramp configured") - offRamp = c.Dest.OffRamp.Address() - } - for _, node := range nodes { - log = node.ConsistentlySeqNumHasNotBeenExecuted(t, c, offRamp, seqNum) - } - return log -} - -func (c *CCIPIntegrationTestHarness) EventuallyCommitReportAccepted(t *testing.T, currentBlock uint64, commitStoreOpts ...common.Address) commit_store_1_2_0.CommitStoreCommitReport { - var commitStore *commit_store_1_2_0.CommitStore - var err error - if len(commitStoreOpts) > 0 { - commitStore, err = commit_store_1_2_0.NewCommitStore(commitStoreOpts[0], c.Dest.Chain.Client()) - require.NoError(t, err) - } else { - require.NotNil(t, c.Dest.CommitStore, "no commitStore configured") - commitStore = c.Dest.CommitStore - } - g := gomega.NewGomegaWithT(t) - var report commit_store_1_2_0.CommitStoreCommitReport - g.Eventually(func() bool { - it, err := commitStore.FilterReportAccepted(&bind.FilterOpts{Start: currentBlock}) - g.Expect(err).NotTo(gomega.HaveOccurred(), "Error filtering ReportAccepted event") - g.Expect(it.Next()).To(gomega.BeTrue(), "No ReportAccepted event found") - report = it.Event.Report - if report.MerkleRoot != [32]byte{} { - t.Log("Report Accepted by commitStore") - return true - } - return false - }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "report has not been committed") - return report -} - -func (c *CCIPIntegrationTestHarness) EventuallyExecutionStateChangedToSuccess(t *testing.T, seqNum []uint64, blockNum uint64, offRampOpts ...common.Address) { - var offRamp *evm_2_evm_offramp_1_2_0.EVM2EVMOffRamp - var err error - if len(offRampOpts) > 0 { - offRamp, err = evm_2_evm_offramp_1_2_0.NewEVM2EVMOffRamp(offRampOpts[0], c.Dest.Chain.Client()) - require.NoError(t, err) - } else { - require.NotNil(t, c.Dest.OffRamp, "no offRamp configured") - offRamp = c.Dest.OffRamp - } - gomega.NewGomegaWithT(t).Eventually(func() bool { - it, err := offRamp.FilterExecutionStateChanged(&bind.FilterOpts{Start: blockNum}, seqNum, [][32]byte{}) - require.NoError(t, err) - for it.Next() { - if cciptypes.MessageExecutionState(it.Event.State) == cciptypes.ExecutionStateSuccess { - t.Logf("ExecutionStateChanged event found for seqNum %d", it.Event.SequenceNumber) - return true - } - } - c.Source.Chain.Commit() - c.Dest.Chain.Commit() - return false - }, testutils.WaitTimeout(t), time.Second). - Should(gomega.BeTrue(), "ExecutionStateChanged Event") -} - -func (c *CCIPIntegrationTestHarness) EventuallyReportCommitted(t *testing.T, max int, commitStoreOpts ...common.Address) uint64 { - var commitStore *commit_store_1_2_0.CommitStore - var err error - var committedSeqNum uint64 - if len(commitStoreOpts) > 0 { - commitStore, err = commit_store_1_2_0.NewCommitStore(commitStoreOpts[0], c.Dest.Chain.Client()) - require.NoError(t, err) - } else { - require.NotNil(t, c.Dest.CommitStore, "no commitStore configured") - commitStore = c.Dest.CommitStore - } - gomega.NewGomegaWithT(t).Eventually(func() bool { - minSeqNum, err := commitStore.GetExpectedNextSequenceNumber(nil) - require.NoError(t, err) - c.Source.Chain.Commit() - c.Dest.Chain.Commit() - t.Log("next expected seq num reported", minSeqNum) - committedSeqNum = minSeqNum - return minSeqNum > uint64(max) - }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue(), "report has not been committed") - return committedSeqNum -} - -func (c *CCIPIntegrationTestHarness) EventuallySendRequested(t *testing.T, seqNum uint64, onRampOpts ...common.Address) { - var onRamp *evm_2_evm_onramp_1_2_0.EVM2EVMOnRamp - var err error - if len(onRampOpts) > 0 { - onRamp, err = evm_2_evm_onramp_1_2_0.NewEVM2EVMOnRamp(onRampOpts[0], c.Source.Chain.Client()) - require.NoError(t, err) - } else { - require.NotNil(t, c.Source.OnRamp, "no onRamp configured") - onRamp = c.Source.OnRamp - } - gomega.NewGomegaWithT(t).Eventually(func() bool { - it, err := onRamp.FilterCCIPSendRequested(nil) - require.NoError(t, err) - for it.Next() { - if it.Event.Message.SequenceNumber == seqNum { - t.Log("sendRequested generated for", seqNum) - return true - } - } - c.Source.Chain.Commit() - c.Dest.Chain.Commit() - return false - }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue(), "sendRequested has not been generated") -} - -func (c *CCIPIntegrationTestHarness) ConsistentlyReportNotCommitted(t *testing.T, max int, commitStoreOpts ...common.Address) { - var commitStore *commit_store_1_2_0.CommitStore - var err error - if len(commitStoreOpts) > 0 { - commitStore, err = commit_store_1_2_0.NewCommitStore(commitStoreOpts[0], c.Dest.Chain.Client()) - require.NoError(t, err) - } else { - require.NotNil(t, c.Dest.CommitStore, "no commitStore configured") - commitStore = c.Dest.CommitStore - } - gomega.NewGomegaWithT(t).Consistently(func() bool { - minSeqNum, err := commitStore.GetExpectedNextSequenceNumber(nil) - require.NoError(t, err) - c.Source.Chain.Commit() - c.Dest.Chain.Commit() - t.Log("min seq num reported", minSeqNum) - require.GreaterOrEqual(t, max, 0) - return minSeqNum > uint64(max) //nolint:gosec // G115 false positive - }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeFalse(), "report has been committed") -} - -func (c *CCIPIntegrationTestHarness) SetupAndStartNodes(ctx context.Context, t *testing.T, bootstrapNodePort int64) (Node, []Node, uint64) { - appBootstrap, bootstrapPeerID, bootstrapTransmitter, bootstrapKb := setupNodeCCIP(t, c.Dest.User, bootstrapNodePort, - "bootstrap_ccip", c.Source.Chain, c.Dest.Chain, big.NewInt(0).SetUint64(c.Source.ChainID), - big.NewInt(0).SetUint64(c.Dest.ChainID), "", 0) - var ( - oracles []confighelper.OracleIdentityExtra - nodes []Node - ) - err := appBootstrap.Start(ctx) - require.NoError(t, err) - t.Cleanup(func() { - require.NoError(t, appBootstrap.Stop()) - }) - bootstrapNode := Node{ - App: appBootstrap, - Transmitter: bootstrapTransmitter, - KeyBundle: bootstrapKb, - } - // Set up the minimum 4 oracles all funded with destination ETH - for i := int64(0); i < 4; i++ { - app, peerID, transmitter, kb := setupNodeCCIP( - t, - c.Dest.User, - int64(freeport.GetOne(t)), - fmt.Sprintf("oracle_ccip%d", i), - c.Source.Chain, - c.Dest.Chain, - big.NewInt(0).SetUint64(c.Source.ChainID), - big.NewInt(0).SetUint64(c.Dest.ChainID), - bootstrapPeerID, - bootstrapNodePort, - ) - nodes = append(nodes, Node{ - App: app, - Transmitter: transmitter, - KeyBundle: kb, - }) - offchainPublicKey, _ := hex.DecodeString(strings.TrimPrefix(kb.OnChainPublicKey(), "0x")) - oracles = append(oracles, confighelper.OracleIdentityExtra{ - OracleIdentity: confighelper.OracleIdentity{ - OnchainPublicKey: offchainPublicKey, - TransmitAccount: types4.Account(transmitter.String()), - OffchainPublicKey: kb.OffchainPublicKey(), - PeerID: peerID, - }, - ConfigEncryptionPublicKey: kb.ConfigEncryptionPublicKey(), - }) - err = app.Start(ctx) - require.NoError(t, err) - t.Cleanup(func() { - require.NoError(t, app.Stop()) - }) - } - - c.Oracles = oracles - commitOnchainConfig := c.CreateDefaultCommitOnchainConfig(t) - commitOffchainConfig := c.CreateDefaultCommitOffchainConfig(t) - execOnchainConfig := c.CreateDefaultExecOnchainConfig(t) - execOffchainConfig := c.CreateDefaultExecOffchainConfig(t) - - configBlock := c.SetupOnchainConfig(t, commitOnchainConfig, commitOffchainConfig, execOnchainConfig, execOffchainConfig) - c.Nodes = nodes - c.Bootstrap = bootstrapNode - //nolint:gosec // G115 - return bootstrapNode, nodes, uint64(configBlock) -} - -func (c *CCIPIntegrationTestHarness) SetUpNodesAndJobs(t *testing.T, pricePipeline string, priceGetterConfig string, usdcAttestationAPI string) integrationtesthelpers.CCIPJobSpecParams { - // setup Jobs - ctx := tests.Context(t) - // Starts nodes and configures them in the OCR contracts. - bootstrapNode, _, configBlock := c.SetupAndStartNodes(ctx, t, int64(freeport.GetOne(t))) - - jobParams := c.NewCCIPJobSpecParams(pricePipeline, priceGetterConfig, configBlock, usdcAttestationAPI) - - // Add the bootstrap job - c.Bootstrap.AddBootstrapJob(t, jobParams.BootstrapJob(c.Dest.CommitStore.Address().Hex())) - c.AddAllJobs(t, jobParams) - - // Replay for bootstrap. - bc, err := bootstrapNode.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(c.Dest.ChainID, 10)) - require.NoError(t, err) - require.LessOrEqual(t, configBlock, uint64(math.MaxInt64)) - require.NoError(t, bc.LogPoller().Replay(tests.Context(t), int64(configBlock))) //nolint:gosec // G115 false positive - c.Dest.Chain.Commit() - - return jobParams -} - -func (c *CCIPIntegrationTestHarness) NewCCIPJobSpecParams(tokenPricesUSDPipeline string, priceGetterConfig string, configBlock uint64, usdcAttestationAPI string) integrationtesthelpers.CCIPJobSpecParams { - return integrationtesthelpers.CCIPJobSpecParams{ - CommitStore: c.Dest.CommitStore.Address(), - OffRamp: c.Dest.OffRamp.Address(), - DestEvmChainId: c.Dest.ChainID, - SourceChainName: "SimulatedSource", - DestChainName: "SimulatedDest", - TokenPricesUSDPipeline: tokenPricesUSDPipeline, - PriceGetterConfig: priceGetterConfig, - DestStartBlock: configBlock, - USDCAttestationAPI: usdcAttestationAPI, - } -} - -func DecodeCommitOnChainConfig(encoded []byte) (ccipdata.CommitOnchainConfig, error) { - var onchainConfig ccipdata.CommitOnchainConfig - unpacked, err := abihelpers.DecodeOCR2Config(encoded) - if err != nil { - return onchainConfig, err - } - onChainCfg := unpacked.OnchainConfig - onchainConfig, err = abihelpers.DecodeAbiStruct[ccipdata.CommitOnchainConfig](onChainCfg) - if err != nil { - return onchainConfig, err - } - return onchainConfig, nil -} - -func DecodeExecOnChainConfig(encoded []byte) (v1_2_0.ExecOnchainConfig, error) { - var onchainConfig v1_2_0.ExecOnchainConfig - unpacked, err := abihelpers.DecodeOCR2Config(encoded) - if err != nil { - return onchainConfig, errors.Wrap(err, "failed to unpack log data") - } - onChainCfg := unpacked.OnchainConfig - onchainConfig, err = abihelpers.DecodeAbiStruct[v1_2_0.ExecOnchainConfig](onChainCfg) - if err != nil { - return onchainConfig, err - } - return onchainConfig, nil -} - -type ksa struct { - keystore.Master - csa keystore.CSA -} - -func (k *ksa) CSA() keystore.CSA { - return k.csa -} - -func NewKsa(db *sqlx.DB, lggr logger.Logger, csa keystore.CSA) *ksa { - return &ksa{ - Master: keystore.New(db, clutils.FastScryptParams, lggr), - csa: csa, - } -} - -type NoopFeedsClient struct{} - -func (n NoopFeedsClient) ApprovedJob(context.Context, *pb.ApprovedJobRequest) (*pb.ApprovedJobResponse, error) { - return &pb.ApprovedJobResponse{}, nil -} - -func (n NoopFeedsClient) Healthcheck(context.Context, *pb.HealthcheckRequest) (*pb.HealthcheckResponse, error) { - return &pb.HealthcheckResponse{}, nil -} - -func (n NoopFeedsClient) UpdateNode(context.Context, *pb.UpdateNodeRequest) (*pb.UpdateNodeResponse, error) { - return &pb.UpdateNodeResponse{}, nil -} - -func (n NoopFeedsClient) RejectedJob(context.Context, *pb.RejectedJobRequest) (*pb.RejectedJobResponse, error) { - return &pb.RejectedJobResponse{}, nil -} - -func (n NoopFeedsClient) CancelledJob(context.Context, *pb.CancelledJobRequest) (*pb.CancelledJobResponse, error) { - return &pb.CancelledJobResponse{}, nil -} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/config_1_4_0.go b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/config_1_4_0.go deleted file mode 100644 index 087c21e9333..00000000000 --- a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/config_1_4_0.go +++ /dev/null @@ -1,75 +0,0 @@ -// Package with set of configs that should be used only within tests suites - -package testhelpers_1_4_0 - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink-common/pkg/config" - - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" -) - -var PermissionLessExecutionThresholdSeconds = uint32(testhelpers.FirstBlockAge.Seconds()) - -func (c *CCIPContracts) CreateDefaultCommitOnchainConfig(t *testing.T) []byte { - config, err := abihelpers.EncodeAbiStruct(ccipdata.CommitOnchainConfig{ - PriceRegistry: c.Dest.PriceRegistry.Address(), - }) - require.NoError(t, err) - return config -} - -func (c *CCIPContracts) CreateDefaultCommitOffchainConfig(t *testing.T) []byte { - return c.createCommitOffchainConfig(t, 10*time.Second, 5*time.Second) -} - -func (c *CCIPContracts) createCommitOffchainConfig(t *testing.T, feeUpdateHearBeat time.Duration, inflightCacheExpiry time.Duration) []byte { - config, err := NewCommitOffchainConfig( - *config.MustNewDuration(feeUpdateHearBeat), - 1, - 1, - *config.MustNewDuration(feeUpdateHearBeat), - 1, - *config.MustNewDuration(inflightCacheExpiry), - false, - ).Encode() - require.NoError(t, err) - return config -} - -func (c *CCIPContracts) CreateDefaultExecOnchainConfig(t *testing.T) []byte { - config, err := abihelpers.EncodeAbiStruct(v1_2_0.ExecOnchainConfig{ - PermissionLessExecutionThresholdSeconds: PermissionLessExecutionThresholdSeconds, - Router: c.Dest.Router.Address(), - PriceRegistry: c.Dest.PriceRegistry.Address(), - MaxDataBytes: 1e5, - MaxNumberOfTokensPerMsg: 5, - MaxPoolReleaseOrMintGas: 200_000, - }) - require.NoError(t, err) - return config -} - -func (c *CCIPContracts) CreateDefaultExecOffchainConfig(t *testing.T) []byte { - return c.createExecOffchainConfig(t, 1*time.Minute, 1*time.Minute) -} - -func (c *CCIPContracts) createExecOffchainConfig(t *testing.T, inflightCacheExpiry time.Duration, rootSnoozeTime time.Duration) []byte { - config, err := NewExecOffchainConfig( - 1, - 5_000_000, - 0.07, - *config.MustNewDuration(inflightCacheExpiry), - *config.MustNewDuration(rootSnoozeTime), - uint32(0), - ).Encode() - require.NoError(t, err) - return config -} diff --git a/integration-tests/ccip-tests/contracts/contract_deployer.go b/integration-tests/ccip-tests/contracts/contract_deployer.go index c97e7bbc0aa..1f2859ae0db 100644 --- a/integration-tests/ccip-tests/contracts/contract_deployer.go +++ b/integration-tests/ccip-tests/contracts/contract_deployer.go @@ -57,7 +57,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" ) @@ -1415,16 +1414,6 @@ func NewCommitOffchainConfig( InflightCacheExpiry, priceReportingDisabled, ), nil - case V1_2_0: - return testhelpers_1_4_0.NewCommitOffchainConfig( - GasPriceHeartBeat, - DAGasPriceDeviationPPB, - ExecGasPriceDeviationPPB, - TokenPriceHeartBeat, - TokenPriceDeviationPPB, - InflightCacheExpiry, - priceReportingDisabled, - ), nil default: return nil, fmt.Errorf("version not supported: %s", VersionMap[CommitStoreContract]) } @@ -1436,8 +1425,6 @@ func NewCommitOnchainConfig( switch VersionMap[CommitStoreContract] { case Latest: return testhelpers.NewCommitOnchainConfig(PriceRegistry), nil - case V1_2_0: - return testhelpers_1_4_0.NewCommitOnchainConfig(PriceRegistry), nil default: return nil, fmt.Errorf("version not supported: %s", VersionMap[CommitStoreContract]) } @@ -1454,15 +1441,6 @@ func NewExecOnchainConfig( switch VersionMap[OffRampContract] { case Latest: return testhelpers.NewExecOnchainConfig(PermissionLessExecutionThresholdSeconds, Router, PriceRegistry, MaxNumberOfTokensPerMsg, MaxDataBytes), nil - case V1_2_0: - return testhelpers_1_4_0.NewExecOnchainConfig( - PermissionLessExecutionThresholdSeconds, - Router, - PriceRegistry, - MaxNumberOfTokensPerMsg, - MaxDataBytes, - MaxPoolReleaseOrMintGas, - ), nil default: return nil, fmt.Errorf("version not supported: %s", VersionMap[OffRampContract]) } @@ -1487,15 +1465,6 @@ func NewExecOffchainConfig( rootSnoozeTime, batchingStrategyID, ), nil - case V1_2_0: - return testhelpers_1_4_0.NewExecOffchainConfig( - destOptimisticConfirmations, - batchGasLimit, - relativeBoostPerWaitHour, - inflightCacheExpiry, - rootSnoozeTime, - batchingStrategyID, - ), nil default: return nil, fmt.Errorf("version not supported: %s", VersionMap[OffRampContract]) } From 84208295f0945c5a1188387c20ea4a1771459216 Mon Sep 17 00:00:00 2001 From: Street <5597260+MStreet3@users.noreply.github.com> Date: Mon, 9 Dec 2024 21:31:34 +0200 Subject: [PATCH 12/29] fix(workflows/syncer): skips fetching data for missing urls (#15519) --- core/services/workflows/syncer/handler.go | 18 +- .../services/workflows/syncer/handler_test.go | 235 ++++++++++++------ 2 files changed, 168 insertions(+), 85 deletions(-) diff --git a/core/services/workflows/syncer/handler.go b/core/services/workflows/syncer/handler.go index 46dcd21ed90..077dbc0cedb 100644 --- a/core/services/workflows/syncer/handler.go +++ b/core/services/workflows/syncer/handler.go @@ -383,14 +383,20 @@ func (h *eventHandler) workflowRegisteredEvent( return fmt.Errorf("failed to fetch binary from %s : %w", payload.BinaryURL, err) } - config, err := h.fetcher(ctx, payload.ConfigURL) - if err != nil { - return fmt.Errorf("failed to fetch config from %s : %w", payload.ConfigURL, err) + var config []byte + if payload.ConfigURL != "" { + config, err = h.fetcher(ctx, payload.ConfigURL) + if err != nil { + return fmt.Errorf("failed to fetch config from %s : %w", payload.ConfigURL, err) + } } - secrets, err := h.fetcher(ctx, payload.SecretsURL) - if err != nil { - return fmt.Errorf("failed to fetch secrets from %s : %w", payload.SecretsURL, err) + var secrets []byte + if payload.SecretsURL != "" { + secrets, err = h.fetcher(ctx, payload.SecretsURL) + if err != nil { + return fmt.Errorf("failed to fetch secrets from %s : %w", payload.SecretsURL, err) + } } // Calculate the hash of the binary and config files diff --git a/core/services/workflows/syncer/handler_test.go b/core/services/workflows/syncer/handler_test.go index bb0a61aea4d..7d11d347a02 100644 --- a/core/services/workflows/syncer/handler_test.go +++ b/core/services/workflows/syncer/handler_test.go @@ -173,59 +173,161 @@ const ( ) func Test_workflowRegisteredHandler(t *testing.T) { - t.Run("success with paused workflow registered", func(t *testing.T) { - var ( - ctx = testutils.Context(t) - lggr = logger.TestLogger(t) - db = pgtest.NewSqlxDB(t) - orm = NewWorkflowRegistryDS(db, lggr) - emitter = custmsg.NewLabeler() + var binaryURL = "http://example.com/binary" + var secretsURL = "http://example.com/secrets" + var configURL = "http://example.com/config" + var config = []byte("") + var wfOwner = []byte("0xOwner") + var binary = wasmtest.CreateTestBinary(binaryCmd, binaryLocation, true, t) + defaultValidationFn := func(t *testing.T, ctx context.Context, h *eventHandler, wfOwner []byte, wfName string, wfID string) { + // Verify the record is updated in the database + dbSpec, err := h.orm.GetWorkflowSpec(ctx, hex.EncodeToString(wfOwner), "workflow-name") + require.NoError(t, err) + require.Equal(t, hex.EncodeToString(wfOwner), dbSpec.WorkflowOwner) + require.Equal(t, "workflow-name", dbSpec.WorkflowName) + require.Equal(t, job.WorkflowSpecStatusActive, dbSpec.Status) - binary = wasmtest.CreateTestBinary(binaryCmd, binaryLocation, true, t) - config = []byte("") - secretsURL = "http://example.com" - binaryURL = "http://example.com/binary" - configURL = "http://example.com/config" - wfOwner = []byte("0xOwner") + // Verify the engine is started + engine, err := h.engineRegistry.Get(wfID) + require.NoError(t, err) + err = engine.Ready() + require.NoError(t, err) + } - fetcher = newMockFetcher(map[string]mockFetchResp{ + var tt = []testCase{ + { + Name: "success with active workflow registered", + fetcher: newMockFetcher(map[string]mockFetchResp{ binaryURL: {Body: binary, Err: nil}, configURL: {Body: config, Err: nil}, secretsURL: {Body: []byte("secrets"), Err: nil}, - }) - ) - - giveWFID, err := pkgworkflows.GenerateWorkflowID(wfOwner, binary, config, secretsURL) - require.NoError(t, err) - - paused := WorkflowRegistryWorkflowRegisteredV1{ - Status: uint8(1), - WorkflowID: giveWFID, - Owner: wfOwner, - WorkflowName: "workflow-name", - BinaryURL: binaryURL, - ConfigURL: configURL, - SecretsURL: secretsURL, - } + }), + GiveConfig: config, + ConfigURL: configURL, + SecretsURL: secretsURL, + BinaryURL: binaryURL, + GiveBinary: binary, + WFOwner: wfOwner, + Event: func(wfID []byte) WorkflowRegistryWorkflowRegisteredV1 { + return WorkflowRegistryWorkflowRegisteredV1{ + Status: uint8(0), + WorkflowID: [32]byte(wfID), + Owner: wfOwner, + WorkflowName: "workflow-name", + BinaryURL: binaryURL, + ConfigURL: configURL, + SecretsURL: secretsURL, + } + }, + validationFn: defaultValidationFn, + }, + { + Name: "success with paused workflow registered", + fetcher: newMockFetcher(map[string]mockFetchResp{ + binaryURL: {Body: binary, Err: nil}, + configURL: {Body: config, Err: nil}, + secretsURL: {Body: []byte("secrets"), Err: nil}, + }), + GiveConfig: config, + ConfigURL: configURL, + SecretsURL: secretsURL, + BinaryURL: binaryURL, + GiveBinary: binary, + WFOwner: wfOwner, + Event: func(wfID []byte) WorkflowRegistryWorkflowRegisteredV1 { + return WorkflowRegistryWorkflowRegisteredV1{ + Status: uint8(1), + WorkflowID: [32]byte(wfID), + Owner: wfOwner, + WorkflowName: "workflow-name", + BinaryURL: binaryURL, + ConfigURL: configURL, + SecretsURL: secretsURL, + } + }, + validationFn: func(t *testing.T, ctx context.Context, h *eventHandler, wfOwner []byte, wfName string, wfID string) { + // Verify the record is updated in the database + dbSpec, err := h.orm.GetWorkflowSpec(ctx, hex.EncodeToString(wfOwner), "workflow-name") + require.NoError(t, err) + require.Equal(t, hex.EncodeToString(wfOwner), dbSpec.WorkflowOwner) + require.Equal(t, "workflow-name", dbSpec.WorkflowName) + require.Equal(t, job.WorkflowSpecStatusPaused, dbSpec.Status) + + // Verify there is no running engine + _, err = h.engineRegistry.Get(wfID) + require.Error(t, err) + }, + }, + { + Name: "skips fetch if config url is missing", + GiveConfig: make([]byte, 0), + ConfigURL: "", + SecretsURL: secretsURL, + BinaryURL: binaryURL, + GiveBinary: binary, + WFOwner: wfOwner, + fetcher: newMockFetcher(map[string]mockFetchResp{ + binaryURL: {Body: binary, Err: nil}, + secretsURL: {Body: []byte("secrets"), Err: nil}, + }), + validationFn: defaultValidationFn, + Event: func(wfID []byte) WorkflowRegistryWorkflowRegisteredV1 { + return WorkflowRegistryWorkflowRegisteredV1{ + Status: uint8(0), + WorkflowID: [32]byte(wfID), + Owner: wfOwner, + WorkflowName: "workflow-name", + BinaryURL: binaryURL, + SecretsURL: secretsURL, + } + }, + }, + { + Name: "skips fetch if secrets url is missing", + GiveConfig: config, + ConfigURL: configURL, + BinaryURL: binaryURL, + GiveBinary: binary, + WFOwner: wfOwner, + fetcher: newMockFetcher(map[string]mockFetchResp{ + binaryURL: {Body: binary, Err: nil}, + configURL: {Body: config, Err: nil}, + }), + validationFn: defaultValidationFn, + Event: func(wfID []byte) WorkflowRegistryWorkflowRegisteredV1 { + return WorkflowRegistryWorkflowRegisteredV1{ + Status: uint8(0), + WorkflowID: [32]byte(wfID), + Owner: wfOwner, + WorkflowName: "workflow-name", + BinaryURL: binaryURL, + ConfigURL: configURL, + } + }, + }, + } - h := &eventHandler{ - lggr: lggr, - orm: orm, - fetcher: fetcher, - emitter: emitter, - } - err = h.workflowRegisteredEvent(ctx, paused) - require.NoError(t, err) + for _, tc := range tt { + testRunningWorkflow(t, tc) + } +} - // Verify the record is updated in the database - dbSpec, err := orm.GetWorkflowSpec(ctx, hex.EncodeToString(wfOwner), "workflow-name") - require.NoError(t, err) - require.Equal(t, hex.EncodeToString(wfOwner), dbSpec.WorkflowOwner) - require.Equal(t, "workflow-name", dbSpec.WorkflowName) - require.Equal(t, job.WorkflowSpecStatusPaused, dbSpec.Status) - }) +type testCase struct { + Name string + SecretsURL string + BinaryURL string + GiveBinary []byte + GiveConfig []byte + ConfigURL string + WFOwner []byte + fetcher FetcherFunc + Event func([]byte) WorkflowRegistryWorkflowRegisteredV1 + validationFn func(t *testing.T, ctx context.Context, h *eventHandler, wfOwner []byte, wfName string, wfID string) +} - t.Run("success with active workflow registered", func(t *testing.T) { +func testRunningWorkflow(t *testing.T, cmd testCase) { + t.Helper() + t.Run(cmd.Name, func(t *testing.T) { var ( ctx = testutils.Context(t) lggr = logger.TestLogger(t) @@ -233,34 +335,20 @@ func Test_workflowRegisteredHandler(t *testing.T) { orm = NewWorkflowRegistryDS(db, lggr) emitter = custmsg.NewLabeler() - binary = wasmtest.CreateTestBinary(binaryCmd, binaryLocation, true, t) - config = []byte("") - secretsURL = "http://example.com" - binaryURL = "http://example.com/binary" - configURL = "http://example.com/config" - wfOwner = []byte("0xOwner") + binary = cmd.GiveBinary + config = cmd.GiveConfig + secretsURL = cmd.SecretsURL + wfOwner = cmd.WFOwner - fetcher = newMockFetcher(map[string]mockFetchResp{ - binaryURL: {Body: binary, Err: nil}, - configURL: {Body: config, Err: nil}, - secretsURL: {Body: []byte("secrets"), Err: nil}, - }) + fetcher = cmd.fetcher ) giveWFID, err := pkgworkflows.GenerateWorkflowID(wfOwner, binary, config, secretsURL) require.NoError(t, err) - require.NoError(t, err) + wfID := hex.EncodeToString(giveWFID[:]) - active := WorkflowRegistryWorkflowRegisteredV1{ - Status: uint8(0), - WorkflowID: giveWFID, - Owner: wfOwner, - WorkflowName: "workflow-name", - BinaryURL: binaryURL, - ConfigURL: configURL, - SecretsURL: secretsURL, - } + event := cmd.Event(giveWFID[:]) er := newEngineRegistry() store := wfstore.NewDBStore(db, lggr, clockwork.NewFakeClock()) @@ -275,21 +363,10 @@ func Test_workflowRegisteredHandler(t *testing.T) { capRegistry: registry, workflowStore: store, } - err = h.workflowRegisteredEvent(ctx, active) - require.NoError(t, err) - - // Verify the record is updated in the database - dbSpec, err := orm.GetWorkflowSpec(ctx, hex.EncodeToString(wfOwner), "workflow-name") + err = h.workflowRegisteredEvent(ctx, event) require.NoError(t, err) - require.Equal(t, hex.EncodeToString(wfOwner), dbSpec.WorkflowOwner) - require.Equal(t, "workflow-name", dbSpec.WorkflowName) - require.Equal(t, job.WorkflowSpecStatusActive, dbSpec.Status) - // Verify the engine is started - engine, err := h.engineRegistry.Get(hex.EncodeToString(giveWFID[:])) - require.NoError(t, err) - err = engine.Ready() - require.NoError(t, err) + cmd.validationFn(t, ctx, h, wfOwner, "workflow-name", wfID) }) } From 202e6b5652d7109c599678d7686e81811ee18373 Mon Sep 17 00:00:00 2001 From: jlaveracll Date: Mon, 9 Dec 2024 16:42:55 -0300 Subject: [PATCH 13/29] [SHIP-3521] Add tests to L2EP contracts to improve test coverage (#14341) * Add tests trying to improve test coverage * Increate testing and clean up * prettier * Update MockBaseSequencerUptimeFeed.sol * Create stale-cougars-approve.md * Update l2ep.gas-snapshot * [Bot] Update changeset file with jira issue * Revert "Update l2ep.gas-snapshot" This reverts commit 6e0d21131eb46355d8ff189370c2bb11a08514e1. * Update l2ep.gas-snapshot * fix comments and clean up scroll tests * Update l2ep.gas-snapshot * Update ZKSyncSequencerUptimeFeed.t.sol * fix gas snapshot * Update ScrollSequencerUptimeFeed.t.sol * Update ScrollSequencerUptimeFeed.t.sol * Update l2ep.gas-snapshot * rename l2ep -> shared to l2ep -> base * cleanup * address feedback * Renames tests to follow Solidity convetions * [Bot] Update changeset file with jira issues --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> Co-authored-by: Mohamed Mehany <7327188+mohamed-mehany@users.noreply.github.com> --- .github/workflows/solidity-foundry.yml | 2 +- contracts/.changeset/thirty-rules-rule.md | 10 + contracts/gas-snapshots/l2ep.gas-snapshot | 79 ++-- .../BaseSequencerUptimeFeed.sol | 19 +- .../l2ep/{shared => base}/BaseValidator.sol | 2 +- .../optimism/OptimismSequencerUptimeFeed.sol | 2 +- .../v0.8/l2ep/optimism/OptimismValidator.sol | 2 +- .../l2ep/scroll/ScrollSequencerUptimeFeed.sol | 2 +- .../src/v0.8/l2ep/scroll/ScrollValidator.sol | 2 +- .../mocks/MockBaseSequencerUptimeFeed.sol | 25 ++ .../l2ep/test/mocks/MockBaseValidator.sol | 23 ++ .../OptimismSequencerUptimeFeed.t.sol | 302 ++------------ .../v1_0_0/optimism/OptimismValidator.t.sol | 24 +- .../scroll/ScrollCrossDomainForwarder.t.sol | 6 - .../scroll/ScrollCrossDomainGovernor.t.sol | 11 - .../scroll/ScrollSequencerUptimeFeed.t.sol | 310 +++----------- .../test/v1_0_0/scroll/ScrollValidator.t.sol | 37 +- .../shared/BaseSequencerUptimeFeed.t.sol | 377 ++++++++++++++++++ .../test/v1_0_0/shared/BaseValidator.t.sol | 57 +++ .../zksync/ZKSyncSequencerUptimeFeed.t.sol | 293 ++------------ .../test/v1_0_0/zksync/ZKSyncValidator.t.sol | 50 +-- .../l2ep/zksync/ZKSyncSequencerUptimeFeed.sol | 2 +- .../src/v0.8/l2ep/zksync/ZKSyncValidator.sol | 2 +- 23 files changed, 702 insertions(+), 937 deletions(-) create mode 100644 contracts/.changeset/thirty-rules-rule.md rename contracts/src/v0.8/l2ep/{shared => base}/BaseSequencerUptimeFeed.sol (93%) rename contracts/src/v0.8/l2ep/{shared => base}/BaseValidator.sol (96%) create mode 100644 contracts/src/v0.8/l2ep/test/mocks/MockBaseSequencerUptimeFeed.sol create mode 100644 contracts/src/v0.8/l2ep/test/mocks/MockBaseValidator.sol create mode 100644 contracts/src/v0.8/l2ep/test/v1_0_0/shared/BaseSequencerUptimeFeed.t.sol create mode 100644 contracts/src/v0.8/l2ep/test/v1_0_0/shared/BaseValidator.t.sol diff --git a/.github/workflows/solidity-foundry.yml b/.github/workflows/solidity-foundry.yml index b94c0236155..850374b0cd3 100644 --- a/.github/workflows/solidity-foundry.yml +++ b/.github/workflows/solidity-foundry.yml @@ -33,7 +33,7 @@ jobs: { "name": "ccip", "setup": { "run-coverage": true, "min-coverage": 98.8, "extra-coverage-params": "--no-match-path='*End2End*'", "run-gas-snapshot": true, "run-forge-fmt": true }}, { "name": "functions", "setup": { "run-coverage": false, "min-coverage": 98.5, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "keystone", "setup": { "run-coverage": true, "min-coverage": 72.8, "run-gas-snapshot": false, "run-forge-fmt": false }}, - { "name": "l2ep", "setup": { "run-coverage": true, "min-coverage": 61.0, "run-gas-snapshot": true, "run-forge-fmt": false }}, + { "name": "l2ep", "setup": { "run-coverage": true, "min-coverage": 65.0, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "liquiditymanager", "setup": { "run-coverage": true, "min-coverage": 44, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "llo-feeds", "setup": { "run-coverage": true, "min-coverage": 49.3, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "operatorforwarder", "setup": { "run-coverage": true, "min-coverage": 55.7, "run-gas-snapshot": true, "run-forge-fmt": false }}, diff --git a/contracts/.changeset/thirty-rules-rule.md b/contracts/.changeset/thirty-rules-rule.md new file mode 100644 index 00000000000..1c69192981c --- /dev/null +++ b/contracts/.changeset/thirty-rules-rule.md @@ -0,0 +1,10 @@ +--- +'@chainlink/contracts': patch +--- + +[L2EP] Refactor tests and fix file exclusion for coverage + + +PR issue: SHIP-3521 + +Solidity Review issue: SHIP-4050 \ No newline at end of file diff --git a/contracts/gas-snapshots/l2ep.gas-snapshot b/contracts/gas-snapshots/l2ep.gas-snapshot index 643127b6212..7caca346f48 100644 --- a/contracts/gas-snapshots/l2ep.gas-snapshot +++ b/contracts/gas-snapshots/l2ep.gas-snapshot @@ -34,6 +34,18 @@ ArbitrumSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerA ArbitrumSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 114527) ArbitrumSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 114610) ArbitrumValidator_Validate:test_PostSequencerOffline() (gas: 69009) +BaseSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface_ReturnsValidData() (gas: 69197) +BaseSequencerUptimeFeed_AggregatorV3Interface:test_getAnswer_ReturnsValidAnswer() (gas: 57300) +BaseSequencerUptimeFeed_AggregatorV3Interface:test_getTimestamp_ReturnsValidTimestamp() (gas: 57151) +BaseSequencerUptimeFeed_Constructor:test_Constructor_InitialState() (gas: 22050) +BaseSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_ProtectReads_AllowWhen_Whitelisted() (gas: 589517) +BaseSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_ProtectReads_DisallowWhen_NotWhitelisted() (gas: 562342) +BaseSequencerUptimeFeed_UpdateStatus:test_updateStatus_IgnoreOutOfOrderUpdates() (gas: 69490) +BaseSequencerUptimeFeed_UpdateStatus:test_updateStatus_UpdateWhen_NoStatusChangeSameTimestamp() (gas: 77166) +BaseSequencerUptimeFeed_UpdateStatus:test_updateStatus_UpdateWhen_StatusChangeAndNoTimeChange() (gas: 96021) +BaseSequencerUptimeFeed_UpdateStatus:test_updateStatus_UpdateWhen_StatusChangeAndTimeChange() (gas: 96100) +BaseSequencerUptimeFeed_transferL1Sender:test_transferL1Sender_CorrectlyTransfersL1Sender() (gas: 1479310) +BaseValidator_GetAndSetGasLimit:test_GetAndSetGasLimit_CorrectlyHandlesGasLimit() (gas: 20119) OptimismCrossDomainForwarder_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47110) OptimismCrossDomainForwarder_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 22135) OptimismCrossDomainForwarder_Constructor:test_InitialState() (gas: 21947) @@ -60,23 +72,10 @@ OptimismCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 4 OptimismCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28733) OptimismCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16456) OptimismCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11044) -OptimismSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 72286) -OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17639) -OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetRoundDataWhenRoundDoesNotExistYet() (gas: 17875) -OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17628) -OptimismSequencerUptimeFeed_Constructor:test_InitialState() (gas: 22002) -OptimismSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 589475) -OptimismSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 562336) -OptimismSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 67804) -OptimismSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13109) -OptimismSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddrAndNotL1SenderAddr() (gas: 23523) -OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 77205) -OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 96089) -OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 96172) -OptimismValidator_SetGasLimit:test_CorrectlyUpdatesTheGasLimit() (gas: 18636) -OptimismValidator_Validate:test_PostSequencerOffline() (gas: 74764) -OptimismValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 74798) -OptimismValidator_Validate:test_RevertsIfCalledByAnAccountWithNoAccess() (gas: 15556) +OptimismSequencerUptimeFeed_Constructor:test_Constructor_InitialState() (gas: 1530881) +OptimismSequencerUptimeFeed_ValidateSender:test_ValidateSender_UpdateStatusWhen_StatusChangeAndNoTimeChange() (gas: 17874) +OptimismValidator_Validate:test_Validate_PostSequencerOffline() (gas: 74773) +OptimismValidator_Validate:test_Validate_PostSequencerStatus_NoStatusChange() (gas: 74788) ScrollCrossDomainForwarder_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47196) ScrollCrossDomainForwarder_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 22185) ScrollCrossDomainForwarder_Constructor:test_InitialState() (gas: 21623) @@ -103,40 +102,12 @@ ScrollCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 489 ScrollCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28791) ScrollCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16456) ScrollCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11044) -ScrollSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 72309) -ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17639) -ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetRoundDataWhenRoundDoesNotExistYet() (gas: 17875) -ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17628) -ScrollSequencerUptimeFeed_Constructor:test_InitialState() (gas: 174353) -ScrollSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 589475) -ScrollSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 562336) -ScrollSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 67850) -ScrollSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13109) -ScrollSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddrAndNotL1SenderAddr() (gas: 23523) -ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 77251) -ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 96135) -ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 96218) -ScrollValidator_SetGasLimit:test_CorrectlyUpdatesTheGasLimit() (gas: 18770) -ScrollValidator_Validate:test_PostSequencerOffline() (gas: 78299) -ScrollValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 78339) -ScrollValidator_Validate:test_RevertsIfCalledByAnAccountWithNoAccess() (gas: 15556) -ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 67090) -ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17639) -ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetRoundDataWhenRoundDoesNotExistYet() (gas: 17875) -ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17628) -ZKSyncSequencerUptimeFeed_Constructor:test_InitialState() (gas: 22006) -ZKSyncSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 589495) -ZKSyncSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 562342) -ZKSyncSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 61883) -ZKSyncSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13055) -ZKSyncSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 71321) -ZKSyncSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 90176) -ZKSyncSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 90259) -ZKSyncValidator_Constructor:test_ConstructingRevertedWithInvalidChainId() (gas: 104069) -ZKSyncValidator_Constructor:test_ConstructingRevertedWithZeroL1BridgeAddress() (gas: 81784) -ZKSyncValidator_Constructor:test_ConstructingRevertedWithZeroL2UpdateFeedAddress() (gas: 81796) -ZKSyncValidator_GetChainId:test_CorrectlyGetsTheChainId() (gas: 8346) -ZKSyncValidator_GetSetL2GasPerPubdataByteLimit:test_CorrectlyGetsAndUpdatesTheGasPerPubdataByteLimit() (gas: 18896) -ZKSyncValidator_Validate:test_PostSequencerOffline() (gas: 52210) -ZKSyncValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 52279) -ZKSyncValidator_Validate:test_RevertsIfCalledByAnAccountWithNoAccess() (gas: 15623) \ No newline at end of file +ScrollSequencerUptimeFeed_Constructor:test_Constructor_InitialState_WhenValidL2XDomainMessenger() (gas: 1511902) +ScrollSequencerUptimeFeed_ValidateSender:test_ValidateSender_UpdateStatusWhen_StatusChangeAndNoTimeChange() (gas: 17864) +ScrollValidator_Validate:test_Validate_PostSequencerOffline() (gas: 78317) +ScrollValidator_Validate:test_Validate_PostSequencerStatus_NoStatusChange() (gas: 78338) +ZKSyncSequencerUptimeFeed_ValidateSender:test_ValidateSender_SuccessWhen_SenderIsValid() (gas: 12611) +ZKSyncValidator_GetChainId:test_GetChainId_CorrectlyGetsTheChainId() (gas: 8369) +ZKSyncValidator_GetSetL2GasPerPubdataByteLimit:test_GetSetL2GasPerPubdataByteLimit_CorrectlyHandlesGasPerPubdataByteLimit() (gas: 18918) +ZKSyncValidator_Validate:test_Validate_PostSequencerOffline() (gas: 52208) +ZKSyncValidator_Validate:test_Validate_PostSequencerStatus_NoStatusChange() (gas: 52280) \ No newline at end of file diff --git a/contracts/src/v0.8/l2ep/shared/BaseSequencerUptimeFeed.sol b/contracts/src/v0.8/l2ep/base/BaseSequencerUptimeFeed.sol similarity index 93% rename from contracts/src/v0.8/l2ep/shared/BaseSequencerUptimeFeed.sol rename to contracts/src/v0.8/l2ep/base/BaseSequencerUptimeFeed.sol index 344270fcff8..81fcb11ca95 100644 --- a/contracts/src/v0.8/l2ep/shared/BaseSequencerUptimeFeed.sol +++ b/contracts/src/v0.8/l2ep/base/BaseSequencerUptimeFeed.sol @@ -59,7 +59,7 @@ abstract contract BaseSequencerUptimeFeed is /// @param l1SenderAddress Address of the L1 contract that is permissioned to call this contract /// @param initialStatus The initial status of the feed constructor(address l1SenderAddress, bool initialStatus) { - // We neet to allow l1SenderAddress to be zero because this contract is deployed first + // We need to allow l1SenderAddress to be zero because this contract is deployed first // After deploying the validator contract, this contract will be updated with the correct L1 sender address _setL1Sender(l1SenderAddress); @@ -81,9 +81,9 @@ abstract contract BaseSequencerUptimeFeed is /// @notice Set the allowed L1 sender for this contract to a new L1 sender /// @dev Can be disabled by setting the L1 sender as `address(0)`. Accessible only by owner. - /// @param to new L1 sender that will be allowed to call `updateStatus` on this contract - function transferL1Sender(address to) external virtual onlyOwner { - _setL1Sender(to); + /// @param newSender new L1 sender that will be allowed to call `updateStatus` on this contract + function transferL1Sender(address newSender) external virtual onlyOwner { + _setL1Sender(newSender); } /// @notice internal method that stores the L1 sender @@ -164,13 +164,10 @@ abstract contract BaseSequencerUptimeFeed is return s_rounds[uint80(roundId)].startedAt; } - /** - * @notice Record a new status and timestamp if it has changed since the last round. - * @dev This function will revert if not called from `l1Sender` via the L1->L2 messenger. - * - * @param status Sequencer status - * @param timestamp Block timestamp of status update - */ + /// @notice Record a new status and timestamp if it has changed since the last round. + /// @dev This function will revert if not called from `l1Sender` via the L1->L2 messenger. + /// @param status Sequencer status + /// @param timestamp Block timestamp of status update function updateStatus(bool status, uint64 timestamp) external override { _validateSender(s_l1Sender); diff --git a/contracts/src/v0.8/l2ep/shared/BaseValidator.sol b/contracts/src/v0.8/l2ep/base/BaseValidator.sol similarity index 96% rename from contracts/src/v0.8/l2ep/shared/BaseValidator.sol rename to contracts/src/v0.8/l2ep/base/BaseValidator.sol index 8b38da391ec..4f9c6912a00 100644 --- a/contracts/src/v0.8/l2ep/shared/BaseValidator.sol +++ b/contracts/src/v0.8/l2ep/base/BaseValidator.sol @@ -24,7 +24,7 @@ abstract contract BaseValidator is SimpleWriteAccessController, AggregatorValida uint32 internal s_gasLimit; /// @param l1CrossDomainMessengerAddress address the L1CrossDomainMessenger contract address - /// @param l2UptimeFeedAddr the address of the SequencerUptimeFeed contract address + /// @param l2UptimeFeedAddr the address of the L2 SequencerUptimeFeed contract address /// @param gasLimit the gasLimit to use for sending a message from L1 to L2 constructor(address l1CrossDomainMessengerAddress, address l2UptimeFeedAddr, uint32 gasLimit) { if (l1CrossDomainMessengerAddress == address(0)) { diff --git a/contracts/src/v0.8/l2ep/optimism/OptimismSequencerUptimeFeed.sol b/contracts/src/v0.8/l2ep/optimism/OptimismSequencerUptimeFeed.sol index 0e6f9c52f22..b160fe46155 100644 --- a/contracts/src/v0.8/l2ep/optimism/OptimismSequencerUptimeFeed.sol +++ b/contracts/src/v0.8/l2ep/optimism/OptimismSequencerUptimeFeed.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -import {BaseSequencerUptimeFeed} from "../shared/BaseSequencerUptimeFeed.sol"; +import {BaseSequencerUptimeFeed} from "../base/BaseSequencerUptimeFeed.sol"; import {IL2CrossDomainMessenger} from "@eth-optimism/contracts/L2/messaging/IL2CrossDomainMessenger.sol"; diff --git a/contracts/src/v0.8/l2ep/optimism/OptimismValidator.sol b/contracts/src/v0.8/l2ep/optimism/OptimismValidator.sol index cf5222f017e..97c202dcd88 100644 --- a/contracts/src/v0.8/l2ep/optimism/OptimismValidator.sol +++ b/contracts/src/v0.8/l2ep/optimism/OptimismValidator.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.19; import {ISequencerUptimeFeed} from "./../interfaces/ISequencerUptimeFeed.sol"; -import {BaseValidator} from "../shared/BaseValidator.sol"; +import {BaseValidator} from "../base/BaseValidator.sol"; import {IL1CrossDomainMessenger} from "@eth-optimism/contracts/L1/messaging/IL1CrossDomainMessenger.sol"; diff --git a/contracts/src/v0.8/l2ep/scroll/ScrollSequencerUptimeFeed.sol b/contracts/src/v0.8/l2ep/scroll/ScrollSequencerUptimeFeed.sol index 40f2941aa69..9c0c22290f2 100644 --- a/contracts/src/v0.8/l2ep/scroll/ScrollSequencerUptimeFeed.sol +++ b/contracts/src/v0.8/l2ep/scroll/ScrollSequencerUptimeFeed.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; -import {BaseSequencerUptimeFeed} from "../shared/BaseSequencerUptimeFeed.sol"; +import {BaseSequencerUptimeFeed} from "../base/BaseSequencerUptimeFeed.sol"; import {IL2ScrollMessenger} from "@scroll-tech/contracts/L2/IL2ScrollMessenger.sol"; diff --git a/contracts/src/v0.8/l2ep/scroll/ScrollValidator.sol b/contracts/src/v0.8/l2ep/scroll/ScrollValidator.sol index b009c80fdfd..0eda14d0adc 100644 --- a/contracts/src/v0.8/l2ep/scroll/ScrollValidator.sol +++ b/contracts/src/v0.8/l2ep/scroll/ScrollValidator.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.24; import {ISequencerUptimeFeed} from "../interfaces/ISequencerUptimeFeed.sol"; -import {BaseValidator} from "../shared/BaseValidator.sol"; +import {BaseValidator} from "../base/BaseValidator.sol"; import {IL1MessageQueue} from "@scroll-tech/contracts/L1/rollup/IL1MessageQueue.sol"; import {IL1ScrollMessenger} from "@scroll-tech/contracts/L1/IL1ScrollMessenger.sol"; diff --git a/contracts/src/v0.8/l2ep/test/mocks/MockBaseSequencerUptimeFeed.sol b/contracts/src/v0.8/l2ep/test/mocks/MockBaseSequencerUptimeFeed.sol new file mode 100644 index 00000000000..50d852faa45 --- /dev/null +++ b/contracts/src/v0.8/l2ep/test/mocks/MockBaseSequencerUptimeFeed.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import {BaseSequencerUptimeFeed} from "../../base/BaseSequencerUptimeFeed.sol"; + +contract MockBaseSequencerUptimeFeed is BaseSequencerUptimeFeed { + string public constant override typeAndVersion = "MockSequencerUptimeFeed 1.1.0-dev"; + + /// @dev this will be used for internal testing + bool private s_validateSenderShouldPass; + + constructor( + address l1SenderAddress, + bool initialStatus, + bool validateSenderShouldPass + ) BaseSequencerUptimeFeed(l1SenderAddress, initialStatus) { + s_validateSenderShouldPass = validateSenderShouldPass; + } + + function _validateSender(address /* l1Sender */) internal view override { + if (!s_validateSenderShouldPass) { + revert InvalidSender(); + } + } +} diff --git a/contracts/src/v0.8/l2ep/test/mocks/MockBaseValidator.sol b/contracts/src/v0.8/l2ep/test/mocks/MockBaseValidator.sol new file mode 100644 index 00000000000..d23efb48656 --- /dev/null +++ b/contracts/src/v0.8/l2ep/test/mocks/MockBaseValidator.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import {BaseValidator} from "../../base/BaseValidator.sol"; + +contract MockBaseValidator is BaseValidator { + string public constant override typeAndVersion = "MockValidator 1.1.0-dev"; + + constructor( + address l1CrossDomainMessengerAddress, + address l2UptimeFeedAddr, + uint32 gasLimit + ) BaseValidator(l1CrossDomainMessengerAddress, l2UptimeFeedAddr, gasLimit) {} + + function validate( + uint256 /* previousRoundId */, + int256 /* previousAnswer */, + uint256 /* currentRoundId */, + int256 /* currentAnswer */ + ) external view override checkAccess returns (bool) { + return true; + } +} diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismSequencerUptimeFeed.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismSequencerUptimeFeed.t.sol index daf50962a1e..34010c313e8 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismSequencerUptimeFeed.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismSequencerUptimeFeed.t.sol @@ -4,30 +4,36 @@ pragma solidity 0.8.24; import {MockOptimismL1CrossDomainMessenger} from "../../../../tests/MockOptimismL1CrossDomainMessenger.sol"; import {MockOptimismL2CrossDomainMessenger} from "../../../../tests/MockOptimismL2CrossDomainMessenger.sol"; import {OptimismSequencerUptimeFeed} from "../../../optimism/OptimismSequencerUptimeFeed.sol"; -import {BaseSequencerUptimeFeed} from "../../../shared/BaseSequencerUptimeFeed.sol"; -import {FeedConsumer} from "../../../../tests/FeedConsumer.sol"; +import {BaseSequencerUptimeFeed} from "../../../base/BaseSequencerUptimeFeed.sol"; import {L2EPTest} from "../L2EPTest.t.sol"; -contract OptimismSequencerUptimeFeedTest is L2EPTest { - /// Constants - uint256 internal constant GAS_USED_DEVIATION = 100; +contract OptimismSequencerUptimeFeed_TestWrapper is OptimismSequencerUptimeFeed { + constructor( + address l1SenderAddress, + address l2CrossDomainMessengerAddr, + bool initialStatus + ) OptimismSequencerUptimeFeed(l1SenderAddress, l2CrossDomainMessengerAddr, initialStatus) {} + + /// @notice Exposes the internal `_validateSender` function for testing + function validateSenderTestWrapper(address l1Sender) external view { + super._validateSender(l1Sender); + } +} + +contract OptimismSequencerUptimeFeed_Setup is L2EPTest { + event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt); /// L2EP contracts MockOptimismL1CrossDomainMessenger internal s_mockOptimismL1CrossDomainMessenger; MockOptimismL2CrossDomainMessenger internal s_mockOptimismL2CrossDomainMessenger; - OptimismSequencerUptimeFeed internal s_optimismSequencerUptimeFeed; - - /// Events - event UpdateIgnored(bool latestStatus, uint64 latestTimestamp, bool incomingStatus, uint64 incomingTimestamp); - event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt); - event RoundUpdated(int256 status, uint64 updatedAt); + OptimismSequencerUptimeFeed_TestWrapper internal s_optimismSequencerUptimeFeed; /// Setup function setUp() public { - // Deploys contracts + // Deploy contracts s_mockOptimismL1CrossDomainMessenger = new MockOptimismL1CrossDomainMessenger(); s_mockOptimismL2CrossDomainMessenger = new MockOptimismL2CrossDomainMessenger(); - s_optimismSequencerUptimeFeed = new OptimismSequencerUptimeFeed( + s_optimismSequencerUptimeFeed = new OptimismSequencerUptimeFeed_TestWrapper( s_l1OwnerAddr, address(s_mockOptimismL2CrossDomainMessenger), false @@ -38,12 +44,14 @@ contract OptimismSequencerUptimeFeedTest is L2EPTest { } } -contract OptimismSequencerUptimeFeed_Constructor is OptimismSequencerUptimeFeedTest { - /// @notice it should have been deployed with the correct initial state - function test_InitialState() public { +contract OptimismSequencerUptimeFeed_Constructor is OptimismSequencerUptimeFeed_Setup { + /// @notice Tests the initial state of the contract + function test_Constructor_InitialState() public { // Sets msg.sender and tx.origin to a valid address vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); + new OptimismSequencerUptimeFeed_TestWrapper(s_l1OwnerAddr, address(s_mockOptimismL2CrossDomainMessenger), false); + // Checks L1 sender address actualL1Addr = s_optimismSequencerUptimeFeed.l1Sender(); assertEq(actualL1Addr, s_l1OwnerAddr); @@ -55,267 +63,33 @@ contract OptimismSequencerUptimeFeed_Constructor is OptimismSequencerUptimeFeedT } } -contract OptimismSequencerUptimeFeed_UpdateStatus is OptimismSequencerUptimeFeedTest { - /// @notice it should revert if called by an address that is not the L2 Cross Domain Messenger - function test_RevertIfNotL2CrossDomainMessengerAddr() public { - // Sets msg.sender and tx.origin to an unauthorized address - vm.startPrank(s_strangerAddr, s_strangerAddr); +contract OptimismSequencerUptimeFeed_ValidateSender is OptimismSequencerUptimeFeed_Setup { + /// @notice Reverts if called by an address that is not the L2 Cross Domain Messenger + function test_ValidateSender_RevertWhen_SenderIsNotL2CrossDomainMessengerAddr() public { + address l2MessengerAddr = address(s_mockOptimismL2CrossDomainMessenger); + // Sets msg.sender to a different address + vm.startPrank(s_strangerAddr, l2MessengerAddr); - // Tries to update the status from an unauthorized account vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(1)); + s_optimismSequencerUptimeFeed.validateSenderTestWrapper(s_l1OwnerAddr); } - /// @notice it should revert if called by an address that is not the L2 Cross Domain Messenger and is not the L1 sender - function test_RevertIfNotL2CrossDomainMessengerAddrAndNotL1SenderAddr() public { + /// @notice Reverts if the L1 sender address is not the L1 Cross Domain Messenger Sender + function test_ValidateSender_RevertWhen_L1CrossDomainMessengerAddrIsNotL1SenderAddr() public { // Sets msg.sender and tx.origin to an unauthorized address - vm.startPrank(s_strangerAddr, s_strangerAddr); - - // Sets mock sender in mock L2 messenger contract - s_mockOptimismL2CrossDomainMessenger.setSender(s_strangerAddr); - - // Tries to update the status from an unauthorized account - vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(1)); - } - - /// @notice it should update status when status has not changed and incoming timestamp is the same as latest - function test_UpdateStatusWhenNoChange() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockOptimismL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Fetches the latest timestamp - uint256 timestamp = s_optimismSequencerUptimeFeed.latestTimestamp(); - - // Submits a status update - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_optimismSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_optimismSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Stores the current round data before updating it - ( - uint80 roundIdBeforeUpdate, - int256 answerBeforeUpdate, - uint256 startedAtBeforeUpdate, - , - uint80 answeredInRoundBeforeUpdate - ) = s_optimismSequencerUptimeFeed.latestRoundData(); - - // Submit another status update with the same status - vm.expectEmit(); - emit RoundUpdated(1, uint64(block.timestamp)); - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(timestamp + 200)); - assertEq(s_optimismSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_optimismSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Stores the current round data after updating it - ( - uint80 roundIdAfterUpdate, - int256 answerAfterUpdate, - uint256 startedAtAfterUpdate, - uint256 updatedAtAfterUpdate, - uint80 answeredInRoundAfterUpdate - ) = s_optimismSequencerUptimeFeed.latestRoundData(); - - // Verifies the latest round data has been properly updated - assertEq(roundIdAfterUpdate, roundIdBeforeUpdate); - assertEq(answerAfterUpdate, answerBeforeUpdate); - assertEq(startedAtAfterUpdate, startedAtBeforeUpdate); - assertEq(answeredInRoundAfterUpdate, answeredInRoundBeforeUpdate); - assertEq(updatedAtAfterUpdate, block.timestamp); - } - - /// @notice it should update status when status has changed and incoming timestamp is newer than the latest - function test_UpdateStatusWhenStatusChangeAndTimeChange() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockOptimismL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Submits a status update - uint256 timestamp = s_optimismSequencerUptimeFeed.latestTimestamp(); - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_optimismSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_optimismSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Submit another status update, different status, newer timestamp should update - timestamp = timestamp + 200; - vm.expectEmit(); - emit AnswerUpdated(0, 3, timestamp); - s_optimismSequencerUptimeFeed.updateStatus(false, uint64(timestamp)); - assertEq(s_optimismSequencerUptimeFeed.latestAnswer(), 0); - assertEq(s_optimismSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - } - - /// @notice it should update status when status has changed and incoming timestamp is the same as latest - function test_UpdateStatusWhenStatusChangeAndNoTimeChange() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockOptimismL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Fetches the latest timestamp - uint256 timestamp = s_optimismSequencerUptimeFeed.latestTimestamp(); - - // Submits a status update - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_optimismSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_optimismSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Submit another status update, different status, same timestamp should update - vm.expectEmit(); - emit AnswerUpdated(0, 3, timestamp); - s_optimismSequencerUptimeFeed.updateStatus(false, uint64(timestamp)); - assertEq(s_optimismSequencerUptimeFeed.latestAnswer(), 0); - assertEq(s_optimismSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - } - - /// @notice it should ignore out-of-order updates - function test_IgnoreOutOfOrderUpdates() public { - // Sets msg.sender and tx.origin to a valid address address l2MessengerAddr = address(s_mockOptimismL2CrossDomainMessenger); vm.startPrank(l2MessengerAddr, l2MessengerAddr); - // Submits a status update - uint256 timestamp = s_optimismSequencerUptimeFeed.latestTimestamp() + 10000; - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_optimismSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_optimismSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Update with different status, but stale timestamp, should be ignored - timestamp = timestamp - 1000; - vm.expectEmit(false, false, false, false); - emit UpdateIgnored(true, 0, true, 0); // arguments are dummy values - // TODO: how can we check that an AnswerUpdated event was NOT emitted - s_optimismSequencerUptimeFeed.updateStatus(false, uint64(timestamp)); + vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); + s_optimismSequencerUptimeFeed.validateSenderTestWrapper(s_strangerAddr); } -} -contract OptimismSequencerUptimeFeed_AggregatorV3Interface is OptimismSequencerUptimeFeedTest { - /// @notice it should return valid answer from getRoundData and latestRoundData - function test_AggregatorV3Interface() public { + /// @notice Updates status when status has changed and incoming timestamp is the same as the latest + function test_ValidateSender_UpdateStatusWhen_StatusChangeAndNoTimeChange() public { // Sets msg.sender and tx.origin to a valid address address l2MessengerAddr = address(s_mockOptimismL2CrossDomainMessenger); vm.startPrank(l2MessengerAddr, l2MessengerAddr); - // Defines helper variables - uint80 roundId; - int256 answer; - uint256 startedAt; - uint256 updatedAt; - uint80 answeredInRound; - - // Checks initial state - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_optimismSequencerUptimeFeed.latestRoundData(); - assertEq(roundId, 1); - assertEq(answer, 0); - assertEq(answeredInRound, roundId); - assertEq(startedAt, updatedAt); - - // Submits status update with different status and newer timestamp, should update - uint256 timestamp = startedAt + 1000; - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_optimismSequencerUptimeFeed.getRoundData(2); - assertEq(roundId, 2); - assertEq(answer, 1); - assertEq(answeredInRound, roundId); - assertEq(startedAt, timestamp); - assertLe(updatedAt, startedAt); - - // Saves round 2 data - uint80 roundId2 = roundId; - int256 answer2 = answer; - uint256 startedAt2 = startedAt; - uint256 updatedAt2 = updatedAt; - uint80 answeredInRound2 = answeredInRound; - - // Checks that last round is still returning the correct data - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_optimismSequencerUptimeFeed.getRoundData(1); - assertEq(roundId, 1); - assertEq(answer, 0); - assertEq(answeredInRound, roundId); - assertEq(startedAt, updatedAt); - - // Assert latestRoundData corresponds to latest round id - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_optimismSequencerUptimeFeed.latestRoundData(); - assertEq(roundId2, roundId); - assertEq(answer2, answer); - assertEq(startedAt2, startedAt); - assertEq(updatedAt2, updatedAt); - assertEq(answeredInRound2, answeredInRound); - } - - /// @notice it should revert from #getRoundData when round does not yet exist (future roundId) - function test_RevertGetRoundDataWhenRoundDoesNotExistYet() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); - - // Gets data from a round that has not happened yet - vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); - s_optimismSequencerUptimeFeed.getRoundData(2); - } - - /// @notice it should revert from #getAnswer when round does not yet exist (future roundId) - function test_RevertGetAnswerWhenRoundDoesNotExistYet() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); - - // Gets data from a round that has not happened yet - vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); - s_optimismSequencerUptimeFeed.getAnswer(2); - } - - /// @notice it should revert from #getTimestamp when round does not yet exist (future roundId) - function test_RevertGetTimestampWhenRoundDoesNotExistYet() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); - - // Gets data from a round that has not happened yet - vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); - s_optimismSequencerUptimeFeed.getTimestamp(2); - } -} - -contract OptimismSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions is OptimismSequencerUptimeFeedTest { - /// @notice it should disallow reads on AggregatorV2V3Interface functions when consuming contract is not whitelisted - function test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() public { - // Deploys a FeedConsumer contract - FeedConsumer feedConsumer = new FeedConsumer(address(s_optimismSequencerUptimeFeed)); - - // Sanity - consumer is not whitelisted - assertEq(s_optimismSequencerUptimeFeed.checkEnabled(), true); - assertEq(s_optimismSequencerUptimeFeed.hasAccess(address(feedConsumer), abi.encode("")), false); - - // Asserts reads are not possible from consuming contract - vm.expectRevert("No access"); - feedConsumer.latestAnswer(); - vm.expectRevert("No access"); - feedConsumer.latestRoundData(); - } - - /// @notice it should allow reads on AggregatorV2V3Interface functions when consuming contract is whitelisted - function test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() public { - // Deploys a FeedConsumer contract - FeedConsumer feedConsumer = new FeedConsumer(address(s_optimismSequencerUptimeFeed)); - - // Whitelist consumer - s_optimismSequencerUptimeFeed.addAccess(address(feedConsumer)); - - // Sanity - consumer is whitelisted - assertEq(s_optimismSequencerUptimeFeed.checkEnabled(), true); - assertEq(s_optimismSequencerUptimeFeed.hasAccess(address(feedConsumer), abi.encode("")), true); - - // Asserts reads are possible from consuming contract - (uint80 roundId, int256 answer, , , ) = feedConsumer.latestRoundData(); - assertEq(feedConsumer.latestAnswer(), 0); - assertEq(roundId, 1); - assertEq(answer, 0); + s_optimismSequencerUptimeFeed.validateSenderTestWrapper(s_l1OwnerAddr); } } diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismValidator.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismValidator.t.sol index ba9e3f872f1..48ff1f7778d 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismValidator.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismValidator.t.sol @@ -9,7 +9,7 @@ import {OptimismSequencerUptimeFeed} from "../../../optimism/OptimismSequencerUp import {OptimismValidator} from "../../../optimism/OptimismValidator.sol"; import {L2EPTest} from "../L2EPTest.t.sol"; -contract OptimismValidatorTest is L2EPTest { +contract OptimismValidator_Setup is L2EPTest { /// Helper constants address internal constant L2_SEQ_STATUS_RECORDER_ADDRESS = 0x491B1dDA0A8fa069bbC1125133A975BF4e85a91b; uint32 internal constant INIT_GAS_LIMIT = 1900000; @@ -42,26 +42,16 @@ contract OptimismValidatorTest is L2EPTest { } } -contract OptimismValidator_SetGasLimit is OptimismValidatorTest { - /// @notice it correctly updates the gas limit - function test_CorrectlyUpdatesTheGasLimit() public { - uint32 newGasLimit = 2000000; - assertEq(s_optimismValidator.getGasLimit(), INIT_GAS_LIMIT); - s_optimismValidator.setGasLimit(newGasLimit); - assertEq(s_optimismValidator.getGasLimit(), newGasLimit); - } -} - -contract OptimismValidator_Validate is OptimismValidatorTest { +contract OptimismValidator_Validate is OptimismValidator_Setup { /// @notice it reverts if called by account with no access - function test_RevertsIfCalledByAnAccountWithNoAccess() public { + function test_Validate_RevertWhen_CalledByAccountWithNoAccess() public { vm.startPrank(s_strangerAddr); vm.expectRevert("No access"); s_optimismValidator.validate(0, 0, 1, 1); } - /// @notice it posts sequencer status when there is not status change - function test_PostSequencerStatusWhenThereIsNotStatusChange() public { + /// @notice it posts sequencer status when there is no status change + function test_Validate_PostSequencerStatus_NoStatusChange() public { // Gives access to the s_eoaValidator s_optimismValidator.addAccess(s_eoaValidator); @@ -84,8 +74,8 @@ contract OptimismValidator_Validate is OptimismValidatorTest { s_optimismValidator.validate(0, 0, 0, 0); } - /// @notice it post sequencer offline - function test_PostSequencerOffline() public { + /// @notice it posts sequencer offline + function test_Validate_PostSequencerOffline() public { // Gives access to the s_eoaValidator s_optimismValidator.addAccess(s_eoaValidator); diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainForwarder.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainForwarder.t.sol index b0ef7df22c1..0025c6b9937 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainForwarder.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainForwarder.t.sol @@ -54,7 +54,6 @@ contract ScrollCrossDomainForwarder_Forward is ScrollCrossDomainForwarderTest { /// @notice it should be callable by crossdomain messenger address / L1 owner function test_Forward() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Defines the cross domain message to send @@ -74,7 +73,6 @@ contract ScrollCrossDomainForwarder_Forward is ScrollCrossDomainForwarderTest { /// @notice it should revert when contract call reverts function test_ForwardRevert() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Sends an invalid message @@ -106,7 +104,6 @@ contract ScrollCrossDomainForwarder_TransferL1Ownership is ScrollCrossDomainForw /// @notice it should be callable by current L1 owner function test_CallableByL1Owner() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Defines the cross domain message to send @@ -124,7 +121,6 @@ contract ScrollCrossDomainForwarder_TransferL1Ownership is ScrollCrossDomainForw /// @notice it should be callable by current L1 owner to zero address function test_CallableByL1OwnerOrZeroAddress() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Defines the cross domain message to send @@ -144,7 +140,6 @@ contract ScrollCrossDomainForwarder_TransferL1Ownership is ScrollCrossDomainForw contract ScrollCrossDomainForwarder_AcceptL1Ownership is ScrollCrossDomainForwarderTest { /// @notice it should not be callable by non pending-owners function test_NotCallableByNonPendingOwners() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Sends the message @@ -159,7 +154,6 @@ contract ScrollCrossDomainForwarder_AcceptL1Ownership is ScrollCrossDomainForwar /// @notice it should be callable by pending L1 owner function test_CallableByPendingL1Owner() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Request ownership transfer diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainGovernor.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainGovernor.t.sol index 5eefaddab70..a2523e5feb6 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainGovernor.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainGovernor.t.sol @@ -58,7 +58,6 @@ contract ScrollCrossDomainGovernor_Forward is ScrollCrossDomainGovernorTest { /// @notice it should be callable by crossdomain messenger address / L1 owner function test_Forward() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Defines the cross domain message to send @@ -78,7 +77,6 @@ contract ScrollCrossDomainGovernor_Forward is ScrollCrossDomainGovernorTest { /// @notice it should revert when contract call reverts function test_ForwardRevert() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Sends an invalid message @@ -93,7 +91,6 @@ contract ScrollCrossDomainGovernor_Forward is ScrollCrossDomainGovernorTest { /// @notice it should be callable by L2 owner function test_CallableByL2Owner() public { - // Sets msg.sender and tx.origin vm.startPrank(s_l1OwnerAddr); // Defines the cross domain message to send @@ -120,7 +117,6 @@ contract ScrollCrossDomainGovernor_ForwardDelegate is ScrollCrossDomainGovernorT /// @notice it should be callable by crossdomain messenger address / L1 owner function test_CallableByCrossDomainMessengerAddressOrL1Owner() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Sends the message @@ -141,7 +137,6 @@ contract ScrollCrossDomainGovernor_ForwardDelegate is ScrollCrossDomainGovernorT /// @notice it should be callable by L2 owner function test_CallableByL2Owner() public { - // Sets msg.sender and tx.origin vm.startPrank(s_l1OwnerAddr); // Sends the message @@ -162,7 +157,6 @@ contract ScrollCrossDomainGovernor_ForwardDelegate is ScrollCrossDomainGovernorT /// @notice it should revert batch when one call fails function test_RevertsBatchWhenOneCallFails() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Sends an invalid message (empty transaction data is not allowed) @@ -184,7 +178,6 @@ contract ScrollCrossDomainGovernor_ForwardDelegate is ScrollCrossDomainGovernorT /// @notice it should bubble up revert when contract call reverts function test_BubbleUpRevert() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Sends an invalid message (empty transaction data is not allowed) @@ -220,7 +213,6 @@ contract ScrollCrossDomainGovernor_TransferL1Ownership is ScrollCrossDomainGover /// @notice it should be callable by current L1 owner function test_CallableByL1Owner() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Defines the cross domain message to send @@ -238,7 +230,6 @@ contract ScrollCrossDomainGovernor_TransferL1Ownership is ScrollCrossDomainGover /// @notice it should be callable by current L1 owner to zero address function test_CallableByL1OwnerOrZeroAddress() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Defines the cross domain message to send @@ -258,7 +249,6 @@ contract ScrollCrossDomainGovernor_TransferL1Ownership is ScrollCrossDomainGover contract ScrollCrossDomainGovernor_AcceptL1Ownership is ScrollCrossDomainGovernorTest { /// @notice it should not be callable by non pending-owners function test_NotCallableByNonPendingOwners() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Sends the message @@ -273,7 +263,6 @@ contract ScrollCrossDomainGovernor_AcceptL1Ownership is ScrollCrossDomainGoverno /// @notice it should be callable by pending L1 owner function test_CallableByPendingL1Owner() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Request ownership transfer diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollSequencerUptimeFeed.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollSequencerUptimeFeed.t.sol index 5e4d8a7a20f..1ad4bfd8119 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollSequencerUptimeFeed.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollSequencerUptimeFeed.t.sol @@ -4,18 +4,30 @@ pragma solidity 0.8.24; import {MockScrollL1CrossDomainMessenger} from "../../mocks/scroll/MockScrollL1CrossDomainMessenger.sol"; import {MockScrollL2CrossDomainMessenger} from "../../mocks/scroll/MockScrollL2CrossDomainMessenger.sol"; import {ScrollSequencerUptimeFeed} from "../../../scroll/ScrollSequencerUptimeFeed.sol"; -import {BaseSequencerUptimeFeed} from "../../../shared/BaseSequencerUptimeFeed.sol"; -import {FeedConsumer} from "../../../../tests/FeedConsumer.sol"; +import {BaseSequencerUptimeFeed} from "../../../base/BaseSequencerUptimeFeed.sol"; import {L2EPTest} from "../L2EPTest.t.sol"; -contract ScrollSequencerUptimeFeedTest is L2EPTest { +contract ScrollSequencerUptimeFeedTestWrapper is ScrollSequencerUptimeFeed { + constructor( + address l1SenderAddress, + address l2CrossDomainMessengerAddr, + bool initialStatus + ) ScrollSequencerUptimeFeed(l1SenderAddress, l2CrossDomainMessengerAddr, initialStatus) {} + + /// @notice It exposes the internal _validateSender function for testing + function validateSenderTestWrapper(address l1Sender) external view { + super._validateSender(l1Sender); + } +} + +contract ScrollSequencerUptimeFeed_Setup is L2EPTest { /// Constants uint256 internal constant GAS_USED_DEVIATION = 100; /// L2EP contracts MockScrollL1CrossDomainMessenger internal s_mockScrollL1CrossDomainMessenger; MockScrollL2CrossDomainMessenger internal s_mockScrollL2CrossDomainMessenger; - ScrollSequencerUptimeFeed internal s_scrollSequencerUptimeFeed; + ScrollSequencerUptimeFeedTestWrapper internal s_scrollSequencerUptimeFeed; /// Events event UpdateIgnored(bool latestStatus, uint64 latestTimestamp, bool incomingStatus, uint64 incomingTimestamp); @@ -27,7 +39,7 @@ contract ScrollSequencerUptimeFeedTest is L2EPTest { // Deploys contracts s_mockScrollL1CrossDomainMessenger = new MockScrollL1CrossDomainMessenger(); s_mockScrollL2CrossDomainMessenger = new MockScrollL2CrossDomainMessenger(); - s_scrollSequencerUptimeFeed = new ScrollSequencerUptimeFeed( + s_scrollSequencerUptimeFeed = new ScrollSequencerUptimeFeedTestWrapper( s_l1OwnerAddr, address(s_mockScrollL2CrossDomainMessenger), false @@ -38,14 +50,13 @@ contract ScrollSequencerUptimeFeedTest is L2EPTest { } } -contract ScrollSequencerUptimeFeed_Constructor is ScrollSequencerUptimeFeedTest { - /// @notice it should have been deployed with the correct initial state - function test_InitialState() public { +contract ScrollSequencerUptimeFeed_Constructor is ScrollSequencerUptimeFeed_Setup { + /// @notice Reverts when L2 Cross Domain Messenger address is invalid + function test_Constructor_RevertWhen_InvalidL2XDomainMessenger() public { // L2 cross domain messenger address must not be the zero address vm.expectRevert(ScrollSequencerUptimeFeed.ZeroAddress.selector); new ScrollSequencerUptimeFeed(s_l1OwnerAddr, address(0), false); - // Sets msg.sender and tx.origin to a valid address vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); // Checks L1 sender @@ -57,269 +68,50 @@ contract ScrollSequencerUptimeFeed_Constructor is ScrollSequencerUptimeFeedTest assertEq(roundId, 1); assertEq(answer, 0); } -} - -contract ScrollSequencerUptimeFeed_UpdateStatus is ScrollSequencerUptimeFeedTest { - /// @notice it should revert if called by an address that is not the L2 Cross Domain Messenger - function test_RevertIfNotL2CrossDomainMessengerAddr() public { - // Sets msg.sender and tx.origin to an unauthorized address - vm.startPrank(s_strangerAddr, s_strangerAddr); - - // Tries to update the status from an unauthorized account - vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(1)); - } - - /// @notice it should revert if called by an address that is not the L2 Cross Domain Messenger and is not the L1 sender - function test_RevertIfNotL2CrossDomainMessengerAddrAndNotL1SenderAddr() public { - // Sets msg.sender and tx.origin to an unauthorized address - vm.startPrank(s_strangerAddr, s_strangerAddr); - - // Sets mock sender in mock L2 messenger contract - s_mockScrollL2CrossDomainMessenger.setSender(s_strangerAddr); - - // Tries to update the status from an unauthorized account - vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(1)); - } - - /// @notice it should update status when status has not changed and incoming timestamp is the same as latest - function test_UpdateStatusWhenNoChange() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Fetches the latest timestamp - uint256 timestamp = s_scrollSequencerUptimeFeed.latestTimestamp(); - - // Submits a status update - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_scrollSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_scrollSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Stores the current round data before updating it - ( - uint80 roundIdBeforeUpdate, - int256 answerBeforeUpdate, - uint256 startedAtBeforeUpdate, - , - uint80 answeredInRoundBeforeUpdate - ) = s_scrollSequencerUptimeFeed.latestRoundData(); - - // Submit another status update with the same status - vm.expectEmit(); - emit RoundUpdated(1, uint64(block.timestamp)); - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(timestamp + 200)); - assertEq(s_scrollSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_scrollSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Stores the current round data after updating it - ( - uint80 roundIdAfterUpdate, - int256 answerAfterUpdate, - uint256 startedAtAfterUpdate, - uint256 updatedAtAfterUpdate, - uint80 answeredInRoundAfterUpdate - ) = s_scrollSequencerUptimeFeed.latestRoundData(); - - // Verifies the latest round data has been properly updated - assertEq(roundIdAfterUpdate, roundIdBeforeUpdate); - assertEq(answerAfterUpdate, answerBeforeUpdate); - assertEq(startedAtAfterUpdate, startedAtBeforeUpdate); - assertEq(answeredInRoundAfterUpdate, answeredInRoundBeforeUpdate); - assertEq(updatedAtAfterUpdate, block.timestamp); - } - - /// @notice it should update status when status has changed and incoming timestamp is newer than the latest - function test_UpdateStatusWhenStatusChangeAndTimeChange() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Submits a status update - uint256 timestamp = s_scrollSequencerUptimeFeed.latestTimestamp(); - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_scrollSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_scrollSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Submit another status update, different status, newer timestamp should update - timestamp = timestamp + 200; - vm.expectEmit(); - emit AnswerUpdated(0, 3, timestamp); - s_scrollSequencerUptimeFeed.updateStatus(false, uint64(timestamp)); - assertEq(s_scrollSequencerUptimeFeed.latestAnswer(), 0); - assertEq(s_scrollSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - } - - /// @notice it should update status when status has changed and incoming timestamp is the same as latest - function test_UpdateStatusWhenStatusChangeAndNoTimeChange() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Fetches the latest timestamp - uint256 timestamp = s_scrollSequencerUptimeFeed.latestTimestamp(); - - // Submits a status update - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_scrollSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_scrollSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Submit another status update, different status, same timestamp should update - vm.expectEmit(); - emit AnswerUpdated(0, 3, timestamp); - s_scrollSequencerUptimeFeed.updateStatus(false, uint64(timestamp)); - assertEq(s_scrollSequencerUptimeFeed.latestAnswer(), 0); - assertEq(s_scrollSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - } - - /// @notice it should ignore out-of-order updates - function test_IgnoreOutOfOrderUpdates() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Submits a status update - uint256 timestamp = s_scrollSequencerUptimeFeed.latestTimestamp() + 10000; - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_scrollSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_scrollSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Update with different status, but stale timestamp, should be ignored - timestamp = timestamp - 1000; - vm.expectEmit(false, false, false, false); - emit UpdateIgnored(true, 0, true, 0); // arguments are dummy values - // TODO: how can we check that an AnswerUpdated event was NOT emitted - s_scrollSequencerUptimeFeed.updateStatus(false, uint64(timestamp)); - } -} - -contract ScrollSequencerUptimeFeed_AggregatorV3Interface is ScrollSequencerUptimeFeedTest { - /// @notice it should return valid answer from getRoundData and latestRoundData - function test_AggregatorV3Interface() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - // Defines helper variables - uint80 roundId; - int256 answer; - uint256 startedAt; - uint256 updatedAt; - uint80 answeredInRound; - - // Checks initial state - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_scrollSequencerUptimeFeed.latestRoundData(); - assertEq(roundId, 1); - assertEq(answer, 0); - assertEq(answeredInRound, roundId); - assertEq(startedAt, updatedAt); - - // Submits status update with different status and newer timestamp, should update - uint256 timestamp = startedAt + 1000; - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_scrollSequencerUptimeFeed.getRoundData(2); - assertEq(roundId, 2); - assertEq(answer, 1); - assertEq(answeredInRound, roundId); - assertEq(startedAt, timestamp); - assertLe(updatedAt, startedAt); + /// @notice Tests initial state with valid L2 Cross Domain Messenger + function test_Constructor_InitialState_WhenValidL2XDomainMessenger() public { + vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); + ScrollSequencerUptimeFeed scrollSequencerUptimeFeed = new ScrollSequencerUptimeFeed( + s_l1OwnerAddr, + address(s_mockScrollL2CrossDomainMessenger), + false + ); - // Saves round 2 data - uint80 roundId2 = roundId; - int256 answer2 = answer; - uint256 startedAt2 = startedAt; - uint256 updatedAt2 = updatedAt; - uint80 answeredInRound2 = answeredInRound; + // Checks L1 sender + address actualL1Addr = scrollSequencerUptimeFeed.l1Sender(); + assertEq(actualL1Addr, s_l1OwnerAddr); - // Checks that last round is still returning the correct data - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_scrollSequencerUptimeFeed.getRoundData(1); + // Checks latest round data + (uint80 roundId, int256 answer, , , ) = scrollSequencerUptimeFeed.latestRoundData(); assertEq(roundId, 1); assertEq(answer, 0); - assertEq(answeredInRound, roundId); - assertEq(startedAt, updatedAt); - - // Assert latestRoundData corresponds to latest round id - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_scrollSequencerUptimeFeed.latestRoundData(); - assertEq(roundId2, roundId); - assertEq(answer2, answer); - assertEq(startedAt2, startedAt); - assertEq(updatedAt2, updatedAt); - assertEq(answeredInRound2, answeredInRound); - } - - /// @notice it should revert from #getRoundData when round does not yet exist (future roundId) - function test_RevertGetRoundDataWhenRoundDoesNotExistYet() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); - - // Gets data from a round that has not happened yet - vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); - s_scrollSequencerUptimeFeed.getRoundData(2); - } - - /// @notice it should revert from #getAnswer when round does not yet exist (future roundId) - function test_RevertGetAnswerWhenRoundDoesNotExistYet() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); - - // Gets data from a round that has not happened yet - vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); - s_scrollSequencerUptimeFeed.getAnswer(2); - } - - /// @notice it should revert from #getTimestamp when round does not yet exist (future roundId) - function test_RevertGetTimestampWhenRoundDoesNotExistYet() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); - - // Gets data from a round that has not happened yet - vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); - s_scrollSequencerUptimeFeed.getTimestamp(2); } } -contract ScrollSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions is ScrollSequencerUptimeFeedTest { - /// @notice it should disallow reads on AggregatorV2V3Interface functions when consuming contract is not whitelisted - function test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() public { - // Deploys a FeedConsumer contract - FeedConsumer feedConsumer = new FeedConsumer(address(s_scrollSequencerUptimeFeed)); - - // Sanity - consumer is not whitelisted - assertEq(s_scrollSequencerUptimeFeed.checkEnabled(), true); - assertEq(s_scrollSequencerUptimeFeed.hasAccess(address(feedConsumer), abi.encode("")), false); +contract ScrollSequencerUptimeFeed_ValidateSender is ScrollSequencerUptimeFeed_Setup { + /// @notice Reverts when sender is not L2 Cross Domain Messenger address + function test_ValidateSender_RevertWhen_SenderIsNotL2CrossDomainMessengerAddr() public { + vm.startPrank(s_strangerAddr); - // Asserts reads are not possible from consuming contract - vm.expectRevert("No access"); - feedConsumer.latestAnswer(); - vm.expectRevert("No access"); - feedConsumer.latestRoundData(); + vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); + s_scrollSequencerUptimeFeed.validateSenderTestWrapper(s_l1OwnerAddr); } - /// @notice it should allow reads on AggregatorV2V3Interface functions when consuming contract is whitelisted - function test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() public { - // Deploys a FeedConsumer contract - FeedConsumer feedConsumer = new FeedConsumer(address(s_scrollSequencerUptimeFeed)); + /// @notice Reverts when L1 Cross Domain Messenger address is not L1 sender address + function test_ValidateSender_RevertWhen_L1CrossDomainMessengerAddrIsNotL1SenderAddr() public { + address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); + vm.startPrank(l2MessengerAddr); - // Whitelist consumer - s_scrollSequencerUptimeFeed.addAccess(address(feedConsumer)); + vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); + s_scrollSequencerUptimeFeed.validateSenderTestWrapper(s_strangerAddr); + } - // Sanity - consumer is whitelisted - assertEq(s_scrollSequencerUptimeFeed.checkEnabled(), true); - assertEq(s_scrollSequencerUptimeFeed.hasAccess(address(feedConsumer), abi.encode("")), true); + /// @notice Updates status when status changes and incoming timestamp is the same as latest + function test_ValidateSender_UpdateStatusWhen_StatusChangeAndNoTimeChange() public { + address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); + vm.startPrank(l2MessengerAddr); - // Asserts reads are possible from consuming contract - (uint80 roundId, int256 answer, , , ) = feedConsumer.latestRoundData(); - assertEq(feedConsumer.latestAnswer(), 0); - assertEq(roundId, 1); - assertEq(answer, 0); + s_scrollSequencerUptimeFeed.validateSenderTestWrapper(s_l1OwnerAddr); } } diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollValidator.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollValidator.t.sol index 1a0bcc856f2..b7708889100 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollValidator.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollValidator.t.sol @@ -10,9 +10,9 @@ import {ScrollSequencerUptimeFeed} from "../../../scroll/ScrollSequencerUptimeFe import {ScrollValidator} from "../../../scroll/ScrollValidator.sol"; import {L2EPTest} from "../L2EPTest.t.sol"; -contract ScrollValidatorTest is L2EPTest { +contract ScrollValidator_Setup is L2EPTest { /// Helper constants - address internal constant L2_SEQ_STATUS_RECORDER_ADDRESS = 0x491B1dDA0A8fa069bbC1125133A975BF4e85a91b; + address internal immutable L2_SEQ_STATUS_RECORDER_ADDRESS = makeAddr("L2_SEQ_STATUS_RECORDER_ADDRESS"); uint32 internal constant INIT_GAS_LIMIT = 1900000; /// L2EP contracts @@ -53,26 +53,31 @@ contract ScrollValidatorTest is L2EPTest { } } -contract ScrollValidator_SetGasLimit is ScrollValidatorTest { - /// @notice it correctly updates the gas limit - function test_CorrectlyUpdatesTheGasLimit() public { - uint32 newGasLimit = 2000000; - assertEq(s_scrollValidator.getGasLimit(), INIT_GAS_LIMIT); - s_scrollValidator.setGasLimit(newGasLimit); - assertEq(s_scrollValidator.getGasLimit(), newGasLimit); +contract ScrollValidator_Constructor is ScrollValidator_Setup { + /// @notice Reverts when L1 message queue address is invalid + function test_Constructor_RevertWhen_InvalidL1MessageQueueAddress() public { + vm.startPrank(s_l1OwnerAddr); + + vm.expectRevert("Invalid L1 message queue address"); + new ScrollValidator( + address(s_mockScrollL1CrossDomainMessenger), + address(s_scrollSequencerUptimeFeed), + address(0), + INIT_GAS_LIMIT + ); } } -contract ScrollValidator_Validate is ScrollValidatorTest { - /// @notice it reverts if called by account with no access - function test_RevertsIfCalledByAnAccountWithNoAccess() public { +contract ScrollValidator_Validate is ScrollValidator_Setup { + /// @notice Reverts if called by an account with no access + function test_Validate_RevertWhen_CalledByAccountWithNoAccess() public { vm.startPrank(s_strangerAddr); vm.expectRevert("No access"); s_scrollValidator.validate(0, 0, 1, 1); } - /// @notice it posts sequencer status when there is not status change - function test_PostSequencerStatusWhenThereIsNotStatusChange() public { + /// @notice Posts sequencer status when there is no status change + function test_Validate_PostSequencerStatus_NoStatusChange() public { // Gives access to the s_eoaValidator s_scrollValidator.addAccess(s_eoaValidator); @@ -96,8 +101,8 @@ contract ScrollValidator_Validate is ScrollValidatorTest { s_scrollValidator.validate(0, 0, 0, 0); } - /// @notice it post sequencer offline - function test_PostSequencerOffline() public { + /// @notice Posts sequencer offline status + function test_Validate_PostSequencerOffline() public { // Gives access to the s_eoaValidator s_scrollValidator.addAccess(s_eoaValidator); diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/shared/BaseSequencerUptimeFeed.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/shared/BaseSequencerUptimeFeed.t.sol new file mode 100644 index 00000000000..20553e33bab --- /dev/null +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/shared/BaseSequencerUptimeFeed.t.sol @@ -0,0 +1,377 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import {Vm} from "forge-std/Test.sol"; +import {AddressAliasHelper} from "../../../../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol"; +import {BaseSequencerUptimeFeed} from "../../../base/BaseSequencerUptimeFeed.sol"; +import {MockBaseSequencerUptimeFeed} from "../../../test/mocks/MockBaseSequencerUptimeFeed.sol"; +import {FeedConsumer} from "../../../../tests/FeedConsumer.sol"; +import {L2EPTest} from "../L2EPTest.t.sol"; + +contract BaseSequencerUptimeFeed_Setup is L2EPTest { + /// Helper Variables + address internal s_aliasedL1OwnerAddress = AddressAliasHelper.applyL1ToL2Alias(s_l1OwnerAddr); + + /// L2EP contracts + BaseSequencerUptimeFeed internal s_sequencerUptimeFeed; + + /// Events + event UpdateIgnored(bool latestStatus, uint64 latestTimestamp, bool incomingStatus, uint64 incomingTimestamp); + event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt); + event RoundUpdated(int256 status, uint64 updatedAt); + event L1SenderTransferred(address indexed from, address indexed to); + + /// Setup + function setUp() public { + // Deploys contracts + s_sequencerUptimeFeed = new MockBaseSequencerUptimeFeed(s_l1OwnerAddr, false, true); + } +} + +contract BaseSequencerUptimeFeed_Constructor is BaseSequencerUptimeFeed_Setup { + /// @notice Tests initial state of the contract + function test_Constructor_InitialState() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); + + // Checks L1 sender + address actualL1Addr = s_sequencerUptimeFeed.l1Sender(); + assertEq(actualL1Addr, s_l1OwnerAddr); + + // Checks latest round data + (uint80 roundId, int256 answer, , , ) = s_sequencerUptimeFeed.latestRoundData(); + assertEq(roundId, 1); + assertEq(answer, 0); + } +} + +contract BaseSequencerUptimeFeed_transferL1Sender is BaseSequencerUptimeFeed_Setup { + /// @notice Tests transferring L1 sender + function test_transferL1Sender_CorrectlyTransfersL1Sender() public { + address initialSender = address(0); + address newSender = makeAddr("newSender"); + + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); + + MockBaseSequencerUptimeFeed sequencerUptimeFeed = new MockBaseSequencerUptimeFeed(initialSender, false, true); + + assertEq(sequencerUptimeFeed.l1Sender(), initialSender); + + // Transfers the L1 sender + vm.expectEmit(); + emit L1SenderTransferred(initialSender, newSender); + sequencerUptimeFeed.transferL1Sender(newSender); + assertEq(sequencerUptimeFeed.l1Sender(), newSender); + + vm.recordLogs(); + // Transfers to the same L1 sender should not emit an event + sequencerUptimeFeed.transferL1Sender(newSender); + assertEq(vm.getRecordedLogs().length, 0); + } + + /// @notice Reverts if called by an unauthorized account + function test_transferL1Sender_RevertWhen_CalledByUnauthorizedAccount() public { + address newSender = makeAddr("newSender"); + + // Sets msg.sender and tx.origin to an unauthorized address + vm.startPrank(s_strangerAddr, s_strangerAddr); + + vm.expectRevert("Only callable by owner"); + s_sequencerUptimeFeed.transferL1Sender(newSender); + } +} + +contract BaseSequencerUptimeFeed_UpdateStatus is BaseSequencerUptimeFeed_Setup { + /// @notice Reverts if called by an unauthorized account + function test_updateStatus_RevertWhen_NotL2CrossDomainMessengerAddr() public { + // Sets msg.sender and tx.origin to an unauthorized address + vm.startPrank(s_strangerAddr, s_strangerAddr); + + BaseSequencerUptimeFeed s_sequencerUptimeFeedFailSenderCheck = new MockBaseSequencerUptimeFeed( + s_l1OwnerAddr, + false, + false + ); + + // Tries to update the status from an unauthorized account + vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); + s_sequencerUptimeFeedFailSenderCheck.updateStatus(true, uint64(1)); + } + + /// @notice Updates status when status has not changed and incoming timestamp is the same as latest + function test_updateStatus_UpdateWhen_NoStatusChangeSameTimestamp() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); + + // Fetches the latest timestamp + uint256 timestamp = s_sequencerUptimeFeed.latestTimestamp(); + + // Submits a status update + vm.expectEmit(); + emit AnswerUpdated(1, 2, timestamp); + s_sequencerUptimeFeed.updateStatus(true, uint64(timestamp)); + assertEq(s_sequencerUptimeFeed.latestAnswer(), 1); + assertEq(s_sequencerUptimeFeed.latestRound(), 2); + assertEq(s_sequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); + + // Stores the current round data before updating it + ( + uint80 roundIdBeforeUpdate, + int256 answerBeforeUpdate, + uint256 startedAtBeforeUpdate, + , + uint80 answeredInRoundBeforeUpdate + ) = s_sequencerUptimeFeed.latestRoundData(); + + // Submit another status update with the same status + vm.expectEmit(); + emit RoundUpdated(1, uint64(block.timestamp)); + s_sequencerUptimeFeed.updateStatus(true, uint64(timestamp + 200)); + assertEq(s_sequencerUptimeFeed.latestAnswer(), 1); + assertEq(s_sequencerUptimeFeed.latestRound(), 2); + assertEq(s_sequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); + + // Stores the current round data after updating it + ( + uint80 roundIdAfterUpdate, + int256 answerAfterUpdate, + uint256 startedAtAfterUpdate, + uint256 updatedAtAfterUpdate, + uint80 answeredInRoundAfterUpdate + ) = s_sequencerUptimeFeed.latestRoundData(); + + // Verifies the latest round data has been properly updated + assertEq(roundIdAfterUpdate, roundIdBeforeUpdate); + assertEq(answerAfterUpdate, answerBeforeUpdate); + assertEq(startedAtAfterUpdate, startedAtBeforeUpdate); + assertEq(answeredInRoundAfterUpdate, answeredInRoundBeforeUpdate); + assertEq(updatedAtAfterUpdate, block.timestamp); + } + + /// @notice Updates status when status has changed and incoming timestamp is newer than the latest + function test_updateStatus_UpdateWhen_StatusChangeAndTimeChange() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); + + // Submits a status update + uint256 timestamp = s_sequencerUptimeFeed.latestTimestamp(); + vm.expectEmit(); + emit AnswerUpdated(1, 2, timestamp); + s_sequencerUptimeFeed.updateStatus(true, uint64(timestamp)); + assertEq(s_sequencerUptimeFeed.latestAnswer(), 1); + assertEq(s_sequencerUptimeFeed.latestRound(), 2); + assertEq(s_sequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); + + // Submit another status update, different status, newer timestamp should update + timestamp = timestamp + 200; + vm.expectEmit(); + emit AnswerUpdated(0, 3, timestamp); + s_sequencerUptimeFeed.updateStatus(false, uint64(timestamp)); + assertEq(s_sequencerUptimeFeed.latestAnswer(), 0); + assertEq(s_sequencerUptimeFeed.latestRound(), 3); + assertEq(s_sequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); + } + + /// @notice Updates status when status has changed and incoming timestamp is the same as latest + function test_updateStatus_UpdateWhen_StatusChangeAndNoTimeChange() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); + + // Fetches the latest timestamp + uint256 timestamp = s_sequencerUptimeFeed.latestTimestamp(); + + // Submits a status update + vm.expectEmit(); + emit AnswerUpdated(1, 2, timestamp); + s_sequencerUptimeFeed.updateStatus(true, uint64(timestamp)); + assertEq(s_sequencerUptimeFeed.latestAnswer(), 1); + assertEq(s_sequencerUptimeFeed.latestRound(), 2); + assertEq(s_sequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); + + // Submit another status update, different status, same timestamp should update + vm.expectEmit(); + emit AnswerUpdated(0, 3, timestamp); + s_sequencerUptimeFeed.updateStatus(false, uint64(timestamp)); + assertEq(s_sequencerUptimeFeed.latestAnswer(), 0); + assertEq(s_sequencerUptimeFeed.latestRound(), 3); + assertEq(s_sequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); + } + + /// @notice Ignores out-of-order updates + function test_updateStatus_IgnoreOutOfOrderUpdates() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); + + // Submits a status update + uint256 timestamp = s_sequencerUptimeFeed.latestTimestamp() + 10000; + vm.expectEmit(); + emit AnswerUpdated(1, 2, timestamp); + s_sequencerUptimeFeed.updateStatus(true, uint64(timestamp)); + assertEq(s_sequencerUptimeFeed.latestAnswer(), 1); + assertEq(s_sequencerUptimeFeed.latestRound(), 2); + assertEq(s_sequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); + + // Update with different status, but stale timestamp, should be ignored + timestamp = timestamp - 1000; + vm.expectEmit(false, false, false, false); + emit UpdateIgnored(true, 0, true, 0); // arguments are dummy values + + vm.recordLogs(); + + // Tries to update with stale timestamp + s_sequencerUptimeFeed.updateStatus(false, uint64(timestamp)); + + Vm.Log[] memory entries = vm.getRecordedLogs(); + + assertEq(entries.length, 1); + assertEq(entries[0].topics[0], keccak256("UpdateIgnored(bool,uint64,bool,uint64)")); + } +} + +contract BaseSequencerUptimeFeed_AggregatorV3Interface is BaseSequencerUptimeFeed_Setup { + /// @notice Returns valid answer from getRoundData and latestRoundData + function test_AggregatorV3Interface_ReturnsValidData() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); + + // Defines helper variables + uint80 roundId; + int256 answer; + uint256 startedAt; + uint256 updatedAt; + uint80 answeredInRound; + + // Checks initial state + (roundId, answer, startedAt, updatedAt, answeredInRound) = s_sequencerUptimeFeed.latestRoundData(); + assertEq(roundId, 1); + assertEq(answer, 0); + assertEq(answeredInRound, roundId); + assertEq(startedAt, updatedAt); + + // Submits status update with different status and newer timestamp, should update + uint256 timestamp = startedAt + 1000; + s_sequencerUptimeFeed.updateStatus(true, uint64(timestamp)); + (roundId, answer, startedAt, updatedAt, answeredInRound) = s_sequencerUptimeFeed.getRoundData(2); + assertEq(roundId, 2); + assertEq(answer, 1); + assertEq(answeredInRound, roundId); + assertEq(startedAt, timestamp); + assertLe(updatedAt, startedAt); + + // Saves round 2 data + uint80 roundId2 = roundId; + int256 answer2 = answer; + uint256 startedAt2 = startedAt; + uint256 updatedAt2 = updatedAt; + uint80 answeredInRound2 = answeredInRound; + + // Checks that last round is still returning the correct data + (roundId, answer, startedAt, updatedAt, answeredInRound) = s_sequencerUptimeFeed.getRoundData(1); + assertEq(roundId, 1); + assertEq(answer, 0); + assertEq(answeredInRound, roundId); + assertEq(startedAt, updatedAt); + + // Assert latestRoundData corresponds to latest round id + (roundId, answer, startedAt, updatedAt, answeredInRound) = s_sequencerUptimeFeed.latestRoundData(); + assertEq(roundId2, roundId); + assertEq(answer2, answer); + assertEq(startedAt2, startedAt); + assertEq(updatedAt2, updatedAt); + assertEq(answeredInRound2, answeredInRound); + } + + /// @notice Reverts when getRoundData is called for a round that does not exist yet + function test_getRoundData_RevertWhen_RoundDoesNotExist() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); + + // Gets data from a round that has not happened yet + vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); + s_sequencerUptimeFeed.getRoundData(2); + } + + /// @notice Returns the getAnswer for the latest round + function test_getAnswer_ReturnsValidAnswer() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); + + uint256 startedAt; + (, , startedAt, , ) = s_sequencerUptimeFeed.latestRoundData(); + + s_sequencerUptimeFeed.updateStatus(true, uint64(startedAt + 1000)); + + assertEq(0, s_sequencerUptimeFeed.getAnswer(1)); + } + + /// @notice Reverts when getAnswer is called for a round that does not exist yet + function test_getAnswer_RevertWhen_RoundDoesNotExist() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); + + // Gets data from a round that has not happened yet + vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); + s_sequencerUptimeFeed.getAnswer(2); + } + + /// @notice Returns the getTimestamp for the latest round + function test_getTimestamp_ReturnsValidTimestamp() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); + + uint256 startedAt; + (, , startedAt, , ) = s_sequencerUptimeFeed.latestRoundData(); + + s_sequencerUptimeFeed.updateStatus(true, uint64(startedAt + 1000)); + + assertEq(startedAt, s_sequencerUptimeFeed.getTimestamp(1)); + } + + /// @notice Reverts when getTimestamp is called for a round that does not exist yet + function test_getTimestamp_RevertWhen_RoundDoesNotExist() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); + + // Gets data from a round that has not happened yet + vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); + s_sequencerUptimeFeed.getTimestamp(2); + } +} + +contract BaseSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions is BaseSequencerUptimeFeed_Setup { + /// @notice Disallows reads on AggregatorV2V3Interface functions when consuming contract is not whitelisted + function test_ProtectReads_DisallowWhen_NotWhitelisted() public { + // Deploys a FeedConsumer contract + FeedConsumer feedConsumer = new FeedConsumer(address(s_sequencerUptimeFeed)); + + // Sanity - consumer is not whitelisted + assertEq(s_sequencerUptimeFeed.checkEnabled(), true); + assertEq(s_sequencerUptimeFeed.hasAccess(address(feedConsumer), abi.encode("")), false); + + // Asserts reads are not possible from consuming contract + vm.expectRevert("No access"); + feedConsumer.latestAnswer(); + vm.expectRevert("No access"); + feedConsumer.latestRoundData(); + } + + /// @notice Allows reads on AggregatorV2V3Interface functions when consuming contract is whitelisted + function test_ProtectReads_AllowWhen_Whitelisted() public { + // Deploys a FeedConsumer contract + FeedConsumer feedConsumer = new FeedConsumer(address(s_sequencerUptimeFeed)); + + // Whitelist consumer + s_sequencerUptimeFeed.addAccess(address(feedConsumer)); + + // Sanity - consumer is whitelisted + assertEq(s_sequencerUptimeFeed.checkEnabled(), true); + assertEq(s_sequencerUptimeFeed.hasAccess(address(feedConsumer), abi.encode("")), true); + + // Asserts reads are possible from consuming contract + (uint80 roundId, int256 answer, , , ) = feedConsumer.latestRoundData(); + assertEq(feedConsumer.latestAnswer(), 0); + assertEq(roundId, 1); + assertEq(answer, 0); + } +} diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/shared/BaseValidator.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/shared/BaseValidator.t.sol new file mode 100644 index 00000000000..4b0868c71b3 --- /dev/null +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/shared/BaseValidator.t.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import {BaseValidator} from "../../../base/BaseValidator.sol"; +import {MockBaseValidator} from "../../mocks/MockBaseValidator.sol"; +import {L2EPTest} from "../L2EPTest.t.sol"; + +contract BaseValidator_Setup is L2EPTest { + address internal immutable L2_SEQ_STATUS_RECORDER_ADDRESS = makeAddr("L2_SEQ_STATUS_RECORDER_ADDRESS"); + address internal immutable DUMMY_L1_XDOMAIN_MSNGR_ADDR = makeAddr("DUMMY_L1_XDOMAIN_MSNGR_ADDR"); + address internal immutable DUMMY_L2_UPTIME_FEED_ADDR = makeAddr("DUMMY_L2_UPTIME_FEED_ADDR"); + uint32 internal constant INIT_GAS_LIMIT = 1900000; + + BaseValidator internal s_baseValidator; + + /// Fake event that will get emitted when `requestL2TransactionDirect` is called + /// Definition is taken from MockZKSyncL1Bridge + event SentMessage(address indexed sender, bytes message); + + /// Setup + function setUp() public { + s_baseValidator = new MockBaseValidator( + DUMMY_L1_XDOMAIN_MSNGR_ADDR, + L2_SEQ_STATUS_RECORDER_ADDRESS, + INIT_GAS_LIMIT + ); + } +} + +contract BaseValidator_Constructor is BaseValidator_Setup { + /// @notice Reverts when L1 bridge address is zero + function test_Constructor_RevertWhen_L1BridgeAddressIsZero() public { + vm.expectRevert(BaseValidator.L1CrossDomainMessengerAddressZero.selector); + new MockBaseValidator(address(0), DUMMY_L2_UPTIME_FEED_ADDR, INIT_GAS_LIMIT); + } + + /// @notice Reverts when L2 Uptime feed address is zero + function test_Constructor_RevertWhen_L2UptimeFeedAddressIsZero() public { + vm.expectRevert(BaseValidator.L2UptimeFeedAddrZero.selector); + new MockBaseValidator(DUMMY_L1_XDOMAIN_MSNGR_ADDR, address(0), INIT_GAS_LIMIT); + } +} + +contract BaseValidator_GetAndSetGasLimit is BaseValidator_Setup { + /// @notice Verifies the correct retrieval and update of the gas limit + function test_GetAndSetGasLimit_CorrectlyHandlesGasLimit() public { + assertEq(s_baseValidator.getGasLimit(), INIT_GAS_LIMIT); + + uint32 newGasLimit = INIT_GAS_LIMIT + 1; + + vm.expectEmit(); + emit BaseValidator.GasLimitUpdated(newGasLimit); + s_baseValidator.setGasLimit(newGasLimit); + + assertEq(s_baseValidator.getGasLimit(), newGasLimit); + } +} diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncSequencerUptimeFeed.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncSequencerUptimeFeed.t.sol index 5b319d32407..8e9c387c875 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncSequencerUptimeFeed.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncSequencerUptimeFeed.t.sol @@ -3,289 +3,50 @@ pragma solidity ^0.8.24; import {AddressAliasHelper} from "../../../../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol"; import {ZKSyncSequencerUptimeFeed} from "../../../zksync/ZKSyncSequencerUptimeFeed.sol"; -import {BaseSequencerUptimeFeed} from "../../../shared/BaseSequencerUptimeFeed.sol"; -import {FeedConsumer} from "../../../../tests/FeedConsumer.sol"; +import {BaseSequencerUptimeFeed} from "../../../base/BaseSequencerUptimeFeed.sol"; import {L2EPTest} from "../L2EPTest.t.sol"; -contract ZKSyncSequencerUptimeFeedTest is L2EPTest { +contract ZKSyncSequencerUptimeFeed_TestWrapper is ZKSyncSequencerUptimeFeed { + constructor(address l1SenderAddress, bool initialStatus) ZKSyncSequencerUptimeFeed(l1SenderAddress, initialStatus) {} + + /// @notice Exposes the internal _validateSender function for testing + function validateSenderTestWrapper(address l1Sender) external view { + super._validateSender(l1Sender); + } +} + +contract ZKSyncSequencerUptimeFeed_Setup is L2EPTest { /// Helper Variables - address internal s_aliasedL1OwnerAddress = AddressAliasHelper.applyL1ToL2Alias(s_l1OwnerAddr); + address internal l1SenderAddress = address(5); + address internal s_aliasedL1SenderAddress = AddressAliasHelper.applyL1ToL2Alias(l1SenderAddress); /// L2EP contracts - ZKSyncSequencerUptimeFeed internal s_zksyncSequencerUptimeFeed; - - /// Events - event UpdateIgnored(bool latestStatus, uint64 latestTimestamp, bool incomingStatus, uint64 incomingTimestamp); - event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt); - event RoundUpdated(int256 status, uint64 updatedAt); + ZKSyncSequencerUptimeFeed_TestWrapper internal s_zksyncSequencerUptimeFeed; /// Setup function setUp() public { // Deploys contracts - s_zksyncSequencerUptimeFeed = new ZKSyncSequencerUptimeFeed(s_l1OwnerAddr, false); - } -} - -contract ZKSyncSequencerUptimeFeed_Constructor is ZKSyncSequencerUptimeFeedTest { - /// @notice it should have been deployed with the correct initial state - function test_InitialState() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); - - // Checks L1 sender - address actualL1Addr = s_zksyncSequencerUptimeFeed.l1Sender(); - assertEq(actualL1Addr, s_l1OwnerAddr); - - // Checks latest round data - (uint80 roundId, int256 answer, , , ) = s_zksyncSequencerUptimeFeed.latestRoundData(); - assertEq(roundId, 1); - assertEq(answer, 0); + s_zksyncSequencerUptimeFeed = new ZKSyncSequencerUptimeFeed_TestWrapper(l1SenderAddress, false); } } -contract ZKSyncSequencerUptimeFeed_UpdateStatus is ZKSyncSequencerUptimeFeedTest { - /// @notice it should revert if called by an unauthorized account - function test_RevertIfNotL2CrossDomainMessengerAddr() public { - // Sets msg.sender and tx.origin to an unauthorized address - vm.startPrank(s_strangerAddr, s_strangerAddr); +contract ZKSyncSequencerUptimeFeed_ValidateSender is ZKSyncSequencerUptimeFeed_Setup { + /// @notice Reverts when pass is not valid + function test_ValidateSender_RevertWhen_PassIsNotValid() public { + // Sets msg.sender and tx.origin to an authorized address + vm.startPrank(s_aliasedL1SenderAddress, s_aliasedL1SenderAddress); // Tries to update the status from an unauthorized account vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); - s_zksyncSequencerUptimeFeed.updateStatus(true, uint64(1)); - } - - /// @notice it should update status when status has not changed and incoming timestamp is the same as latest - function test_UpdateStatusWhenNoChange() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); - - // Fetches the latest timestamp - uint256 timestamp = s_zksyncSequencerUptimeFeed.latestTimestamp(); - - // Submits a status update - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_zksyncSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_zksyncSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_zksyncSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Stores the current round data before updating it - ( - uint80 roundIdBeforeUpdate, - int256 answerBeforeUpdate, - uint256 startedAtBeforeUpdate, - , - uint80 answeredInRoundBeforeUpdate - ) = s_zksyncSequencerUptimeFeed.latestRoundData(); - - // Submit another status update with the same status - vm.expectEmit(); - emit RoundUpdated(1, uint64(block.timestamp)); - s_zksyncSequencerUptimeFeed.updateStatus(true, uint64(timestamp + 200)); - assertEq(s_zksyncSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_zksyncSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Stores the current round data after updating it - ( - uint80 roundIdAfterUpdate, - int256 answerAfterUpdate, - uint256 startedAtAfterUpdate, - uint256 updatedAtAfterUpdate, - uint80 answeredInRoundAfterUpdate - ) = s_zksyncSequencerUptimeFeed.latestRoundData(); - - // Verifies the latest round data has been properly updated - assertEq(roundIdAfterUpdate, roundIdBeforeUpdate); - assertEq(answerAfterUpdate, answerBeforeUpdate); - assertEq(startedAtAfterUpdate, startedAtBeforeUpdate); - assertEq(answeredInRoundAfterUpdate, answeredInRoundBeforeUpdate); - assertEq(updatedAtAfterUpdate, block.timestamp); - } - - /// @notice it should update status when status has changed and incoming timestamp is newer than the latest - function test_UpdateStatusWhenStatusChangeAndTimeChange() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); - - // Submits a status update - uint256 timestamp = s_zksyncSequencerUptimeFeed.latestTimestamp(); - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_zksyncSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_zksyncSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_zksyncSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Submit another status update, different status, newer timestamp should update - timestamp = timestamp + 200; - vm.expectEmit(); - emit AnswerUpdated(0, 3, timestamp); - s_zksyncSequencerUptimeFeed.updateStatus(false, uint64(timestamp)); - assertEq(s_zksyncSequencerUptimeFeed.latestAnswer(), 0); - assertEq(s_zksyncSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - } - - /// @notice it should update status when status has changed and incoming timestamp is the same as latest - function test_UpdateStatusWhenStatusChangeAndNoTimeChange() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); - - // Fetches the latest timestamp - uint256 timestamp = s_zksyncSequencerUptimeFeed.latestTimestamp(); - - // Submits a status update - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_zksyncSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_zksyncSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_zksyncSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Submit another status update, different status, same timestamp should update - vm.expectEmit(); - emit AnswerUpdated(0, 3, timestamp); - s_zksyncSequencerUptimeFeed.updateStatus(false, uint64(timestamp)); - assertEq(s_zksyncSequencerUptimeFeed.latestAnswer(), 0); - assertEq(s_zksyncSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - } - - /// @notice it should ignore out-of-order updates - function test_IgnoreOutOfOrderUpdates() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); - - // Submits a status update - uint256 timestamp = s_zksyncSequencerUptimeFeed.latestTimestamp() + 10000; - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_zksyncSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_zksyncSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_zksyncSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Update with different status, but stale timestamp, should be ignored - timestamp = timestamp - 1000; - vm.expectEmit(false, false, false, false); - emit UpdateIgnored(true, 0, true, 0); // arguments are dummy values - // TODO: how can we check that an AnswerUpdated event was NOT emitted - s_zksyncSequencerUptimeFeed.updateStatus(false, uint64(timestamp)); - } -} - -contract ZKSyncSequencerUptimeFeed_AggregatorV3Interface is ZKSyncSequencerUptimeFeedTest { - /// @notice it should return valid answer from getRoundData and latestRoundData - function test_AggregatorV3Interface() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); - - // Defines helper variables - uint80 roundId; - int256 answer; - uint256 startedAt; - uint256 updatedAt; - uint80 answeredInRound; - - // Checks initial state - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_zksyncSequencerUptimeFeed.latestRoundData(); - assertEq(roundId, 1); - assertEq(answer, 0); - assertEq(answeredInRound, roundId); - assertEq(startedAt, updatedAt); - - // Submits status update with different status and newer timestamp, should update - uint256 timestamp = startedAt + 1000; - s_zksyncSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_zksyncSequencerUptimeFeed.getRoundData(2); - assertEq(roundId, 2); - assertEq(answer, 1); - assertEq(answeredInRound, roundId); - assertEq(startedAt, timestamp); - assertLe(updatedAt, startedAt); - - // Saves round 2 data - uint80 roundId2 = roundId; - int256 answer2 = answer; - uint256 startedAt2 = startedAt; - uint256 updatedAt2 = updatedAt; - uint80 answeredInRound2 = answeredInRound; - - // Checks that last round is still returning the correct data - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_zksyncSequencerUptimeFeed.getRoundData(1); - assertEq(roundId, 1); - assertEq(answer, 0); - assertEq(answeredInRound, roundId); - assertEq(startedAt, updatedAt); - - // Assert latestRoundData corresponds to latest round id - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_zksyncSequencerUptimeFeed.latestRoundData(); - assertEq(roundId2, roundId); - assertEq(answer2, answer); - assertEq(startedAt2, startedAt); - assertEq(updatedAt2, updatedAt); - assertEq(answeredInRound2, answeredInRound); - } - - /// @notice it should revert from #getRoundData when round does not yet exist (future roundId) - function test_RevertGetRoundDataWhenRoundDoesNotExistYet() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); - - // Gets data from a round that has not happened yet - vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); - s_zksyncSequencerUptimeFeed.getRoundData(2); - } - - /// @notice it should revert from #getAnswer when round does not yet exist (future roundId) - function test_RevertGetAnswerWhenRoundDoesNotExistYet() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); - - // Gets data from a round that has not happened yet - vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); - s_zksyncSequencerUptimeFeed.getAnswer(2); - } - - /// @notice it should revert from #getTimestamp when round does not yet exist (future roundId) - function test_RevertGetTimestampWhenRoundDoesNotExistYet() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); - - // Gets data from a round that has not happened yet - vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); - s_zksyncSequencerUptimeFeed.getTimestamp(2); + s_zksyncSequencerUptimeFeed.validateSenderTestWrapper(address(6)); } -} - -contract ZKSyncSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions is ZKSyncSequencerUptimeFeedTest { - /// @notice it should disallow reads on AggregatorV2V3Interface functions when consuming contract is not whitelisted - function test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() public { - // Deploys a FeedConsumer contract - FeedConsumer feedConsumer = new FeedConsumer(address(s_zksyncSequencerUptimeFeed)); - - // Sanity - consumer is not whitelisted - assertEq(s_zksyncSequencerUptimeFeed.checkEnabled(), true); - assertEq(s_zksyncSequencerUptimeFeed.hasAccess(address(feedConsumer), abi.encode("")), false); - - // Asserts reads are not possible from consuming contract - vm.expectRevert("No access"); - feedConsumer.latestAnswer(); - vm.expectRevert("No access"); - feedConsumer.latestRoundData(); - } - - /// @notice it should allow reads on AggregatorV2V3Interface functions when consuming contract is whitelisted - function test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() public { - // Deploys a FeedConsumer contract - FeedConsumer feedConsumer = new FeedConsumer(address(s_zksyncSequencerUptimeFeed)); - - // Whitelist consumer - s_zksyncSequencerUptimeFeed.addAccess(address(feedConsumer)); - // Sanity - consumer is whitelisted - assertEq(s_zksyncSequencerUptimeFeed.checkEnabled(), true); - assertEq(s_zksyncSequencerUptimeFeed.hasAccess(address(feedConsumer), abi.encode("")), true); + /// @notice Passes when sender is valid + function test_ValidateSender_SuccessWhen_SenderIsValid() public { + // Sets msg.sender and tx.origin to an authorized address + vm.startPrank(s_aliasedL1SenderAddress, s_aliasedL1SenderAddress); - // Asserts reads are possible from consuming contract - (uint80 roundId, int256 answer, , , ) = feedConsumer.latestRoundData(); - assertEq(feedConsumer.latestAnswer(), 0); - assertEq(roundId, 1); - assertEq(answer, 0); + // Tries to update the status from an authorized account + s_zksyncSequencerUptimeFeed.validateSenderTestWrapper(l1SenderAddress); } } diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncValidator.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncValidator.t.sol index 1a0f16d6ae0..e36a2732c27 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncValidator.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncValidator.t.sol @@ -4,13 +4,13 @@ pragma solidity ^0.8.24; import {MockBridgehub} from "../../mocks/zksync/MockZKSyncL1Bridge.sol"; import {ISequencerUptimeFeed} from "../../../interfaces/ISequencerUptimeFeed.sol"; import {ZKSyncValidator} from "../../../zksync/ZKSyncValidator.sol"; -import {BaseValidator} from "../../../shared/BaseValidator.sol"; +import {BaseValidator} from "../../../base/BaseValidator.sol"; import {L2EPTest} from "../L2EPTest.t.sol"; -contract ZKSyncValidatorTest is L2EPTest { - address internal constant L2_SEQ_STATUS_RECORDER_ADDRESS = address(0x491B1dDA0A8fa069bbC1125133A975BF4e85a91b); - address internal constant DUMMY_L1_XDOMAIN_MSNGR_ADDR = address(0xa04Fc18f012B1a5A8231c7Ee4b916Dd6dbd271b6); - address internal constant DUMMY_L2_UPTIME_FEED_ADDR = address(0xFe31891940A2e5f04B76eD8bD1038E44127d1512); +contract ZKSyncValidator_Setup is L2EPTest { + address internal immutable L2_SEQ_STATUS_RECORDER_ADDRESS = makeAddr("L2_SEQ_STATUS_RECORDER_ADDRESS"); + address internal immutable DUMMY_L1_XDOMAIN_MSNGR_ADDR = makeAddr("DUMMY_L1_XDOMAIN_MSNGR_ADDR"); + address internal immutable DUMMY_L2_UPTIME_FEED_ADDR = makeAddr("DUMMY_L2_UPTIME_FEED_ADDR"); uint32 internal constant INIT_GAS_PER_PUBDATA_BYTE_LIMIT = 800; uint32 internal constant INIT_GAS_LIMIT = 1900000; uint32 internal constant MAIN_NET_CHAIN_ID = 300; @@ -38,9 +38,9 @@ contract ZKSyncValidatorTest is L2EPTest { } } -contract ZKSyncValidator_Constructor is ZKSyncValidatorTest { - /// @notice it correctly validates that the chain id is valid - function test_ConstructingRevertedWithInvalidChainId() public { +contract ZKSyncValidator_Constructor is ZKSyncValidator_Setup { + /// @notice Reverts when chain ID is invalid + function test_Constructor_RevertWhen_ChainIdIsInvalid() public { vm.expectRevert(ZKSyncValidator.InvalidChainID.selector); new ZKSyncValidator( DUMMY_L1_XDOMAIN_MSNGR_ADDR, @@ -51,8 +51,8 @@ contract ZKSyncValidator_Constructor is ZKSyncValidatorTest { ); } - /// @notice it correctly validates that the L1 bridge address is not zero - function test_ConstructingRevertedWithZeroL1BridgeAddress() public { + /// @notice Reverts when L1 bridge address is zero + function test_Constructor_RevertWhen_L1BridgeAddressIsZero() public { vm.expectRevert(BaseValidator.L1CrossDomainMessengerAddressZero.selector); new ZKSyncValidator( address(0), @@ -63,8 +63,8 @@ contract ZKSyncValidator_Constructor is ZKSyncValidatorTest { ); } - /// @notice it correctly validates that the L2 Uptime feed address is not zero - function test_ConstructingRevertedWithZeroL2UpdateFeedAddress() public { + /// @notice Reverts when L2 update feed address is zero + function test_Constructor_RevertWhen_L2UpdateFeedAddressIsZero() public { vm.expectRevert(BaseValidator.L2UptimeFeedAddrZero.selector); new ZKSyncValidator( DUMMY_L1_XDOMAIN_MSNGR_ADDR, @@ -76,9 +76,9 @@ contract ZKSyncValidator_Constructor is ZKSyncValidatorTest { } } -contract ZKSyncValidator_GetSetL2GasPerPubdataByteLimit is ZKSyncValidatorTest { - /// @notice it correctly updates the gas limit per pubdata byte - function test_CorrectlyGetsAndUpdatesTheGasPerPubdataByteLimit() public { +contract ZKSyncValidator_GetSetL2GasPerPubdataByteLimit is ZKSyncValidator_Setup { + /// @notice Correctly gets and updates the gas per pubdata byte limit + function test_GetSetL2GasPerPubdataByteLimit_CorrectlyHandlesGasPerPubdataByteLimit() public { assertEq(s_zksyncValidator.getL2GasPerPubdataByteLimit(), INIT_GAS_PER_PUBDATA_BYTE_LIMIT); uint32 newGasPerPubDataByteLimit = 2000000; @@ -87,23 +87,23 @@ contract ZKSyncValidator_GetSetL2GasPerPubdataByteLimit is ZKSyncValidatorTest { } } -contract ZKSyncValidator_GetChainId is ZKSyncValidatorTest { - /// @notice it correctly gets the chain id - function test_CorrectlyGetsTheChainId() public { +contract ZKSyncValidator_GetChainId is ZKSyncValidator_Setup { + /// @notice Correctly gets the chain ID + function test_GetChainId_CorrectlyGetsTheChainId() public view { assertEq(s_zksyncValidator.getChainId(), MAIN_NET_CHAIN_ID); } } -contract ZKSyncValidator_Validate is ZKSyncValidatorTest { - /// @notice it reverts if called by account with no access - function test_RevertsIfCalledByAnAccountWithNoAccess() public { +contract ZKSyncValidator_Validate is ZKSyncValidator_Setup { + /// @notice Reverts if called by an account with no access + function test_Validate_RevertWhen_CalledByAccountWithNoAccess() public { vm.startPrank(s_strangerAddr); vm.expectRevert("No access"); s_zksyncValidator.validate(0, 0, 1, 1); } - /// @notice it posts sequencer status when there is not status change - function test_PostSequencerStatusWhenThereIsNotStatusChange() public { + /// @notice Posts sequencer status when there is no status change + function test_Validate_PostSequencerStatus_NoStatusChange() public { // Gives access to the s_eoaValidator s_zksyncValidator.addAccess(s_eoaValidator); @@ -126,8 +126,8 @@ contract ZKSyncValidator_Validate is ZKSyncValidatorTest { s_zksyncValidator.validate(0, 0, 0, 0); } - /// @notice it post sequencer offline - function test_PostSequencerOffline() public { + /// @notice Posts sequencer offline status + function test_Validate_PostSequencerOffline() public { // Gives access to the s_eoaValidator s_zksyncValidator.addAccess(s_eoaValidator); diff --git a/contracts/src/v0.8/l2ep/zksync/ZKSyncSequencerUptimeFeed.sol b/contracts/src/v0.8/l2ep/zksync/ZKSyncSequencerUptimeFeed.sol index cb520d2d0ac..e464cc7407d 100644 --- a/contracts/src/v0.8/l2ep/zksync/ZKSyncSequencerUptimeFeed.sol +++ b/contracts/src/v0.8/l2ep/zksync/ZKSyncSequencerUptimeFeed.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -import {BaseSequencerUptimeFeed} from "../shared/BaseSequencerUptimeFeed.sol"; +import {BaseSequencerUptimeFeed} from "../base/BaseSequencerUptimeFeed.sol"; import {AddressAliasHelper} from "../../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol"; diff --git a/contracts/src/v0.8/l2ep/zksync/ZKSyncValidator.sol b/contracts/src/v0.8/l2ep/zksync/ZKSyncValidator.sol index 10f68ce286d..39ba0cd839a 100644 --- a/contracts/src/v0.8/l2ep/zksync/ZKSyncValidator.sol +++ b/contracts/src/v0.8/l2ep/zksync/ZKSyncValidator.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.19; import {ISequencerUptimeFeed} from "./../interfaces/ISequencerUptimeFeed.sol"; -import {BaseValidator} from "../shared/BaseValidator.sol"; +import {BaseValidator} from "../base/BaseValidator.sol"; import {IBridgehub, L2TransactionRequestDirect} from "@zksync/contracts/l1-contracts/contracts/bridgehub/IBridgehub.sol"; From 75f9cf0e3a7e83f838d74f4e27b8c9fde8ce7962 Mon Sep 17 00:00:00 2001 From: "Simon B.Robert" Date: Mon, 9 Dec 2024 14:47:30 -0500 Subject: [PATCH 14/29] Initial commit for RMN Home config changeset (#15525) * Initial commit for RMN Home config changeset * Add RMNRemote changeset * Integrate with develop * Update deployment/ccip/changeset/cs_update_rmn_config_test.go Co-authored-by: Makram * Address PR feedback * Address some more feedback on the PR * Make MCMS optional for RMN changeset * Update deployment/ccip/changeset/cs_update_rmn_config.go Co-authored-by: Anindita Ghosh <88458927+AnieeG@users.noreply.github.com> * Address PR comments --------- Co-authored-by: Makram Co-authored-by: Anindita Ghosh <88458927+AnieeG@users.noreply.github.com> --- .../ccip/changeset/cs_update_rmn_config.go | 440 ++++++++++++++++++ .../changeset/cs_update_rmn_config_test.go | 184 ++++++++ 2 files changed, 624 insertions(+) create mode 100644 deployment/ccip/changeset/cs_update_rmn_config.go create mode 100644 deployment/ccip/changeset/cs_update_rmn_config_test.go diff --git a/deployment/ccip/changeset/cs_update_rmn_config.go b/deployment/ccip/changeset/cs_update_rmn_config.go new file mode 100644 index 00000000000..7e4d09af20f --- /dev/null +++ b/deployment/ccip/changeset/cs_update_rmn_config.go @@ -0,0 +1,440 @@ +package changeset + +import ( + "fmt" + "math/big" + "reflect" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" + mcmsWrappers "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_home" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_remote" +) + +func getDeployer(e deployment.Environment, chain uint64, mcmConfig *MCMSConfig) *bind.TransactOpts { + if mcmConfig == nil { + return e.Chains[chain].DeployerKey + } + + return deployment.SimTransactOpts() +} + +type MCMSConfig struct { + MinDelay time.Duration +} + +type SetRMNHomeCandidateConfig struct { + HomeChainSelector uint64 + RMNStaticConfig rmn_home.RMNHomeStaticConfig + RMNDynamicConfig rmn_home.RMNHomeDynamicConfig + DigestToOverride [32]byte + MCMSConfig *MCMSConfig +} + +func (c SetRMNHomeCandidateConfig) Validate(state CCIPOnChainState) error { + err := deployment.IsValidChainSelector(c.HomeChainSelector) + if err != nil { + return err + } + + if len(c.RMNDynamicConfig.OffchainConfig) != 0 { + return fmt.Errorf("RMNDynamicConfig.OffchainConfig must be empty") + } + if len(c.RMNStaticConfig.OffchainConfig) != 0 { + return fmt.Errorf("RMNStaticConfig.OffchainConfig must be empty") + } + + if len(c.RMNStaticConfig.Nodes) > 256 { + return fmt.Errorf("RMNStaticConfig.Nodes must be less than 256") + } + + var ( + peerIds = make(map[[32]byte]struct{}) + offchainPublicKeys = make(map[[32]byte]struct{}) + ) + + for _, node := range c.RMNStaticConfig.Nodes { + if _, exists := peerIds[node.PeerId]; exists { + return fmt.Errorf("peerId %x is duplicated", node.PeerId) + } + peerIds[node.PeerId] = struct{}{} + + if _, exists := offchainPublicKeys[node.OffchainPublicKey]; exists { + return fmt.Errorf("offchainPublicKey %x is duplicated", node.OffchainPublicKey) + } + offchainPublicKeys[node.OffchainPublicKey] = struct{}{} + } + rmnHome := state.Chains[c.HomeChainSelector].RMNHome + + if rmnHome == nil { + return fmt.Errorf("RMNHome not found for chain %d", c.HomeChainSelector) + } + + currentDigest, err := rmnHome.GetCandidateDigest(nil) + if err != nil { + return fmt.Errorf("failed to get RMNHome candidate digest: %w", err) + } + + if currentDigest != c.DigestToOverride { + return fmt.Errorf("current digest (%x) does not match digest to override (%x)", currentDigest[:], c.DigestToOverride[:]) + } + + return nil +} + +type PromoteRMNHomeCandidateConfig struct { + HomeChainSelector uint64 + DigestToPromote [32]byte + MCMSConfig *MCMSConfig +} + +func (c PromoteRMNHomeCandidateConfig) Validate(state CCIPOnChainState) error { + err := deployment.IsValidChainSelector(c.HomeChainSelector) + if err != nil { + return err + } + + rmnHome := state.Chains[c.HomeChainSelector].RMNHome + if rmnHome == nil { + return fmt.Errorf("RMNHome not found for chain %d", c.HomeChainSelector) + } + + currentCandidateDigest, err := rmnHome.GetCandidateDigest(nil) + if err != nil { + return fmt.Errorf("failed to get RMNHome candidate digest: %w", err) + } + + if currentCandidateDigest != c.DigestToPromote { + return fmt.Errorf("current digest (%x) does not match digest to promote (%x)", currentCandidateDigest[:], c.DigestToPromote[:]) + } + + return nil +} + +// NewSetRMNHomeCandidateConfigChangeset creates a changeset to set the RMNHome candidate config +// DigestToOverride is the digest of the current candidate config that the new config will override +// StaticConfig contains the list of nodes with their peerIDs (found in their rageproxy keystore) and offchain public keys (found in the RMN keystore) +// DynamicConfig contains the list of source chains with their chain selectors, f value and the bitmap of the nodes that are oberver for each source chain +// The bitmap is a 256 bit array where each bit represents a node. If the bit matching the index of the node in the static config is set it means that the node is an observer +func NewSetRMNHomeCandidateConfigChangeset(e deployment.Environment, config SetRMNHomeCandidateConfig) (deployment.ChangesetOutput, error) { + state, err := LoadOnchainState(e) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to load onchain state: %w", err) + } + + err = config.Validate(state) + if err != nil { + return deployment.ChangesetOutput{}, err + } + + homeChain, ok := e.Chains[config.HomeChainSelector] + if !ok { + return deployment.ChangesetOutput{}, fmt.Errorf("chain %d not found", config.HomeChainSelector) + } + + rmnHome := state.Chains[config.HomeChainSelector].RMNHome + if rmnHome == nil { + return deployment.ChangesetOutput{}, fmt.Errorf("RMNHome not found for chain %s", homeChain.String()) + } + + deployer := getDeployer(e, config.HomeChainSelector, config.MCMSConfig) + setCandidateTx, err := rmnHome.SetCandidate(deployer, config.RMNStaticConfig, config.RMNDynamicConfig, config.DigestToOverride) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("build RMNHome set candidate calldata for chain %s: %w", homeChain.String(), err) + } + + if config.MCMSConfig == nil { + chain := e.Chains[config.HomeChainSelector] + _, err := chain.Confirm(setCandidateTx) + + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to confirm tx for chain %s: %w", homeChain.String(), deployment.MaybeDataErr(err)) + } + + return deployment.ChangesetOutput{}, nil + } + + op := mcms.Operation{ + To: rmnHome.Address(), + Data: setCandidateTx.Data(), + Value: big.NewInt(0), + } + + batches := []timelock.BatchChainOperation{ + { + ChainIdentifier: mcms.ChainIdentifier(config.HomeChainSelector), + Batch: []mcms.Operation{op}, + }, + } + + timelocksPerChain := buildTimelockAddressPerChain(e, state) + + proposerMCMSes := buildProposerPerChain(e, state) + + prop, err := proposalutils.BuildProposalFromBatches( + timelocksPerChain, + proposerMCMSes, + batches, + "proposal to set candidate config", + config.MCMSConfig.MinDelay, + ) + + return deployment.ChangesetOutput{ + Proposals: []timelock.MCMSWithTimelockProposal{*prop}, + }, nil +} + +func NewPromoteCandidateConfigChangeset(e deployment.Environment, config PromoteRMNHomeCandidateConfig) (deployment.ChangesetOutput, error) { + state, err := LoadOnchainState(e) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to load onchain state: %w", err) + } + + err = config.Validate(state) + if err != nil { + return deployment.ChangesetOutput{}, err + } + + homeChain, ok := e.Chains[config.HomeChainSelector] + + if !ok { + return deployment.ChangesetOutput{}, fmt.Errorf("chain %d not found", config.HomeChainSelector) + } + + rmnHome := state.Chains[config.HomeChainSelector].RMNHome + if rmnHome == nil { + return deployment.ChangesetOutput{}, fmt.Errorf("RMNHome not found for chain %s", homeChain.String()) + } + + currentCandidateDigest, err := rmnHome.GetCandidateDigest(nil) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to get RMNHome candidate digest for chain %s: %w", homeChain.String(), err) + } + + currentActiveDigest, err := rmnHome.GetActiveDigest(nil) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to get RMNHome active digest for chain %s: %w", homeChain.String(), err) + } + + deployer := getDeployer(e, config.HomeChainSelector, config.MCMSConfig) + promoteCandidateTx, err := rmnHome.PromoteCandidateAndRevokeActive(deployer, currentCandidateDigest, currentActiveDigest) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("get call data to promote RMNHome candidate digest for chain %s: %w", homeChain.String(), err) + } + + if config.MCMSConfig == nil { + chain := e.Chains[config.HomeChainSelector] + _, err := chain.Confirm(promoteCandidateTx) + + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to confirm tx for chain %s: %w", homeChain.String(), deployment.MaybeDataErr(err)) + } + + return deployment.ChangesetOutput{}, nil + } + + op := mcms.Operation{ + To: rmnHome.Address(), + Data: promoteCandidateTx.Data(), + Value: big.NewInt(0), + } + + batches := []timelock.BatchChainOperation{ + { + ChainIdentifier: mcms.ChainIdentifier(config.HomeChainSelector), + Batch: []mcms.Operation{op}, + }, + } + + timelocksPerChain := buildTimelockAddressPerChain(e, state) + + proposerMCMSes := buildProposerPerChain(e, state) + + prop, err := proposalutils.BuildProposalFromBatches( + timelocksPerChain, + proposerMCMSes, + batches, + "proposal to promote candidate config", + config.MCMSConfig.MinDelay, + ) + + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to build proposal for chain %s: %w", homeChain.String(), err) + } + + return deployment.ChangesetOutput{ + Proposals: []timelock.MCMSWithTimelockProposal{*prop}, + }, nil +} + +func buildTimelockPerChain(e deployment.Environment, state CCIPOnChainState) map[uint64]*mcmsWrappers.RBACTimelock { + timelocksPerChain := make(map[uint64]*mcmsWrappers.RBACTimelock) + for _, chain := range e.Chains { + timelocksPerChain[chain.Selector] = state.Chains[chain.Selector].Timelock + } + return timelocksPerChain +} + +func buildTimelockAddressPerChain(e deployment.Environment, state CCIPOnChainState) map[uint64]common.Address { + timelocksPerChain := buildTimelockPerChain(e, state) + timelockAddressPerChain := make(map[uint64]common.Address) + for chain, timelock := range timelocksPerChain { + timelockAddressPerChain[chain] = timelock.Address() + } + return timelockAddressPerChain +} + +func buildProposerPerChain(e deployment.Environment, state CCIPOnChainState) map[uint64]*gethwrappers.ManyChainMultiSig { + proposerPerChain := make(map[uint64]*gethwrappers.ManyChainMultiSig) + for _, chain := range e.Chains { + proposerPerChain[chain.Selector] = state.Chains[chain.Selector].ProposerMcm + } + return proposerPerChain +} + +func buildRMNRemotePerChain(e deployment.Environment, state CCIPOnChainState) map[uint64]*rmn_remote.RMNRemote { + timelocksPerChain := make(map[uint64]*rmn_remote.RMNRemote) + for _, chain := range e.Chains { + timelocksPerChain[chain.Selector] = state.Chains[chain.Selector].RMNRemote + } + return timelocksPerChain +} + +type SetRMNRemoteConfig struct { + HomeChainSelector uint64 + Signers []rmn_remote.RMNRemoteSigner + F uint64 + MCMSConfig *MCMSConfig +} + +func (c SetRMNRemoteConfig) Validate() error { + err := deployment.IsValidChainSelector(c.HomeChainSelector) + if err != nil { + return err + } + + for i := 0; i < len(c.Signers)-1; i++ { + if c.Signers[i].NodeIndex >= c.Signers[i+1].NodeIndex { + return fmt.Errorf("signers must be in ascending order of nodeIndex") + } + } + + if len(c.Signers) < 2*int(c.F)+1 { + return fmt.Errorf("signers count must greater than or equal to %d", 2*c.F+1) + } + + return nil +} + +func NewSetRMNRemoteConfigChangeset(e deployment.Environment, config SetRMNRemoteConfig) (deployment.ChangesetOutput, error) { + state, err := LoadOnchainState(e) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to load onchain state: %w", err) + } + + lggr := e.Logger + + err = config.Validate() + if err != nil { + return deployment.ChangesetOutput{}, err + } + + homeChain, ok := e.Chains[config.HomeChainSelector] + + if !ok { + return deployment.ChangesetOutput{}, fmt.Errorf("chain %d not found", config.HomeChainSelector) + } + + rmnHome := state.Chains[config.HomeChainSelector].RMNHome + if rmnHome == nil { + return deployment.ChangesetOutput{}, fmt.Errorf("RMNHome not found for chain %s", homeChain.String()) + } + + activeConfig, err := rmnHome.GetActiveDigest(nil) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to get RMNHome active digest for chain %s: %w", homeChain.String(), err) + } + + rmnRemotePerChain := buildRMNRemotePerChain(e, state) + batches := make([]timelock.BatchChainOperation, 0) + for chain, remote := range rmnRemotePerChain { + if remote == nil { + continue + } + + currentVersionConfig, err := remote.GetVersionedConfig(nil) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to get RMNRemote config for chain %s: %w", e.Chains[chain].String(), err) + } + + newConfig := rmn_remote.RMNRemoteConfig{ + RmnHomeContractConfigDigest: activeConfig, + Signers: config.Signers, + F: config.F, + } + + if reflect.DeepEqual(currentVersionConfig.Config, newConfig) { + lggr.Infow("RMNRemote config already up to date", "chain", e.Chains[chain].String()) + continue + } + + deployer := getDeployer(e, chain, config.MCMSConfig) + tx, err := remote.SetConfig(deployer, newConfig) + + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("build call data to set RMNRemote config for chain %s: %w", e.Chains[chain].String(), err) + } + + if config.MCMSConfig == nil { + _, err := e.Chains[chain].Confirm(tx) + + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to confirm tx for chain %s: %w", e.Chains[chain].String(), deployment.MaybeDataErr(err)) + } + } + + op := mcms.Operation{ + To: remote.Address(), + Data: tx.Data(), + Value: big.NewInt(0), + } + + batch := timelock.BatchChainOperation{ + ChainIdentifier: mcms.ChainIdentifier(chain), + Batch: []mcms.Operation{op}, + } + + batches = append(batches, batch) + } + + if config.MCMSConfig == nil { + return deployment.ChangesetOutput{}, nil + } + + timelocksPerChain := buildTimelockAddressPerChain(e, state) + + proposerMCMSes := buildProposerPerChain(e, state) + + prop, err := proposalutils.BuildProposalFromBatches( + timelocksPerChain, + proposerMCMSes, + batches, + "proposal to promote candidate config", + config.MCMSConfig.MinDelay, + ) + + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to build proposal for chain %s: %w", homeChain.String(), err) + } + + return deployment.ChangesetOutput{ + Proposals: []timelock.MCMSWithTimelockProposal{*prop}, + }, nil +} diff --git a/deployment/ccip/changeset/cs_update_rmn_config_test.go b/deployment/ccip/changeset/cs_update_rmn_config_test.go new file mode 100644 index 00000000000..deae3e2e771 --- /dev/null +++ b/deployment/ccip/changeset/cs_update_rmn_config_test.go @@ -0,0 +1,184 @@ +package changeset + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/deployment" + commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" + "github.com/smartcontractkit/chainlink/deployment/environment/memory" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_home" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_remote" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +type updateRMNConfigTestCase struct { + useMCMS bool + name string +} + +func TestUpdateRMNConfig(t *testing.T) { + t.Parallel() + testCases := []updateRMNConfigTestCase{ + { + useMCMS: true, + name: "with MCMS", + }, + { + useMCMS: false, + name: "without MCMS", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + updateRMNConfig(t, tc) + }) + } +} + +func updateRMNConfig(t *testing.T, tc updateRMNConfigTestCase) { + e := NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), memory.MemoryEnvironmentConfig{ + Chains: 2, + Nodes: 4, + Bootstraps: 1, + }, nil) + + state, err := LoadOnchainState(e.Env) + require.NoError(t, err) + + contractsByChain := make(map[uint64][]common.Address) + rmnRemoteAddressesByChain := buildRMNRemoteAddressPerChain(e.Env, state) + for chainSelector, rmnRemoteAddress := range rmnRemoteAddressesByChain { + contractsByChain[chainSelector] = []common.Address{rmnRemoteAddress} + } + + contractsByChain[e.HomeChainSel] = append(contractsByChain[e.HomeChainSel], state.Chains[e.HomeChainSel].RMNHome.Address()) + + timelocksPerChain := buildTimelockPerChain(e.Env, state) + if tc.useMCMS { + // This is required because RMNHome is initially owned by the deployer + _, err = commonchangeset.ApplyChangesets(t, e.Env, timelocksPerChain, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(commonchangeset.TransferToMCMSWithTimelock), + Config: commonchangeset.TransferToMCMSWithTimelockConfig{ + ContractsByChain: contractsByChain, + MinDelay: 0, + }, + }, + }) + } + + rmnHome := state.Chains[e.HomeChainSel].RMNHome + + previousCandidateDigest, err := rmnHome.GetCandidateDigest(nil) + require.NoError(t, err) + previousActiveDigest, err := rmnHome.GetActiveDigest(nil) + require.NoError(t, err) + + var mcmsConfig *MCMSConfig = nil + + if tc.useMCMS { + mcmsConfig = &MCMSConfig{ + MinDelay: 0, + } + } + + setRMNHomeCandidateConfig := SetRMNHomeCandidateConfig{ + HomeChainSelector: e.HomeChainSel, + RMNStaticConfig: rmn_home.RMNHomeStaticConfig{ + Nodes: []rmn_home.RMNHomeNode{}, + OffchainConfig: []byte(""), + }, + RMNDynamicConfig: rmn_home.RMNHomeDynamicConfig{ + SourceChains: []rmn_home.RMNHomeSourceChain{}, + OffchainConfig: []byte(""), + }, + MCMSConfig: mcmsConfig, + } + + _, err = commonchangeset.ApplyChangesets(t, e.Env, timelocksPerChain, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(NewSetRMNHomeCandidateConfigChangeset), + Config: setRMNHomeCandidateConfig, + }, + }) + + require.NoError(t, err) + + state, err = LoadOnchainState(e.Env) + require.NoError(t, err) + + currentCandidateDigest, err := rmnHome.GetCandidateDigest(nil) + require.NoError(t, err) + currentActiveDigest, err := rmnHome.GetActiveDigest(nil) + require.NoError(t, err) + + require.NotEqual(t, previousCandidateDigest, currentCandidateDigest) + require.Equal(t, previousActiveDigest, currentActiveDigest) + + promoteConfig := PromoteRMNHomeCandidateConfig{ + HomeChainSelector: e.HomeChainSel, + DigestToPromote: currentCandidateDigest, + MCMSConfig: mcmsConfig, + } + + _, err = commonchangeset.ApplyChangesets(t, e.Env, timelocksPerChain, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(NewPromoteCandidateConfigChangeset), + Config: promoteConfig, + }, + }) + + require.NoError(t, err) + currentActiveDigest, err = rmnHome.GetActiveDigest(nil) + + require.NoError(t, err) + require.NotEqual(t, previousActiveDigest, currentActiveDigest) + + setRemoteConfig := SetRMNRemoteConfig{ + HomeChainSelector: e.HomeChainSel, + Signers: []rmn_remote.RMNRemoteSigner{ + { + OnchainPublicKey: common.Address{}, + NodeIndex: 0, + }, + }, + F: 0, + MCMSConfig: mcmsConfig, + } + + _, err = commonchangeset.ApplyChangesets(t, e.Env, timelocksPerChain, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(NewSetRMNRemoteConfigChangeset), + Config: setRemoteConfig, + }, + }) + + require.NoError(t, err) + rmnRemotePerChain := buildRMNRemotePerChain(e.Env, state) + for _, rmnRemote := range rmnRemotePerChain { + remoteConfigSetEvents, err := rmnRemote.FilterConfigSet(nil, nil) + require.NoError(t, err) + var lastEvent *rmn_remote.RMNRemoteConfigSet + for remoteConfigSetEvents.Next() { + lastEvent = remoteConfigSetEvents.Event + } + require.NotNil(t, lastEvent) + require.Equal(t, lastEvent.Config.RmnHomeContractConfigDigest, currentActiveDigest) + } +} + +func buildRMNRemoteAddressPerChain(e deployment.Environment, state CCIPOnChainState) map[uint64]common.Address { + rmnRemotePerChain := buildRMNRemotePerChain(e, state) + rmnRemoteAddressPerChain := make(map[uint64]common.Address) + for chain, remote := range rmnRemotePerChain { + if remote == nil { + continue + } + rmnRemoteAddressPerChain[chain] = remote.Address() + } + return rmnRemoteAddressPerChain +} From 7b6e20f1b40506467349eb0203178aa2c51f5d41 Mon Sep 17 00:00:00 2001 From: krehermann <16602512+krehermann@users.noreply.github.com> Date: Mon, 9 Dec 2024 13:04:55 -0700 Subject: [PATCH 15/29] update nodes changeset mcms (#15543) * support mcms in ocr3 contract config changeset * test working for ocr3 config with mcms * migrate deployment test to setup test env * fix test * refactor forwarder configuration changeset for mcms * refactor capability update changeset mcms * plumbing update nodes * update node with mcms --- .changeset/many-crews-wave.md | 5 + deployment/keystone/capability_management.go | 94 +++++++------ .../keystone/changeset/deploy_ocr3_test.go | 9 +- deployment/keystone/changeset/helpers_test.go | 10 +- .../internal/append_node_capabilities.go | 5 +- .../keystone/changeset/internal/test/utils.go | 1 + .../keystone/changeset/internal/update_don.go | 7 +- .../internal/update_node_capabilities.go | 6 +- .../changeset/internal/update_nodes.go | 60 ++++++++- .../changeset/update_node_capabilities.go | 2 + deployment/keystone/changeset/update_nodes.go | 38 +++++- .../keystone/changeset/update_nodes_test.go | 125 ++++++++++++++++++ deployment/keystone/deploy.go | 5 +- 13 files changed, 296 insertions(+), 71 deletions(-) create mode 100644 .changeset/many-crews-wave.md create mode 100644 deployment/keystone/changeset/update_nodes_test.go diff --git a/.changeset/many-crews-wave.md b/.changeset/many-crews-wave.md new file mode 100644 index 00000000000..328a00e2f48 --- /dev/null +++ b/.changeset/many-crews-wave.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal refactor update nodes changeset to support mcms diff --git a/deployment/keystone/capability_management.go b/deployment/keystone/capability_management.go index 4e15ea897ab..888cba5b931 100644 --- a/deployment/keystone/capability_management.go +++ b/deployment/keystone/capability_management.go @@ -2,8 +2,8 @@ package keystone import ( "fmt" - "strings" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/deployment" kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" @@ -11,56 +11,35 @@ import ( // AddCapabilities adds the capabilities to the registry // it tries to add all capabilities in one go, if that fails, it falls back to adding them one by one -func AddCapabilities(lggr logger.Logger, registry *kcr.CapabilitiesRegistry, chain deployment.Chain, capabilities []kcr.CapabilitiesRegistryCapability) error { + +func AddCapabilities(lggr logger.Logger, registry *kcr.CapabilitiesRegistry, chain deployment.Chain, capabilities []kcr.CapabilitiesRegistryCapability, useMCMS bool) ([]timelock.MCMSWithTimelockProposal, error) { if len(capabilities) == 0 { - return nil + return nil, nil } - // dedup capabilities - var deduped []kcr.CapabilitiesRegistryCapability - seen := make(map[string]struct{}) - for _, cap := range capabilities { - if _, ok := seen[CapabilityID(cap)]; !ok { - seen[CapabilityID(cap)] = struct{}{} - deduped = append(deduped, cap) - } + deduped, err := dedupCapabilities(registry, capabilities) + if err != nil { + return nil, fmt.Errorf("failed to dedup capabilities: %w", err) } - - tx, err := registry.AddCapabilities(chain.DeployerKey, deduped) + txOpts := chain.DeployerKey + if useMCMS { + txOpts = deployment.SimTransactOpts() + } + tx, err := registry.AddCapabilities(txOpts, deduped) if err != nil { err = DecodeErr(kcr.CapabilitiesRegistryABI, err) - // no typed errors in the abi, so we have to do string matching - // try to add all capabilities in one go, if that fails, fall back to 1-by-1 - if !strings.Contains(err.Error(), "CapabilityAlreadyExists") { - return fmt.Errorf("failed to call AddCapabilities: %w", err) - } - lggr.Warnw("capabilities already exist, falling back to 1-by-1", "capabilities", deduped) - for _, cap := range deduped { - tx, err = registry.AddCapabilities(chain.DeployerKey, []kcr.CapabilitiesRegistryCapability{cap}) - if err != nil { - err = DecodeErr(kcr.CapabilitiesRegistryABI, err) - if strings.Contains(err.Error(), "CapabilityAlreadyExists") { - lggr.Warnw("capability already exists, skipping", "capability", cap) - continue - } - return fmt.Errorf("failed to call AddCapabilities for capability %v: %w", cap, err) - } - // 1-by-1 tx is pending and we need to wait for it to be mined - _, err = chain.Confirm(tx) - if err != nil { - return fmt.Errorf("failed to confirm AddCapabilities confirm transaction %s: %w", tx.Hash().String(), err) - } - lggr.Debugw("registered capability", "capability", cap) - - } - } else { - // the bulk add tx is pending and we need to wait for it to be mined + return nil, fmt.Errorf("failed to add capabilities: %w", err) + } + var proposals []timelock.MCMSWithTimelockProposal + if !useMCMS { _, err = chain.Confirm(tx) if err != nil { - return fmt.Errorf("failed to confirm AddCapabilities confirm transaction %s: %w", tx.Hash().String(), err) + return nil, fmt.Errorf("failed to confirm AddCapabilities confirm transaction %s: %w", tx.Hash().String(), err) } lggr.Info("registered capabilities", "capabilities", deduped) + } else { + // TODO } - return nil + return proposals, nil } // CapabilityID returns a unique id for the capability @@ -68,3 +47,36 @@ func AddCapabilities(lggr logger.Logger, registry *kcr.CapabilitiesRegistry, cha func CapabilityID(c kcr.CapabilitiesRegistryCapability) string { return fmt.Sprintf("%s@%s", c.LabelledName, c.Version) } + +// dedupCapabilities deduplicates the capabilities +// dedup capabilities with respect to the registry +// contract reverts on adding the same capability twice and that would cause the whole transaction to revert +// which is very bad for us for mcms +func dedupCapabilities(registry *kcr.CapabilitiesRegistry, capabilities []kcr.CapabilitiesRegistryCapability) ([]kcr.CapabilitiesRegistryCapability, error) { + var out []kcr.CapabilitiesRegistryCapability + existing, err := registry.GetCapabilities(nil) + if err != nil { + return nil, fmt.Errorf("failed to call GetCapabilities: %w", err) + } + existingByID := make(map[[32]byte]struct{}) + for _, cap := range existing { + existingByID[cap.HashedId] = struct{}{} + } + seen := make(map[string]struct{}) + for _, candidate := range capabilities { + h, err := registry.GetHashedCapabilityId(nil, candidate.LabelledName, candidate.Version) + if err != nil { + return nil, fmt.Errorf("failed to call GetHashedCapabilityId: %w", err) + } + // dedup input capabilities + if _, exists := seen[CapabilityID(candidate)]; exists { + continue + } + seen[CapabilityID(candidate)] = struct{}{} + // dedup with respect to the registry + if _, exists := existingByID[h]; !exists { + out = append(out, candidate) + } + } + return out, nil +} diff --git a/deployment/keystone/changeset/deploy_ocr3_test.go b/deployment/keystone/changeset/deploy_ocr3_test.go index 0e5fea6b7c6..ae00f19fc22 100644 --- a/deployment/keystone/changeset/deploy_ocr3_test.go +++ b/deployment/keystone/changeset/deploy_ocr3_test.go @@ -46,7 +46,6 @@ func TestDeployOCR3(t *testing.T) { func TestConfigureOCR3(t *testing.T) { t.Parallel() - lggr := logger.Test(t) c := kslib.OracleConfig{ MaxFaultyOracles: 1, @@ -119,13 +118,9 @@ func TestConfigureOCR3(t *testing.T) { assert.NotNil(t, csOut.Proposals) t.Logf("got: %v", csOut.Proposals[0]) - contractSetsResp, err := kslib.GetContractSets(lggr, &kslib.GetContractSetsRequest{ - Chains: te.Env.Chains, - AddressBook: te.Env.ExistingAddresses, - }) - require.NoError(t, err) + contracts := te.ContractSets()[te.RegistrySelector] var timelocks = map[uint64]*gethwrappers.RBACTimelock{ - te.RegistrySelector: contractSetsResp.ContractSets[te.RegistrySelector].Timelock, + te.RegistrySelector: contracts.Timelock, } // now apply the changeset such that the proposal is signed and execed w2 := &bytes.Buffer{} diff --git a/deployment/keystone/changeset/helpers_test.go b/deployment/keystone/changeset/helpers_test.go index faf112867ce..a4e98efd550 100644 --- a/deployment/keystone/changeset/helpers_test.go +++ b/deployment/keystone/changeset/helpers_test.go @@ -115,6 +115,7 @@ func (te TestEnv) ContractSets() map[uint64]kslib.ContractSet { } // SetupTestEnv sets up a keystone test environment with the given configuration +// TODO: make more configurable; eg many tests don't need all the nodes (like when testing a registry change) func SetupTestEnv(t *testing.T, c TestConfig) TestEnv { require.NoError(t, c.Validate()) lggr := logger.Test(t) @@ -220,15 +221,13 @@ func SetupTestEnv(t *testing.T, c TestConfig) TestEnv { } var allDons = []keystone.DonCapabilities{wfDon, cwDon, assetDon} - _, err = kschangeset.ConfigureInitialContractsChangeset(env, kschangeset.InitialContractsCfg{ + csOut, err := kschangeset.ConfigureInitialContractsChangeset(env, kschangeset.InitialContractsCfg{ RegistryChainSel: registryChainSel, Dons: allDons, OCR3Config: &ocr3Config, }) require.NoError(t, err) - // TODO: KS-rm_deploy_opt - //require.Nil(t, csOut.AddressBook, "no new addresses should be created in configure initial contracts") - //require.NoError(t, env.ExistingAddresses.Merge(csOut.AddressBook)) + require.Nil(t, csOut.AddressBook, "no new addresses should be created in configure initial contracts") req := &keystone.GetContractSetsRequest{ Chains: env.Chains, @@ -256,8 +255,7 @@ func SetupTestEnv(t *testing.T, c TestConfig) TestEnv { validateDon(t, gotRegistry, assetNodes, assetDon) if c.UseMCMS { - // TODO: mcms on all the chains, currently only on the registry chain. need to fix this for forwarders - // deploy, configure and xfer ownership of MCMS + // deploy, configure and xfer ownership of MCMS on all chains timelockCfgs := make(map[uint64]commontypes.MCMSWithTimelockConfig) for sel := range env.Chains { t.Logf("Enabling MCMS on chain %d", sel) diff --git a/deployment/keystone/changeset/internal/append_node_capabilities.go b/deployment/keystone/changeset/internal/append_node_capabilities.go index cb28c03c6f5..6168356c351 100644 --- a/deployment/keystone/changeset/internal/append_node_capabilities.go +++ b/deployment/keystone/changeset/internal/append_node_capabilities.go @@ -15,6 +15,7 @@ type AppendNodeCapabilitiesRequest struct { Registry *kcr.CapabilitiesRegistry P2pToCapabilities map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability + UseMCMS bool } func (req *AppendNodeCapabilitiesRequest) Validate() error { @@ -36,7 +37,7 @@ func AppendNodeCapabilitiesImpl(lggr logger.Logger, req *AppendNodeCapabilitiesR for _, cap := range req.P2pToCapabilities { capabilities = append(capabilities, cap...) } - err := kslib.AddCapabilities(lggr, req.Registry, req.Chain, capabilities) + proposals, err := kslib.AddCapabilities(lggr, req.Registry, req.Chain, capabilities, req.UseMCMS) if err != nil { return nil, fmt.Errorf("failed to add capabilities: %w", err) } @@ -55,10 +56,12 @@ func AppendNodeCapabilitiesImpl(lggr logger.Logger, req *AppendNodeCapabilitiesR Chain: req.Chain, Registry: req.Registry, P2pToUpdates: updatesByPeer, + UseMCMS: req.UseMCMS, } resp, err := UpdateNodes(lggr, updateNodesReq) if err != nil { return nil, fmt.Errorf("failed to update nodes: %w", err) } + resp.Proposals = append(proposals, resp.Proposals...) return resp, nil } diff --git a/deployment/keystone/changeset/internal/test/utils.go b/deployment/keystone/changeset/internal/test/utils.go index 6fe4a8f4a2e..a7aed2c9cb1 100644 --- a/deployment/keystone/changeset/internal/test/utils.go +++ b/deployment/keystone/changeset/internal/test/utils.go @@ -33,6 +33,7 @@ type SetupTestRegistryRequest struct { P2pToCapabilities map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability NopToNodes map[kcr.CapabilitiesRegistryNodeOperator][]*internal.P2PSignerEnc Dons []Don + // TODO maybe add support for MCMS at this level } type SetupTestRegistryResponse struct { diff --git a/deployment/keystone/changeset/internal/update_don.go b/deployment/keystone/changeset/internal/update_don.go index 4883368dc4d..d56f77c1c78 100644 --- a/deployment/keystone/changeset/internal/update_don.go +++ b/deployment/keystone/changeset/internal/update_don.go @@ -9,6 +9,7 @@ import ( "sort" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" @@ -31,6 +32,8 @@ type UpdateDonRequest struct { P2PIDs []p2pkey.PeerID // this is the unique identifier for the don CapabilityConfigs []CapabilityConfig // if Config subfield is nil, a default config is used + + UseMCMS bool } func (r *UpdateDonRequest) appendNodeCapabilitiesRequest() *AppendNodeCapabilitiesRequest { @@ -38,6 +41,7 @@ func (r *UpdateDonRequest) appendNodeCapabilitiesRequest() *AppendNodeCapabiliti Chain: r.Chain, Registry: r.Registry, P2pToCapabilities: make(map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability), + UseMCMS: r.UseMCMS, } for _, p2pid := range r.P2PIDs { if _, exists := out.P2pToCapabilities[p2pid]; !exists { @@ -61,7 +65,8 @@ func (r *UpdateDonRequest) Validate() error { } type UpdateDonResponse struct { - DonInfo kcr.CapabilitiesRegistryDONInfo + DonInfo kcr.CapabilitiesRegistryDONInfo + Proposals []timelock.MCMSWithTimelockProposal } func UpdateDon(lggr logger.Logger, req *UpdateDonRequest) (*UpdateDonResponse, error) { diff --git a/deployment/keystone/changeset/internal/update_node_capabilities.go b/deployment/keystone/changeset/internal/update_node_capabilities.go index 0420c46f27d..72e6f99ee49 100644 --- a/deployment/keystone/changeset/internal/update_node_capabilities.go +++ b/deployment/keystone/changeset/internal/update_node_capabilities.go @@ -15,6 +15,8 @@ type UpdateNodeCapabilitiesImplRequest struct { Registry *kcr.CapabilitiesRegistry P2pToCapabilities map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability + + UseMCMS bool } func (req *UpdateNodeCapabilitiesImplRequest) Validate() error { @@ -37,7 +39,7 @@ func UpdateNodeCapabilitiesImpl(lggr logger.Logger, req *UpdateNodeCapabilitiesI for _, cap := range req.P2pToCapabilities { capabilities = append(capabilities, cap...) } - err := kslib.AddCapabilities(lggr, req.Registry, req.Chain, capabilities) + proposals, err := kslib.AddCapabilities(lggr, req.Registry, req.Chain, capabilities, req.UseMCMS) if err != nil { return nil, fmt.Errorf("failed to add capabilities: %w", err) } @@ -51,10 +53,12 @@ func UpdateNodeCapabilitiesImpl(lggr logger.Logger, req *UpdateNodeCapabilitiesI Chain: req.Chain, Registry: req.Registry, P2pToUpdates: p2pToUpdates, + UseMCMS: req.UseMCMS, } resp, err := UpdateNodes(lggr, updateNodesReq) if err != nil { return nil, fmt.Errorf("failed to update nodes: %w", err) } + resp.Proposals = append(proposals, resp.Proposals...) return resp, nil } diff --git a/deployment/keystone/changeset/internal/update_nodes.go b/deployment/keystone/changeset/internal/update_nodes.go index b8a08c37e50..2eba6d063df 100644 --- a/deployment/keystone/changeset/internal/update_nodes.go +++ b/deployment/keystone/changeset/internal/update_nodes.go @@ -5,15 +5,21 @@ import ( "encoding/hex" "errors" "fmt" + "math/big" "sort" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink-common/pkg/logger" kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" kslib "github.com/smartcontractkit/chainlink/deployment/keystone" ) @@ -30,6 +36,9 @@ type UpdateNodesRequest struct { Registry *kcr.CapabilitiesRegistry P2pToUpdates map[p2pkey.PeerID]NodeUpdate + + ContractSet kslib.ContractSet // contract set for the given chain + UseMCMS bool } func (req *UpdateNodesRequest) NodeParams() ([]kcr.CapabilitiesRegistryNodeParams, error) { @@ -80,10 +89,12 @@ func (req *UpdateNodesRequest) Validate() error { type UpdateNodesResponse struct { NodeParams []kcr.CapabilitiesRegistryNodeParams + Proposals []timelock.MCMSWithTimelockProposal } // UpdateNodes updates the nodes in the registry -// the update sets the signer and capabilities for each node. it does not append capabilities to the existing ones +// the update sets the signer and capabilities for each node. +// The nodes and capabilities must already exist in the registry. func UpdateNodes(lggr logger.Logger, req *UpdateNodesRequest) (*UpdateNodesResponse, error) { if err := req.Validate(); err != nil { return nil, fmt.Errorf("failed to validate request: %w", err) @@ -94,17 +105,54 @@ func UpdateNodes(lggr logger.Logger, req *UpdateNodesRequest) (*UpdateNodesRespo err = kslib.DecodeErr(kcr.CapabilitiesRegistryABI, err) return nil, fmt.Errorf("failed to make node params: %w", err) } - tx, err := req.Registry.UpdateNodes(req.Chain.DeployerKey, params) + txOpts := req.Chain.DeployerKey + if req.UseMCMS { + txOpts = deployment.SimTransactOpts() + } + tx, err := req.Registry.UpdateNodes(txOpts, params) if err != nil { err = kslib.DecodeErr(kcr.CapabilitiesRegistryABI, err) return nil, fmt.Errorf("failed to call UpdateNodes: %w", err) } - _, err = req.Chain.Confirm(tx) - if err != nil { - return nil, fmt.Errorf("failed to confirm UpdateNodes confirm transaction %s: %w", tx.Hash().String(), err) + var proposals []timelock.MCMSWithTimelockProposal + if !req.UseMCMS { + _, err = req.Chain.Confirm(tx) + if err != nil { + return nil, fmt.Errorf("failed to confirm UpdateNodes confirm transaction %s: %w", tx.Hash().String(), err) + } + } else { + ops := timelock.BatchChainOperation{ + ChainIdentifier: mcms.ChainIdentifier(req.Chain.Selector), + Batch: []mcms.Operation{ + { + To: req.Registry.Address(), + Data: tx.Data(), + Value: big.NewInt(0), + }, + }, + } + timelocksPerChain := map[uint64]common.Address{ + req.Chain.Selector: req.ContractSet.Timelock.Address(), + } + proposerMCMSes := map[uint64]*gethwrappers.ManyChainMultiSig{ + req.Chain.Selector: req.ContractSet.ProposerMcm, + } + + proposal, err := proposalutils.BuildProposalFromBatches( + timelocksPerChain, + proposerMCMSes, + []timelock.BatchChainOperation{ops}, + "proposal to set update nodes", + 0, + ) + if err != nil { + return nil, fmt.Errorf("failed to build proposal: %w", err) + } + proposals = append(proposals, *proposal) } - return &UpdateNodesResponse{NodeParams: params}, nil + + return &UpdateNodesResponse{NodeParams: params, Proposals: proposals}, nil } // AppendCapabilities appends the capabilities to the existing capabilities of the nodes listed in p2pIds in the registry diff --git a/deployment/keystone/changeset/update_node_capabilities.go b/deployment/keystone/changeset/update_node_capabilities.go index 1d6dde6af5a..655614ed7f0 100644 --- a/deployment/keystone/changeset/update_node_capabilities.go +++ b/deployment/keystone/changeset/update_node_capabilities.go @@ -54,6 +54,7 @@ type MutateNodeCapabilitiesRequest struct { RegistryChainSel uint64 P2pToCapabilities map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability + UseMCMS bool } func (req *MutateNodeCapabilitiesRequest) Validate() error { @@ -95,6 +96,7 @@ func (req *MutateNodeCapabilitiesRequest) updateNodeCapabilitiesImplRequest(e de Chain: registryChain, Registry: registry, P2pToCapabilities: req.P2pToCapabilities, + UseMCMS: req.UseMCMS, }, nil } diff --git a/deployment/keystone/changeset/update_nodes.go b/deployment/keystone/changeset/update_nodes.go index 7e436160d2e..76b095d0949 100644 --- a/deployment/keystone/changeset/update_nodes.go +++ b/deployment/keystone/changeset/update_nodes.go @@ -4,21 +4,49 @@ import ( "fmt" "github.com/smartcontractkit/chainlink/deployment" + + kslib "github.com/smartcontractkit/chainlink/deployment/keystone" "github.com/smartcontractkit/chainlink/deployment/keystone/changeset/internal" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" ) var _ deployment.ChangeSet[*UpdateNodesRequest] = UpdateNodes -type UpdateNodesRequest = internal.UpdateNodesRequest +type UpdateNodesRequest struct { + RegistryChainSel uint64 + P2pToUpdates map[p2pkey.PeerID]NodeUpdate + + UseMCMS bool +} type NodeUpdate = internal.NodeUpdate // UpdateNodes updates the a set of nodes. -// This a complex action in practice that involves registering missing capabilities, adding the nodes, and updating -// the capabilities of the DON +// The nodes and capabilities in the request must already exist in the registry contract. func UpdateNodes(env deployment.Environment, req *UpdateNodesRequest) (deployment.ChangesetOutput, error) { - _, err := internal.UpdateNodes(env.Logger, req) + // extract the registry contract and chain from the environment + registryChain, ok := env.Chains[req.RegistryChainSel] + if !ok { + return deployment.ChangesetOutput{}, fmt.Errorf("registry chain selector %d does not exist in environment", req.RegistryChainSel) + } + contracts, err := kslib.GetContractSets(env.Logger, &kslib.GetContractSetsRequest{ + Chains: env.Chains, + AddressBook: env.ExistingAddresses, + }) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to get contract sets: %w", err) + } + + resp, err := internal.UpdateNodes(env.Logger, &internal.UpdateNodesRequest{ + Chain: registryChain, + Registry: contracts.ContractSets[req.RegistryChainSel].CapabilitiesRegistry, + ContractSet: contracts.ContractSets[req.RegistryChainSel], + P2pToUpdates: req.P2pToUpdates, + UseMCMS: req.UseMCMS, + }) if err != nil { return deployment.ChangesetOutput{}, fmt.Errorf("failed to update don: %w", err) } - return deployment.ChangesetOutput{}, nil + return deployment.ChangesetOutput{ + Proposals: resp.Proposals, + }, nil } diff --git a/deployment/keystone/changeset/update_nodes_test.go b/deployment/keystone/changeset/update_nodes_test.go new file mode 100644 index 00000000000..10c08333d22 --- /dev/null +++ b/deployment/keystone/changeset/update_nodes_test.go @@ -0,0 +1,125 @@ +package changeset_test + +import ( + "encoding/hex" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/exp/maps" + + "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" + commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" + "github.com/smartcontractkit/chainlink/deployment/keystone/changeset" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" +) + +func TestUpdateNodes(t *testing.T) { + t.Parallel() + + t.Run("no mcms", func(t *testing.T) { + te := SetupTestEnv(t, TestConfig{ + WFDonConfig: DonConfig{N: 4}, + AssetDonConfig: DonConfig{N: 4}, + WriterDonConfig: DonConfig{N: 4}, + NumChains: 1, + }) + + updates := make(map[p2pkey.PeerID]changeset.NodeUpdate) + i := uint8(0) + for id, _ := range te.WFNodes { + k, err := p2pkey.MakePeerID(id) + require.NoError(t, err) + pubKey := [32]byte{31: i + 1} + // don't set capabilities or nop b/c those must already exist in the contract + // those ops must be a different proposal when using MCMS + updates[k] = changeset.NodeUpdate{ + EncryptionPublicKey: hex.EncodeToString(pubKey[:]), + Signer: [32]byte{0: i + 1}, + } + i++ + } + + cfg := changeset.UpdateNodesRequest{ + RegistryChainSel: te.RegistrySelector, + P2pToUpdates: updates, + } + + csOut, err := changeset.UpdateNodes(te.Env, &cfg) + require.NoError(t, err) + require.Len(t, csOut.Proposals, 0) + require.Nil(t, csOut.AddressBook) + + validateUpdate(t, te, updates) + }) + + t.Run("with mcms", func(t *testing.T) { + te := SetupTestEnv(t, TestConfig{ + WFDonConfig: DonConfig{N: 4}, + AssetDonConfig: DonConfig{N: 4}, + WriterDonConfig: DonConfig{N: 4}, + NumChains: 1, + UseMCMS: true, + }) + + updates := make(map[p2pkey.PeerID]changeset.NodeUpdate) + i := uint8(0) + for id, _ := range te.WFNodes { + k, err := p2pkey.MakePeerID(id) + require.NoError(t, err) + pubKey := [32]byte{31: i + 1} + // don't set capabilities or nop b/c those must already exist in the contract + // those ops must be a different proposal when using MCMS + updates[k] = changeset.NodeUpdate{ + EncryptionPublicKey: hex.EncodeToString(pubKey[:]), + Signer: [32]byte{0: i + 1}, + } + i++ + } + + cfg := changeset.UpdateNodesRequest{ + RegistryChainSel: te.RegistrySelector, + P2pToUpdates: updates, + UseMCMS: true, + } + + csOut, err := changeset.UpdateNodes(te.Env, &cfg) + require.NoError(t, err) + require.Len(t, csOut.Proposals, 1) + require.Nil(t, csOut.AddressBook) + + // now apply the changeset such that the proposal is signed and execed + contracts := te.ContractSets()[te.RegistrySelector] + timelocks := map[uint64]*gethwrappers.RBACTimelock{ + te.RegistrySelector: contracts.Timelock, + } + _, err = commonchangeset.ApplyChangesets(t, te.Env, timelocks, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(changeset.UpdateNodes), + Config: &changeset.UpdateNodesRequest{ + RegistryChainSel: te.RegistrySelector, + P2pToUpdates: updates, + UseMCMS: true, + }, + }, + }) + require.NoError(t, err) + + validateUpdate(t, te, updates) + }) + +} + +// validateUpdate checks reads nodes from the registry and checks they have the expected updates +func validateUpdate(t *testing.T, te TestEnv, expected map[p2pkey.PeerID]changeset.NodeUpdate) { + registry := te.ContractSets()[te.RegistrySelector].CapabilitiesRegistry + wfP2PIDs := p2pIDs(t, maps.Keys(te.WFNodes)) + nodes, err := registry.GetNodesByP2PIds(nil, wfP2PIDs) + require.NoError(t, err) + require.Len(t, nodes, len(wfP2PIDs)) + for _, node := range nodes { + // only check the fields that were updated + assert.Equal(t, expected[node.P2pId].EncryptionPublicKey, hex.EncodeToString(node.EncryptionPublicKey[:])) + assert.Equal(t, expected[node.P2pId].Signer, node.Signer) + } +} diff --git a/deployment/keystone/deploy.go b/deployment/keystone/deploy.go index 9bd291e9c1e..4dd8b8c495a 100644 --- a/deployment/keystone/deploy.go +++ b/deployment/keystone/deploy.go @@ -21,7 +21,6 @@ import ( "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" - "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" @@ -483,8 +482,8 @@ func RegisterCapabilities(lggr logger.Logger, req RegisterCapabilitiesRequest) ( for cap := range uniqueCaps { capabilities = append(capabilities, cap) } - - err = AddCapabilities(lggr, registry, registryChain, capabilities) + // not using mcms; ignore proposals + _, err = AddCapabilities(lggr, registry, registryChain, capabilities, false) if err != nil { return nil, fmt.Errorf("failed to add capabilities: %w", err) } From 45898fc6752d4aae410cb6f07f9d9817b3ab2bec Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Mon, 9 Dec 2024 13:03:15 -0800 Subject: [PATCH 16/29] feat: conditionally run unit tests (#15347) * feat: conditionally run unit tests * feat: separate action to different steps * feat: combine core unit tests * update setup env action * feat: collect coverage * chore: cleanup * chore: less run conditions, lower concurrency, proper action version * fix: dont modify ci-core.yml Did some testing trying to see if I could speed up test binary building through caching. It seems like the cache saving doesn't work when the composite action is nested. * fix: no nested composite actions --- .../actions/setup-ci-core-tests/action.yml | 61 ++++ .github/workflows/ci-core-partial.yml | 287 ++++++++++++++++++ 2 files changed, 348 insertions(+) create mode 100644 .github/actions/setup-ci-core-tests/action.yml create mode 100644 .github/workflows/ci-core-partial.yml diff --git a/.github/actions/setup-ci-core-tests/action.yml b/.github/actions/setup-ci-core-tests/action.yml new file mode 100644 index 00000000000..a2cf3f4103c --- /dev/null +++ b/.github/actions/setup-ci-core-tests/action.yml @@ -0,0 +1,61 @@ +name: Setup CI Core Tests +description: | + Shared setup steps for ci-core. + Note: Other actions should not be called from this action. There is + weird behavior when nesting reusable actions. +inputs: + + go-mod-download-directory: + description: | + The directory to run go mod download in. If not provided, it will not run go mod download. + required: false + default: "" + + db-url: + description: | + The expected database URL + required: true + +runs: + using: composite + steps: + - name: Touching core/web/assets/index.html + shell: bash + run: mkdir -p core/web/assets && touch core/web/assets/index.html + + - name: Download Go vendor packages + shell: bash + run: go mod download + + - name: Go Mod Download (optional) + if: ${{ inputs.go-mod-download-directory != '' }} + shell: bash + working-directory: ${{ inputs.go-mod-download-directory }} + run: go mod download + + - name: Build binary + shell: bash + run: go build -o chainlink.test . + + - name: Setup DB + shell: bash + run: ./chainlink.test local db preparetest + env: + CL_DATABASE_URL: ${{ inputs.db-url }} + + - name: Install LOOP Plugins + shell: bash + run: | + pushd $(go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-feeds) + go install ./cmd/chainlink-feeds + popd + pushd $(go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-data-streams) + go install ./mercury/cmd/chainlink-mercury + popd + pushd $(go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-solana) + go install ./pkg/solana/cmd/chainlink-solana + popd + pushd $(go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-starknet/relayer) + go install ./pkg/chainlink/cmd/chainlink-starknet + popd + diff --git a/.github/workflows/ci-core-partial.yml b/.github/workflows/ci-core-partial.yml new file mode 100644 index 00000000000..c9752d4e1e4 --- /dev/null +++ b/.github/workflows/ci-core-partial.yml @@ -0,0 +1,287 @@ +name: Core Unit Tests + +on: + push: + branches: + - develop + # - "release/*" + # merge_group: + pull_request: + schedule: + - cron: "0 1 * * *" + +env: + # We explicitly have this env var not be "CL_DATABASE_URL" to avoid having it be used by core related tests + # when they should not be using it, while still allowing us to DRY up the setup + DB_URL: postgresql://postgres:postgres@localhost:5432/chainlink_test?sslmode=disable + +jobs: + filter: + name: Detect Changes + permissions: + pull-requests: read + outputs: + should-run-all-tests: ${{ steps.match-some.outputs.test-data == 'true' }} + should-collect-coverage: ${{ github.event_name == 'schedule' }} + runs-on: ubuntu-latest + steps: + - name: Checkout the repo + uses: actions/checkout@v4.2.1 + with: + repository: smartcontractkit/chainlink + - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 + id: match-some + with: + # "if any changed file matches one or more of the conditions" (https://github.com/dorny/paths-filter/issues/225) + predicate-quantifier: some + # test-data - any changes to any testdata files/paths + filters: | + test-data: + - '**/testdata/**' + + run-unit-tests: + name: Tests (${{ matrix.type.test-suite }}) + needs: filter + runs-on: ubuntu22.04-32cores-128GB + permissions: + id-token: write + contents: write + strategy: + fail-fast: false + matrix: + type: + - test-suite: "core" + module-directory: "./" + build-flags: "-tags=integration" + - test-suite: "ccip-deployment" + module-directory: "./deployment" + steps: + - name: Checkout the repo + uses: actions/checkout@v4.2.1 + + - name: Setup NodeJS + uses: ./.github/actions/setup-nodejs + with: + prod: "true" + + - name: Setup Go + uses: ./.github/actions/setup-go + with: + build-cache-version: ${{ matrix.type.test-suite }} + restore-build-cache-only: "false" + + - name: Setup Solana + uses: ./.github/actions/setup-solana + + - name: Setup wasmd + uses: ./.github/actions/setup-wasmd + + - name: Setup Postgres + uses: ./.github/actions/setup-postgres + + - name: Setup CI Core Environment + uses: ./.github/actions/setup-ci-core-tests + with: + db-url: ${{ env.DB_URL }} + go-mod-download-directory: ${{ matrix.type.test-suite == 'ccip-deployment' && matrix.type.module-directory || '' }} + + - name: Build Tests + uses: smartcontractkit/.github/apps/go-conditional-tests@37882e110590e636627a26371bdbd56ddfcce821 # go-conditional-tests@0.1.0 + timeout-minutes: 10 + with: + pipeline-step: "build" + build-concurrency: "32" + collect-coverage: ${{ needs.filter.outputs.should-collect-coverage }} + test-suite: ${{ matrix.type.test-suite }} + module-directory: ${{ matrix.type.module-directory }} + github-token: ${{ secrets.GITHUB_TOKEN }} + build-flags: ${{ matrix.type.build-flags }} + + - name: Run Tests + uses: smartcontractkit/.github/apps/go-conditional-tests@37882e110590e636627a26371bdbd56ddfcce821 # go-conditional-tests@0.1.0 + timeout-minutes: 15 + env: + CL_DATABASE_URL: ${{ env.DB_URL }} + with: + pipeline-step: "run" + run-concurrency: "16" + run-all-tests: ${{ needs.filter.outputs.should-run-all-tests }} + collect-coverage: ${{ needs.filter.outputs.should-collect-coverage }} + test-suite: ${{ matrix.type.test-suite }} + module-directory: ${{ matrix.type.module-directory }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Update Test Index + uses: smartcontractkit/.github/apps/go-conditional-tests@37882e110590e636627a26371bdbd56ddfcce821 # go-conditional-tests@0.1.0 + with: + pipeline-step: "update" + collect-coverage: ${{ needs.filter.outputs.should-collect-coverage }} + test-suite: ${{ matrix.type.test-suite }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Print postgres logs + if: ${{ always() }} + run: docker compose logs postgres | tee ../../../postgres_logs.txt + working-directory: ./.github/actions/setup-postgres + + scan: + name: SonarQube Scan + needs: [run-unit-tests, filter] + if: ${{ needs.filter.outputs.should-collect-coverage == 'true' }} + runs-on: ubuntu-latest + steps: + - name: Checkout the repo + uses: actions/checkout@v4.2.1 + with: + # fetches all history for all tags and branches to provide more metadata for sonar reports + fetch-depth: 0 + + - name: Download all workflow run artifacts + uses: actions/download-artifact@v4.1.8 + with: + path: coverage + pattern: coverage-* + merge-multiple: true + + - name: Check and Set SonarQube Report Paths + shell: bash + run: | + ARGS="" + sonarqube_coverage_report_paths=$(find ./coverage -name '*.cover.out' | paste -sd "," -) + + # TODO uncomment when linting in enabled + # Check and assign paths for lint reports + # if [ -d "golangci-lint-report" ]; then + # sonarqube_lint_report_paths=$(find golangci-lint-report -name 'golangci-lint-report.xml' | paste -sd "," -) + # else + # sonarqube_lint_report_paths="" + # fi + # if [[ -z "$sonarqube_lint_report_paths" ]]; then + # echo "::warning::No lint report paths found, will not pass to sonarqube" + # else + # echo "Found lint report paths: $sonarqube_lint_report_paths" + # ARGS="$ARGS -Dsonar.go.golangci-lint.reportPaths=$sonarqube_lint_report_paths" + # fi + + if [[ -z "$sonarqube_coverage_report_paths" ]]; then + echo "::warning::No coverage report paths found, will not pass to sonarqube" + else + echo "Found coverage report paths: $sonarqube_coverage_report_paths" + ARGS="$ARGS -Dsonar.go.coverage.reportPaths=$sonarqube_coverage_report_paths" + fi + + echo "Final SONARQUBE_ARGS: $ARGS" + echo "SONARQUBE_ARGS=$ARGS" >> $GITHUB_ENV + + - name: SonarQube Scan + if: ${{ env.SONARQUBE_ARGS != '' }} + uses: sonarsource/sonarqube-scan-action@aecaf43ae57e412bd97d70ef9ce6076e672fe0a9 # v2.3.0 + with: + args: ${{ env.SONARQUBE_ARGS }} + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + SONAR_SCANNER_OPTS: "-Xms6g -Xmx8g" + + run-fuzz-tests: + name: Tests (fuzz) + runs-on: ubuntu22.04-32cores-128GB + if: ${{ github.event_name == 'schedule' }} + steps: + - name: Checkout the repo + uses: actions/checkout@v4.2.1 + + - name: Setup Go + uses: ./.github/actions/setup-go + with: + build-cache-version: "fuzz" + restore-build-cache-only: "true" + + - name: Setup Solana + uses: ./.github/actions/setup-solana + + - name: Setup wasmd + uses: ./.github/actions/setup-wasmd + + - name: Setup Postgres + uses: ./.github/actions/setup-postgres + + - name: Setup CI Core Environment + uses: ./.github/actions/setup-ci-core-tests + with: + db-url: ${{ env.DB_URL }} + + - name: Increase Timeouts + if: ${{ github.event_name == 'schedule'}} + run: | + echo "FUZZ_TIMEOUT_MINUTES=10">> $GITHUB_ENV + + - name: Run Fuzz Tests + env: + OUTPUT_FILE: ./output.txt + CL_DATABASE_URL: ${{ env.DB_URL }} + run: ./tools/bin/go_core_fuzz ./... + + - name: Print postgres logs + if: ${{ always() }} + run: docker compose logs postgres | tee ../../../postgres_logs.txt + working-directory: ./.github/actions/setup-postgres + + run-race-tests: + name: Tests (race) + runs-on: ubuntu22.04-32cores-128GB + if: ${{ github.event_name == 'schedule' }} + steps: + - name: Checkout the repo + uses: actions/checkout@v4.2.1 + + - name: Setup Go + uses: ./.github/actions/setup-go + with: + build-cache-version: "race" + restore-build-cache-only: "true" + + - name: Setup Solana + uses: ./.github/actions/setup-solana + + - name: Setup wasmd + uses: ./.github/actions/setup-wasmd + + - name: Setup Postgres + uses: ./.github/actions/setup-postgres + + - name: Setup CI Core Environment + uses: ./.github/actions/setup-ci-core-tests + with: + db-url: ${{ env.DB_URL }} + + - name: Increase Timeouts + if: ${{ github.event_name == 'schedule'}} + run: | + echo "TIMEOUT=10m" >> $GITHUB_ENV + echo "COUNT=50" >> $GITHUB_ENV + + - name: Run Race Tests + env: + OUTPUT_FILE: ./output.txt + CL_DATABASE_URL: ${{ env.DB_URL }} + run: ./tools/bin/go_core_race_tests ./... + + - name: Print Races + id: print-races + if: ${{ failure() }} + run: | + find race.* | xargs cat > race.txt + if [[ -s race.txt ]]; then + cat race.txt + echo "post_to_slack=true" >> $GITHUB_OUTPUT + else + echo "post_to_slack=false" >> $GITHUB_OUTPUT + fi + echo "github.event_name: ${{ github.event_name }}" + echo "github.ref: ${{ github.ref }}" + + - name: Print postgres logs + if: ${{ always() }} + run: docker compose logs postgres | tee ../../../postgres_logs.txt + working-directory: ./.github/actions/setup-postgres From aae1def589edf40effb808bf5d29ba792c99d3a4 Mon Sep 17 00:00:00 2001 From: Anindita Ghosh <88458927+AnieeG@users.noreply.github.com> Date: Mon, 9 Dec 2024 22:53:43 -0800 Subject: [PATCH 17/29] remove deployCCIPContracts (#15586) --- .../ccip/changeset/cs_add_chain_test.go | 15 ++++++++- deployment/ccip/changeset/cs_deploy_chain.go | 32 ------------------- 2 files changed, 14 insertions(+), 33 deletions(-) diff --git a/deployment/ccip/changeset/cs_add_chain_test.go b/deployment/ccip/changeset/cs_add_chain_test.go index c8d872236c2..2873b3bf613 100644 --- a/deployment/ccip/changeset/cs_add_chain_test.go +++ b/deployment/ccip/changeset/cs_add_chain_test.go @@ -80,10 +80,23 @@ func TestAddChainInbound(t *testing.T) { for _, chain := range initialDeploy { chainConfig[chain] = DefaultOCRParams(e.FeedChainSel, nil, nil) } - err = deployCCIPContracts(e.Env, newAddresses, NewChainsConfig{ + newChainCfg := NewChainsConfig{ HomeChainSel: e.HomeChainSel, FeedChainSel: e.FeedChainSel, ChainConfigByChain: chainConfig, + } + e.Env, err = commonchangeset.ApplyChangesets(t, e.Env, nil, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(DeployChainContracts), + Config: DeployChainContractsConfig{ + ChainSelectors: newChainCfg.Chains(), + HomeChainSelector: newChainCfg.HomeChainSel, + }, + }, + { + Changeset: commonchangeset.WrapChangeSet(ConfigureNewChains), + Config: newChainCfg, + }, }) require.NoError(t, err) diff --git a/deployment/ccip/changeset/cs_deploy_chain.go b/deployment/ccip/changeset/cs_deploy_chain.go index e2762b27578..de6e4b5f466 100644 --- a/deployment/ccip/changeset/cs_deploy_chain.go +++ b/deployment/ccip/changeset/cs_deploy_chain.go @@ -65,38 +65,6 @@ func (c DeployChainContractsConfig) Validate() error { return nil } -// deployCCIPContracts assumes the following contracts are deployed: -// - Capability registry -// - CCIP home -// - RMN home -// - Fee tokens on all chains. -// and present in ExistingAddressBook. -// It then deploys the rest of the CCIP chain contracts to the selected chains -// registers the nodes with the capability registry and creates a DON for -// each new chain. -func deployCCIPContracts( - e deployment.Environment, - ab deployment.AddressBook, - c NewChainsConfig) error { - err := deployChainContractsForChains(e, ab, c.HomeChainSel, c.Chains()) - if err != nil { - e.Logger.Errorw("Failed to deploy chain contracts", "err", err) - return err - } - err = e.ExistingAddresses.Merge(ab) - if err != nil { - e.Logger.Errorw("Failed to merge address book", "err", err) - return err - } - err = configureChain(e, c) - if err != nil { - e.Logger.Errorw("Failed to add chain", "err", err) - return err - } - - return nil -} - func deployChainContractsForChains( e deployment.Environment, ab deployment.AddressBook, From 99b666fbcbccb926e6dbac11896bf7e7ee5c25ea Mon Sep 17 00:00:00 2001 From: Graham Goh Date: Tue, 10 Dec 2024 18:53:50 +1100 Subject: [PATCH 18/29] fix(operator-ui): fix duplicate chain id in chain config dialog (#15585) There was an issue raised [here](https://chainlink-core.slack.com/archives/C06NF17JK9N/p1733437678773739?thread_ts=1733412322.287769&cid=C06NF17JK9N) impacting the chain config dialog of the operator ui, because the chain id is no longer unique now that we work with multichain, we need to handle it better by considering the network and chain id together instead of just chainid. Context: https://github.com/smartcontractkit/operator-ui/pull/97 JIRA: https://smartcontract-it.atlassian.net/browse/DPA-1384 --- .changeset/six-coins-mix.md | 5 +++++ core/web/assets/index.html | 2 +- core/web/assets/index.html.gz | Bin 419 -> 420 bytes ...c1e482.js => main.008c37495ba29761321d.js} | 2 +- ....js.gz => main.008c37495ba29761321d.js.gz} | Bin 1198074 -> 1198171 bytes operator_ui/TAG | 2 +- 6 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 .changeset/six-coins-mix.md rename core/web/assets/{main.ec7b7e88c8c965c1e482.js => main.008c37495ba29761321d.js} (90%) rename core/web/assets/{main.ec7b7e88c8c965c1e482.js.gz => main.008c37495ba29761321d.js.gz} (92%) diff --git a/.changeset/six-coins-mix.md b/.changeset/six-coins-mix.md new file mode 100644 index 00000000000..2877aa3012a --- /dev/null +++ b/.changeset/six-coins-mix.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#bugfix fix: duplicate chain id in chain config dialog diff --git a/core/web/assets/index.html b/core/web/assets/index.html index 6e2fd9cf254..ae1aac9ede0 100644 --- a/core/web/assets/index.html +++ b/core/web/assets/index.html @@ -1 +1 @@ -Operator UIChainlink
\ No newline at end of file +Operator UIChainlink
\ No newline at end of file diff --git a/core/web/assets/index.html.gz b/core/web/assets/index.html.gz index 9d9d6b9151f5f943cc67dbc3175f825a8407d3ef..a65173c97c81ceb7da51eee8443c4d0395a6644d 100644 GIT binary patch literal 420 zcmV;V0bBkbiwFP!000021C^3bYa1~T#lMOw=&A8)Z70niq|G5vNTC#(=FsC{g|oXF$i@VKB%LJ$|#LqxZn8A1}V`#NF);i8@&tvO0I zQvRh1MyKn*Mf^?_dCpo51$(Clk+I$xQxg=KO$&HwC~fJr$tcDTKzU{~phNJxp`;Jfi+&8)#A#oG#2V`vjUgYmRtx OSk>QPQcP380ssJ`k;5qf literal 419 zcmV;U0bKqciwFP!000021C^3NYuqpph5w2w=&8GwlO~NDBi&mbKU=pXFsguEVIFZNg^4L%!Aqd;zA)vdM8A1}U{W@X>;jEq>tXU-+ zDE(3ygVSZ;EdC&hJSVM&jJ?x?$XITTDG{>FrWw3c6!-K}B^2Wapfoco@_YveVdpuH z8B2M4dEax6AaetY&7a7glay-DyblN?mCAE8zLdKjB88*-#yb|ieP7p`tGeD?*R?)1 zD#w6jK>RQAJk=}u3kYU{@b1BLD*wWo9;Uf^9#Q`_tNBBnrU-j9FWW^shkpN>&^hwr zGmWA;>@hpNTw0avoi8t*h6x^5TVa(CNy$J(!8lgdoC|G7lcLV)%q+7{M^kIfiZ{!u N{swyIDQUn0007U@#6AE3 diff --git a/core/web/assets/main.ec7b7e88c8c965c1e482.js b/core/web/assets/main.008c37495ba29761321d.js similarity index 90% rename from core/web/assets/main.ec7b7e88c8c965c1e482.js rename to core/web/assets/main.008c37495ba29761321d.js index 5640ce7c29e..b9feeec3d83 100644 --- a/core/web/assets/main.ec7b7e88c8c965c1e482.js +++ b/core/web/assets/main.008c37495ba29761321d.js @@ -171,4 +171,4 @@ object-assign */ Object.defineProperty(t,"__esModule",{value:!0}),"undefined"==typeof window||"function"!=typeof MessageChannel){var n,r,i,a,o,s=null,u=null,c=function(){if(null!==s)try{var e=t.unstable_now();s(!0,e),s=null}catch(n){throw setTimeout(c,0),n}},l=Date.now();t.unstable_now=function(){return Date.now()-l},n=function(e){null!==s?setTimeout(n,0,e):(s=e,setTimeout(c,0))},r=function(e,t){u=setTimeout(e,t)},i=function(){clearTimeout(u)},a=function(){return!1},o=t.unstable_forceFrameRate=function(){}}else{var f=window.performance,d=window.Date,h=window.setTimeout,p=window.clearTimeout;if("undefined"!=typeof console){var b=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!=typeof b&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")}if("object"==typeof f&&"function"==typeof f.now)t.unstable_now=function(){return f.now()};else{var m=d.now();t.unstable_now=function(){return d.now()-m}}var g=!1,v=null,y=-1,w=5,_=0;a=function(){return t.unstable_now()>=_},o=function(){},t.unstable_forceFrameRate=function(e){0>e||125M(o,n))void 0!==u&&0>M(u,o)?(e[r]=u,e[s]=n,r=s):(e[r]=o,e[a]=n,r=a);else if(void 0!==u&&0>M(u,n))e[r]=u,e[s]=n,r=s;else break a}}return t}return null}function M(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var O=[],A=[],L=1,C=null,I=3,D=!1,N=!1,P=!1;function R(e){for(var t=x(A);null!==t;){if(null===t.callback)T(A);else if(t.startTime<=e)T(A),t.sortIndex=t.expirationTime,k(O,t);else break;t=x(A)}}function j(e){if(P=!1,R(e),!N){if(null!==x(O))N=!0,n(F);else{var t=x(A);null!==t&&r(j,t.startTime-e)}}}function F(e,n){N=!1,P&&(P=!1,i()),D=!0;var o=I;try{for(R(n),C=x(O);null!==C&&(!(C.expirationTime>n)||e&&!a());){var s=C.callback;if(null!==s){C.callback=null,I=C.priorityLevel;var u=s(C.expirationTime<=n);n=t.unstable_now(),"function"==typeof u?C.callback=u:C===x(O)&&T(O),R(n)}else T(O);C=x(O)}if(null!==C)var c=!0;else{var l=x(A);null!==l&&r(j,l.startTime-n),c=!1}return c}finally{C=null,I=o,D=!1}}function Y(e){switch(e){case 1:return -1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var B=o;t.unstable_ImmediatePriority=1,t.unstable_UserBlockingPriority=2,t.unstable_NormalPriority=3,t.unstable_IdlePriority=5,t.unstable_LowPriority=4,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=I;I=e;try{return t()}finally{I=n}},t.unstable_next=function(e){switch(I){case 1:case 2:case 3:var t=3;break;default:t=I}var n=I;I=t;try{return e()}finally{I=n}},t.unstable_scheduleCallback=function(e,a,o){var s=t.unstable_now();if("object"==typeof o&&null!==o){var u=o.delay;u="number"==typeof u&&0s?(e.sortIndex=u,k(A,e),null===x(O)&&e===x(A)&&(P?i():P=!0,r(j,u-s))):(e.sortIndex=o,k(O,e),N||D||(N=!0,n(F))),e},t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_wrapCallback=function(e){var t=I;return function(){var n=I;I=t;try{return e.apply(this,arguments)}finally{I=n}}},t.unstable_getCurrentPriorityLevel=function(){return I},t.unstable_shouldYield=function(){var e=t.unstable_now();R(e);var n=x(O);return n!==C&&null!==C&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function c(e,t,n){var r=t.length-1;if(r=0?(i>0&&(e.lastNeed=i-1),i):--r=0?(i>0&&(e.lastNeed=i-2),i):--r=0?(i>0&&(2===i?i=0:e.lastNeed=i-3),i):0}function l(e,t,n){if((192&t[0])!=128)return e.lastNeed=0,"�";if(e.lastNeed>1&&t.length>1){if((192&t[1])!=128)return e.lastNeed=1,"�";if(e.lastNeed>2&&t.length>2&&(192&t[2])!=128)return e.lastNeed=2,"�"}}function f(e){var t=this.lastTotal-this.lastNeed,n=l(this,e,t);return void 0!==n?n:this.lastNeed<=e.length?(e.copy(this.lastChar,t,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):void(e.copy(this.lastChar,t,0,e.length),this.lastNeed-=e.length)}function d(e,t){var n=c(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=n;var r=e.length-(n-this.lastNeed);return e.copy(this.lastChar,0,r),e.toString("utf8",t,r)}function h(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+"�":t}function p(e,t){if((e.length-t)%2==0){var n=e.toString("utf16le",t);if(n){var r=n.charCodeAt(n.length-1);if(r>=55296&&r<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],n.slice(0,-1)}return n}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function b(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var n=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,n)}return t}function m(e,t){var n=(e.length-t)%3;return 0===n?e.toString("base64",t):(this.lastNeed=3-n,this.lastTotal=3,1===n?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-n))}function g(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function v(e){return e.toString(this.encoding)}function y(e){return e&&e.length?this.write(e):""}t.s=s,s.prototype.write=function(e){var t,n;if(0===e.length)return"";if(this.lastNeed){if(void 0===(t=this.fillLast(e)))return"";n=this.lastNeed,this.lastNeed=0}else n=0;return n */ var r=n(48764),i=r.Buffer;function a(e,t){for(var n in e)t[n]=e[n]}function o(e,t,n){return i(e,t,n)}i.from&&i.alloc&&i.allocUnsafe&&i.allocUnsafeSlow?e.exports=r:(a(r,t),t.Buffer=o),o.prototype=Object.create(i.prototype),a(i,o),o.from=function(e,t,n){if("number"==typeof e)throw TypeError("Argument must not be a number");return i(e,t,n)},o.alloc=function(e,t,n){if("number"!=typeof e)throw TypeError("Argument must be a number");var r=i(e);return void 0!==t?"string"==typeof n?r.fill(t,n):r.fill(t):r.fill(0),r},o.allocUnsafe=function(e){if("number"!=typeof e)throw TypeError("Argument must be a number");return i(e)},o.allocUnsafeSlow=function(e){if("number"!=typeof e)throw TypeError("Argument must be a number");return r.SlowBuffer(e)}},93379(e,t,n){"use strict";var r,i,a=function(){return void 0===r&&(r=Boolean(window&&document&&document.all&&!window.atob)),r},o=(i={},function(e){if(void 0===i[e]){var t=document.querySelector(e);if(window.HTMLIFrameElement&&t instanceof window.HTMLIFrameElement)try{t=t.contentDocument.head}catch(n){t=null}i[e]=t}return i[e]}),s=[];function u(e){for(var t=-1,n=0;nAp});var r,i,a,o,s,u,c,l=n(67294),f=n.t(l,2),d=n(39814),h=n(5977),p=n(57209),b=n(32316),m=n(95880),g=n(17051),v=n(71381),y=n(81701),w=n(3022),_=n(60323),E=n(87591),S=n(25649),k=n(28902),x=n(71426),T=n(48884),M=n(94184),O=n.n(M),A=n(37703),L=n(73935),C=function(){if("undefined"!=typeof Map)return Map;function e(e,t){var n=-1;return e.some(function(e,r){return e[0]===t&&(n=r,!0)}),n}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(t){var n=e(this.__entries__,t),r=this.__entries__[n];return r&&r[1]},t.prototype.set=function(t,n){var r=e(this.__entries__,t);~r?this.__entries__[r][1]=n:this.__entries__.push([t,n])},t.prototype.delete=function(t){var n=this.__entries__,r=e(n,t);~r&&n.splice(r,1)},t.prototype.has=function(t){return!!~e(this.__entries__,t)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(e,t){void 0===t&&(t=null);for(var n=0,r=this.__entries__;n0},e.prototype.connect_=function(){I&&!this.connected_&&(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),Y?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){I&&this.connected_&&(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(e){var t=e.propertyName,n=void 0===t?"":t;F.some(function(e){return!!~n.indexOf(e)})&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),U=function(e,t){for(var n=0,r=Object.keys(t);n0},e}(),er="undefined"!=typeof WeakMap?new WeakMap:new C,ei=function(){function e(t){if(!(this instanceof e))throw TypeError("Cannot call a class as a function.");if(!arguments.length)throw TypeError("1 argument required, but only 0 present.");var n=B.getInstance(),r=new en(t,n,this);er.set(this,r)}return e}();["observe","unobserve","disconnect"].forEach(function(e){ei.prototype[e]=function(){var t;return(t=er.get(this))[e].apply(t,arguments)}});var ea=void 0!==D.ResizeObserver?D.ResizeObserver:ei;let eo=ea;var es=function(e){var t=[],n=null,r=function(){for(var r=arguments.length,i=Array(r),a=0;a=t||n<0||f&&r>=a}function g(){var e=eb();if(m(e))return v(e);s=setTimeout(g,b(e))}function v(e){return(s=void 0,d&&r)?h(e):(r=i=void 0,o)}function y(){void 0!==s&&clearTimeout(s),c=0,r=u=i=s=void 0}function w(){return void 0===s?o:v(eb())}function _(){var e=eb(),n=m(e);if(r=arguments,i=this,u=e,n){if(void 0===s)return p(u);if(f)return clearTimeout(s),s=setTimeout(g,t),h(u)}return void 0===s&&(s=setTimeout(g,t)),o}return t=ez(t)||0,ed(n)&&(l=!!n.leading,a=(f="maxWait"in n)?eW(ez(n.maxWait)||0,t):a,d="trailing"in n?!!n.trailing:d),_.cancel=y,_.flush=w,_}let eq=eV;var eZ="Expected a function";function eX(e,t,n){var r=!0,i=!0;if("function"!=typeof e)throw TypeError(eZ);return ed(n)&&(r="leading"in n?!!n.leading:r,i="trailing"in n?!!n.trailing:i),eq(e,t,{leading:r,maxWait:t,trailing:i})}let eJ=eX;var eQ={debounce:eq,throttle:eJ},e1=function(e){return eQ[e]},e0=function(e){return"function"==typeof e},e2=function(){return"undefined"==typeof window},e3=function(e){return e instanceof Element||e instanceof HTMLDocument};function e4(e){return(e4="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function e6(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}function e5(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&l.createElement(tG.Z,{variant:"indeterminate",classes:r}))};tK.propTypes={fetchCount:el().number.isRequired};let tV=(0,b.withStyles)(tW)(tK);var tq=n(5536);let tZ=n.p+"ba8bbf16ebf8e1d05bef.svg";function tX(){return(tX=Object.assign||function(e){for(var t=1;t120){for(var d=Math.floor(u/80),h=u%80,p=[],b=0;b0},name:{enumerable:!1},nodes:{enumerable:!1},source:{enumerable:!1},positions:{enumerable:!1},originalError:{enumerable:!1}}),null!=s&&s.stack)?(Object.defineProperty(nf(b),"stack",{value:s.stack,writable:!0,configurable:!0}),nl(b)):(Error.captureStackTrace?Error.captureStackTrace(nf(b),n):Object.defineProperty(nf(b),"stack",{value:Error().stack,writable:!0,configurable:!0}),b)}return ns(n,[{key:"toString",value:function(){return nw(this)}},{key:t4.YF,get:function(){return"Object"}}]),n}(nd(Error));function ny(e){return void 0===e||0===e.length?void 0:e}function nw(e){var t=e.message;if(e.nodes)for(var n=0,r=e.nodes;n",EOF:"",BANG:"!",DOLLAR:"$",AMP:"&",PAREN_L:"(",PAREN_R:")",SPREAD:"...",COLON:":",EQUALS:"=",AT:"@",BRACKET_L:"[",BRACKET_R:"]",BRACE_L:"{",PIPE:"|",BRACE_R:"}",NAME:"Name",INT:"Int",FLOAT:"Float",STRING:"String",BLOCK_STRING:"BlockString",COMMENT:"Comment"}),nx=n(10143),nT=Object.freeze({QUERY:"QUERY",MUTATION:"MUTATION",SUBSCRIPTION:"SUBSCRIPTION",FIELD:"FIELD",FRAGMENT_DEFINITION:"FRAGMENT_DEFINITION",FRAGMENT_SPREAD:"FRAGMENT_SPREAD",INLINE_FRAGMENT:"INLINE_FRAGMENT",VARIABLE_DEFINITION:"VARIABLE_DEFINITION",SCHEMA:"SCHEMA",SCALAR:"SCALAR",OBJECT:"OBJECT",FIELD_DEFINITION:"FIELD_DEFINITION",ARGUMENT_DEFINITION:"ARGUMENT_DEFINITION",INTERFACE:"INTERFACE",UNION:"UNION",ENUM:"ENUM",ENUM_VALUE:"ENUM_VALUE",INPUT_OBJECT:"INPUT_OBJECT",INPUT_FIELD_DEFINITION:"INPUT_FIELD_DEFINITION"}),nM=n(87392),nO=function(){function e(e){var t=new nS.WU(nk.SOF,0,0,0,0,null);this.source=e,this.lastToken=t,this.token=t,this.line=1,this.lineStart=0}var t=e.prototype;return t.advance=function(){return this.lastToken=this.token,this.token=this.lookahead()},t.lookahead=function(){var e,t=this.token;if(t.kind!==nk.EOF)do t=null!==(e=t.next)&&void 0!==e?e:t.next=nC(this,t);while(t.kind===nk.COMMENT)return t},e}();function nA(e){return e===nk.BANG||e===nk.DOLLAR||e===nk.AMP||e===nk.PAREN_L||e===nk.PAREN_R||e===nk.SPREAD||e===nk.COLON||e===nk.EQUALS||e===nk.AT||e===nk.BRACKET_L||e===nk.BRACKET_R||e===nk.BRACE_L||e===nk.PIPE||e===nk.BRACE_R}function nL(e){return isNaN(e)?nk.EOF:e<127?JSON.stringify(String.fromCharCode(e)):'"\\u'.concat(("00"+e.toString(16).toUpperCase()).slice(-4),'"')}function nC(e,t){for(var n=e.source,r=n.body,i=r.length,a=t.end;a31||9===a))return new nS.WU(nk.COMMENT,t,s,n,r,i,o.slice(t+1,s))}function nN(e,t,n,r,i,a){var o=e.body,s=n,u=t,c=!1;if(45===s&&(s=o.charCodeAt(++u)),48===s){if((s=o.charCodeAt(++u))>=48&&s<=57)throw n_(e,u,"Invalid number, unexpected digit after 0: ".concat(nL(s),"."))}else u=nP(e,u,s),s=o.charCodeAt(u);if(46===s&&(c=!0,s=o.charCodeAt(++u),u=nP(e,u,s),s=o.charCodeAt(u)),(69===s||101===s)&&(c=!0,(43===(s=o.charCodeAt(++u))||45===s)&&(s=o.charCodeAt(++u)),u=nP(e,u,s),s=o.charCodeAt(u)),46===s||nU(s))throw n_(e,u,"Invalid number, expected digit but got: ".concat(nL(s),"."));return new nS.WU(c?nk.FLOAT:nk.INT,t,u,r,i,a,o.slice(t,u))}function nP(e,t,n){var r=e.body,i=t,a=n;if(a>=48&&a<=57){do a=r.charCodeAt(++i);while(a>=48&&a<=57)return i}throw n_(e,i,"Invalid number, expected digit but got: ".concat(nL(a),"."))}function nR(e,t,n,r,i){for(var a=e.body,o=t+1,s=o,u=0,c="";o=48&&e<=57?e-48:e>=65&&e<=70?e-55:e>=97&&e<=102?e-87:-1}function nB(e,t,n,r,i){for(var a=e.body,o=a.length,s=t+1,u=0;s!==o&&!isNaN(u=a.charCodeAt(s))&&(95===u||u>=48&&u<=57||u>=65&&u<=90||u>=97&&u<=122);)++s;return new nS.WU(nk.NAME,t,s,n,r,i,a.slice(t,s))}function nU(e){return 95===e||e>=65&&e<=90||e>=97&&e<=122}function nH(e,t){return new n$(e,t).parseDocument()}var n$=function(){function e(e,t){var n=(0,nx.T)(e)?e:new nx.H(e);this._lexer=new nO(n),this._options=t}var t=e.prototype;return t.parseName=function(){var e=this.expectToken(nk.NAME);return{kind:nE.h.NAME,value:e.value,loc:this.loc(e)}},t.parseDocument=function(){var e=this._lexer.token;return{kind:nE.h.DOCUMENT,definitions:this.many(nk.SOF,this.parseDefinition,nk.EOF),loc:this.loc(e)}},t.parseDefinition=function(){if(this.peek(nk.NAME))switch(this._lexer.token.value){case"query":case"mutation":case"subscription":return this.parseOperationDefinition();case"fragment":return this.parseFragmentDefinition();case"schema":case"scalar":case"type":case"interface":case"union":case"enum":case"input":case"directive":return this.parseTypeSystemDefinition();case"extend":return this.parseTypeSystemExtension()}else if(this.peek(nk.BRACE_L))return this.parseOperationDefinition();else if(this.peekDescription())return this.parseTypeSystemDefinition();throw this.unexpected()},t.parseOperationDefinition=function(){var e,t=this._lexer.token;if(this.peek(nk.BRACE_L))return{kind:nE.h.OPERATION_DEFINITION,operation:"query",name:void 0,variableDefinitions:[],directives:[],selectionSet:this.parseSelectionSet(),loc:this.loc(t)};var n=this.parseOperationType();return this.peek(nk.NAME)&&(e=this.parseName()),{kind:nE.h.OPERATION_DEFINITION,operation:n,name:e,variableDefinitions:this.parseVariableDefinitions(),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}},t.parseOperationType=function(){var e=this.expectToken(nk.NAME);switch(e.value){case"query":return"query";case"mutation":return"mutation";case"subscription":return"subscription"}throw this.unexpected(e)},t.parseVariableDefinitions=function(){return this.optionalMany(nk.PAREN_L,this.parseVariableDefinition,nk.PAREN_R)},t.parseVariableDefinition=function(){var e=this._lexer.token;return{kind:nE.h.VARIABLE_DEFINITION,variable:this.parseVariable(),type:(this.expectToken(nk.COLON),this.parseTypeReference()),defaultValue:this.expectOptionalToken(nk.EQUALS)?this.parseValueLiteral(!0):void 0,directives:this.parseDirectives(!0),loc:this.loc(e)}},t.parseVariable=function(){var e=this._lexer.token;return this.expectToken(nk.DOLLAR),{kind:nE.h.VARIABLE,name:this.parseName(),loc:this.loc(e)}},t.parseSelectionSet=function(){var e=this._lexer.token;return{kind:nE.h.SELECTION_SET,selections:this.many(nk.BRACE_L,this.parseSelection,nk.BRACE_R),loc:this.loc(e)}},t.parseSelection=function(){return this.peek(nk.SPREAD)?this.parseFragment():this.parseField()},t.parseField=function(){var e,t,n=this._lexer.token,r=this.parseName();return this.expectOptionalToken(nk.COLON)?(e=r,t=this.parseName()):t=r,{kind:nE.h.FIELD,alias:e,name:t,arguments:this.parseArguments(!1),directives:this.parseDirectives(!1),selectionSet:this.peek(nk.BRACE_L)?this.parseSelectionSet():void 0,loc:this.loc(n)}},t.parseArguments=function(e){var t=e?this.parseConstArgument:this.parseArgument;return this.optionalMany(nk.PAREN_L,t,nk.PAREN_R)},t.parseArgument=function(){var e=this._lexer.token,t=this.parseName();return this.expectToken(nk.COLON),{kind:nE.h.ARGUMENT,name:t,value:this.parseValueLiteral(!1),loc:this.loc(e)}},t.parseConstArgument=function(){var e=this._lexer.token;return{kind:nE.h.ARGUMENT,name:this.parseName(),value:(this.expectToken(nk.COLON),this.parseValueLiteral(!0)),loc:this.loc(e)}},t.parseFragment=function(){var e=this._lexer.token;this.expectToken(nk.SPREAD);var t=this.expectOptionalKeyword("on");return!t&&this.peek(nk.NAME)?{kind:nE.h.FRAGMENT_SPREAD,name:this.parseFragmentName(),directives:this.parseDirectives(!1),loc:this.loc(e)}:{kind:nE.h.INLINE_FRAGMENT,typeCondition:t?this.parseNamedType():void 0,directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(e)}},t.parseFragmentDefinition=function(){var e,t=this._lexer.token;return(this.expectKeyword("fragment"),(null===(e=this._options)||void 0===e?void 0:e.experimentalFragmentVariables)===!0)?{kind:nE.h.FRAGMENT_DEFINITION,name:this.parseFragmentName(),variableDefinitions:this.parseVariableDefinitions(),typeCondition:(this.expectKeyword("on"),this.parseNamedType()),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}:{kind:nE.h.FRAGMENT_DEFINITION,name:this.parseFragmentName(),typeCondition:(this.expectKeyword("on"),this.parseNamedType()),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}},t.parseFragmentName=function(){if("on"===this._lexer.token.value)throw this.unexpected();return this.parseName()},t.parseValueLiteral=function(e){var t=this._lexer.token;switch(t.kind){case nk.BRACKET_L:return this.parseList(e);case nk.BRACE_L:return this.parseObject(e);case nk.INT:return this._lexer.advance(),{kind:nE.h.INT,value:t.value,loc:this.loc(t)};case nk.FLOAT:return this._lexer.advance(),{kind:nE.h.FLOAT,value:t.value,loc:this.loc(t)};case nk.STRING:case nk.BLOCK_STRING:return this.parseStringLiteral();case nk.NAME:switch(this._lexer.advance(),t.value){case"true":return{kind:nE.h.BOOLEAN,value:!0,loc:this.loc(t)};case"false":return{kind:nE.h.BOOLEAN,value:!1,loc:this.loc(t)};case"null":return{kind:nE.h.NULL,loc:this.loc(t)};default:return{kind:nE.h.ENUM,value:t.value,loc:this.loc(t)}}case nk.DOLLAR:if(!e)return this.parseVariable()}throw this.unexpected()},t.parseStringLiteral=function(){var e=this._lexer.token;return this._lexer.advance(),{kind:nE.h.STRING,value:e.value,block:e.kind===nk.BLOCK_STRING,loc:this.loc(e)}},t.parseList=function(e){var t=this,n=this._lexer.token,r=function(){return t.parseValueLiteral(e)};return{kind:nE.h.LIST,values:this.any(nk.BRACKET_L,r,nk.BRACKET_R),loc:this.loc(n)}},t.parseObject=function(e){var t=this,n=this._lexer.token,r=function(){return t.parseObjectField(e)};return{kind:nE.h.OBJECT,fields:this.any(nk.BRACE_L,r,nk.BRACE_R),loc:this.loc(n)}},t.parseObjectField=function(e){var t=this._lexer.token,n=this.parseName();return this.expectToken(nk.COLON),{kind:nE.h.OBJECT_FIELD,name:n,value:this.parseValueLiteral(e),loc:this.loc(t)}},t.parseDirectives=function(e){for(var t=[];this.peek(nk.AT);)t.push(this.parseDirective(e));return t},t.parseDirective=function(e){var t=this._lexer.token;return this.expectToken(nk.AT),{kind:nE.h.DIRECTIVE,name:this.parseName(),arguments:this.parseArguments(e),loc:this.loc(t)}},t.parseTypeReference=function(){var e,t=this._lexer.token;return(this.expectOptionalToken(nk.BRACKET_L)?(e=this.parseTypeReference(),this.expectToken(nk.BRACKET_R),e={kind:nE.h.LIST_TYPE,type:e,loc:this.loc(t)}):e=this.parseNamedType(),this.expectOptionalToken(nk.BANG))?{kind:nE.h.NON_NULL_TYPE,type:e,loc:this.loc(t)}:e},t.parseNamedType=function(){var e=this._lexer.token;return{kind:nE.h.NAMED_TYPE,name:this.parseName(),loc:this.loc(e)}},t.parseTypeSystemDefinition=function(){var e=this.peekDescription()?this._lexer.lookahead():this._lexer.token;if(e.kind===nk.NAME)switch(e.value){case"schema":return this.parseSchemaDefinition();case"scalar":return this.parseScalarTypeDefinition();case"type":return this.parseObjectTypeDefinition();case"interface":return this.parseInterfaceTypeDefinition();case"union":return this.parseUnionTypeDefinition();case"enum":return this.parseEnumTypeDefinition();case"input":return this.parseInputObjectTypeDefinition();case"directive":return this.parseDirectiveDefinition()}throw this.unexpected(e)},t.peekDescription=function(){return this.peek(nk.STRING)||this.peek(nk.BLOCK_STRING)},t.parseDescription=function(){if(this.peekDescription())return this.parseStringLiteral()},t.parseSchemaDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("schema");var n=this.parseDirectives(!0),r=this.many(nk.BRACE_L,this.parseOperationTypeDefinition,nk.BRACE_R);return{kind:nE.h.SCHEMA_DEFINITION,description:t,directives:n,operationTypes:r,loc:this.loc(e)}},t.parseOperationTypeDefinition=function(){var e=this._lexer.token,t=this.parseOperationType();this.expectToken(nk.COLON);var n=this.parseNamedType();return{kind:nE.h.OPERATION_TYPE_DEFINITION,operation:t,type:n,loc:this.loc(e)}},t.parseScalarTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("scalar");var n=this.parseName(),r=this.parseDirectives(!0);return{kind:nE.h.SCALAR_TYPE_DEFINITION,description:t,name:n,directives:r,loc:this.loc(e)}},t.parseObjectTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("type");var n=this.parseName(),r=this.parseImplementsInterfaces(),i=this.parseDirectives(!0),a=this.parseFieldsDefinition();return{kind:nE.h.OBJECT_TYPE_DEFINITION,description:t,name:n,interfaces:r,directives:i,fields:a,loc:this.loc(e)}},t.parseImplementsInterfaces=function(){var e;if(!this.expectOptionalKeyword("implements"))return[];if((null===(e=this._options)||void 0===e?void 0:e.allowLegacySDLImplementsInterfaces)===!0){var t=[];this.expectOptionalToken(nk.AMP);do t.push(this.parseNamedType());while(this.expectOptionalToken(nk.AMP)||this.peek(nk.NAME))return t}return this.delimitedMany(nk.AMP,this.parseNamedType)},t.parseFieldsDefinition=function(){var e;return(null===(e=this._options)||void 0===e?void 0:e.allowLegacySDLEmptyFields)===!0&&this.peek(nk.BRACE_L)&&this._lexer.lookahead().kind===nk.BRACE_R?(this._lexer.advance(),this._lexer.advance(),[]):this.optionalMany(nk.BRACE_L,this.parseFieldDefinition,nk.BRACE_R)},t.parseFieldDefinition=function(){var e=this._lexer.token,t=this.parseDescription(),n=this.parseName(),r=this.parseArgumentDefs();this.expectToken(nk.COLON);var i=this.parseTypeReference(),a=this.parseDirectives(!0);return{kind:nE.h.FIELD_DEFINITION,description:t,name:n,arguments:r,type:i,directives:a,loc:this.loc(e)}},t.parseArgumentDefs=function(){return this.optionalMany(nk.PAREN_L,this.parseInputValueDef,nk.PAREN_R)},t.parseInputValueDef=function(){var e,t=this._lexer.token,n=this.parseDescription(),r=this.parseName();this.expectToken(nk.COLON);var i=this.parseTypeReference();this.expectOptionalToken(nk.EQUALS)&&(e=this.parseValueLiteral(!0));var a=this.parseDirectives(!0);return{kind:nE.h.INPUT_VALUE_DEFINITION,description:n,name:r,type:i,defaultValue:e,directives:a,loc:this.loc(t)}},t.parseInterfaceTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("interface");var n=this.parseName(),r=this.parseImplementsInterfaces(),i=this.parseDirectives(!0),a=this.parseFieldsDefinition();return{kind:nE.h.INTERFACE_TYPE_DEFINITION,description:t,name:n,interfaces:r,directives:i,fields:a,loc:this.loc(e)}},t.parseUnionTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("union");var n=this.parseName(),r=this.parseDirectives(!0),i=this.parseUnionMemberTypes();return{kind:nE.h.UNION_TYPE_DEFINITION,description:t,name:n,directives:r,types:i,loc:this.loc(e)}},t.parseUnionMemberTypes=function(){return this.expectOptionalToken(nk.EQUALS)?this.delimitedMany(nk.PIPE,this.parseNamedType):[]},t.parseEnumTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("enum");var n=this.parseName(),r=this.parseDirectives(!0),i=this.parseEnumValuesDefinition();return{kind:nE.h.ENUM_TYPE_DEFINITION,description:t,name:n,directives:r,values:i,loc:this.loc(e)}},t.parseEnumValuesDefinition=function(){return this.optionalMany(nk.BRACE_L,this.parseEnumValueDefinition,nk.BRACE_R)},t.parseEnumValueDefinition=function(){var e=this._lexer.token,t=this.parseDescription(),n=this.parseName(),r=this.parseDirectives(!0);return{kind:nE.h.ENUM_VALUE_DEFINITION,description:t,name:n,directives:r,loc:this.loc(e)}},t.parseInputObjectTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("input");var n=this.parseName(),r=this.parseDirectives(!0),i=this.parseInputFieldsDefinition();return{kind:nE.h.INPUT_OBJECT_TYPE_DEFINITION,description:t,name:n,directives:r,fields:i,loc:this.loc(e)}},t.parseInputFieldsDefinition=function(){return this.optionalMany(nk.BRACE_L,this.parseInputValueDef,nk.BRACE_R)},t.parseTypeSystemExtension=function(){var e=this._lexer.lookahead();if(e.kind===nk.NAME)switch(e.value){case"schema":return this.parseSchemaExtension();case"scalar":return this.parseScalarTypeExtension();case"type":return this.parseObjectTypeExtension();case"interface":return this.parseInterfaceTypeExtension();case"union":return this.parseUnionTypeExtension();case"enum":return this.parseEnumTypeExtension();case"input":return this.parseInputObjectTypeExtension()}throw this.unexpected(e)},t.parseSchemaExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("schema");var t=this.parseDirectives(!0),n=this.optionalMany(nk.BRACE_L,this.parseOperationTypeDefinition,nk.BRACE_R);if(0===t.length&&0===n.length)throw this.unexpected();return{kind:nE.h.SCHEMA_EXTENSION,directives:t,operationTypes:n,loc:this.loc(e)}},t.parseScalarTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("scalar");var t=this.parseName(),n=this.parseDirectives(!0);if(0===n.length)throw this.unexpected();return{kind:nE.h.SCALAR_TYPE_EXTENSION,name:t,directives:n,loc:this.loc(e)}},t.parseObjectTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("type");var t=this.parseName(),n=this.parseImplementsInterfaces(),r=this.parseDirectives(!0),i=this.parseFieldsDefinition();if(0===n.length&&0===r.length&&0===i.length)throw this.unexpected();return{kind:nE.h.OBJECT_TYPE_EXTENSION,name:t,interfaces:n,directives:r,fields:i,loc:this.loc(e)}},t.parseInterfaceTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("interface");var t=this.parseName(),n=this.parseImplementsInterfaces(),r=this.parseDirectives(!0),i=this.parseFieldsDefinition();if(0===n.length&&0===r.length&&0===i.length)throw this.unexpected();return{kind:nE.h.INTERFACE_TYPE_EXTENSION,name:t,interfaces:n,directives:r,fields:i,loc:this.loc(e)}},t.parseUnionTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("union");var t=this.parseName(),n=this.parseDirectives(!0),r=this.parseUnionMemberTypes();if(0===n.length&&0===r.length)throw this.unexpected();return{kind:nE.h.UNION_TYPE_EXTENSION,name:t,directives:n,types:r,loc:this.loc(e)}},t.parseEnumTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("enum");var t=this.parseName(),n=this.parseDirectives(!0),r=this.parseEnumValuesDefinition();if(0===n.length&&0===r.length)throw this.unexpected();return{kind:nE.h.ENUM_TYPE_EXTENSION,name:t,directives:n,values:r,loc:this.loc(e)}},t.parseInputObjectTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("input");var t=this.parseName(),n=this.parseDirectives(!0),r=this.parseInputFieldsDefinition();if(0===n.length&&0===r.length)throw this.unexpected();return{kind:nE.h.INPUT_OBJECT_TYPE_EXTENSION,name:t,directives:n,fields:r,loc:this.loc(e)}},t.parseDirectiveDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("directive"),this.expectToken(nk.AT);var n=this.parseName(),r=this.parseArgumentDefs(),i=this.expectOptionalKeyword("repeatable");this.expectKeyword("on");var a=this.parseDirectiveLocations();return{kind:nE.h.DIRECTIVE_DEFINITION,description:t,name:n,arguments:r,repeatable:i,locations:a,loc:this.loc(e)}},t.parseDirectiveLocations=function(){return this.delimitedMany(nk.PIPE,this.parseDirectiveLocation)},t.parseDirectiveLocation=function(){var e=this._lexer.token,t=this.parseName();if(void 0!==nT[t.value])return t;throw this.unexpected(e)},t.loc=function(e){var t;if((null===(t=this._options)||void 0===t?void 0:t.noLocation)!==!0)return new nS.Ye(e,this._lexer.lastToken,this._lexer.source)},t.peek=function(e){return this._lexer.token.kind===e},t.expectToken=function(e){var t=this._lexer.token;if(t.kind===e)return this._lexer.advance(),t;throw n_(this._lexer.source,t.start,"Expected ".concat(nG(e),", found ").concat(nz(t),"."))},t.expectOptionalToken=function(e){var t=this._lexer.token;if(t.kind===e)return this._lexer.advance(),t},t.expectKeyword=function(e){var t=this._lexer.token;if(t.kind===nk.NAME&&t.value===e)this._lexer.advance();else throw n_(this._lexer.source,t.start,'Expected "'.concat(e,'", found ').concat(nz(t),"."))},t.expectOptionalKeyword=function(e){var t=this._lexer.token;return t.kind===nk.NAME&&t.value===e&&(this._lexer.advance(),!0)},t.unexpected=function(e){var t=null!=e?e:this._lexer.token;return n_(this._lexer.source,t.start,"Unexpected ".concat(nz(t),"."))},t.any=function(e,t,n){this.expectToken(e);for(var r=[];!this.expectOptionalToken(n);)r.push(t.call(this));return r},t.optionalMany=function(e,t,n){if(this.expectOptionalToken(e)){var r=[];do r.push(t.call(this));while(!this.expectOptionalToken(n))return r}return[]},t.many=function(e,t,n){this.expectToken(e);var r=[];do r.push(t.call(this));while(!this.expectOptionalToken(n))return r},t.delimitedMany=function(e,t){this.expectOptionalToken(e);var n=[];do n.push(t.call(this));while(this.expectOptionalToken(e))return n},e}();function nz(e){var t=e.value;return nG(e.kind)+(null!=t?' "'.concat(t,'"'):"")}function nG(e){return nA(e)?'"'.concat(e,'"'):e}var nW=new Map,nK=new Map,nV=!0,nq=!1;function nZ(e){return e.replace(/[\s,]+/g," ").trim()}function nX(e){return nZ(e.source.body.substring(e.start,e.end))}function nJ(e){var t=new Set,n=[];return e.definitions.forEach(function(e){if("FragmentDefinition"===e.kind){var r=e.name.value,i=nX(e.loc),a=nK.get(r);a&&!a.has(i)?nV&&console.warn("Warning: fragment with name "+r+" already exists.\ngraphql-tag enforces all fragment names across your application to be unique; read more about\nthis in the docs: http://dev.apollodata.com/core/fragments.html#unique-names"):a||nK.set(r,a=new Set),a.add(i),t.has(i)||(t.add(i),n.push(e))}else n.push(e)}),(0,t0.pi)((0,t0.pi)({},e),{definitions:n})}function nQ(e){var t=new Set(e.definitions);t.forEach(function(e){e.loc&&delete e.loc,Object.keys(e).forEach(function(n){var r=e[n];r&&"object"==typeof r&&t.add(r)})});var n=e.loc;return n&&(delete n.startToken,delete n.endToken),e}function n1(e){var t=nZ(e);if(!nW.has(t)){var n=nH(e,{experimentalFragmentVariables:nq,allowLegacyFragmentVariables:nq});if(!n||"Document"!==n.kind)throw Error("Not a valid GraphQL document.");nW.set(t,nQ(nJ(n)))}return nW.get(t)}function n0(e){for(var t=[],n=1;n, or pass an ApolloClient instance in via options.'):(0,n9.kG)(!!n,32),n}var rp=n(10542),rb=n(53712),rm=n(21436),rg=Object.prototype.hasOwnProperty;function rv(e,t){return void 0===t&&(t=Object.create(null)),ry(rh(t.client),e).useQuery(t)}function ry(e,t){var n=(0,l.useRef)();n.current&&e===n.current.client&&t===n.current.query||(n.current=new rw(e,t,n.current));var r=n.current,i=(0,l.useState)(0),a=(i[0],i[1]);return r.forceUpdate=function(){a(function(e){return e+1})},r}var rw=function(){function e(e,t,n){this.client=e,this.query=t,this.ssrDisabledResult=(0,rp.J)({loading:!0,data:void 0,error:void 0,networkStatus:ru.I.loading}),this.skipStandbyResult=(0,rp.J)({loading:!1,data:void 0,error:void 0,networkStatus:ru.I.ready}),this.toQueryResultCache=new(n7.mr?WeakMap:Map),rd(t,r.Query);var i=n&&n.result,a=i&&i.data;a&&(this.previousData=a)}return e.prototype.forceUpdate=function(){__DEV__&&n9.kG.warn("Calling default no-op implementation of InternalState#forceUpdate")},e.prototype.executeQuery=function(e){var t,n=this;e.query&&Object.assign(this,{query:e.query}),this.watchQueryOptions=this.createWatchQueryOptions(this.queryHookOptions=e);var r=this.observable.reobserveAsConcast(this.getObsQueryOptions());return this.previousData=(null===(t=this.result)||void 0===t?void 0:t.data)||this.previousData,this.result=void 0,this.forceUpdate(),new Promise(function(e){var t;r.subscribe({next:function(e){t=e},error:function(){e(n.toQueryResult(n.observable.getCurrentResult()))},complete:function(){e(n.toQueryResult(t))}})})},e.prototype.useQuery=function(e){var t=this;this.renderPromises=(0,l.useContext)((0,ro.K)()).renderPromises,this.useOptions(e);var n=this.useObservableQuery(),r=rt((0,l.useCallback)(function(){if(t.renderPromises)return function(){};var e=function(){var e=t.result,r=n.getCurrentResult();!(e&&e.loading===r.loading&&e.networkStatus===r.networkStatus&&(0,ri.D)(e.data,r.data))&&t.setResult(r)},r=function(a){var o=n.last;i.unsubscribe();try{n.resetLastResults(),i=n.subscribe(e,r)}finally{n.last=o}if(!rg.call(a,"graphQLErrors"))throw a;var s=t.result;(!s||s&&s.loading||!(0,ri.D)(a,s.error))&&t.setResult({data:s&&s.data,error:a,loading:!1,networkStatus:ru.I.error})},i=n.subscribe(e,r);return function(){return setTimeout(function(){return i.unsubscribe()})}},[n,this.renderPromises,this.client.disableNetworkFetches,]),function(){return t.getCurrentResult()},function(){return t.getCurrentResult()});return this.unsafeHandlePartialRefetch(r),this.toQueryResult(r)},e.prototype.useOptions=function(t){var n,r=this.createWatchQueryOptions(this.queryHookOptions=t),i=this.watchQueryOptions;!(0,ri.D)(r,i)&&(this.watchQueryOptions=r,i&&this.observable&&(this.observable.reobserve(this.getObsQueryOptions()),this.previousData=(null===(n=this.result)||void 0===n?void 0:n.data)||this.previousData,this.result=void 0)),this.onCompleted=t.onCompleted||e.prototype.onCompleted,this.onError=t.onError||e.prototype.onError,(this.renderPromises||this.client.disableNetworkFetches)&&!1===this.queryHookOptions.ssr&&!this.queryHookOptions.skip?this.result=this.ssrDisabledResult:this.queryHookOptions.skip||"standby"===this.watchQueryOptions.fetchPolicy?this.result=this.skipStandbyResult:(this.result===this.ssrDisabledResult||this.result===this.skipStandbyResult)&&(this.result=void 0)},e.prototype.getObsQueryOptions=function(){var e=[],t=this.client.defaultOptions.watchQuery;return t&&e.push(t),this.queryHookOptions.defaultOptions&&e.push(this.queryHookOptions.defaultOptions),e.push((0,rb.o)(this.observable&&this.observable.options,this.watchQueryOptions)),e.reduce(ra.J)},e.prototype.createWatchQueryOptions=function(e){void 0===e&&(e={});var t,n=e.skip,r=Object.assign((e.ssr,e.onCompleted,e.onError,e.defaultOptions,(0,t0._T)(e,["skip","ssr","onCompleted","onError","defaultOptions"])),{query:this.query});if(this.renderPromises&&("network-only"===r.fetchPolicy||"cache-and-network"===r.fetchPolicy)&&(r.fetchPolicy="cache-first"),r.variables||(r.variables={}),n){var i=r.fetchPolicy,a=void 0===i?this.getDefaultFetchPolicy():i,o=r.initialFetchPolicy;Object.assign(r,{initialFetchPolicy:void 0===o?a:o,fetchPolicy:"standby"})}else r.fetchPolicy||(r.fetchPolicy=(null===(t=this.observable)||void 0===t?void 0:t.options.initialFetchPolicy)||this.getDefaultFetchPolicy());return r},e.prototype.getDefaultFetchPolicy=function(){var e,t;return(null===(e=this.queryHookOptions.defaultOptions)||void 0===e?void 0:e.fetchPolicy)||(null===(t=this.client.defaultOptions.watchQuery)||void 0===t?void 0:t.fetchPolicy)||"cache-first"},e.prototype.onCompleted=function(e){},e.prototype.onError=function(e){},e.prototype.useObservableQuery=function(){var e=this.observable=this.renderPromises&&this.renderPromises.getSSRObservable(this.watchQueryOptions)||this.observable||this.client.watchQuery(this.getObsQueryOptions());this.obsQueryFields=(0,l.useMemo)(function(){return{refetch:e.refetch.bind(e),reobserve:e.reobserve.bind(e),fetchMore:e.fetchMore.bind(e),updateQuery:e.updateQuery.bind(e),startPolling:e.startPolling.bind(e),stopPolling:e.stopPolling.bind(e),subscribeToMore:e.subscribeToMore.bind(e)}},[e]);var t=!(!1===this.queryHookOptions.ssr||this.queryHookOptions.skip);return this.renderPromises&&t&&(this.renderPromises.registerSSRObservable(e),e.getCurrentResult().loading&&this.renderPromises.addObservableQueryPromise(e)),e},e.prototype.setResult=function(e){var t=this.result;t&&t.data&&(this.previousData=t.data),this.result=e,this.forceUpdate(),this.handleErrorOrCompleted(e)},e.prototype.handleErrorOrCompleted=function(e){var t=this;if(!e.loading){var n=this.toApolloError(e);Promise.resolve().then(function(){n?t.onError(n):e.data&&t.onCompleted(e.data)}).catch(function(e){__DEV__&&n9.kG.warn(e)})}},e.prototype.toApolloError=function(e){return(0,rm.O)(e.errors)?new rs.cA({graphQLErrors:e.errors}):e.error},e.prototype.getCurrentResult=function(){return this.result||this.handleErrorOrCompleted(this.result=this.observable.getCurrentResult()),this.result},e.prototype.toQueryResult=function(e){var t=this.toQueryResultCache.get(e);if(t)return t;var n=e.data,r=(e.partial,(0,t0._T)(e,["data","partial"]));return this.toQueryResultCache.set(e,t=(0,t0.pi)((0,t0.pi)((0,t0.pi)({data:n},r),this.obsQueryFields),{client:this.client,observable:this.observable,variables:this.observable.variables,called:!this.queryHookOptions.skip,previousData:this.previousData})),!t.error&&(0,rm.O)(e.errors)&&(t.error=new rs.cA({graphQLErrors:e.errors})),t},e.prototype.unsafeHandlePartialRefetch=function(e){e.partial&&this.queryHookOptions.partialRefetch&&!e.loading&&(!e.data||0===Object.keys(e.data).length)&&"cache-only"!==this.observable.options.fetchPolicy&&(Object.assign(e,{loading:!0,networkStatus:ru.I.refetch}),this.observable.refetch())},e}();function r_(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]?arguments[0]:{};return rv(iH,e)},iz=function(){var e=ij(),t=parseInt(e.get("page")||"1",10),n=parseInt(e.get("per")||"50",10),r=i$({variables:{offset:(t-1)*n,limit:n},fetchPolicy:"network-only"}),i=r.data,a=r.loading,o=r.error;return a?l.createElement(iR,null):o?l.createElement(iD,{error:o}):i?l.createElement(iI,{chains:i.chains.results,page:t,pageSize:n,total:i.chains.metadata.total}):null},iG=n(67932),iW=n(8126),iK="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function iV(e){if(iq())return Intl.DateTimeFormat.supportedLocalesOf(e)[0]}function iq(){return("undefined"==typeof Intl?"undefined":iK(Intl))==="object"&&"function"==typeof Intl.DateTimeFormat}var iZ="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},iX=function(){function e(e,t){for(var n=0;n=i.length)break;s=i[o++]}else{if((o=i.next()).done)break;s=o.value}var s,u=s;if((void 0===e?"undefined":iZ(e))!=="object")return;e=e[u]}return e}},{key:"put",value:function(){for(var e=arguments.length,t=Array(e),n=0;n=o.length)break;c=o[u++]}else{if((u=o.next()).done)break;c=u.value}var c,l=c;"object"!==iZ(a[l])&&(a[l]={}),a=a[l]}return a[i]=r}}]),e}();let i1=iQ;var i0=new i1;function i2(e,t){if(!iq())return function(e){return e.toString()};var n=i4(e),r=JSON.stringify(t),i=i0.get(String(n),r)||i0.put(String(n),r,new Intl.DateTimeFormat(n,t));return function(e){return i.format(e)}}var i3={};function i4(e){var t=e.toString();return i3[t]?i3[t]:i3[t]=iV(e)}var i6="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function i5(e){return i8(e)?e:new Date(e)}function i8(e){return e instanceof Date||i9(e)}function i9(e){return(void 0===e?"undefined":i6(e))==="object"&&"function"==typeof e.getTime}var i7=n(54087),ae=n.n(i7);function at(e,t){if(0===e.length)return 0;for(var n=0,r=e.length-1,i=void 0;n<=r;){var a=t(e[i=Math.floor((r+n)/2)]);if(0===a)return i;if(a<0){if((n=i+1)>r)return n}else if((r=i-1)=t.nextUpdateTime)aa(t,this.instances);else break}},scheduleNextTick:function(){var e=this;this.scheduledTick=ae()(function(){e.tick(),e.scheduleNextTick()})},start:function(){this.scheduleNextTick()},stop:function(){ae().cancel(this.scheduledTick)}};function ai(e){var t=an(e.getNextValue(),2),n=t[0],r=t[1];e.setValue(n),e.nextUpdateTime=r}function aa(e,t){ai(e),as(t,e),ao(t,e)}function ao(e,t){var n=au(e,t);e.splice(n,0,t)}function as(e,t){var n=e.indexOf(t);e.splice(n,1)}function au(e,t){var n=t.nextUpdateTime;return at(e,function(e){return e.nextUpdateTime===n?0:e.nextUpdateTime>n?1:-1})}var ac=(0,ec.oneOfType)([(0,ec.shape)({minTime:ec.number,formatAs:ec.string.isRequired}),(0,ec.shape)({test:ec.func,formatAs:ec.string.isRequired}),(0,ec.shape)({minTime:ec.number,format:ec.func.isRequired}),(0,ec.shape)({test:ec.func,format:ec.func.isRequired})]),al=(0,ec.oneOfType)([ec.string,(0,ec.shape)({steps:(0,ec.arrayOf)(ac).isRequired,labels:(0,ec.oneOfType)([ec.string,(0,ec.arrayOf)(ec.string)]).isRequired,round:ec.string})]),af=Object.assign||function(e){for(var t=1;t=0)&&Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function ap(e){var t=e.date,n=e.future,r=e.timeStyle,i=e.round,a=e.minTimeLeft,o=e.tooltip,s=e.component,u=e.container,c=e.wrapperComponent,f=e.wrapperProps,d=e.locale,h=e.locales,p=e.formatVerboseDate,b=e.verboseDateFormat,m=e.updateInterval,g=e.tick,v=ah(e,["date","future","timeStyle","round","minTimeLeft","tooltip","component","container","wrapperComponent","wrapperProps","locale","locales","formatVerboseDate","verboseDateFormat","updateInterval","tick"]),y=(0,l.useMemo)(function(){return d&&(h=[d]),h.concat(iW.Z.getDefaultLocale())},[d,h]),w=(0,l.useMemo)(function(){return new iW.Z(y)},[y]);t=(0,l.useMemo)(function(){return i5(t)},[t]);var _=(0,l.useCallback)(function(){var e=Date.now(),o=void 0;if(n&&e>=t.getTime()&&(e=t.getTime(),o=!0),void 0!==a){var s=t.getTime()-1e3*a;e>s&&(e=s,o=!0)}var u=w.format(t,r,{getTimeToNextUpdate:!0,now:e,future:n,round:i}),c=ad(u,2),l=c[0],f=c[1];return f=o?ag:m||f||6e4,[l,e+f]},[t,n,r,m,i,a,w]),E=(0,l.useRef)();E.current=_;var S=(0,l.useMemo)(_,[]),k=ad(S,2),x=k[0],T=k[1],M=(0,l.useState)(x),O=ad(M,2),A=O[0],L=O[1],C=ad((0,l.useState)(),2),I=C[0],D=C[1],N=(0,l.useRef)();(0,l.useEffect)(function(){if(g)return N.current=ar.add({getNextValue:function(){return E.current()},setValue:L,nextUpdateTime:T}),function(){return N.current.stop()}},[g]),(0,l.useEffect)(function(){if(N.current)N.current.forceUpdate();else{var e=_(),t=ad(e,1)[0];L(t)}},[_]),(0,l.useEffect)(function(){D(!0)},[]);var P=(0,l.useMemo)(function(){if("undefined"!=typeof window)return i2(y,b)},[y,b]),R=(0,l.useMemo)(function(){if("undefined"!=typeof window)return p?p(t):P(t)},[t,p,P]),j=l.createElement(s,af({date:t,verboseDate:I?R:void 0,tooltip:o},v),A),F=c||u;return F?l.createElement(F,af({},f,{verboseDate:I?R:void 0}),j):j}ap.propTypes={date:el().oneOfType([el().instanceOf(Date),el().number]).isRequired,locale:el().string,locales:el().arrayOf(el().string),future:el().bool,timeStyle:al,round:el().string,minTimeLeft:el().number,component:el().elementType.isRequired,tooltip:el().bool.isRequired,formatVerboseDate:el().func,verboseDateFormat:el().object,updateInterval:el().oneOfType([el().number,el().arrayOf(el().shape({threshold:el().number,interval:el().number.isRequired}))]),tick:el().bool,wrapperComponent:el().func,wrapperProps:el().object},ap.defaultProps={locales:[],component:av,tooltip:!0,verboseDateFormat:{weekday:"long",day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"2-digit",second:"2-digit"},tick:!0},ap=l.memo(ap);let ab=ap;var am,ag=31536e9;function av(e){var t=e.date,n=e.verboseDate,r=e.tooltip,i=e.children,a=ah(e,["date","verboseDate","tooltip","children"]),o=(0,l.useMemo)(function(){return t.toISOString()},[t]);return l.createElement("time",af({},a,{dateTime:o,title:r?n:void 0}),i)}av.propTypes={date:el().instanceOf(Date).isRequired,verboseDate:el().string,tooltip:el().bool.isRequired,children:el().string.isRequired};var ay=n(30381),aw=n.n(ay),a_=n(31657);function aE(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function aS(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0?new rs.cA({graphQLErrors:i}):void 0;if(u===s.current.mutationId&&!c.ignoreResults){var f={called:!0,loading:!1,data:r,error:l,client:a};s.current.isMounted&&!(0,ri.D)(s.current.result,f)&&o(s.current.result=f)}var d=e.onCompleted||(null===(n=s.current.options)||void 0===n?void 0:n.onCompleted);return null==d||d(t.data,c),t}).catch(function(t){if(u===s.current.mutationId&&s.current.isMounted){var n,r={loading:!1,error:t,data:void 0,called:!0,client:a};(0,ri.D)(s.current.result,r)||o(s.current.result=r)}var i=e.onError||(null===(n=s.current.options)||void 0===n?void 0:n.onError);if(i)return i(t,c),{data:void 0,errors:t};throw t})},[]),c=(0,l.useCallback)(function(){s.current.isMounted&&o({called:!1,loading:!1,client:n})},[]);return(0,l.useEffect)(function(){return s.current.isMounted=!0,function(){s.current.isMounted=!1}},[]),[u,(0,t0.pi)({reset:c},a)]}var os=n(59067),ou=n(28428),oc=n(11186),ol=n(78513);function of(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var od=function(e){return(0,b.createStyles)({paper:{display:"flex",margin:"".concat(2.5*e.spacing.unit,"px 0"),padding:"".concat(3*e.spacing.unit,"px ").concat(3.5*e.spacing.unit,"px")},content:{flex:1,width:"100%"},actions:of({marginTop:-(1.5*e.spacing.unit),marginLeft:-(4*e.spacing.unit)},e.breakpoints.up("sm"),{marginLeft:0,marginRight:-(1.5*e.spacing.unit)}),itemBlock:{border:"1px solid rgba(224, 224, 224, 1)",borderRadius:e.shape.borderRadius,padding:2*e.spacing.unit,marginTop:e.spacing.unit},itemBlockText:{overflowWrap:"anywhere"}})},oh=(0,b.withStyles)(od)(function(e){var t=e.actions,n=e.children,r=e.classes;return l.createElement(ii.default,{className:r.paper},l.createElement("div",{className:r.content},n),t&&l.createElement("div",{className:r.actions},t))}),op=function(e){var t=e.title;return l.createElement(x.default,{variant:"subtitle2",gutterBottom:!0},t)},ob=function(e){var t=e.children,n=e.value;return l.createElement(x.default,{variant:"body1",noWrap:!0},t||n)},om=(0,b.withStyles)(od)(function(e){var t=e.children,n=e.classes,r=e.value;return l.createElement("div",{className:n.itemBlock},l.createElement(x.default,{variant:"body1",className:n.itemBlockText},t||r))});function og(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]-1}let sq=sV;function sZ(e,t){var n=this.__data__,r=sH(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this}let sX=sZ;function sJ(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t-1&&e%1==0&&e-1&&e%1==0&&e<=cC}let cD=cI;var cN="[object Arguments]",cP="[object Array]",cR="[object Boolean]",cj="[object Date]",cF="[object Error]",cY="[object Function]",cB="[object Map]",cU="[object Number]",cH="[object Object]",c$="[object RegExp]",cz="[object Set]",cG="[object String]",cW="[object WeakMap]",cK="[object ArrayBuffer]",cV="[object DataView]",cq="[object Float64Array]",cZ="[object Int8Array]",cX="[object Int16Array]",cJ="[object Int32Array]",cQ="[object Uint8Array]",c1="[object Uint8ClampedArray]",c0="[object Uint16Array]",c2="[object Uint32Array]",c3={};function c4(e){return eD(e)&&cD(e.length)&&!!c3[eC(e)]}c3["[object Float32Array]"]=c3[cq]=c3[cZ]=c3[cX]=c3[cJ]=c3[cQ]=c3[c1]=c3[c0]=c3[c2]=!0,c3[cN]=c3[cP]=c3[cK]=c3[cR]=c3[cV]=c3[cj]=c3[cF]=c3[cY]=c3[cB]=c3[cU]=c3[cH]=c3[c$]=c3[cz]=c3[cG]=c3[cW]=!1;let c6=c4;function c5(e){return function(t){return e(t)}}let c8=c5;var c9=n(79730),c7=c9.Z&&c9.Z.isTypedArray,le=c7?c8(c7):c6;let lt=le;var ln=Object.prototype.hasOwnProperty;function lr(e,t){var n=cx(e),r=!n&&cS(e),i=!n&&!r&&(0,cT.Z)(e),a=!n&&!r&&!i&<(e),o=n||r||i||a,s=o?cb(e.length,String):[],u=s.length;for(var c in e)(t||ln.call(e,c))&&!(o&&("length"==c||i&&("offset"==c||"parent"==c)||a&&("buffer"==c||"byteLength"==c||"byteOffset"==c)||cL(c,u)))&&s.push(c);return s}let li=lr;var la=Object.prototype;function lo(e){var t=e&&e.constructor;return e===("function"==typeof t&&t.prototype||la)}let ls=lo;var lu=sT(Object.keys,Object);let lc=lu;var ll=Object.prototype.hasOwnProperty;function lf(e){if(!ls(e))return lc(e);var t=[];for(var n in Object(e))ll.call(e,n)&&"constructor"!=n&&t.push(n);return t}let ld=lf;function lh(e){return null!=e&&cD(e.length)&&!ur(e)}let lp=lh;function lb(e){return lp(e)?li(e):ld(e)}let lm=lb;function lg(e,t){return e&&ch(t,lm(t),e)}let lv=lg;function ly(e){var t=[];if(null!=e)for(var n in Object(e))t.push(n);return t}let lw=ly;var l_=Object.prototype.hasOwnProperty;function lE(e){if(!ed(e))return lw(e);var t=ls(e),n=[];for(var r in e)"constructor"==r&&(t||!l_.call(e,r))||n.push(r);return n}let lS=lE;function lk(e){return lp(e)?li(e,!0):lS(e)}let lx=lk;function lT(e,t){return e&&ch(t,lx(t),e)}let lM=lT;var lO=n(42896);function lA(e,t){var n=-1,r=e.length;for(t||(t=Array(r));++n=0||(i[n]=e[n]);return i}function hu(e){if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}var hc=function(e){return Array.isArray(e)&&0===e.length},hl=function(e){return"function"==typeof e},hf=function(e){return null!==e&&"object"==typeof e},hd=function(e){return String(Math.floor(Number(e)))===e},hh=function(e){return"[object String]"===Object.prototype.toString.call(e)},hp=function(e){return 0===l.Children.count(e)},hb=function(e){return hf(e)&&hl(e.then)};function hm(e,t,n,r){void 0===r&&(r=0);for(var i=d8(t);e&&r=0?[]:{}}}return(0===a?e:i)[o[a]]===n?e:(void 0===n?delete i[o[a]]:i[o[a]]=n,0===a&&void 0===n&&delete r[o[a]],r)}function hv(e,t,n,r){void 0===n&&(n=new WeakMap),void 0===r&&(r={});for(var i=0,a=Object.keys(e);i0?t.map(function(t){return x(t,hm(e,t))}):[Promise.resolve("DO_NOT_DELETE_YOU_WILL_BE_FIRED")]).then(function(e){return e.reduce(function(e,n,r){return"DO_NOT_DELETE_YOU_WILL_BE_FIRED"===n||n&&(e=hg(e,t[r],n)),e},{})})},[x]),M=(0,l.useCallback)(function(e){return Promise.all([T(e),h.validationSchema?k(e):{},h.validate?S(e):{}]).then(function(e){var t=e[0],n=e[1],r=e[2];return sk.all([t,n,r],{arrayMerge:hL})})},[h.validate,h.validationSchema,T,S,k]),O=hN(function(e){return void 0===e&&(e=_.values),E({type:"SET_ISVALIDATING",payload:!0}),M(e).then(function(e){return v.current&&(E({type:"SET_ISVALIDATING",payload:!1}),sd()(_.errors,e)||E({type:"SET_ERRORS",payload:e})),e})});(0,l.useEffect)(function(){o&&!0===v.current&&sd()(p.current,h.initialValues)&&O(p.current)},[o,O]);var A=(0,l.useCallback)(function(e){var t=e&&e.values?e.values:p.current,n=e&&e.errors?e.errors:b.current?b.current:h.initialErrors||{},r=e&&e.touched?e.touched:m.current?m.current:h.initialTouched||{},i=e&&e.status?e.status:g.current?g.current:h.initialStatus;p.current=t,b.current=n,m.current=r,g.current=i;var a=function(){E({type:"RESET_FORM",payload:{isSubmitting:!!e&&!!e.isSubmitting,errors:n,touched:r,status:i,values:t,isValidating:!!e&&!!e.isValidating,submitCount:e&&e.submitCount&&"number"==typeof e.submitCount?e.submitCount:0}})};if(h.onReset){var o=h.onReset(_.values,V);hb(o)?o.then(a):a()}else a()},[h.initialErrors,h.initialStatus,h.initialTouched]);(0,l.useEffect)(function(){!0===v.current&&!sd()(p.current,h.initialValues)&&(c&&(p.current=h.initialValues,A()),o&&O(p.current))},[c,h.initialValues,A,o,O]),(0,l.useEffect)(function(){c&&!0===v.current&&!sd()(b.current,h.initialErrors)&&(b.current=h.initialErrors||hS,E({type:"SET_ERRORS",payload:h.initialErrors||hS}))},[c,h.initialErrors]),(0,l.useEffect)(function(){c&&!0===v.current&&!sd()(m.current,h.initialTouched)&&(m.current=h.initialTouched||hk,E({type:"SET_TOUCHED",payload:h.initialTouched||hk}))},[c,h.initialTouched]),(0,l.useEffect)(function(){c&&!0===v.current&&!sd()(g.current,h.initialStatus)&&(g.current=h.initialStatus,E({type:"SET_STATUS",payload:h.initialStatus}))},[c,h.initialStatus,h.initialTouched]);var L=hN(function(e){if(y.current[e]&&hl(y.current[e].validate)){var t=hm(_.values,e),n=y.current[e].validate(t);return hb(n)?(E({type:"SET_ISVALIDATING",payload:!0}),n.then(function(e){return e}).then(function(t){E({type:"SET_FIELD_ERROR",payload:{field:e,value:t}}),E({type:"SET_ISVALIDATING",payload:!1})})):(E({type:"SET_FIELD_ERROR",payload:{field:e,value:n}}),Promise.resolve(n))}return h.validationSchema?(E({type:"SET_ISVALIDATING",payload:!0}),k(_.values,e).then(function(e){return e}).then(function(t){E({type:"SET_FIELD_ERROR",payload:{field:e,value:t[e]}}),E({type:"SET_ISVALIDATING",payload:!1})})):Promise.resolve()}),C=(0,l.useCallback)(function(e,t){var n=t.validate;y.current[e]={validate:n}},[]),I=(0,l.useCallback)(function(e){delete y.current[e]},[]),D=hN(function(e,t){return E({type:"SET_TOUCHED",payload:e}),(void 0===t?i:t)?O(_.values):Promise.resolve()}),N=(0,l.useCallback)(function(e){E({type:"SET_ERRORS",payload:e})},[]),P=hN(function(e,t){var r=hl(e)?e(_.values):e;return E({type:"SET_VALUES",payload:r}),(void 0===t?n:t)?O(r):Promise.resolve()}),R=(0,l.useCallback)(function(e,t){E({type:"SET_FIELD_ERROR",payload:{field:e,value:t}})},[]),j=hN(function(e,t,r){return E({type:"SET_FIELD_VALUE",payload:{field:e,value:t}}),(void 0===r?n:r)?O(hg(_.values,e,t)):Promise.resolve()}),F=(0,l.useCallback)(function(e,t){var n,r=t,i=e;if(!hh(e)){e.persist&&e.persist();var a=e.target?e.target:e.currentTarget,o=a.type,s=a.name,u=a.id,c=a.value,l=a.checked,f=(a.outerHTML,a.options),d=a.multiple;r=t||s||u,i=/number|range/.test(o)?(n=parseFloat(c),isNaN(n)?"":n):/checkbox/.test(o)?hI(hm(_.values,r),l,c):d?hC(f):c}r&&j(r,i)},[j,_.values]),Y=hN(function(e){if(hh(e))return function(t){return F(t,e)};F(e)}),B=hN(function(e,t,n){return void 0===t&&(t=!0),E({type:"SET_FIELD_TOUCHED",payload:{field:e,value:t}}),(void 0===n?i:n)?O(_.values):Promise.resolve()}),U=(0,l.useCallback)(function(e,t){e.persist&&e.persist();var n,r=e.target,i=r.name,a=r.id;r.outerHTML,B(t||i||a,!0)},[B]),H=hN(function(e){if(hh(e))return function(t){return U(t,e)};U(e)}),$=(0,l.useCallback)(function(e){hl(e)?E({type:"SET_FORMIK_STATE",payload:e}):E({type:"SET_FORMIK_STATE",payload:function(){return e}})},[]),z=(0,l.useCallback)(function(e){E({type:"SET_STATUS",payload:e})},[]),G=(0,l.useCallback)(function(e){E({type:"SET_ISSUBMITTING",payload:e})},[]),W=hN(function(){return E({type:"SUBMIT_ATTEMPT"}),O().then(function(e){var t,n=e instanceof Error;if(!n&&0===Object.keys(e).length){try{if(void 0===(t=q()))return}catch(r){throw r}return Promise.resolve(t).then(function(e){return v.current&&E({type:"SUBMIT_SUCCESS"}),e}).catch(function(e){if(v.current)throw E({type:"SUBMIT_FAILURE"}),e})}if(v.current&&(E({type:"SUBMIT_FAILURE"}),n))throw e})}),K=hN(function(e){e&&e.preventDefault&&hl(e.preventDefault)&&e.preventDefault(),e&&e.stopPropagation&&hl(e.stopPropagation)&&e.stopPropagation(),W().catch(function(e){console.warn("Warning: An unhandled error was caught from submitForm()",e)})}),V={resetForm:A,validateForm:O,validateField:L,setErrors:N,setFieldError:R,setFieldTouched:B,setFieldValue:j,setStatus:z,setSubmitting:G,setTouched:D,setValues:P,setFormikState:$,submitForm:W},q=hN(function(){return f(_.values,V)}),Z=hN(function(e){e&&e.preventDefault&&hl(e.preventDefault)&&e.preventDefault(),e&&e.stopPropagation&&hl(e.stopPropagation)&&e.stopPropagation(),A()}),X=(0,l.useCallback)(function(e){return{value:hm(_.values,e),error:hm(_.errors,e),touched:!!hm(_.touched,e),initialValue:hm(p.current,e),initialTouched:!!hm(m.current,e),initialError:hm(b.current,e)}},[_.errors,_.touched,_.values]),J=(0,l.useCallback)(function(e){return{setValue:function(t,n){return j(e,t,n)},setTouched:function(t,n){return B(e,t,n)},setError:function(t){return R(e,t)}}},[j,B,R]),Q=(0,l.useCallback)(function(e){var t=hf(e),n=t?e.name:e,r=hm(_.values,n),i={name:n,value:r,onChange:Y,onBlur:H};if(t){var a=e.type,o=e.value,s=e.as,u=e.multiple;"checkbox"===a?void 0===o?i.checked=!!r:(i.checked=!!(Array.isArray(r)&&~r.indexOf(o)),i.value=o):"radio"===a?(i.checked=r===o,i.value=o):"select"===s&&u&&(i.value=i.value||[],i.multiple=!0)}return i},[H,Y,_.values]),ee=(0,l.useMemo)(function(){return!sd()(p.current,_.values)},[p.current,_.values]),et=(0,l.useMemo)(function(){return void 0!==s?ee?_.errors&&0===Object.keys(_.errors).length:!1!==s&&hl(s)?s(h):s:_.errors&&0===Object.keys(_.errors).length},[s,ee,_.errors,h]);return ha({},_,{initialValues:p.current,initialErrors:b.current,initialTouched:m.current,initialStatus:g.current,handleBlur:H,handleChange:Y,handleReset:Z,handleSubmit:K,resetForm:A,setErrors:N,setFormikState:$,setFieldTouched:B,setFieldValue:j,setFieldError:R,setStatus:z,setSubmitting:G,setTouched:D,setValues:P,submitForm:W,validateForm:O,validateField:L,isValid:et,dirty:ee,unregisterField:I,registerField:C,getFieldProps:Q,getFieldMeta:X,getFieldHelpers:J,validateOnBlur:i,validateOnChange:n,validateOnMount:o})}function hT(e){var t=hx(e),n=e.component,r=e.children,i=e.render,a=e.innerRef;return(0,l.useImperativeHandle)(a,function(){return t}),(0,l.createElement)(hw,{value:t},n?(0,l.createElement)(n,t):i?i(t):r?hl(r)?r(t):hp(r)?null:l.Children.only(r):null)}function hM(e){var t={};if(e.inner){if(0===e.inner.length)return hg(t,e.path,e.message);for(var n=e.inner,r=Array.isArray(n),i=0,n=r?n:n[Symbol.iterator]();;){if(r){if(i>=n.length)break;a=n[i++]}else{if((i=n.next()).done)break;a=i.value}var a,o=a;hm(t,o.path)||(t=hg(t,o.path,o.message))}}return t}function hO(e,t,n,r){void 0===n&&(n=!1),void 0===r&&(r={});var i=hA(e);return t[n?"validateSync":"validate"](i,{abortEarly:!1,context:r})}function hA(e){var t=Array.isArray(e)?[]:{};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){var r=String(n);!0===Array.isArray(e[r])?t[r]=e[r].map(function(e){return!0===Array.isArray(e)||sR(e)?hA(e):""!==e?e:void 0}):sR(e[r])?t[r]=hA(e[r]):t[r]=""!==e[r]?e[r]:void 0}return t}function hL(e,t,n){var r=e.slice();return t.forEach(function(t,i){if(void 0===r[i]){var a=!1!==n.clone&&n.isMergeableObject(t);r[i]=a?sk(Array.isArray(t)?[]:{},t,n):t}else n.isMergeableObject(t)?r[i]=sk(e[i],t,n):-1===e.indexOf(t)&&r.push(t)}),r}function hC(e){return Array.from(e).filter(function(e){return e.selected}).map(function(e){return e.value})}function hI(e,t,n){if("boolean"==typeof e)return Boolean(t);var r=[],i=!1,a=-1;if(Array.isArray(e))r=e,i=(a=e.indexOf(n))>=0;else if(!n||"true"==n||"false"==n)return Boolean(t);return t&&n&&!i?r.concat(n):i?r.slice(0,a).concat(r.slice(a+1)):r}var hD="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement?l.useLayoutEffect:l.useEffect;function hN(e){var t=(0,l.useRef)(e);return hD(function(){t.current=e}),(0,l.useCallback)(function(){for(var e=arguments.length,n=Array(e),r=0;re?t:e},0);return Array.from(ha({},e,{length:t+1}))};(function(e){function t(t){var n;return(n=e.call(this,t)||this).updateArrayField=function(e,t,r){var i=n.props,a=i.name;(0,i.formik.setFormikState)(function(n){var i="function"==typeof r?r:e,o="function"==typeof t?t:e,s=hg(n.values,a,e(hm(n.values,a))),u=r?i(hm(n.errors,a)):void 0,c=t?o(hm(n.touched,a)):void 0;return hc(u)&&(u=void 0),hc(c)&&(c=void 0),ha({},n,{values:s,errors:r?hg(n.errors,a,u):n.errors,touched:t?hg(n.touched,a,c):n.touched})})},n.push=function(e){return n.updateArrayField(function(t){return[].concat(hU(t),[hi(e)])},!1,!1)},n.handlePush=function(e){return function(){return n.push(e)}},n.swap=function(e,t){return n.updateArrayField(function(n){return hF(n,e,t)},!0,!0)},n.handleSwap=function(e,t){return function(){return n.swap(e,t)}},n.move=function(e,t){return n.updateArrayField(function(n){return hj(n,e,t)},!0,!0)},n.handleMove=function(e,t){return function(){return n.move(e,t)}},n.insert=function(e,t){return n.updateArrayField(function(n){return hY(n,e,t)},function(t){return hY(t,e,null)},function(t){return hY(t,e,null)})},n.handleInsert=function(e,t){return function(){return n.insert(e,t)}},n.replace=function(e,t){return n.updateArrayField(function(n){return hB(n,e,t)},!1,!1)},n.handleReplace=function(e,t){return function(){return n.replace(e,t)}},n.unshift=function(e){var t=-1;return n.updateArrayField(function(n){var r=n?[e].concat(n):[e];return t<0&&(t=r.length),r},function(e){var n=e?[null].concat(e):[null];return t<0&&(t=n.length),n},function(e){var n=e?[null].concat(e):[null];return t<0&&(t=n.length),n}),t},n.handleUnshift=function(e){return function(){return n.unshift(e)}},n.handleRemove=function(e){return function(){return n.remove(e)}},n.handlePop=function(){return function(){return n.pop()}},n.remove=n.remove.bind(hu(n)),n.pop=n.pop.bind(hu(n)),n}ho(t,e);var n=t.prototype;return n.componentDidUpdate=function(e){this.props.validateOnChange&&this.props.formik.validateOnChange&&!sd()(hm(e.formik.values,e.name),hm(this.props.formik.values,this.props.name))&&this.props.formik.validateForm(this.props.formik.values)},n.remove=function(e){var t;return this.updateArrayField(function(n){var r=n?hU(n):[];return t||(t=r[e]),hl(r.splice)&&r.splice(e,1),r},!0,!0),t},n.pop=function(){var e;return this.updateArrayField(function(t){var n=t;return e||(e=n&&n.pop&&n.pop()),n},!0,!0),e},n.render=function(){var e={push:this.push,pop:this.pop,swap:this.swap,move:this.move,insert:this.insert,replace:this.replace,unshift:this.unshift,remove:this.remove,handlePush:this.handlePush,handlePop:this.handlePop,handleSwap:this.handleSwap,handleMove:this.handleMove,handleInsert:this.handleInsert,handleReplace:this.handleReplace,handleUnshift:this.handleUnshift,handleRemove:this.handleRemove},t=this.props,n=t.component,r=t.render,i=t.children,a=t.name,o=hs(t.formik,["validate","validationSchema"]),s=ha({},e,{form:o,name:a});return n?(0,l.createElement)(n,s):r?r(s):i?"function"==typeof i?i(s):hp(i)?null:l.Children.only(i):null},t})(l.Component).defaultProps={validateOnChange:!0},l.Component,l.Component;var hH=n(24802),h$=n(71209),hz=n(91750),hG=n(11970),hW=n(4689),hK=n(67598),hV=function(){return(hV=Object.assign||function(e){for(var t,n=1,r=arguments.length;nt.indexOf(r)&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,r=Object.getOwnPropertySymbols(e);it.indexOf(r[i])&&(n[r[i]]=e[r[i]]);return n}function hZ(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hq(n,["onBlur"]),a=e.form,o=a.isSubmitting,s=a.touched,u=a.errors,c=e.onBlur,l=e.helperText,f=hq(e,["disabled","field","form","onBlur","helperText"]),d=hm(u,i.name),h=hm(s,i.name)&&!!d;return hV(hV({variant:f.variant,error:h,helperText:h?d:l,disabled:null!=t?t:o,onBlur:null!=c?c:function(e){r(null!=e?e:i.name)}},i),f)}function hX(e){var t=e.children,n=hq(e,["children"]);return(0,l.createElement)(iw.Z,hV({},hZ(n)),t)}function hJ(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hq(n,["onBlur"]),a=e.form.isSubmitting,o=(e.type,e.onBlur),s=hq(e,["disabled","field","form","type","onBlur"]);return hV(hV({disabled:null!=t?t:a,onBlur:null!=o?o:function(e){r(null!=e?e:i.name)}},i),s)}function hQ(e){return(0,l.createElement)(hH.Z,hV({},hJ(e)))}function h1(e){var t,n=e.disabled,r=e.field,i=r.onBlur,a=hq(r,["onBlur"]),o=e.form.isSubmitting,s=(e.type,e.onBlur),u=hq(e,["disabled","field","form","type","onBlur"]);return hV(hV({disabled:null!=n?n:o,indeterminate:!Array.isArray(a.value)&&null==a.value,onBlur:null!=s?s:function(e){i(null!=e?e:a.name)}},a),u)}function h0(e){return(0,l.createElement)(h$.Z,hV({},h1(e)))}function h2(e){var t=e.Label,n=hq(e,["Label"]);return(0,l.createElement)(hz.Z,hV({control:(0,l.createElement)(h$.Z,hV({},h1(n)))},t))}function h3(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hq(n,["onBlur"]),a=e.form.isSubmitting,o=e.onBlur,s=hq(e,["disabled","field","form","onBlur"]);return hV(hV({disabled:null!=t?t:a,onBlur:null!=o?o:function(e){r(null!=e?e:i.name)}},i),s)}function h4(e){return(0,l.createElement)(hG.default,hV({},h3(e)))}function h6(e){var t=e.field,n=t.onBlur,r=hq(t,["onBlur"]),i=(e.form,e.onBlur),a=hq(e,["field","form","onBlur"]);return hV(hV({onBlur:null!=i?i:function(e){n(null!=e?e:r.name)}},r),a)}function h5(e){return(0,l.createElement)(hW.Z,hV({},h6(e)))}function h8(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hq(n,["onBlur"]),a=e.form.isSubmitting,o=e.onBlur,s=hq(e,["disabled","field","form","onBlur"]);return hV(hV({disabled:null!=t?t:a,onBlur:null!=o?o:function(e){r(null!=e?e:i.name)}},i),s)}function h9(e){return(0,l.createElement)(hK.default,hV({},h8(e)))}hX.displayName="FormikMaterialUITextField",hQ.displayName="FormikMaterialUISwitch",h0.displayName="FormikMaterialUICheckbox",h2.displayName="FormikMaterialUICheckboxWithLabel",h4.displayName="FormikMaterialUISelect",h5.displayName="FormikMaterialUIRadioGroup",h9.displayName="FormikMaterialUIInputBase";try{a=Map}catch(h7){}try{o=Set}catch(pe){}function pt(e,t,n){if(!e||"object"!=typeof e||"function"==typeof e)return e;if(e.nodeType&&"cloneNode"in e)return e.cloneNode(!0);if(e instanceof Date)return new Date(e.getTime());if(e instanceof RegExp)return RegExp(e);if(Array.isArray(e))return e.map(pn);if(a&&e instanceof a)return new Map(Array.from(e.entries()));if(o&&e instanceof o)return new Set(Array.from(e.values()));if(e instanceof Object){t.push(e);var r=Object.create(e);for(var i in n.push(r),e){var s=t.findIndex(function(t){return t===e[i]});r[i]=s>-1?n[s]:pt(e[i],t,n)}return r}return e}function pn(e){return pt(e,[],[])}let pr=Object.prototype.toString,pi=Error.prototype.toString,pa=RegExp.prototype.toString,po="undefined"!=typeof Symbol?Symbol.prototype.toString:()=>"",ps=/^Symbol\((.*)\)(.*)$/;function pu(e){if(e!=+e)return"NaN";let t=0===e&&1/e<0;return t?"-0":""+e}function pc(e,t=!1){if(null==e||!0===e||!1===e)return""+e;let n=typeof e;if("number"===n)return pu(e);if("string"===n)return t?`"${e}"`:e;if("function"===n)return"[Function "+(e.name||"anonymous")+"]";if("symbol"===n)return po.call(e).replace(ps,"Symbol($1)");let r=pr.call(e).slice(8,-1);return"Date"===r?isNaN(e.getTime())?""+e:e.toISOString(e):"Error"===r||e instanceof Error?"["+pi.call(e)+"]":"RegExp"===r?pa.call(e):null}function pl(e,t){let n=pc(e,t);return null!==n?n:JSON.stringify(e,function(e,n){let r=pc(this[e],t);return null!==r?r:n},2)}let pf={default:"${path} is invalid",required:"${path} is a required field",oneOf:"${path} must be one of the following values: ${values}",notOneOf:"${path} must not be one of the following values: ${values}",notType({path:e,type:t,value:n,originalValue:r}){let i=null!=r&&r!==n,a=`${e} must be a \`${t}\` type, but the final value was: \`${pl(n,!0)}\``+(i?` (cast from the value \`${pl(r,!0)}\`).`:".");return null===n&&(a+='\n If "null" is intended as an empty value be sure to mark the schema as `.nullable()`'),a},defined:"${path} must be defined"},pd={length:"${path} must be exactly ${length} characters",min:"${path} must be at least ${min} characters",max:"${path} must be at most ${max} characters",matches:'${path} must match the following: "${regex}"',email:"${path} must be a valid email",url:"${path} must be a valid URL",uuid:"${path} must be a valid UUID",trim:"${path} must be a trimmed string",lowercase:"${path} must be a lowercase string",uppercase:"${path} must be a upper case string"},ph={min:"${path} must be greater than or equal to ${min}",max:"${path} must be less than or equal to ${max}",lessThan:"${path} must be less than ${less}",moreThan:"${path} must be greater than ${more}",positive:"${path} must be a positive number",negative:"${path} must be a negative number",integer:"${path} must be an integer"},pp={min:"${path} field must be later than ${min}",max:"${path} field must be at earlier than ${max}"},pb={isValue:"${path} field must be ${value}"},pm={noUnknown:"${path} field has unspecified keys: ${unknown}"},pg={min:"${path} field must have at least ${min} items",max:"${path} field must have less than or equal to ${max} items",length:"${path} must be have ${length} items"};Object.assign(Object.create(null),{mixed:pf,string:pd,number:ph,date:pp,object:pm,array:pg,boolean:pb});var pv=n(18721),py=n.n(pv);let pw=e=>e&&e.__isYupSchema__;class p_{constructor(e,t){if(this.refs=e,this.refs=e,"function"==typeof t){this.fn=t;return}if(!py()(t,"is"))throw TypeError("`is:` is required for `when()` conditions");if(!t.then&&!t.otherwise)throw TypeError("either `then:` or `otherwise:` is required for `when()` conditions");let{is:n,then:r,otherwise:i}=t,a="function"==typeof n?n:(...e)=>e.every(e=>e===n);this.fn=function(...e){let t=e.pop(),n=e.pop(),o=a(...e)?r:i;if(o)return"function"==typeof o?o(n):n.concat(o.resolve(t))}}resolve(e,t){let n=this.refs.map(e=>e.getValue(null==t?void 0:t.value,null==t?void 0:t.parent,null==t?void 0:t.context)),r=this.fn.apply(e,n.concat(e,t));if(void 0===r||r===e)return e;if(!pw(r))throw TypeError("conditions must return a schema object");return r.resolve(t)}}let pE=p_;function pS(e){return null==e?[]:[].concat(e)}function pk(){return(pk=Object.assign||function(e){for(var t=1;tpl(t[n])):"function"==typeof e?e(t):e}static isError(e){return e&&"ValidationError"===e.name}constructor(e,t,n,r){super(),this.name="ValidationError",this.value=t,this.path=n,this.type=r,this.errors=[],this.inner=[],pS(e).forEach(e=>{pT.isError(e)?(this.errors.push(...e.errors),this.inner=this.inner.concat(e.inner.length?e.inner:e)):this.errors.push(e)}),this.message=this.errors.length>1?`${this.errors.length} errors occurred`:this.errors[0],Error.captureStackTrace&&Error.captureStackTrace(this,pT)}}let pM=e=>{let t=!1;return(...n)=>{t||(t=!0,e(...n))}};function pO(e,t){let{endEarly:n,tests:r,args:i,value:a,errors:o,sort:s,path:u}=e,c=pM(t),l=r.length,f=[];if(o=o||[],!l)return o.length?c(new pT(o,a,u)):c(null,a);for(let d=0;d=0||(i[n]=e[n]);return i}function pR(e){function t(t,n){let{value:r,path:i="",label:a,options:o,originalValue:s,sync:u}=t,c=pP(t,["value","path","label","options","originalValue","sync"]),{name:l,test:f,params:d,message:h}=e,{parent:p,context:b}=o;function m(e){return pD.isRef(e)?e.getValue(r,p,b):e}function g(e={}){let t=pL()(pN({value:r,originalValue:s,label:a,path:e.path||i},d,e.params),m),n=new pT(pT.formatError(e.message||h,t),r,t.path,e.type||l);return n.params=t,n}let v=pN({path:i,parent:p,type:l,createError:g,resolve:m,options:o,originalValue:s},c);if(!u){try{Promise.resolve(f.call(v,r,v)).then(e=>{pT.isError(e)?n(e):e?n(null,e):n(g())})}catch(y){n(y)}return}let w;try{var _;if(w=f.call(v,r,v),"function"==typeof(null==(_=w)?void 0:_.then))throw Error(`Validation test of type: "${v.type}" returned a Promise during a synchronous validate. This test will finish after the validate call has returned`)}catch(E){n(E);return}pT.isError(w)?n(w):w?n(null,w):n(g())}return t.OPTIONS=e,t}pD.prototype.__isYupRef=!0;let pj=e=>e.substr(0,e.length-1).substr(1);function pF(e,t,n,r=n){let i,a,o;return t?((0,pC.forEach)(t,(s,u,c)=>{let l=u?pj(s):s;if((e=e.resolve({context:r,parent:i,value:n})).innerType){let f=c?parseInt(l,10):0;if(n&&f>=n.length)throw Error(`Yup.reach cannot resolve an array item at index: ${s}, in the path: ${t}. because there is no value at that index. `);i=n,n=n&&n[f],e=e.innerType}if(!c){if(!e.fields||!e.fields[l])throw Error(`The schema does not contain the path: ${t}. (failed at: ${o} which is a type: "${e._type}")`);i=n,n=n&&n[l],e=e.fields[l]}a=l,o=u?"["+s+"]":"."+s}),{schema:e,parent:i,parentPath:a}):{parent:i,parentPath:t,schema:e}}class pY{constructor(){this.list=new Set,this.refs=new Map}get size(){return this.list.size+this.refs.size}describe(){let e=[];for(let t of this.list)e.push(t);for(let[,n]of this.refs)e.push(n.describe());return e}toArray(){return Array.from(this.list).concat(Array.from(this.refs.values()))}add(e){pD.isRef(e)?this.refs.set(e.key,e):this.list.add(e)}delete(e){pD.isRef(e)?this.refs.delete(e.key):this.list.delete(e)}has(e,t){if(this.list.has(e))return!0;let n,r=this.refs.values();for(;!(n=r.next()).done;)if(t(n.value)===e)return!0;return!1}clone(){let e=new pY;return e.list=new Set(this.list),e.refs=new Map(this.refs),e}merge(e,t){let n=this.clone();return e.list.forEach(e=>n.add(e)),e.refs.forEach(e=>n.add(e)),t.list.forEach(e=>n.delete(e)),t.refs.forEach(e=>n.delete(e)),n}}function pB(){return(pB=Object.assign||function(e){for(var t=1;t{this.typeError(pf.notType)}),this.type=(null==e?void 0:e.type)||"mixed",this.spec=pB({strip:!1,strict:!1,abortEarly:!0,recursive:!0,nullable:!1,presence:"optional"},null==e?void 0:e.spec)}get _type(){return this.type}_typeCheck(e){return!0}clone(e){if(this._mutate)return e&&Object.assign(this.spec,e),this;let t=Object.create(Object.getPrototypeOf(this));return t.type=this.type,t._typeError=this._typeError,t._whitelistError=this._whitelistError,t._blacklistError=this._blacklistError,t._whitelist=this._whitelist.clone(),t._blacklist=this._blacklist.clone(),t.exclusiveTests=pB({},this.exclusiveTests),t.deps=[...this.deps],t.conditions=[...this.conditions],t.tests=[...this.tests],t.transforms=[...this.transforms],t.spec=pn(pB({},this.spec,e)),t}label(e){var t=this.clone();return t.spec.label=e,t}meta(...e){if(0===e.length)return this.spec.meta;let t=this.clone();return t.spec.meta=Object.assign(t.spec.meta||{},e[0]),t}withMutation(e){let t=this._mutate;this._mutate=!0;let n=e(this);return this._mutate=t,n}concat(e){if(!e||e===this)return this;if(e.type!==this.type&&"mixed"!==this.type)throw TypeError(`You cannot \`concat()\` schema's of different types: ${this.type} and ${e.type}`);let t=this,n=e.clone(),r=pB({},t.spec,n.spec);return n.spec=r,n._typeError||(n._typeError=t._typeError),n._whitelistError||(n._whitelistError=t._whitelistError),n._blacklistError||(n._blacklistError=t._blacklistError),n._whitelist=t._whitelist.merge(e._whitelist,e._blacklist),n._blacklist=t._blacklist.merge(e._blacklist,e._whitelist),n.tests=t.tests,n.exclusiveTests=t.exclusiveTests,n.withMutation(t=>{e.tests.forEach(e=>{t.test(e.OPTIONS)})}),n}isType(e){return!!this.spec.nullable&&null===e||this._typeCheck(e)}resolve(e){let t=this;if(t.conditions.length){let n=t.conditions;(t=t.clone()).conditions=[],t=(t=n.reduce((t,n)=>n.resolve(t,e),t)).resolve(e)}return t}cast(e,t={}){let n=this.resolve(pB({value:e},t)),r=n._cast(e,t);if(void 0!==e&&!1!==t.assert&&!0!==n.isType(r)){let i=pl(e),a=pl(r);throw TypeError(`The value of ${t.path||"field"} could not be cast to a value that satisfies the schema type: "${n._type}". attempted value: ${i} -`+(a!==i?`result of cast: ${a}`:""))}return r}_cast(e,t){let n=void 0===e?e:this.transforms.reduce((t,n)=>n.call(this,t,e,this),e);return void 0===n&&(n=this.getDefault()),n}_validate(e,t={},n){let{sync:r,path:i,from:a=[],originalValue:o=e,strict:s=this.spec.strict,abortEarly:u=this.spec.abortEarly}=t,c=e;s||(c=this._cast(c,pB({assert:!1},t)));let l={value:c,path:i,options:t,originalValue:o,schema:this,label:this.spec.label,sync:r,from:a},f=[];this._typeError&&f.push(this._typeError),this._whitelistError&&f.push(this._whitelistError),this._blacklistError&&f.push(this._blacklistError),pO({args:l,value:c,path:i,sync:r,tests:f,endEarly:u},e=>{if(e)return void n(e,c);pO({tests:this.tests,args:l,path:i,sync:r,value:c,endEarly:u},n)})}validate(e,t,n){let r=this.resolve(pB({},t,{value:e}));return"function"==typeof n?r._validate(e,t,n):new Promise((n,i)=>r._validate(e,t,(e,t)=>{e?i(e):n(t)}))}validateSync(e,t){let n;return this.resolve(pB({},t,{value:e}))._validate(e,pB({},t,{sync:!0}),(e,t)=>{if(e)throw e;n=t}),n}isValid(e,t){return this.validate(e,t).then(()=>!0,e=>{if(pT.isError(e))return!1;throw e})}isValidSync(e,t){try{return this.validateSync(e,t),!0}catch(n){if(pT.isError(n))return!1;throw n}}_getDefault(){let e=this.spec.default;return null==e?e:"function"==typeof e?e.call(this):pn(e)}getDefault(e){return this.resolve(e||{})._getDefault()}default(e){return 0===arguments.length?this._getDefault():this.clone({default:e})}strict(e=!0){var t=this.clone();return t.spec.strict=e,t}_isPresent(e){return null!=e}defined(e=pf.defined){return this.test({message:e,name:"defined",exclusive:!0,test:e=>void 0!==e})}required(e=pf.required){return this.clone({presence:"required"}).withMutation(t=>t.test({message:e,name:"required",exclusive:!0,test(e){return this.schema._isPresent(e)}}))}notRequired(){var e=this.clone({presence:"optional"});return e.tests=e.tests.filter(e=>"required"!==e.OPTIONS.name),e}nullable(e=!0){return this.clone({nullable:!1!==e})}transform(e){var t=this.clone();return t.transforms.push(e),t}test(...e){let t;if(void 0===(t=1===e.length?"function"==typeof e[0]?{test:e[0]}:e[0]:2===e.length?{name:e[0],test:e[1]}:{name:e[0],message:e[1],test:e[2]}).message&&(t.message=pf.default),"function"!=typeof t.test)throw TypeError("`test` is a required parameters");let n=this.clone(),r=pR(t),i=t.exclusive||t.name&&!0===n.exclusiveTests[t.name];if(t.exclusive&&!t.name)throw TypeError("Exclusive tests must provide a unique `name` identifying the test");return t.name&&(n.exclusiveTests[t.name]=!!t.exclusive),n.tests=n.tests.filter(e=>e.OPTIONS.name!==t.name||!i&&e.OPTIONS.test!==r.OPTIONS.test),n.tests.push(r),n}when(e,t){Array.isArray(e)||"string"==typeof e||(t=e,e=".");let n=this.clone(),r=pS(e).map(e=>new pD(e));return r.forEach(e=>{e.isSibling&&n.deps.push(e.key)}),n.conditions.push(new pE(r,t)),n}typeError(e){var t=this.clone();return t._typeError=pR({message:e,name:"typeError",test(e){return!!(void 0===e||this.schema.isType(e))||this.createError({params:{type:this.schema._type}})}}),t}oneOf(e,t=pf.oneOf){var n=this.clone();return e.forEach(e=>{n._whitelist.add(e),n._blacklist.delete(e)}),n._whitelistError=pR({message:t,name:"oneOf",test(e){if(void 0===e)return!0;let t=this.schema._whitelist;return!!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}notOneOf(e,t=pf.notOneOf){var n=this.clone();return e.forEach(e=>{n._blacklist.add(e),n._whitelist.delete(e)}),n._blacklistError=pR({message:t,name:"notOneOf",test(e){let t=this.schema._blacklist;return!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}strip(e=!0){let t=this.clone();return t.spec.strip=e,t}describe(){let e=this.clone(),{label:t,meta:n}=e.spec,r={meta:n,label:t,type:e.type,oneOf:e._whitelist.describe(),notOneOf:e._blacklist.describe(),tests:e.tests.map(e=>({name:e.OPTIONS.name,params:e.OPTIONS.params})).filter((e,t,n)=>n.findIndex(t=>t.name===e.name)===t)};return r}}for(let pH of(pU.prototype.__isYupSchema__=!0,["validate","validateSync"]))pU.prototype[`${pH}At`]=function(e,t,n={}){let{parent:r,parentPath:i,schema:a}=pF(this,e,t,n.context);return a[pH](r&&r[i],pB({},n,{parent:r,path:e}))};for(let p$ of["equals","is"])pU.prototype[p$]=pU.prototype.oneOf;for(let pz of["not","nope"])pU.prototype[pz]=pU.prototype.notOneOf;pU.prototype.optional=pU.prototype.notRequired;let pG=pU;function pW(){return new pG}pW.prototype=pG.prototype;let pK=e=>null==e;function pV(){return new pq}class pq extends pU{constructor(){super({type:"boolean"}),this.withMutation(()=>{this.transform(function(e){if(!this.isType(e)){if(/^(true|1)$/i.test(String(e)))return!0;if(/^(false|0)$/i.test(String(e)))return!1}return e})})}_typeCheck(e){return e instanceof Boolean&&(e=e.valueOf()),"boolean"==typeof e}isTrue(e=pb.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"true"},test:e=>pK(e)||!0===e})}isFalse(e=pb.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"false"},test:e=>pK(e)||!1===e})}}pV.prototype=pq.prototype;let pZ=/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,pX=/^((https?|ftp):)?\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,pJ=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i,pQ=e=>pK(e)||e===e.trim(),p1=({}).toString();function p0(){return new p2}class p2 extends pU{constructor(){super({type:"string"}),this.withMutation(()=>{this.transform(function(e){if(this.isType(e)||Array.isArray(e))return e;let t=null!=e&&e.toString?e.toString():e;return t===p1?e:t})})}_typeCheck(e){return e instanceof String&&(e=e.valueOf()),"string"==typeof e}_isPresent(e){return super._isPresent(e)&&!!e.length}length(e,t=pd.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pK(t)||t.length===this.resolve(e)}})}min(e,t=pd.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t.length>=this.resolve(e)}})}max(e,t=pd.max){return this.test({name:"max",exclusive:!0,message:t,params:{max:e},test(t){return pK(t)||t.length<=this.resolve(e)}})}matches(e,t){let n=!1,r,i;return t&&("object"==typeof t?{excludeEmptyString:n=!1,message:r,name:i}=t:r=t),this.test({name:i||"matches",message:r||pd.matches,params:{regex:e},test:t=>pK(t)||""===t&&n||-1!==t.search(e)})}email(e=pd.email){return this.matches(pZ,{name:"email",message:e,excludeEmptyString:!0})}url(e=pd.url){return this.matches(pX,{name:"url",message:e,excludeEmptyString:!0})}uuid(e=pd.uuid){return this.matches(pJ,{name:"uuid",message:e,excludeEmptyString:!1})}ensure(){return this.default("").transform(e=>null===e?"":e)}trim(e=pd.trim){return this.transform(e=>null!=e?e.trim():e).test({message:e,name:"trim",test:pQ})}lowercase(e=pd.lowercase){return this.transform(e=>pK(e)?e:e.toLowerCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pK(e)||e===e.toLowerCase()})}uppercase(e=pd.uppercase){return this.transform(e=>pK(e)?e:e.toUpperCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pK(e)||e===e.toUpperCase()})}}p0.prototype=p2.prototype;let p3=e=>e!=+e;function p4(){return new p6}class p6 extends pU{constructor(){super({type:"number"}),this.withMutation(()=>{this.transform(function(e){let t=e;if("string"==typeof t){if(""===(t=t.replace(/\s/g,"")))return NaN;t=+t}return this.isType(t)?t:parseFloat(t)})})}_typeCheck(e){return e instanceof Number&&(e=e.valueOf()),"number"==typeof e&&!p3(e)}min(e,t=ph.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t>=this.resolve(e)}})}max(e,t=ph.max){return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pK(t)||t<=this.resolve(e)}})}lessThan(e,t=ph.lessThan){return this.test({message:t,name:"max",exclusive:!0,params:{less:e},test(t){return pK(t)||tthis.resolve(e)}})}positive(e=ph.positive){return this.moreThan(0,e)}negative(e=ph.negative){return this.lessThan(0,e)}integer(e=ph.integer){return this.test({name:"integer",message:e,test:e=>pK(e)||Number.isInteger(e)})}truncate(){return this.transform(e=>pK(e)?e:0|e)}round(e){var t,n=["ceil","floor","round","trunc"];if("trunc"===(e=(null==(t=e)?void 0:t.toLowerCase())||"round"))return this.truncate();if(-1===n.indexOf(e.toLowerCase()))throw TypeError("Only valid options for round() are: "+n.join(", "));return this.transform(t=>pK(t)?t:Math[e](t))}}p4.prototype=p6.prototype;var p5=/^(\d{4}|[+\-]\d{6})(?:-?(\d{2})(?:-?(\d{2}))?)?(?:[ T]?(\d{2}):?(\d{2})(?::?(\d{2})(?:[,\.](\d{1,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?)?)?$/;function p8(e){var t,n,r=[1,4,5,6,7,10,11],i=0;if(n=p5.exec(e)){for(var a,o=0;a=r[o];++o)n[a]=+n[a]||0;n[2]=(+n[2]||1)-1,n[3]=+n[3]||1,n[7]=n[7]?String(n[7]).substr(0,3):0,(void 0===n[8]||""===n[8])&&(void 0===n[9]||""===n[9])?t=+new Date(n[1],n[2],n[3],n[4],n[5],n[6],n[7]):("Z"!==n[8]&&void 0!==n[9]&&(i=60*n[10]+n[11],"+"===n[9]&&(i=0-i)),t=Date.UTC(n[1],n[2],n[3],n[4],n[5]+i,n[6],n[7]))}else t=Date.parse?Date.parse(e):NaN;return t}let p9=new Date(""),p7=e=>"[object Date]"===Object.prototype.toString.call(e);function be(){return new bt}class bt extends pU{constructor(){super({type:"date"}),this.withMutation(()=>{this.transform(function(e){return this.isType(e)?e:(e=p8(e),isNaN(e)?p9:new Date(e))})})}_typeCheck(e){return p7(e)&&!isNaN(e.getTime())}prepareParam(e,t){let n;if(pD.isRef(e))n=e;else{let r=this.cast(e);if(!this._typeCheck(r))throw TypeError(`\`${t}\` must be a Date or a value that can be \`cast()\` to a Date`);n=r}return n}min(e,t=pp.min){let n=this.prepareParam(e,"min");return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(e){return pK(e)||e>=this.resolve(n)}})}max(e,t=pp.max){var n=this.prepareParam(e,"max");return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(e){return pK(e)||e<=this.resolve(n)}})}}bt.INVALID_DATE=p9,be.prototype=bt.prototype,be.INVALID_DATE=p9;var bn=n(11865),br=n.n(bn),bi=n(68929),ba=n.n(bi),bo=n(67523),bs=n.n(bo),bu=n(94633),bc=n.n(bu);function bl(e,t=[]){let n=[],r=[];function i(e,i){var a=(0,pC.split)(e)[0];~r.indexOf(a)||r.push(a),~t.indexOf(`${i}-${a}`)||n.push([i,a])}for(let a in e)if(py()(e,a)){let o=e[a];~r.indexOf(a)||r.push(a),pD.isRef(o)&&o.isSibling?i(o.path,a):pw(o)&&"deps"in o&&o.deps.forEach(e=>i(e,a))}return bc().array(r,n).reverse()}function bf(e,t){let n=1/0;return e.some((e,r)=>{var i;if((null==(i=t.path)?void 0:i.indexOf(e))!==-1)return n=r,!0}),n}function bd(e){return(t,n)=>bf(e,t)-bf(e,n)}function bh(){return(bh=Object.assign||function(e){for(var t=1;t"[object Object]"===Object.prototype.toString.call(e);function bb(e,t){let n=Object.keys(e.fields);return Object.keys(t).filter(e=>-1===n.indexOf(e))}let bm=bd([]);class bg extends pU{constructor(e){super({type:"object"}),this.fields=Object.create(null),this._sortErrors=bm,this._nodes=[],this._excludedEdges=[],this.withMutation(()=>{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null}),e&&this.shape(e)})}_typeCheck(e){return bp(e)||"function"==typeof e}_cast(e,t={}){var n;let r=super._cast(e,t);if(void 0===r)return this.getDefault();if(!this._typeCheck(r))return r;let i=this.fields,a=null!=(n=t.stripUnknown)?n:this.spec.noUnknown,o=this._nodes.concat(Object.keys(r).filter(e=>-1===this._nodes.indexOf(e))),s={},u=bh({},t,{parent:s,__validating:t.__validating||!1}),c=!1;for(let l of o){let f=i[l],d=py()(r,l);if(f){let h,p=r[l];u.path=(t.path?`${t.path}.`:"")+l;let b="spec"in(f=f.resolve({value:p,context:t.context,parent:s}))?f.spec:void 0,m=null==b?void 0:b.strict;if(null==b?void 0:b.strip){c=c||l in r;continue}void 0!==(h=t.__validating&&m?r[l]:f.cast(r[l],u))&&(s[l]=h)}else d&&!a&&(s[l]=r[l]);s[l]!==r[l]&&(c=!0)}return c?s:r}_validate(e,t={},n){let r=[],{sync:i,from:a=[],originalValue:o=e,abortEarly:s=this.spec.abortEarly,recursive:u=this.spec.recursive}=t;a=[{schema:this,value:o},...a],t.__validating=!0,t.originalValue=o,t.from=a,super._validate(e,t,(e,c)=>{if(e){if(!pT.isError(e)||s)return void n(e,c);r.push(e)}if(!u||!bp(c)){n(r[0]||null,c);return}o=o||c;let l=this._nodes.map(e=>(n,r)=>{let i=-1===e.indexOf(".")?(t.path?`${t.path}.`:"")+e:`${t.path||""}["${e}"]`,s=this.fields[e];if(s&&"validate"in s){s.validate(c[e],bh({},t,{path:i,from:a,strict:!0,parent:c,originalValue:o[e]}),r);return}r(null)});pO({sync:i,tests:l,value:c,errors:r,endEarly:s,sort:this._sortErrors,path:t.path},n)})}clone(e){let t=super.clone(e);return t.fields=bh({},this.fields),t._nodes=this._nodes,t._excludedEdges=this._excludedEdges,t._sortErrors=this._sortErrors,t}concat(e){let t=super.concat(e),n=t.fields;for(let[r,i]of Object.entries(this.fields)){let a=n[r];void 0===a?n[r]=i:a instanceof pU&&i instanceof pU&&(n[r]=i.concat(a))}return t.withMutation(()=>t.shape(n))}getDefaultFromShape(){let e={};return this._nodes.forEach(t=>{let n=this.fields[t];e[t]="default"in n?n.getDefault():void 0}),e}_getDefault(){return"default"in this.spec?super._getDefault():this._nodes.length?this.getDefaultFromShape():void 0}shape(e,t=[]){let n=this.clone(),r=Object.assign(n.fields,e);if(n.fields=r,n._sortErrors=bd(Object.keys(r)),t.length){Array.isArray(t[0])||(t=[t]);let i=t.map(([e,t])=>`${e}-${t}`);n._excludedEdges=n._excludedEdges.concat(i)}return n._nodes=bl(r,n._excludedEdges),n}pick(e){let t={};for(let n of e)this.fields[n]&&(t[n]=this.fields[n]);return this.clone().withMutation(e=>(e.fields={},e.shape(t)))}omit(e){let t=this.clone(),n=t.fields;for(let r of(t.fields={},e))delete n[r];return t.withMutation(()=>t.shape(n))}from(e,t,n){let r=(0,pC.getter)(e,!0);return this.transform(i=>{if(null==i)return i;let a=i;return py()(i,e)&&(a=bh({},i),n||delete a[e],a[t]=r(i)),a})}noUnknown(e=!0,t=pm.noUnknown){"string"==typeof e&&(t=e,e=!0);let n=this.test({name:"noUnknown",exclusive:!0,message:t,test(t){if(null==t)return!0;let n=bb(this.schema,t);return!e||0===n.length||this.createError({params:{unknown:n.join(", ")}})}});return n.spec.noUnknown=e,n}unknown(e=!0,t=pm.noUnknown){return this.noUnknown(!e,t)}transformKeys(e){return this.transform(t=>t&&bs()(t,(t,n)=>e(n)))}camelCase(){return this.transformKeys(ba())}snakeCase(){return this.transformKeys(br())}constantCase(){return this.transformKeys(e=>br()(e).toUpperCase())}describe(){let e=super.describe();return e.fields=pL()(this.fields,e=>e.describe()),e}}function bv(e){return new bg(e)}function by(){return(by=Object.assign||function(e){for(var t=1;t{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null})})}_typeCheck(e){return Array.isArray(e)}get _subType(){return this.innerType}_cast(e,t){let n=super._cast(e,t);if(!this._typeCheck(n)||!this.innerType)return n;let r=!1,i=n.map((e,n)=>{let i=this.innerType.cast(e,by({},t,{path:`${t.path||""}[${n}]`}));return i!==e&&(r=!0),i});return r?i:n}_validate(e,t={},n){var r,i;let a=[],o=t.sync,s=t.path,u=this.innerType,c=null!=(r=t.abortEarly)?r:this.spec.abortEarly,l=null!=(i=t.recursive)?i:this.spec.recursive,f=null!=t.originalValue?t.originalValue:e;super._validate(e,t,(e,r)=>{if(e){if(!pT.isError(e)||c)return void n(e,r);a.push(e)}if(!l||!u||!this._typeCheck(r)){n(a[0]||null,r);return}f=f||r;let i=Array(r.length);for(let d=0;du.validate(h,b,t)}pO({sync:o,path:s,value:r,errors:a,endEarly:c,tests:i},n)})}clone(e){let t=super.clone(e);return t.innerType=this.innerType,t}concat(e){let t=super.concat(e);return t.innerType=this.innerType,e.innerType&&(t.innerType=t.innerType?t.innerType.concat(e.innerType):e.innerType),t}of(e){let t=this.clone();if(!pw(e))throw TypeError("`array.of()` sub-schema must be a valid yup schema not: "+pl(e));return t.innerType=e,t}length(e,t=pg.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pK(t)||t.length===this.resolve(e)}})}min(e,t){return t=t||pg.min,this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t.length>=this.resolve(e)}})}max(e,t){return t=t||pg.max,this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pK(t)||t.length<=this.resolve(e)}})}ensure(){return this.default(()=>[]).transform((e,t)=>this._typeCheck(e)?e:null==t?[]:[].concat(t))}compact(e){let t=e?(t,n,r)=>!e(t,n,r):e=>!!e;return this.transform(e=>null!=e?e.filter(t):e)}describe(){let e=super.describe();return this.innerType&&(e.innerType=this.innerType.describe()),e}nullable(e=!0){return super.nullable(e)}defined(){return super.defined()}required(e){return super.required(e)}}bw.prototype=b_.prototype;var bE=bv().shape({name:p0().required("Required"),url:p0().required("Required")}),bS=function(e){var t=e.initialValues,n=e.onSubmit,r=e.submitButtonText,i=e.nameDisabled,a=void 0!==i&&i;return l.createElement(hT,{initialValues:t,validationSchema:bE,onSubmit:n},function(e){var t=e.isSubmitting;return l.createElement(l.Fragment,null,l.createElement(hR,{"data-testid":"bridge-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hP,{component:hX,id:"name",name:"name",label:"Name",disabled:a,required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hP,{component:hX,id:"url",name:"url",label:"Bridge URL",placeholder:"https://",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"url-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:7},l.createElement(hP,{component:hX,id:"minimumContractPayment",name:"minimumContractPayment",label:"Minimum Contract Payment",placeholder:"0",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"minimumContractPayment-helper-text"}})),l.createElement(d.Z,{item:!0,xs:7},l.createElement(hP,{component:hX,id:"confirmations",name:"confirmations",label:"Confirmations",placeholder:"0",type:"number",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"confirmations-helper-text"}})))),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},r)))))})},bk=function(e){var t=e.bridge,n=e.onSubmit,r={name:t.name,url:t.url,minimumContractPayment:t.minimumContractPayment,confirmations:t.confirmations};return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:40},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Edit Bridge",action:l.createElement(aA.Z,{component:tz,href:"/bridges/".concat(t.id)},"Cancel")}),l.createElement(aW.Z,null,l.createElement(bS,{nameDisabled:!0,initialValues:r,onSubmit:n,submitButtonText:"Save Bridge"}))))))};function bx(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]&&arguments[0],t=e?function(){return l.createElement(x.default,{variant:"body1"},"Loading...")}:function(){return null};return{isLoading:e,LoadingPlaceholder:t}},mc=n(76023);function ml(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function mB(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=4?[e[0],e[1],e[2],e[3],"".concat(e[0],".").concat(e[1]),"".concat(e[0],".").concat(e[2]),"".concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[0]),"".concat(e[1],".").concat(e[2]),"".concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[1]),"".concat(e[2],".").concat(e[3]),"".concat(e[3],".").concat(e[0]),"".concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[0]),"".concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[1],".").concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[2],".").concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[3],".").concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[2],".").concat(e[1],".").concat(e[0])]:void 0}var mZ={};function mX(e){if(0===e.length||1===e.length)return e;var t=e.join(".");return mZ[t]||(mZ[t]=mq(e)),mZ[t]}function mJ(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0;return mX(e.filter(function(e){return"token"!==e})).reduce(function(e,t){return mK({},e,n[t])},t)}function mQ(e){return e.join(" ")}function m1(e,t){var n=0;return function(r){return n+=1,r.map(function(r,i){return m0({node:r,stylesheet:e,useInlineStyles:t,key:"code-segment-".concat(n,"-").concat(i)})})}}function m0(e){var t=e.node,n=e.stylesheet,r=e.style,i=void 0===r?{}:r,a=e.useInlineStyles,o=e.key,s=t.properties,u=t.type,c=t.tagName,f=t.value;if("text"===u)return f;if(c){var d,h=m1(n,a);if(a){var p=Object.keys(n).reduce(function(e,t){return t.split(".").forEach(function(t){e.includes(t)||e.push(t)}),e},[]),b=s.className&&s.className.includes("token")?["token"]:[],m=s.className&&b.concat(s.className.filter(function(e){return!p.includes(e)}));d=mK({},s,{className:mQ(m)||void 0,style:mJ(s.className,Object.assign({},s.style,i),n)})}else d=mK({},s,{className:mQ(s.className)});var g=h(t.children);return l.createElement(c,(0,mV.Z)({key:o},d),g)}}let m2=function(e,t){return -1!==e.listLanguages().indexOf(t)};var m3=/\n/g;function m4(e){return e.match(m3)}function m6(e){var t=e.lines,n=e.startingLineNumber,r=e.style;return t.map(function(e,t){var i=t+n;return l.createElement("span",{key:"line-".concat(t),className:"react-syntax-highlighter-line-number",style:"function"==typeof r?r(i):r},"".concat(i,"\n"))})}function m5(e){var t=e.codeString,n=e.codeStyle,r=e.containerStyle,i=void 0===r?{float:"left",paddingRight:"10px"}:r,a=e.numberStyle,o=void 0===a?{}:a,s=e.startingLineNumber;return l.createElement("code",{style:Object.assign({},n,i)},m6({lines:t.replace(/\n$/,"").split("\n"),style:o,startingLineNumber:s}))}function m8(e){return"".concat(e.toString().length,".25em")}function m9(e,t){return{type:"element",tagName:"span",properties:{key:"line-number--".concat(e),className:["comment","linenumber","react-syntax-highlighter-line-number"],style:t},children:[{type:"text",value:e}]}}function m7(e,t,n){var r,i={display:"inline-block",minWidth:m8(n),paddingRight:"1em",textAlign:"right",userSelect:"none"};return mK({},i,"function"==typeof e?e(t):e)}function ge(e){var t=e.children,n=e.lineNumber,r=e.lineNumberStyle,i=e.largestLineNumber,a=e.showInlineLineNumbers,o=e.lineProps,s=void 0===o?{}:o,u=e.className,c=void 0===u?[]:u,l=e.showLineNumbers,f=e.wrapLongLines,d="function"==typeof s?s(n):s;if(d.className=c,n&&a){var h=m7(r,n,i);t.unshift(m9(n,h))}return f&l&&(d.style=mK({},d.style,{display:"flex"})),{type:"element",tagName:"span",properties:d,children:t}}function gt(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],r=0;r2&&void 0!==arguments[2]?arguments[2]:[];return ge({children:e,lineNumber:t,lineNumberStyle:s,largestLineNumber:o,showInlineLineNumbers:i,lineProps:n,className:a,showLineNumbers:r,wrapLongLines:u})}function b(e,t){if(r&&t&&i){var n=m7(s,t,o);e.unshift(m9(t,n))}return e}function m(e,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];return t||r.length>0?p(e,n,r):b(e,n)}for(var g=function(){var e=l[h],t=e.children[0].value;if(m4(t)){var n=t.split("\n");n.forEach(function(t,i){var o=r&&f.length+a,s={type:"text",value:"".concat(t,"\n")};if(0===i){var u=l.slice(d+1,h).concat(ge({children:[s],className:e.properties.className})),c=m(u,o);f.push(c)}else if(i===n.length-1){if(l[h+1]&&l[h+1].children&&l[h+1].children[0]){var p={type:"text",value:"".concat(t)},b=ge({children:[p],className:e.properties.className});l.splice(h+1,0,b)}else{var g=[s],v=m(g,o,e.properties.className);f.push(v)}}else{var y=[s],w=m(y,o,e.properties.className);f.push(w)}}),d=h}h++};h code[class*="language-"]':{background:"#f5f2f0",padding:".1em",borderRadius:".3em",whiteSpace:"normal"},comment:{color:"slategray"},prolog:{color:"slategray"},doctype:{color:"slategray"},cdata:{color:"slategray"},punctuation:{color:"#999"},namespace:{Opacity:".7"},property:{color:"#905"},tag:{color:"#905"},boolean:{color:"#905"},number:{color:"#905"},constant:{color:"#905"},symbol:{color:"#905"},deleted:{color:"#905"},selector:{color:"#690"},"attr-name":{color:"#690"},string:{color:"#690"},char:{color:"#690"},builtin:{color:"#690"},inserted:{color:"#690"},operator:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},entity:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)",cursor:"help"},url:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".language-css .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".style .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},atrule:{color:"#07a"},"attr-value":{color:"#07a"},keyword:{color:"#07a"},function:{color:"#DD4A68"},"class-name":{color:"#DD4A68"},regex:{color:"#e90"},important:{color:"#e90",fontWeight:"bold"},variable:{color:"#e90"},bold:{fontWeight:"bold"},italic:{fontStyle:"italic"}};var gu=n(98695),gc=n.n(gu);let gl=["abap","abnf","actionscript","ada","agda","al","antlr4","apacheconf","apl","applescript","aql","arduino","arff","asciidoc","asm6502","aspnet","autohotkey","autoit","bash","basic","batch","bbcode","birb","bison","bnf","brainfuck","brightscript","bro","bsl","c","cil","clike","clojure","cmake","coffeescript","concurnas","cpp","crystal","csharp","csp","css-extras","css","cypher","d","dart","dax","dhall","diff","django","dns-zone-file","docker","ebnf","editorconfig","eiffel","ejs","elixir","elm","erb","erlang","etlua","excel-formula","factor","firestore-security-rules","flow","fortran","fsharp","ftl","gcode","gdscript","gedcom","gherkin","git","glsl","gml","go","graphql","groovy","haml","handlebars","haskell","haxe","hcl","hlsl","hpkp","hsts","http","ichigojam","icon","iecst","ignore","inform7","ini","io","j","java","javadoc","javadoclike","javascript","javastacktrace","jolie","jq","js-extras","js-templates","jsdoc","json","json5","jsonp","jsstacktrace","jsx","julia","keyman","kotlin","latex","latte","less","lilypond","liquid","lisp","livescript","llvm","lolcode","lua","makefile","markdown","markup-templating","markup","matlab","mel","mizar","mongodb","monkey","moonscript","n1ql","n4js","nand2tetris-hdl","naniscript","nasm","neon","nginx","nim","nix","nsis","objectivec","ocaml","opencl","oz","parigp","parser","pascal","pascaligo","pcaxis","peoplecode","perl","php-extras","php","phpdoc","plsql","powerquery","powershell","processing","prolog","properties","protobuf","pug","puppet","pure","purebasic","purescript","python","q","qml","qore","r","racket","reason","regex","renpy","rest","rip","roboconf","robotframework","ruby","rust","sas","sass","scala","scheme","scss","shell-session","smali","smalltalk","smarty","sml","solidity","solution-file","soy","sparql","splunk-spl","sqf","sql","stan","stylus","swift","t4-cs","t4-templating","t4-vb","tap","tcl","textile","toml","tsx","tt2","turtle","twig","typescript","typoscript","unrealscript","vala","vbnet","velocity","verilog","vhdl","vim","visual-basic","warpscript","wasm","wiki","xeora","xml-doc","xojo","xquery","yaml","yang","zig"];var gf=go(gc(),gs);gf.supportedLanguages=gl;let gd=gf;var gh=n(64566);function gp(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function gb(){var e=gp(["\n query FetchConfigV2 {\n configv2 {\n user\n effective\n }\n }\n"]);return gb=function(){return e},e}var gm=n0(gb()),gg=function(e){var t=e.children;return l.createElement(ir.Z,null,l.createElement(r7.default,{component:"th",scope:"row",colSpan:3},t))},gv=function(){return l.createElement(gg,null,"...")},gy=function(e){var t=e.children;return l.createElement(gg,null,t)},gw=function(e){var t=e.loading,n=e.toml,r=e.error,i=void 0===r?"":r,a=e.title,o=e.expanded;if(i)return l.createElement(gy,null,i);if(t)return l.createElement(gv,null);a||(a="TOML");var s={display:"block"};return l.createElement(x.default,null,l.createElement(mP.Z,{defaultExpanded:o},l.createElement(mR.Z,{expandIcon:l.createElement(gh.Z,null)},a),l.createElement(mj.Z,{style:s},l.createElement(gd,{language:"toml",style:gs},n))))},g_=function(){var e=rv(gm,{fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return(null==t?void 0:t.configv2.effective)=="N/A"?l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"TOML Configuration"}),l.createElement(gw,{title:"V2 config dump:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0})))):l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"TOML Configuration"}),l.createElement(gw,{title:"User specified:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0,expanded:!0}),l.createElement(gw,{title:"Effective (with defaults):",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.effective,showHead:!0})))))},gE=n(34823),gS=function(e){return(0,b.createStyles)({cell:{paddingTop:1.5*e.spacing.unit,paddingBottom:1.5*e.spacing.unit}})},gk=(0,b.withStyles)(gS)(function(e){var t=e.classes,n=(0,A.I0)();(0,l.useEffect)(function(){n((0,ty.DQ)())});var r=(0,A.v9)(gE.N,A.wU);return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Node"}),l.createElement(r8.Z,null,l.createElement(r9.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,{className:t.cell},l.createElement(x.default,null,"Version"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.version))),l.createElement(ir.Z,null,l.createElement(r7.default,{className:t.cell},l.createElement(x.default,null,"SHA"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.commitSHA))))))}),gx=function(){return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,sm:12,md:8},l.createElement(d.Z,{container:!0},l.createElement(g_,null))),l.createElement(d.Z,{item:!0,sm:12,md:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gk,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mN,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mE,null))))))},gT=function(){return l.createElement(gx,null)},gM=function(){return l.createElement(gT,null)},gO=n(44431),gA=1e18,gL=function(e){return new gO.BigNumber(e).dividedBy(gA).toFixed(8)},gC=function(e){var t=e.keys,n=e.chainID,r=e.hideHeaderTitle;return l.createElement(l.Fragment,null,l.createElement(sl.Z,{title:!r&&"Account Balances",subheader:"Chain ID "+n}),l.createElement(aW.Z,null,l.createElement(w.default,{dense:!1,disablePadding:!0},t&&t.map(function(e,r){return l.createElement(l.Fragment,null,l.createElement(_.default,{disableGutters:!0,key:["acc-balance",n.toString(),r.toString()].join("-")},l.createElement(E.Z,{primary:l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(op,{title:"Address"}),l.createElement(ob,{value:e.address})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(op,{title:"Native Token Balance"}),l.createElement(ob,{value:e.ethBalance||"--"})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(op,{title:"LINK Balance"}),l.createElement(ob,{value:e.linkBalance?gL(e.linkBalance):"--"}))))})),r+1s&&l.createElement(gB.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,{className:r.footer},l.createElement(aA.Z,{href:"/runs",component:tz},"View More"))))))});function vt(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vn(){var e=vt(["\n ","\n query FetchRecentJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...RecentJobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return vn=function(){return e},e}var vr=5,vi=n0(vn(),g9),va=function(){var e=rv(vi,{variables:{offset:0,limit:vr},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(ve,{data:t,errorMsg:null==r?void 0:r.message,loading:n,maxRunsSize:vr})},vo=function(e){return(0,b.createStyles)({style:{textAlign:"center",padding:2.5*e.spacing.unit,position:"fixed",left:"0",bottom:"0",width:"100%",borderRadius:0},bareAnchor:{color:e.palette.common.black,textDecoration:"none"}})},vs=(0,b.withStyles)(vo)(function(e){var t=e.classes,n=(0,A.v9)(gE.N,A.wU),r=(0,A.I0)();return(0,l.useEffect)(function(){r((0,ty.DQ)())}),l.createElement(ii.default,{className:t.style},l.createElement(x.default,null,"Chainlink Node ",n.version," at commit"," ",l.createElement("a",{target:"_blank",rel:"noopener noreferrer",href:"https://github.com/smartcontractkit/chainlink/commit/".concat(n.commitSHA),className:t.bareAnchor},n.commitSHA)))}),vu=function(e){return(0,b.createStyles)({cell:{borderColor:e.palette.divider,borderTop:"1px solid",borderBottom:"none",paddingTop:2*e.spacing.unit,paddingBottom:2*e.spacing.unit,paddingLeft:2*e.spacing.unit},block:{display:"block"},overflowEllipsis:{textOverflow:"ellipsis",overflow:"hidden"}})},vc=(0,b.withStyles)(vu)(function(e){var t=e.classes,n=e.job;return l.createElement(ir.Z,null,l.createElement(r7.default,{scope:"row",className:t.cell},l.createElement(d.Z,{container:!0,spacing:0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(ih,{href:"/jobs/".concat(n.id),classes:{linkContent:t.block}},l.createElement(x.default,{className:t.overflowEllipsis,variant:"body1",component:"span",color:"primary"},n.name||n.id))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,{variant:"body1",color:"textSecondary"},"Created ",l.createElement(aO,{tooltip:!0},n.createdAt))))))});function vl(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vf(){var e=vl(["\n fragment RecentJobsPayload_ResultsFields on Job {\n id\n name\n createdAt\n }\n"]);return vf=function(){return e},e}var vd=n0(vf()),vh=function(){return(0,b.createStyles)({cardHeader:{borderBottom:0},table:{tableLayout:"fixed"}})},vp=(0,b.withStyles)(vh)(function(e){var t,n,r=e.classes,i=e.data,a=e.errorMsg,o=e.loading;return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Recent Jobs",className:r.cardHeader}),l.createElement(r8.Z,{className:r.table},l.createElement(r9.Z,null,l.createElement(g$,{visible:o}),l.createElement(gz,{visible:(null===(t=null==i?void 0:i.jobs.results)||void 0===t?void 0:t.length)===0},"No recently created jobs"),l.createElement(gU,{msg:a}),null===(n=null==i?void 0:i.jobs.results)||void 0===n?void 0:n.map(function(e,t){return l.createElement(vc,{job:e,key:t})}))))});function vb(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vm(){var e=vb(["\n ","\n query FetchRecentJobs($offset: Int, $limit: Int) {\n jobs(offset: $offset, limit: $limit) {\n results {\n ...RecentJobsPayload_ResultsFields\n }\n }\n }\n"]);return vm=function(){return e},e}var vg=5,vv=n0(vm(),vd),vy=function(){var e=rv(vv,{variables:{offset:0,limit:vg},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(vp,{data:t,errorMsg:null==r?void 0:r.message,loading:n})},vw=function(){return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:8},l.createElement(va,null)),l.createElement(d.Z,{item:!0,xs:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gY,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(vy,null))))),l.createElement(vs,null))},v_=function(){return l.createElement(vw,null)},vE=function(){return l.createElement(v_,null)},vS=n(87239),vk=function(e){switch(e){case"DirectRequestSpec":return"Direct Request";case"FluxMonitorSpec":return"Flux Monitor";default:return e.replace(/Spec$/,"")}},vx=n(5022),vT=n(78718),vM=n.n(vT);function vO(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1?t-1:0),r=1;r1?t-1:0),r=1;re.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&n.map(function(e){return l.createElement(ir.Z,{key:e.id,style:{cursor:"pointer"},onClick:function(){return r.push("/runs/".concat(e.id))}},l.createElement(r7.default,{className:t.idCell,scope:"row"},l.createElement("div",{className:t.runDetails},l.createElement(x.default,{variant:"h5",color:"primary",component:"span"},e.id))),l.createElement(r7.default,{className:t.stampCell},l.createElement(x.default,{variant:"body1",color:"textSecondary",className:t.stamp},"Created ",l.createElement(aO,{tooltip:!0},e.createdAt))),l.createElement(r7.default,{className:t.statusCell,scope:"row"},l.createElement(x.default,{variant:"body1",className:O()(t.status,yh(t,e.status))},e.status.toLowerCase())))})))}),yb=n(16839),ym=n.n(yb);function yg(e){var t=e.replace(/\w+\s*=\s*<([^>]|[\r\n])*>/g,""),n=ym().read(t),r=n.edges();return n.nodes().map(function(e){var t={id:e,parentIds:r.filter(function(t){return t.w===e}).map(function(e){return e.v})};return Object.keys(n.node(e)).length>0&&(t.attributes=n.node(e)),t})}var yv=n(94164),yy=function(e){var t=e.data,n=[];return(null==t?void 0:t.attributes)&&Object.keys(t.attributes).forEach(function(e){var r;n.push(l.createElement("div",{key:e},l.createElement(x.default,{variant:"body1",color:"textSecondary",component:"div"},l.createElement("b",null,e,":")," ",null===(r=t.attributes)||void 0===r?void 0:r[e])))}),l.createElement("div",null,t&&l.createElement(x.default,{variant:"body1",color:"textPrimary"},l.createElement("b",null,t.id)),n)},yw=n(73343),y_=n(3379),yE=n.n(y_);function yS(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nwindow.innerWidth?u-r.getBoundingClientRect().width-a:u+a,n=c+r.getBoundingClientRect().height+i>window.innerHeight?c-r.getBoundingClientRect().height-a:c+a,r.style.opacity=String(1),r.style.top="".concat(n,"px"),r.style.left="".concat(t,"px"),r.style.zIndex=String(1)}},h=function(e){var t=document.getElementById("tooltip-d3-chart-".concat(e));t&&(t.style.opacity=String(0),t.style.zIndex=String(-1))};return l.createElement("div",{style:{fontFamily:"sans-serif",fontWeight:"normal"}},l.createElement(yv.kJ,{id:"task-list-graph-d3",data:i,config:s,onMouseOverNode:d,onMouseOutNode:h},"D3 chart"),n.map(function(e){return l.createElement("div",{key:"d3-tooltip-key-".concat(e.id),id:"tooltip-d3-chart-".concat(e.id),style:{position:"absolute",opacity:"0",border:"1px solid rgba(0, 0, 0, 0.1)",padding:yw.r.spacing.unit,background:"white",borderRadius:5,zIndex:-1,inlineSize:"min-content"}},l.createElement(yy,{data:e}))}))};function yL(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nyY&&l.createElement("div",{className:t.runDetails},l.createElement(aA.Z,{href:"/jobs/".concat(n.id,"/runs"),component:tz},"View more")))),l.createElement(d.Z,{item:!0,xs:12,sm:6},l.createElement(yF,{observationSource:n.observationSource})))});function yH(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]?arguments[0]:"";try{return vx.parse(e),!0}catch(t){return!1}})}),wW=function(e){var t=e.initialValues,n=e.onSubmit,r=e.onTOMLChange;return l.createElement(hT,{initialValues:t,validationSchema:wG,onSubmit:n},function(e){var t=e.isSubmitting,n=e.values;return r&&r(n.toml),l.createElement(hR,{"data-testid":"job-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"toml",name:"toml",label:"Job Spec (TOML)",required:!0,fullWidth:!0,multiline:!0,rows:10,rowsMax:25,variant:"outlined",autoComplete:"off",FormHelperTextProps:{"data-testid":"toml-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},"Create Job"))))})},wK=n(50109),wV="persistSpec";function wq(e){var t=e.query,n=new URLSearchParams(t).get("definition");return n?(wK.t8(wV,n),{toml:n}):{toml:wK.U2(wV)||""}}var wZ=function(e){var t=e.onSubmit,n=e.onTOMLChange,r=wq({query:(0,h.TH)().search}),i=function(e){var t=e.replace(/[\u200B-\u200D\uFEFF]/g,"");wK.t8("".concat(wV),t),n&&n(t)};return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"New Job"}),l.createElement(aW.Z,null,l.createElement(wW,{initialValues:r,onSubmit:t,onTOMLChange:i})))};function wX(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n1&&void 0!==arguments[1]?arguments[1]:{},n=t.start,r=void 0===n?6:n,i=t.end,a=void 0===i?4:i;return e.substring(0,r)+"..."+e.substring(e.length-a)}function _M(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(_W,e)},_V=function(){var e=_K({fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error,i=e.refetch;return l.createElement(_U,{loading:n,data:t,errorMsg:null==r?void 0:r.message,refetch:i})},_q=function(e){var t=e.csaKey;return l.createElement(ir.Z,{hover:!0},l.createElement(r7.default,null,l.createElement(x.default,{variant:"body1"},t.publicKey," ",l.createElement(_x,{data:t.publicKey}))))};function _Z(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function _X(){var e=_Z(["\n fragment CSAKeysPayload_ResultsFields on CSAKey {\n id\n publicKey\n }\n"]);return _X=function(){return e},e}var _J=n0(_X()),_Q=function(e){var t,n,r,i=e.data,a=e.errorMsg,o=e.loading,s=e.onCreate;return l.createElement(r5.Z,null,l.createElement(sl.Z,{action:(null===(t=null==i?void 0:i.csaKeys.results)||void 0===t?void 0:t.length)===0&&l.createElement(ok.default,{variant:"outlined",color:"primary",onClick:s},"New CSA Key"),title:"CSA Key",subheader:"Manage your CSA Key"}),l.createElement(r8.Z,null,l.createElement(ie.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,null,"Public Key"))),l.createElement(r9.Z,null,l.createElement(g$,{visible:o}),l.createElement(gz,{visible:(null===(n=null==i?void 0:i.csaKeys.results)||void 0===n?void 0:n.length)===0}),l.createElement(gU,{msg:a}),null===(r=null==i?void 0:i.csaKeys.results)||void 0===r?void 0:r.map(function(e,t){return l.createElement(_q,{csaKey:e,key:t})}))))};function _1(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(EM,e)};function EA(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(EJ,e)},E3=function(){return oo(EQ)},E4=function(){return oo(E1)},E6=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return rv(E0,e)};function E5(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(SK,e)};function Sq(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function kV(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}var kq=function(e){var t=e.run,n=l.useMemo(function(){var e=t.inputs,n=t.outputs,r=t.taskRuns,i=kK(t,["inputs","outputs","taskRuns"]),a={};try{a=JSON.parse(e)}catch(o){a={}}return kW(kz({},i),{inputs:a,outputs:n,taskRuns:r})},[t]);return l.createElement(r5.Z,null,l.createElement(aW.Z,null,l.createElement(kH,{object:n})))};function kZ(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function kX(e){for(var t=1;t0&&l.createElement(kr,{errors:t.allErrors})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(h.rs,null,l.createElement(h.AW,{path:"".concat(n,"/json")},l.createElement(kq,{run:t})),l.createElement(h.AW,{path:n},t.taskRuns.length>0&&l.createElement(kN,{taskRuns:t.taskRuns,observationSource:t.job.observationSource}))))))))};function k5(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function k8(){var e=k5(["\n ","\n query FetchJobRun($id: ID!) {\n jobRun(id: $id) {\n __typename\n ... on JobRun {\n ...JobRunPayload_Fields\n }\n ... on NotFoundError {\n message\n }\n }\n }\n"]);return k8=function(){return e},e}var k9=n0(k8(),k4),k7=function(){var e=rv(k9,{variables:{id:(0,h.UO)().id}}),t=e.data,n=e.loading,r=e.error;if(n)return l.createElement(iR,null);if(r)return l.createElement(iD,{error:r});var i=null==t?void 0:t.jobRun;switch(null==i?void 0:i.__typename){case"JobRun":return l.createElement(k6,{run:i});case"NotFoundError":return l.createElement(oa,null);default:return null}};function xe(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xt(){var e=xe(["\n fragment JobRunsPayload_ResultsFields on JobRun {\n id\n allErrors\n createdAt\n finishedAt\n status\n job {\n id\n }\n }\n"]);return xt=function(){return e},e}var xn=n0(xt()),xr=function(e){var t=e.loading,n=e.data,r=e.page,i=e.pageSize,a=(0,h.k6)(),o=l.useMemo(function(){return null==n?void 0:n.jobRuns.results.map(function(e){var t,n=e.allErrors,r=e.id,i=e.createdAt;return{id:r,createdAt:i,errors:n,finishedAt:e.finishedAt,status:e.status}})},[n]);return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(iy,null,"Job Runs")),t&&l.createElement(iR,null),n&&o&&l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(yp,{runs:o}),l.createElement(it.Z,{component:"div",count:n.jobRuns.metadata.total,rowsPerPage:i,rowsPerPageOptions:[i],page:r-1,onChangePage:function(e,t){a.push("/runs?page=".concat(t+1,"&per=").concat(i))},onChangeRowsPerPage:function(){},backIconButtonProps:{"aria-label":"prev-page"},nextIconButtonProps:{"aria-label":"next-page"}})))))};function xi(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xa(){var e=xi(["\n ","\n query FetchJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...JobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return xa=function(){return e},e}var xo=n0(xa(),xn),xs=function(){var e=ij(),t=parseInt(e.get("page")||"1",10),n=parseInt(e.get("per")||"25",10),r=rv(xo,{variables:{offset:(t-1)*n,limit:n},fetchPolicy:"cache-and-network"}),i=r.data,a=r.loading,o=r.error;return o?l.createElement(iD,{error:o}):l.createElement(xr,{loading:a,data:i,page:t,pageSize:n})},xu=function(){var e=(0,h.$B)().path;return l.createElement(h.rs,null,l.createElement(h.AW,{exact:!0,path:e},l.createElement(xs,null)),l.createElement(h.AW,{path:"".concat(e,"/:id")},l.createElement(k7,null)))};function xc(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xl(){var e=xc(["\n fragment FetchFeedsManagersPayload_ResultsFields on FeedsManager {\n __typename\n id\n name\n uri\n publicKey\n isConnectionActive\n createdAt\n disabledAt\n }\n query FetchFeedsManagers {\n feedsManagers {\n results {\n ...FetchFeedsManagersPayload_ResultsFields\n }\n }\n }\n"]);return xl=function(){return e},e}var xf=n0(xl()),xd=function(e){return rv(xf,e)},xh=n(47559),xp=n(83165),xb=n(47298),xm=n(81395),xg=function(){return(0,b.createStyles)({root:{display:"flex"},activeIcon:{color:xh.default[500]},inactiveIcon:{color:xp.default[500]},text:{marginLeft:4}})},xv=(0,b.withStyles)(xg)(function(e){var t=e.isActive,n=e.activeText,r=e.inactiveText,i=e.classes;return l.createElement("div",{className:i.root},t?l.createElement(xm.Z,{fontSize:"small",className:i.activeIcon}):l.createElement(xb.Z,{fontSize:"small",className:i.inactiveIcon}),l.createElement(x.default,{variant:"body1",inline:!0,className:i.text},t?n:r))}),xy=(0,b.withStyles)(iu)(function(e){var t=e.jobDistributor,n=e.classes;return l.createElement(ir.Z,{className:n.row,hover:!0},l.createElement(r7.default,{className:n.cell,component:"th",scope:"row"},l.createElement(ih,{className:n.link,href:"/job_distributors/".concat(t.id)},t.name)),l.createElement(r7.default,null,l.createElement(xv,{isActive:t.isConnectionActive,activeText:"Connected",inactiveText:"Disconnected"})),l.createElement(r7.default,null,l.createElement(xv,{isActive:!t.disabledAt,activeText:"Enabled",inactiveText:"Disabled"})),l.createElement(r7.default,null,_T(t.publicKey,{start:6,end:6}),l.createElement(_x,{data:t.publicKey})),l.createElement(r7.default,null,t.uri))}),xw=function(e){var t=e.jobDistributors;return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:9},l.createElement(iy,null,"Job Distributors")),l.createElement(d.Z,{item:!0,xs:3},l.createElement(d.Z,{container:!0,justify:"flex-end"},l.createElement(d.Z,{item:!0},l.createElement(aA.Z,{variant:"secondary",component:tz,href:"/job_distributors/new"},"New Job Distributor")))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(r8.Z,null,l.createElement(ie.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,null,"Name"),l.createElement(r7.default,null,"Connection Status"),l.createElement(r7.default,null,"Status"),l.createElement(r7.default,null,"CSA Public Key"),l.createElement(r7.default,null,"RPC URL"))),l.createElement(r9.Z,null,0===t.length&&l.createElement(ir.Z,null,l.createElement(r7.default,{component:"th",scope:"row",colSpan:3},"Job Distributors have not been registered")),t.map(function(e){return l.createElement(xy,{key:e.id,jobDistributor:e})})))))))},x_=function(){var e,t=xd({fetchPolicy:"cache-and-network"}),n=t.data,r=t.loading,i=t.error;return r?l.createElement(iR,null):i?l.createElement(iD,{error:i}):l.createElement(xw,{jobDistributors:null!==(e=null==n?void 0:n.feedsManagers.results)&&void 0!==e?e:[]})},xE=bv().shape({name:p0().required("Required"),uri:p0().required("Required"),publicKey:p0().required("Required")}),xS=function(e){var t=e.initialValues,n=e.onSubmit;return l.createElement(hT,{initialValues:t,validationSchema:xE,onSubmit:n},function(e){var t=e.isSubmitting,n=e.submitForm;return l.createElement(hR,{"data-testid":"feeds-manager-form"},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"name",name:"name",label:"Name",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:!1,md:6}),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"uri",name:"uri",label:"URI",required:!0,fullWidth:!0,helperText:"Provided by the Job Distributor operator",FormHelperTextProps:{"data-testid":"uri-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"publicKey",name:"publicKey",label:"Public Key",required:!0,fullWidth:!0,helperText:"Provided by the Job Distributor operator",FormHelperTextProps:{"data-testid":"publicKey-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(ok.default,{variant:"contained",color:"primary",disabled:t,onClick:n},"Submit"))))})},xk=function(e){var t=e.data,n=e.onSubmit,r={name:t.name,uri:t.uri,publicKey:t.publicKey};return l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Edit Job Distributor"}),l.createElement(aW.Z,null,l.createElement(xS,{initialValues:r,onSubmit:n})))))};function xx(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(xZ,e)},xJ=function(){return(0,b.createStyles)({root:{fontSize:24}})},xQ=(0,b.withStyles)(xJ)(function(e){var t=e.children,n=e.classes;return l.createElement(x.default,{variant:"h2",className:n.root},t)}),x1=n(9290),x0=n(74923);function x2(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function TT(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}function TM(e,t){return Tv(e)||TE(e,t)||TA(e,t)||TS()}function TO(e){return Ty(e)||T_(e)||TA(e)||Tk()}function TA(e,t){if(e){if("string"==typeof e)return Tg(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return Tg(e,t)}}var TL=function(e){return"SN_MAIN"===e||"SN_SEPOLIA"===e},TC=bv().shape({chainID:p0().required("Required"),chainType:p0().required("Required"),accountAddr:p0().required("Required"),accountAddrPubKey:p0().nullable(),adminAddr:p0(),ocr1Multiaddr:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&t},then:p0().required("Required").nullable()}).nullable(),ocr1P2PPeerID:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr1KeyBundleID:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2Multiaddr:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&t},then:p0().required("Required").nullable()}).nullable(),ocr2P2PPeerID:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2KeyBundleID:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2CommitPluginEnabled:pV().required("Required"),ocr2ExecutePluginEnabled:pV().required("Required"),ocr2MedianPluginEnabled:pV().required("Required"),ocr2MercuryPluginEnabled:pV().required("Required"),ocr2ForwarderAddress:p0().nullable()}),TI=function(e){return(0,b.createStyles)({supportedJobOptionsPaper:{padding:2*e.spacing.unit}})},TD=function(e){var t=e.addresses,n=Tx(e,["addresses"]),r=h_(),i=r.values,a=i.chainID,o=i.accountAddr,s=r.setFieldValue,u=TM(l.useState(!1),2),c=u[0],f=u[1],d=l.useRef();l.useEffect(function(){d.current=a},[a]),l.useEffect(function(){a!==d.current&&(s(n.name,""),f(!1))},[a,s,n.name]);var h=function(e){var t=e.target.value;"custom"===t?(f(!0),s(n.name,"")):(f(!1),s(n.name,t))};return l.createElement(l.Fragment,null,!TL(a)&&l.createElement(hP,Tw({},n,{select:!0,value:c?"custom":o,onChange:h}),t.map(function(e){return l.createElement(tE.default,{key:e,value:e},e)})),TL(a)&&l.createElement(hP,{component:hX,id:"accountAddr",name:"accountAddr",label:"Enter your account address",inputProps:{"data-testid":"customAccountAddr-input"},helperText:"The account address used for this chain",required:!0,fullWidth:!0}),TL(a)&&l.createElement("div",null,l.createElement(hP,{component:hX,id:"accountAddrPubKey",name:"accountAddrPubKey",label:"Account Address Public Key",required:!0,fullWidth:!0,helperText:"The public key for your account address",FormHelperTextProps:{"data-testid":"accountAddrPubKey-helper-text"}})))},TN=(0,b.withStyles)(TI)(function(e){var t=e.classes,n=e.editing,r=void 0!==n&&n,i=e.innerRef,a=e.initialValues,o=e.onSubmit,s=e.chains,u=void 0===s?[]:s,c=e.accountsEVM,f=void 0===c?[]:c,h=e.accountsNonEvm,p=e.p2pKeys,b=void 0===p?[]:p,m=e.ocrKeys,g=void 0===m?[]:m,v=e.ocr2Keys,y=void 0===v?[]:v,w=e.showSubmit,_=void 0!==w&&w,E=TO(y).sort(function(e,t){var n,r,i;return e.chainType===t.chainType?e.id.localeCompare(t.id):null!==(i=null===(n=e.chainType)||void 0===n?void 0:n.localeCompare(null!==(r=t.chainType)&&void 0!==r?r:""))&&void 0!==i?i:0});return l.createElement(hT,{innerRef:i,initialValues:a,validationSchema:TC,onSubmit:o},function(e){var n,i,a=e.values,o=[];switch(a.chainType){case Tm.EVM:o=f.filter(function(e){return e.chain.id==a.chainID&&!e.isDisabled}).map(function(e){return e.address});break;case Tm.APTOS:o=null!==(n=null==h?void 0:h.aptosKeys.results.map(function(e){return e.account}))&&void 0!==n?n:[];break;case Tm.SOLANA:o=null!==(i=null==h?void 0:h.solanaKeys.results.map(function(e){return e.id}))&&void 0!==i?i:[];break;default:o=[]}var s=u.filter(function(e){return e.network.toUpperCase()===a.chainType});return l.createElement(hR,{"data-testid":"feeds-manager-form",id:"chain-configuration-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"chainType",name:"chainType",label:"Chain Type",select:!0,required:!0,fullWidth:!0,disabled:r},l.createElement(tE.default,{key:Tm.EVM,value:Tm.EVM},"EVM"),l.createElement(tE.default,{key:Tm.APTOS,value:Tm.APTOS},"APTOS"),l.createElement(tE.default,{key:Tm.SOLANA,value:Tm.SOLANA},"SOLANA"))),l.createElement(d.Z,{item:!0,xs:12,md:6},s.length>0&&!r?l.createElement(hP,{component:hX,id:"chainID",name:"chainID",label:"Chain ID",required:!0,fullWidth:!0,select:!0,disabled:r,inputProps:{"data-testid":"chainID-input"},FormHelperTextProps:{"data-testid":"chainID-helper-text"}},s.map(function(e){return l.createElement(tE.default,{key:e.id,value:e.id},e.id)})):l.createElement(hP,{component:hX,id:"chainID",name:"chainID",label:"Chain ID",required:!0,fullWidth:!0,disabled:r,inputProps:{"data-testid":"chainID-manual-input"},FormHelperTextProps:{"data-testid":"chainID-helper-manual-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},o.length>0?l.createElement(TD,{component:hX,id:"accountAddr",name:"accountAddr",label:"Account Address",inputProps:{"data-testid":"accountAddr-input"},required:!0,fullWidth:!0,select:!0,helperText:"The account address used for this chain",addresses:o,FormHelperTextProps:{"data-testid":"accountAddr-helper-text"}}):l.createElement(hP,{component:hX,id:"accountAddr",name:"accountAddr",label:"Account Address",inputProps:{"data-testid":"accountAddr-manual-input"},required:!0,fullWidth:!0,helperText:"The account address used for this chain",FormHelperTextProps:{"data-testid":"accountAddr-helper-manual-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"adminAddr",name:"adminAddr",label:"Admin Address",fullWidth:!0,helperText:"The address used for LINK payments",FormHelperTextProps:{"data-testid":"adminAddr-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,null,"Supported Job Types")),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"fluxMonitorEnabled",type:"checkbox",Label:{label:"Flux Monitor"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr1Enabled",type:"checkbox",Label:{label:"OCR"}}),a.ocr1Enabled&&l.createElement(ii.default,{className:t.supportedJobOptionsPaper},l.createElement(d.Z,{container:!0,spacing:8},l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr1IsBootstrap",type:"checkbox",Label:{label:"Is this node running as a bootstrap peer?"}})),a.ocr1IsBootstrap?l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"ocr1Multiaddr",name:"ocr1Multiaddr",label:"Multiaddr",required:!0,fullWidth:!0,helperText:"The OCR Multiaddr which oracles use to query for network information",FormHelperTextProps:{"data-testid":"ocr1Multiaddr-helper-text"}})):l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr1P2PPeerID",name:"ocr1P2PPeerID",label:"Peer ID",select:!0,required:!0,fullWidth:!0,helperText:"The Peer ID used for this chain",FormHelperTextProps:{"data-testid":"ocr1P2PPeerID-helper-text"}},b.map(function(e){return l.createElement(tE.default,{key:e.peerID,value:e.peerID},e.peerID)}))),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr1KeyBundleID",name:"ocr1KeyBundleID",label:"Key Bundle ID",select:!0,required:!0,fullWidth:!0,helperText:"The OCR Key Bundle ID used for this chain",FormHelperTextProps:{"data-testid":"ocr1KeyBundleID-helper-text"}},g.map(function(e){return l.createElement(tE.default,{key:e.id,value:e.id},e.id)})))))))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr2Enabled",type:"checkbox",Label:{label:"OCR2"}}),a.ocr2Enabled&&l.createElement(ii.default,{className:t.supportedJobOptionsPaper},l.createElement(d.Z,{container:!0,spacing:8},l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr2IsBootstrap",type:"checkbox",Label:{label:"Is this node running as a bootstrap peer?"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr2P2PPeerID",name:"ocr2P2PPeerID",label:"Peer ID",select:!0,required:!a.ocr2IsBootstrap,fullWidth:!0,helperText:"The Peer ID used for this chain",FormHelperTextProps:{"data-testid":"ocr2P2PPeerID-helper-text"}},b.map(function(e){return l.createElement(tE.default,{key:e.peerID,value:e.peerID},e.peerID)}))),a.ocr2IsBootstrap?l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"ocr2Multiaddr",name:"ocr2Multiaddr",label:"Multiaddr",required:!0,fullWidth:!0,helperText:"The OCR2 Multiaddr which oracles use to query for network information",FormHelperTextProps:{"data-testid":"ocr2Multiaddr-helper-text"}})):l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr2KeyBundleID",name:"ocr2KeyBundleID",label:"Key Bundle ID",select:!0,required:!0,fullWidth:!0,helperText:"The OCR2 Key Bundle ID used for this chain",FormHelperTextProps:{"data-testid":"ocr2KeyBundleID-helper-text"}},E.map(function(e){return l.createElement(tE.default,{key:e.id,value:e.id},e.id," (",e.chainType,")")}))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,null,"Supported Plugins")),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2CommitPluginEnabled",type:"checkbox",Label:{label:"Commit"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2ExecutePluginEnabled",type:"checkbox",Label:{label:"Execute"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2RebalancerPluginEnabled",type:"checkbox",Label:{label:"Rebalancer"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2MedianPluginEnabled",type:"checkbox",Label:{label:"Median"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2MercuryPluginEnabled",type:"checkbox",Label:{label:"Mercury"}})),l.createElement(d.Z,{item:!0,xs:12,md:12},l.createElement(hP,{component:hX,id:"ocr2ForwarderAddress",name:"ocr2ForwarderAddress",label:"Forwarder Address (optional)",fullWidth:!0,helperText:"The forwarder address from the Operator Forwarder Contract",FormHelperTextProps:{"data-testid":"ocr2ForwarderAddress-helper-text"}}))))))),_&&l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",size:"large"},"Submit"))))})});function TP(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function TR(){var e=TP(["\n fragment AptosKeysPayload_ResultsFields on AptosKey {\n account\n id\n }\n"]);return TR=function(){return e},e}function Tj(){var e=TP(["\n fragment SolanaKeysPayload_ResultsFields on SolanaKey {\n id\n }\n"]);return Tj=function(){return e},e}function TF(){var e=TP(["\n ","\n ","\n query FetchNonEvmKeys {\n aptosKeys {\n results {\n ...AptosKeysPayload_ResultsFields\n }\n }\n solanaKeys {\n results {\n ...SolanaKeysPayload_ResultsFields\n }\n }\n }\n"]);return TF=function(){return e},e}var TY=n0(TR()),TB=n0(Tj()),TU=n0(TF(),TY,TB),TH=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return rv(TU,e)},T$=function(e){var t=e.onClose,n=e.open,r=e.onSubmit,i=l.useRef(),a=i$({fetchPolicy:"network-only"}).data,o=_K({fetchPolicy:"cache-and-network"}).data,s=TH({fetchPolicy:"cache-and-network"}).data,u=SV({fetchPolicy:"cache-and-network"}).data,c=EO({fetchPolicy:"cache-and-network"}).data,f=E2({fetchPolicy:"cache-and-network"}).data,d={chainID:"",chainType:Tm.EVM,accountAddr:"",adminAddr:"",accountAddrPubKey:"",fluxMonitorEnabled:!1,ocr1Enabled:!1,ocr1IsBootstrap:!1,ocr1Multiaddr:"",ocr1P2PPeerID:"",ocr1KeyBundleID:"",ocr2Enabled:!1,ocr2IsBootstrap:!1,ocr2Multiaddr:"",ocr2P2PPeerID:"",ocr2KeyBundleID:"",ocr2CommitPluginEnabled:!1,ocr2ExecutePluginEnabled:!1,ocr2MedianPluginEnabled:!1,ocr2MercuryPluginEnabled:!1,ocr2RebalancerPluginEnabled:!1,ocr2ForwarderAddress:""},h=a?a.chains.results:[],p=o?o.ethKeys.results:[],b=u?u.p2pKeys.results:[],m=c?c.ocrKeyBundles.results:[],g=f?f.ocr2KeyBundles.results:[];return l.createElement(aD.Z,{onClose:t,open:n,disableBackdropClick:!0},l.createElement(oO.Z,{disableTypography:!0},l.createElement(x.default,{variant:"body2"},"New Supported Chain")),l.createElement(oT.Z,null,l.createElement(TN,{innerRef:i,initialValues:d,onSubmit:r,chains:h,accountsEVM:p,accountsNonEvm:s,p2pKeys:b,ocrKeys:m,ocr2Keys:g})),l.createElement(ox.Z,null,l.createElement(ok.default,{onClick:t},"Cancel"),l.createElement(ok.default,{color:"primary",type:"submit",form:"chain-configuration-form",variant:"contained"},"Submit")))},Tz=function(e){var t=e.cfg,n=e.onClose,r=e.open,i=e.onSubmit,a=l.useRef(),o=i$({fetchPolicy:"network-only"}).data,s=_K({fetchPolicy:"cache-and-network"}).data,u=TH({fetchPolicy:"cache-and-network"}).data,c=SV({fetchPolicy:"cache-and-network"}).data,f=EO({fetchPolicy:"cache-and-network"}).data,d=E2({fetchPolicy:"cache-and-network"}).data;if(!t)return null;var h={chainID:t.chainID,chainType:t.chainType,accountAddr:t.accountAddr,adminAddr:t.adminAddr,accountAddrPubKey:t.accountAddrPubKey,fluxMonitorEnabled:t.fluxMonitorJobConfig.enabled,ocr1Enabled:t.ocr1JobConfig.enabled,ocr1IsBootstrap:t.ocr1JobConfig.isBootstrap,ocr1Multiaddr:t.ocr1JobConfig.multiaddr,ocr1P2PPeerID:t.ocr1JobConfig.p2pPeerID,ocr1KeyBundleID:t.ocr1JobConfig.keyBundleID,ocr2Enabled:t.ocr2JobConfig.enabled,ocr2IsBootstrap:t.ocr2JobConfig.isBootstrap,ocr2Multiaddr:t.ocr2JobConfig.multiaddr,ocr2P2PPeerID:t.ocr2JobConfig.p2pPeerID,ocr2KeyBundleID:t.ocr2JobConfig.keyBundleID,ocr2CommitPluginEnabled:t.ocr2JobConfig.plugins.commit,ocr2ExecutePluginEnabled:t.ocr2JobConfig.plugins.execute,ocr2MedianPluginEnabled:t.ocr2JobConfig.plugins.median,ocr2MercuryPluginEnabled:t.ocr2JobConfig.plugins.mercury,ocr2RebalancerPluginEnabled:t.ocr2JobConfig.plugins.rebalancer,ocr2ForwarderAddress:t.ocr2JobConfig.forwarderAddress},p=o?o.chains.results:[],b=s?s.ethKeys.results:[],m=c?c.p2pKeys.results:[],g=f?f.ocrKeyBundles.results:[],v=d?d.ocr2KeyBundles.results:[];return l.createElement(aD.Z,{onClose:n,open:r,disableBackdropClick:!0},l.createElement(oO.Z,{disableTypography:!0},l.createElement(x.default,{variant:"body2"},"Edit Supported Chain")),l.createElement(oT.Z,null,l.createElement(TN,{innerRef:a,initialValues:h,onSubmit:i,chains:p,accountsEVM:b,accountsNonEvm:u,p2pKeys:m,ocrKeys:g,ocr2Keys:v,editing:!0})),l.createElement(ox.Z,null,l.createElement(ok.default,{onClick:n},"Cancel"),l.createElement(ok.default,{color:"primary",type:"submit",form:"chain-configuration-form",variant:"contained"},"Submit")))};function TG(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);nt.version?e:t})},[o]),g=l.useMemo(function(){return M1(o).sort(function(e,t){return t.version-e.version})},[o]),v=function(e,t,n){switch(e){case"PENDING":return l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"text",color:"secondary",onClick:function(){return b("reject",t)}},"Reject"),m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status&&l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve"),m.id===t&&"DELETED"===n.status&&n.pendingUpdate&&l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("cancel",t)}},"Cancel"),l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs")));case"APPROVED":return l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"contained",onClick:function(){return b("cancel",t)}},"Cancel"),"DELETED"===n.status&&n.pendingUpdate&&l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs"));case"CANCELLED":if(m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status)return l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve");return null;default:return null}};return l.createElement("div",null,g.map(function(e,n){return l.createElement(mP.Z,{defaultExpanded:0===n,key:n},l.createElement(mR.Z,{expandIcon:l.createElement(gh.Z,null)},l.createElement(x.default,{className:t.versionText},"Version ",e.version),l.createElement(Es.Z,{label:e.status,color:"APPROVED"===e.status?"primary":"default",variant:"REJECTED"===e.status||"CANCELLED"===e.status?"outlined":"default"}),l.createElement("div",{className:t.proposedAtContainer},l.createElement(x.default,null,"Proposed ",l.createElement(aO,{tooltip:!0},e.createdAt)))),l.createElement(mj.Z,{className:t.expansionPanelDetails},l.createElement("div",{className:t.actions},l.createElement("div",{className:t.editContainer},0===n&&("PENDING"===e.status||"CANCELLED"===e.status)&&"DELETED"!==s.status&&"REVOKED"!==s.status&&l.createElement(ok.default,{variant:"contained",onClick:function(){return p(!0)}},"Edit")),l.createElement("div",{className:t.actionsContainer},v(e.status,e.id,s))),l.createElement(gd,{language:"toml",style:gs,"data-testid":"codeblock"},e.definition)))}),l.createElement(oC,{open:null!=c,title:c?M6[c.action].title:"",body:c?M6[c.action].body:"",onConfirm:function(){if(c){switch(c.action){case"approve":n(c.id);break;case"cancel":r(c.id);break;case"reject":i(c.id)}f(null)}},cancelButtonText:"Cancel",onCancel:function(){return f(null)}}),l.createElement(Mz,{open:h,onClose:function(){return p(!1)},initialValues:{definition:m.definition,id:m.id},onSubmit:a}))});function M8(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function M9(){var e=M8(["\n ","\n fragment JobProposalPayloadFields on JobProposal {\n id\n externalJobID\n remoteUUID\n jobID\n specs {\n ...JobProposal_SpecsFields\n }\n status\n pendingUpdate\n }\n"]);return M9=function(){return e},e}var M7=n0(M9(),M3),Oe=function(e){var t=e.onApprove,n=e.onCancel,r=e.onReject,i=e.onUpdateSpec,a=e.proposal;return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(iy,null,"Job Proposal #",a.id))),l.createElement(MF,{proposal:a}),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(xQ,null,"Specs"))),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(M5,{proposal:a,specs:a.specs,onReject:r,onApprove:t,onCancel:n,onUpdateSpec:i}))))};function Ot(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);nU,tA:()=>$,KL:()=>H,Iw:()=>V,DQ:()=>W,cB:()=>T,LO:()=>M,t5:()=>k,qt:()=>x,Jc:()=>C,L7:()=>Y,EO:()=>B});var r,i,a=n(66289),o=n(41800),s=n.n(o),u=n(67932);(i=r||(r={})).IN_PROGRESS="in_progress",i.PENDING_INCOMING_CONFIRMATIONS="pending_incoming_confirmations",i.PENDING_CONNECTION="pending_connection",i.PENDING_BRIDGE="pending_bridge",i.PENDING_SLEEP="pending_sleep",i.ERRORED="errored",i.COMPLETED="completed";var c=n(87013),l=n(19084),f=n(34823);function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]j,v2:()=>F});var r=n(66289);function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var a="/sessions",o="/sessions",s=function e(t){var n=this;i(this,e),this.api=t,this.createSession=function(e){return n.create(e)},this.destroySession=function(){return n.destroy()},this.create=this.api.createResource(a),this.destroy=this.api.deleteResource(o)};function u(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var c="/v2/bulk_delete_runs",l=function e(t){var n=this;u(this,e),this.api=t,this.bulkDeleteJobRuns=function(e){return n.destroy(e)},this.destroy=this.api.deleteResource(c)};function f(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var d="/v2/chains/evm",h="".concat(d,"/:id"),p=function e(t){var n=this;f(this,e),this.api=t,this.getChains=function(){return n.index()},this.createChain=function(e){return n.create(e)},this.destroyChain=function(e){return n.destroy(void 0,{id:e})},this.updateChain=function(e,t){return n.update(t,{id:e})},this.index=this.api.fetchResource(d),this.create=this.api.createResource(d),this.destroy=this.api.deleteResource(h),this.update=this.api.updateResource(h)};function b(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var m="/v2/keys/evm/chain",g=function e(t){var n=this;b(this,e),this.api=t,this.chain=function(e){var t=new URLSearchParams;t.append("address",e.address),t.append("evmChainID",e.evmChainID),null!==e.abandon&&t.append("abandon",String(e.abandon)),null!==e.enabled&&t.append("enabled",String(e.enabled));var r=m+"?"+t.toString();return n.api.createResource(r)()}};function v(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var y="/v2/jobs",w="".concat(y,"/:specId/runs"),_=function e(t){var n=this;v(this,e),this.api=t,this.createJobRunV2=function(e,t){return n.post(t,{specId:e})},this.post=this.api.createResource(w,!0)};function E(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var S="/v2/log",k=function e(t){var n=this;E(this,e),this.api=t,this.getLogConfig=function(){return n.show()},this.updateLogConfig=function(e){return n.update(e)},this.show=this.api.fetchResource(S),this.update=this.api.updateResource(S)};function x(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var T="/v2/nodes",M=function e(t){var n=this;x(this,e),this.api=t,this.getNodes=function(){return n.index()},this.createNode=function(e){return n.create(e)},this.index=this.api.fetchResource(T),this.create=this.api.createResource(T)};function O(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var A="/v2/enroll_webauthn",L=function e(t){var n=this;O(this,e),this.api=t,this.beginKeyRegistration=function(e){return n.create(e)},this.finishKeyRegistration=function(e){return n.put(e)},this.create=this.api.fetchResource(A),this.put=this.api.createResource(A)};function C(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var I="/v2/build_info",D=function e(t){var n=this;C(this,e),this.api=t,this.show=function(){return n.api.GET(I)()}};function N(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var P=function e(t){N(this,e),this.api=t,this.buildInfo=new D(this.api),this.bulkDeleteRuns=new l(this.api),this.chains=new p(this.api),this.logConfig=new k(this.api),this.nodes=new M(this.api),this.jobs=new _(this.api),this.webauthn=new L(this.api),this.evmKeys=new g(this.api)},R=new r.V0({base:void 0}),j=new s(R),F=new P(R)},1398(e,t,n){"use strict";n.d(t,{Z:()=>d});var r=n(67294),i=n(32316),a=n(83638),o=n(94184),s=n.n(o);function u(){return(u=Object.assign||function(e){for(var t=1;tc});var r=n(67294),i=n(32316);function a(){return(a=Object.assign||function(e){for(var t=1;tx,jK:()=>v});var r=n(67294),i=n(37703),a=n(45697),o=n.n(a),s=n(82204),u=n(71426),c=n(94184),l=n.n(c),f=n(32316),d=function(e){var t=e.palette.success||{},n=e.palette.warning||{};return{base:{paddingLeft:5*e.spacing.unit,paddingRight:5*e.spacing.unit},success:{backgroundColor:t.main,color:t.contrastText},error:{backgroundColor:e.palette.error.dark,color:e.palette.error.contrastText},warning:{backgroundColor:n.contrastText,color:n.main}}},h=function(e){var t,n=e.success,r=e.error,i=e.warning,a=e.classes,o=e.className;return n?t=a.success:r?t=a.error:i&&(t=a.warning),l()(a.base,o,t)},p=function(e){return r.createElement(s.Z,{className:h(e),square:!0},r.createElement(u.default,{variant:"body2",color:"inherit",component:"div"},e.children))};p.defaultProps={success:!1,error:!1,warning:!1},p.propTypes={success:o().bool,error:o().bool,warning:o().bool};let b=(0,f.withStyles)(d)(p);var m=function(){return r.createElement(r.Fragment,null,"Unhandled error. Please help us by opening a"," ",r.createElement("a",{href:"https://github.com/smartcontractkit/chainlink/issues/new"},"bug report"))};let g=m;function v(e){return"string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null)}function y(e,t){var n;return n="string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null),r.createElement("p",{key:t},n)}var w=function(e){var t=e.notifications;return r.createElement(b,{error:!0},t.map(y))},_=function(e){var t=e.notifications;return r.createElement(b,{success:!0},t.map(y))},E=function(e){var t=e.errors,n=e.successes;return r.createElement("div",null,(null==t?void 0:t.length)>0&&r.createElement(w,{notifications:t}),n.length>0&&r.createElement(_,{notifications:n}))},S=function(e){return{errors:e.notifications.errors,successes:e.notifications.successes}},k=(0,i.$j)(S)(E);let x=k},9409(e,t,n){"use strict";n.d(t,{ZP:()=>j});var r=n(67294),i=n(37703),a=n(5977),o=n(32316),s=n(1398),u=n(82204),c=n(30060),l=n(71426),f=n(60520),d=n(39814),h=n(57209),p=n(26842),b=n(3950),m=n(5536),g=n(45697),v=n.n(g);let y=n.p+"9f6d832ef97e8493764e.svg";function w(){return(w=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&_.map(function(e,t){return r.createElement(d.Z,{item:!0,xs:12,key:t},r.createElement(u.Z,{raised:!1,className:v.error},r.createElement(c.Z,null,r.createElement(l.default,{variant:"body1",className:v.errorText},(0,b.jK)(e)))))}),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"email",label:"Email",margin:"normal",value:n,onChange:m("email"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"password",label:"Password",type:"password",autoComplete:"password",margin:"normal",value:h,onChange:m("password"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(d.Z,{container:!0,spacing:0,justify:"center"},r.createElement(d.Z,{item:!0},r.createElement(s.Z,{type:"submit",variant:"primary"},"Access Account")))),y&&r.createElement(l.default,{variant:"body1",color:"textSecondary"},"Signing in...")))))))},P=function(e){return{fetching:e.authentication.fetching,authenticated:e.authentication.allowed,errors:e.notifications.errors}},R=(0,i.$j)(P,x({submitSignIn:p.L7}))(N);let j=(0,h.wU)(e)((0,o.withStyles)(D)(R))},16353(e,t,n){"use strict";n.d(t,{ZP:()=>H,rH:()=>U});var r,i=n(37703),a=n(97779),o=n(9541),s=n(19084);function u(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:h,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.Mk.RECEIVE_SIGNOUT_SUCCESS:case s.Mk.RECEIVE_SIGNIN_SUCCESS:var n={allowed:t.authenticated};return o.Ks(n),f(c({},e,n),{errors:[]});case s.Mk.RECEIVE_SIGNIN_FAIL:var r={allowed:!1};return o.Ks(r),f(c({},e,r),{errors:[]});case s.Mk.RECEIVE_SIGNIN_ERROR:case s.Mk.RECEIVE_SIGNOUT_ERROR:var i={allowed:!1};return o.Ks(i),f(c({},e,i),{errors:t.errors||[]});default:return e}};let b=p;function m(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function g(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:_,t=arguments.length>1?arguments[1]:void 0;return t.type?t.type.startsWith(r.REQUEST)?y(g({},e),{count:e.count+1}):t.type.startsWith(r.RECEIVE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type.startsWith(r.RESPONSE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type===s.di.REDIRECT?y(g({},e),{count:0}):e:e};let S=E;function k(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function x(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:O,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.MATCH_ROUTE:return M(x({},O),{currentUrl:t.pathname});case s.Ih.NOTIFY_SUCCESS:var n={component:t.component,props:t.props};return M(x({},e),{successes:[n],errors:[]});case s.Ih.NOTIFY_SUCCESS_MSG:return M(x({},e),{successes:[t.msg],errors:[]});case s.Ih.NOTIFY_ERROR:var r=t.error.errors,i=null==r?void 0:r.map(function(e){return L(t,e)});return M(x({},e),{successes:[],errors:i});case s.Ih.NOTIFY_ERROR_MSG:return M(x({},e),{successes:[],errors:[t.msg]});case s.Mk.RECEIVE_SIGNIN_FAIL:return M(x({},e),{successes:[],errors:["Your email or password is incorrect. Please try again"]});default:return e}};function L(e,t){return{component:e.component,props:{msg:t.detail}}}let C=A;function I(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function D(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:R,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.REDIRECT:return P(D({},e),{to:t.to});case s.di.MATCH_ROUTE:return P(D({},e),{to:void 0});default:return e}};let F=j;var Y=n(87013),B=(0,a.UY)({authentication:b,fetching:S,notifications:C,redirect:F,buildInfo:Y.Z});B(void 0,{type:"INITIAL_STATE"});var U=i.v9;let H=B},19084(e,t,n){"use strict";var r,i,a,o,s,u,c,l,f,d;n.d(t,{Ih:()=>i,Mk:()=>a,Y0:()=>s,di:()=>r,jp:()=>o}),n(67294),(u=r||(r={})).REDIRECT="REDIRECT",u.MATCH_ROUTE="MATCH_ROUTE",(c=i||(i={})).NOTIFY_SUCCESS="NOTIFY_SUCCESS",c.NOTIFY_SUCCESS_MSG="NOTIFY_SUCCESS_MSG",c.NOTIFY_ERROR="NOTIFY_ERROR",c.NOTIFY_ERROR_MSG="NOTIFY_ERROR_MSG",(l=a||(a={})).REQUEST_SIGNIN="REQUEST_SIGNIN",l.RECEIVE_SIGNIN_SUCCESS="RECEIVE_SIGNIN_SUCCESS",l.RECEIVE_SIGNIN_FAIL="RECEIVE_SIGNIN_FAIL",l.RECEIVE_SIGNIN_ERROR="RECEIVE_SIGNIN_ERROR",l.RECEIVE_SIGNOUT_SUCCESS="RECEIVE_SIGNOUT_SUCCESS",l.RECEIVE_SIGNOUT_ERROR="RECEIVE_SIGNOUT_ERROR",(f=o||(o={})).RECEIVE_CREATE_ERROR="RECEIVE_CREATE_ERROR",f.RECEIVE_CREATE_SUCCESS="RECEIVE_CREATE_SUCCESS",f.RECEIVE_DELETE_ERROR="RECEIVE_DELETE_ERROR",f.RECEIVE_DELETE_SUCCESS="RECEIVE_DELETE_SUCCESS",f.RECEIVE_UPDATE_ERROR="RECEIVE_UPDATE_ERROR",f.RECEIVE_UPDATE_SUCCESS="RECEIVE_UPDATE_SUCCESS",f.REQUEST_CREATE="REQUEST_CREATE",f.REQUEST_DELETE="REQUEST_DELETE",f.REQUEST_UPDATE="REQUEST_UPDATE",f.UPSERT_CONFIGURATION="UPSERT_CONFIGURATION",f.UPSERT_JOB_RUN="UPSERT_JOB_RUN",f.UPSERT_JOB_RUNS="UPSERT_JOB_RUNS",f.UPSERT_TRANSACTION="UPSERT_TRANSACTION",f.UPSERT_TRANSACTIONS="UPSERT_TRANSACTIONS",f.UPSERT_BUILD_INFO="UPSERT_BUILD_INFO",(d=s||(s={})).FETCH_BUILD_INFO_REQUESTED="FETCH_BUILD_INFO_REQUESTED",d.FETCH_BUILD_INFO_SUCCEEDED="FETCH_BUILD_INFO_SUCCEEDED",d.FETCH_BUILD_INFO_FAILED="FETCH_BUILD_INFO_FAILED"},87013(e,t,n){"use strict";n.d(t,{Y:()=>o,Z:()=>u});var r=n(19084);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:o,t=arguments.length>1?arguments[1]:void 0;return t.type===r.Y0.FETCH_BUILD_INFO_SUCCEEDED?a({},t.buildInfo):e};let u=s},34823(e,t,n){"use strict";n.d(t,{N:()=>r});var r=function(e){return e.buildInfo}},73343(e,t,n){"use strict";n.d(t,{r:()=>u});var r=n(19350),i=n(32316),a=n(59114),o=n(5324),s={props:{MuiGrid:{spacing:3*o.default.unit},MuiCardHeader:{titleTypographyProps:{color:"secondary"}}},palette:{action:{hoverOpacity:.3},primary:{light:"#E5F1FF",main:"#3c40c6",contrastText:"#fff"},secondary:{main:"#3d5170"},success:{light:"#e8faf1",main:r.ek.A700,dark:r.ek[700],contrastText:r.y0.white},warning:{light:"#FFFBF1",main:"#fff6b6",contrastText:"#fad27a"},error:{light:"#ffdada",main:"#f44336",dark:"#d32f2f",contrastText:"#fff"},background:{default:"#f5f6f8",appBar:"#3c40c6"},text:{primary:(0,a.darken)(r.BA.A700,.7),secondary:"#818ea3"},listPendingStatus:{background:"#fef7e5",color:"#fecb4c"},listCompletedStatus:{background:"#e9faf2",color:"#4ed495"}},shape:{borderRadius:o.default.unit},overrides:{MuiButton:{root:{borderRadius:o.default.unit/2,textTransform:"none"},sizeLarge:{padding:void 0,fontSize:void 0,paddingTop:o.default.unit,paddingBottom:o.default.unit,paddingLeft:5*o.default.unit,paddingRight:5*o.default.unit}},MuiTableCell:{body:{fontSize:"1rem"},head:{fontSize:"1rem",fontWeight:400}},MuiCardHeader:{root:{borderBottom:"1px solid rgba(0, 0, 0, 0.12)"},action:{marginTop:-2,marginRight:0,"& >*":{marginLeft:2*o.default.unit}},subheader:{marginTop:.5*o.default.unit}}},typography:{useNextVariants:!0,fontFamily:"-apple-system,BlinkMacSystemFont,Roboto,Helvetica,Arial,sans-serif",button:{textTransform:"none",fontSize:"1.2em"},body1:{fontSize:"1.0rem",fontWeight:400,lineHeight:"1.46429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body2:{fontSize:"1.0rem",fontWeight:500,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body1Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"1rem",lineHeight:1.5,letterSpacing:-.4},body2Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"0.875rem",lineHeight:1.5,letterSpacing:-.4},display1:{color:"#818ea3",fontSize:"2.125rem",fontWeight:400,lineHeight:"1.20588em",letterSpacing:-.4},display2:{color:"#818ea3",fontSize:"2.8125rem",fontWeight:400,lineHeight:"1.13333em",marginLeft:"-.02em",letterSpacing:-.4},display3:{color:"#818ea3",fontSize:"3.5rem",fontWeight:400,lineHeight:"1.30357em",marginLeft:"-.02em",letterSpacing:-.4},display4:{fontSize:14,fontWeightLight:300,fontWeightMedium:500,fontWeightRegular:400,letterSpacing:-.4},h1:{color:"rgb(29, 29, 29)",fontSize:"6rem",fontWeight:300,lineHeight:1},h2:{color:"rgb(29, 29, 29)",fontSize:"3.75rem",fontWeight:300,lineHeight:1},h3:{color:"rgb(29, 29, 29)",fontSize:"3rem",fontWeight:400,lineHeight:1.04},h4:{color:"rgb(29, 29, 29)",fontSize:"2.125rem",fontWeight:400,lineHeight:1.17},h5:{color:"rgb(29, 29, 29)",fontSize:"1.5rem",fontWeight:400,lineHeight:1.33,letterSpacing:-.4},h6:{fontSize:"0.8rem",fontWeight:450,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},subheading:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:"1.5em",letterSpacing:-.4},subtitle1:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:1.75,letterSpacing:-.4},subtitle2:{color:"rgb(29, 29, 29)",fontSize:"0.875rem",fontWeight:500,lineHeight:1.57,letterSpacing:-.4}},shadows:["none","0px 1px 3px 0px rgba(0, 0, 0, 0.1),0px 1px 1px 0px rgba(0, 0, 0, 0.04),0px 2px 1px -1px rgba(0, 0, 0, 0.02)","0px 1px 5px 0px rgba(0, 0, 0, 0.1),0px 2px 2px 0px rgba(0, 0, 0, 0.04),0px 3px 1px -2px rgba(0, 0, 0, 0.02)","0px 1px 8px 0px rgba(0, 0, 0, 0.1),0px 3px 4px 0px rgba(0, 0, 0, 0.04),0px 3px 3px -2px rgba(0, 0, 0, 0.02)","0px 2px 4px -1px rgba(0, 0, 0, 0.1),0px 4px 5px 0px rgba(0, 0, 0, 0.04),0px 1px 10px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 5px 8px 0px rgba(0, 0, 0, 0.04),0px 1px 14px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 6px 10px 0px rgba(0, 0, 0, 0.04),0px 1px 18px 0px rgba(0, 0, 0, 0.02)","0px 4px 5px -2px rgba(0, 0, 0, 0.1),0px 7px 10px 1px rgba(0, 0, 0, 0.04),0px 2px 16px 1px rgba(0, 0, 0, 0.02)","0px 5px 5px -3px rgba(0, 0, 0, 0.1),0px 8px 10px 1px rgba(0, 0, 0, 0.04),0px 3px 14px 2px rgba(0, 0, 0, 0.02)","0px 5px 6px -3px rgba(0, 0, 0, 0.1),0px 9px 12px 1px rgba(0, 0, 0, 0.04),0px 3px 16px 2px rgba(0, 0, 0, 0.02)","0px 6px 6px -3px rgba(0, 0, 0, 0.1),0px 10px 14px 1px rgba(0, 0, 0, 0.04),0px 4px 18px 3px rgba(0, 0, 0, 0.02)","0px 6px 7px -4px rgba(0, 0, 0, 0.1),0px 11px 15px 1px rgba(0, 0, 0, 0.04),0px 4px 20px 3px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 12px 17px 2px rgba(0, 0, 0, 0.04),0px 5px 22px 4px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 13px 19px 2px rgba(0, 0, 0, 0.04),0px 5px 24px 4px rgba(0, 0, 0, 0.02)","0px 7px 9px -4px rgba(0, 0, 0, 0.1),0px 14px 21px 2px rgba(0, 0, 0, 0.04),0px 5px 26px 4px rgba(0, 0, 0, 0.02)","0px 8px 9px -5px rgba(0, 0, 0, 0.1),0px 15px 22px 2px rgba(0, 0, 0, 0.04),0px 6px 28px 5px rgba(0, 0, 0, 0.02)","0px 8px 10px -5px rgba(0, 0, 0, 0.1),0px 16px 24px 2px rgba(0, 0, 0, 0.04),0px 6px 30px 5px rgba(0, 0, 0, 0.02)","0px 8px 11px -5px rgba(0, 0, 0, 0.1),0px 17px 26px 2px rgba(0, 0, 0, 0.04),0px 6px 32px 5px rgba(0, 0, 0, 0.02)","0px 9px 11px -5px rgba(0, 0, 0, 0.1),0px 18px 28px 2px rgba(0, 0, 0, 0.04),0px 7px 34px 6px rgba(0, 0, 0, 0.02)","0px 9px 12px -6px rgba(0, 0, 0, 0.1),0px 19px 29px 2px rgba(0, 0, 0, 0.04),0px 7px 36px 6px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 20px 31px 3px rgba(0, 0, 0, 0.04),0px 8px 38px 7px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 21px 33px 3px rgba(0, 0, 0, 0.04),0px 8px 40px 7px rgba(0, 0, 0, 0.02)","0px 10px 14px -6px rgba(0, 0, 0, 0.1),0px 22px 35px 3px rgba(0, 0, 0, 0.04),0px 8px 42px 7px rgba(0, 0, 0, 0.02)","0px 11px 14px -7px rgba(0, 0, 0, 0.1),0px 23px 36px 3px rgba(0, 0, 0, 0.04),0px 9px 44px 8px rgba(0, 0, 0, 0.02)","0px 11px 15px -7px rgba(0, 0, 0, 0.1),0px 24px 38px 3px rgba(0, 0, 0, 0.04),0px 9px 46px 8px rgba(0, 0, 0, 0.02)",]},u=(0,i.createMuiTheme)(s)},66289(e,t,n){"use strict";function r(e){if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}function a(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(e){return!1}}function o(e,t,n){return(o=a()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var i=new(Function.bind.apply(e,r));return n&&f(i,n.prototype),i}).apply(null,arguments)}function s(e){return(s=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function u(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&f(e,t)}function c(e){return -1!==Function.toString.call(e).indexOf("[native code]")}function l(e,t){return t&&("object"===p(t)||"function"==typeof t)?t:r(e)}function f(e,t){return(f=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}n.d(t,{V0:()=>B,_7:()=>v});var d,h,p=function(e){return e&&"undefined"!=typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};function b(e){var t="function"==typeof Map?new Map:void 0;return(b=function(e){if(null===e||!c(e))return e;if("function"!=typeof e)throw TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return o(e,arguments,s(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),f(n,e)})(e)}function m(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(e){return!1}}function g(e){var t=m();return function(){var n,r=s(e);if(t){var i=s(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return l(this,n)}}var v=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"AuthenticationError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e},],r}return n}(b(Error)),y=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"BadRequestError")).errors=a,r}return n}(b(Error)),w=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnprocessableEntityError")).errors=e,r}return n}(b(Error)),_=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"ServerError")).errors=e,r}return n}(b(Error)),E=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"ConflictError")).errors=a,r}return n}(b(Error)),S=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnknownResponseError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e.statusText},],r}return n}(b(Error));function k(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:2e4;return Promise.race([fetch(e,t),new Promise(function(e,t){return setTimeout(function(){return t(Error("timeout"))},n)}),])}function x(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=200&&e.status<300))return[3,2];return[2,e.json()];case 2:if(400!==e.status)return[3,3];return[2,e.json().then(function(e){throw new y(e)})];case 3:if(401!==e.status)return[3,4];throw new v(e);case 4:if(422!==e.status)return[3,6];return[4,$(e)];case 5:throw n=i.sent(),new w(n);case 6:if(409!==e.status)return[3,7];return[2,e.json().then(function(e){throw new E(e)})];case 7:if(!(e.status>=500))return[3,9];return[4,$(e)];case 8:throw r=i.sent(),new _(r);case 9:throw new S(e);case 10:return[2]}})})).apply(this,arguments)}function $(e){return z.apply(this,arguments)}function z(){return(z=j(function(e){return Y(this,function(t){return[2,e.json().then(function(t){return t.errors?t.errors.map(function(t){return{status:e.status,detail:t.detail}}):G(e)}).catch(function(){return G(e)})]})})).apply(this,arguments)}function G(e){return[{status:e.status,detail:e.statusText},]}},50109(e,t,n){"use strict";n.d(t,{LK:()=>o,U2:()=>i,eT:()=>s,t8:()=>a});var r=n(12795);function i(e){return r.ZP.getItem("chainlink.".concat(e))}function a(e,t){r.ZP.setItem("chainlink.".concat(e),t)}function o(e){var t=i(e),n={};if(t)try{return JSON.parse(t)}catch(r){}return n}function s(e,t){a(e,JSON.stringify(t))}},9541(e,t,n){"use strict";n.d(t,{Ks:()=>u,Tp:()=>a,iR:()=>o,pm:()=>s});var r=n(50109),i="persistURL";function a(){return r.U2(i)||""}function o(e){r.t8(i,e)}function s(){return r.LK("authentication")}function u(e){r.eT("authentication",e)}},67121(e,t,n){"use strict";function r(e){var t,n=e.Symbol;return"function"==typeof n?n.observable?t=n.observable:(t=n("observable"),n.observable=t):t="@@observable",t}n.r(t),n.d(t,{default:()=>o}),e=n.hmd(e),i="undefined"!=typeof self?self:"undefined"!=typeof window?window:void 0!==n.g?n.g:e;var i,a=r(i);let o=a},2177(e,t,n){"use strict";n.d(t,{Z:()=>o});var r=!0,i="Invariant failed";function a(e,t){if(!e){if(r)throw Error(i);throw Error(i+": "+(t||""))}}let o=a},11742(e){e.exports=function(){var e=document.getSelection();if(!e.rangeCount)return function(){};for(var t=document.activeElement,n=[],r=0;ru,ZT:()=>i,_T:()=>o,ev:()=>c,mG:()=>s,pi:()=>a});var r=function(e,t){return(r=Object.setPrototypeOf||({__proto__:[]})instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,t)};function i(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return(a=Object.assign||function(e){for(var t,n=1,r=arguments.length;nt.indexOf(r)&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,r=Object.getOwnPropertySymbols(e);it.indexOf(r[i])&&Object.prototype.propertyIsEnumerable.call(e,r[i])&&(n[r[i]]=e[r[i]]);return n}function s(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||(n=Promise))(function(n,a){function o(e){try{u(r.next(e))}catch(t){a(t)}}function s(e){try{u(r.throw(e))}catch(t){a(t)}}function u(e){e.done?n(e.value):i(e.value).then(o,s)}u((r=r.apply(e,t||[])).next())})}function u(e,t){var n,r,i,a,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(e){return function(t){return u([e,t])}}function u(a){if(n)throw TypeError("Generator is already executing.");for(;o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!(i=(i=o.trys).length>0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]r})},94927(e,t,n){function r(e,t){if(i("noDeprecation"))return e;var n=!1;function r(){if(!n){if(i("throwDeprecation"))throw Error(t);i("traceDeprecation")?console.trace(t):console.warn(t),n=!0}return e.apply(this,arguments)}return r}function i(e){try{if(!n.g.localStorage)return!1}catch(t){return!1}var r=n.g.localStorage[e];return null!=r&&"true"===String(r).toLowerCase()}e.exports=r},42473(e){"use strict";var t=function(){};e.exports=t},84763(e){e.exports=Worker},47529(e){e.exports=n;var t=Object.prototype.hasOwnProperty;function n(){for(var e={},n=0;ne.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}e.exports=i,e.exports.__esModule=!0,e.exports.default=e.exports},7071(e){function t(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},94993(e,t,n){var r=n(18698).default,i=n(66115);function a(e,t){if(t&&("object"===r(t)||"function"==typeof t))return t;if(void 0!==t)throw TypeError("Derived constructors may only return object or undefined");return i(e)}e.exports=a,e.exports.__esModule=!0,e.exports.default=e.exports},6015(e){function t(n,r){return e.exports=t=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},e.exports.__esModule=!0,e.exports.default=e.exports,t(n,r)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},861(e,t,n){var r=n(63405),i=n(79498),a=n(86116),o=n(42281);function s(e){return r(e)||i(e)||a(e)||o()}e.exports=s,e.exports.__esModule=!0,e.exports.default=e.exports},18698(e){function t(n){return e.exports=t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e.exports.__esModule=!0,e.exports.default=e.exports,t(n)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},86116(e,t,n){var r=n(73897);function i(e,t){if(e){if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return r(e,t)}}e.exports=i,e.exports.__esModule=!0,e.exports.default=e.exports},1644(e,t,n){"use strict";var r,i;function a(e){return!!e&&e<7}n.d(t,{I:()=>r,O:()=>a}),(i=r||(r={}))[i.loading=1]="loading",i[i.setVariables=2]="setVariables",i[i.fetchMore=3]="fetchMore",i[i.refetch=4]="refetch",i[i.poll=6]="poll",i[i.ready=7]="ready",i[i.error=8]="error"},30990(e,t,n){"use strict";n.d(t,{MS:()=>s,YG:()=>a,cA:()=>c,ls:()=>o});var r=n(70655);n(83952);var i=n(13154),a=Symbol();function o(e){return!!e.extensions&&Array.isArray(e.extensions[a])}function s(e){return e.hasOwnProperty("graphQLErrors")}var u=function(e){var t=(0,r.ev)((0,r.ev)((0,r.ev)([],e.graphQLErrors,!0),e.clientErrors,!0),e.protocolErrors,!0);return e.networkError&&t.push(e.networkError),t.map(function(e){return(0,i.s)(e)&&e.message||"Error message not found."}).join("\n")},c=function(e){function t(n){var r=n.graphQLErrors,i=n.protocolErrors,a=n.clientErrors,o=n.networkError,s=n.errorMessage,c=n.extraInfo,l=e.call(this,s)||this;return l.name="ApolloError",l.graphQLErrors=r||[],l.protocolErrors=i||[],l.clientErrors=a||[],l.networkError=o||null,l.message=s||u(l),l.extraInfo=c,l.__proto__=t.prototype,l}return(0,r.ZT)(t,e),t}(Error)},85317(e,t,n){"use strict";n.d(t,{K:()=>a});var r=n(67294),i=n(30320).aS?Symbol.for("__APOLLO_CONTEXT__"):"__APOLLO_CONTEXT__";function a(){var e=r.createContext[i];return e||(Object.defineProperty(r.createContext,i,{value:e=r.createContext({}),enumerable:!1,writable:!1,configurable:!0}),e.displayName="ApolloContext"),e}},21436(e,t,n){"use strict";n.d(t,{O:()=>i,k:()=>r});var r=Array.isArray;function i(e){return Array.isArray(e)&&e.length>0}},30320(e,t,n){"use strict";n.d(t,{DN:()=>s,JC:()=>l,aS:()=>o,mr:()=>i,sy:()=>a});var r=n(83952),i="function"==typeof WeakMap&&"ReactNative"!==(0,r.wY)(function(){return navigator.product}),a="function"==typeof WeakSet,o="function"==typeof Symbol&&"function"==typeof Symbol.for,s=o&&Symbol.asyncIterator,u="function"==typeof(0,r.wY)(function(){return window.document.createElement}),c=(0,r.wY)(function(){return navigator.userAgent.indexOf("jsdom")>=0})||!1,l=u&&!c},53712(e,t,n){"use strict";function r(){for(var e=[],t=0;tr})},10542(e,t,n){"use strict";n.d(t,{J:()=>o}),n(83952);var r=n(13154);function i(e){var t=new Set([e]);return t.forEach(function(e){(0,r.s)(e)&&a(e)===e&&Object.getOwnPropertyNames(e).forEach(function(n){(0,r.s)(e[n])&&t.add(e[n])})}),e}function a(e){if(__DEV__&&!Object.isFrozen(e))try{Object.freeze(e)}catch(t){if(t instanceof TypeError)return null;throw t}return e}function o(e){return __DEV__&&i(e),e}},14012(e,t,n){"use strict";n.d(t,{J:()=>a});var r=n(70655),i=n(53712);function a(e,t){return(0,i.o)(e,t,t.variables&&{variables:(0,r.pi)((0,r.pi)({},e&&e.variables),t.variables)})}},13154(e,t,n){"use strict";function r(e){return null!==e&&"object"==typeof e}n.d(t,{s:()=>r})},83952(e,t,n){"use strict";n.d(t,{ej:()=>u,kG:()=>c,wY:()=>h});var r,i=n(70655),a="Invariant Violation",o=Object.setPrototypeOf,s=void 0===o?function(e,t){return e.__proto__=t,e}:o,u=function(e){function t(n){void 0===n&&(n=a);var r=e.call(this,"number"==typeof n?a+": "+n+" (see https://github.com/apollographql/invariant-packages)":n)||this;return r.framesToPop=1,r.name=a,s(r,t.prototype),r}return(0,i.ZT)(t,e),t}(Error);function c(e,t){if(!e)throw new u(t)}var l=["debug","log","warn","error","silent"],f=l.indexOf("log");function d(e){return function(){if(l.indexOf(e)>=f)return(console[e]||console.log).apply(console,arguments)}}function h(e){try{return e()}catch(t){}}(r=c||(c={})).debug=d("debug"),r.log=d("log"),r.warn=d("warn"),r.error=d("error");let p=h(function(){return globalThis})||h(function(){return window})||h(function(){return self})||h(function(){return global})||h(function(){return h.constructor("return this")()});var b="__",m=[b,b].join("DEV");function g(){try{return Boolean(__DEV__)}catch(e){return Object.defineProperty(p,m,{value:"production"!==h(function(){return"production"}),enumerable:!1,configurable:!0,writable:!0}),p[m]}}let v=g();function y(e){try{return e()}catch(t){}}var w=y(function(){return globalThis})||y(function(){return window})||y(function(){return self})||y(function(){return global})||y(function(){return y.constructor("return this")()}),_=!1;function E(){!w||y(function(){return"production"})||y(function(){return process})||(Object.defineProperty(w,"process",{value:{env:{NODE_ENV:"production"}},configurable:!0,enumerable:!1,writable:!0}),_=!0)}function S(){_&&(delete w.process,_=!1)}E();var k=n(10143);function x(){return k.H,S()}function T(){__DEV__?c("boolean"==typeof v,v):c("boolean"==typeof v,39)}x(),T()},4942(e,t,n){"use strict";function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}n.d(t,{Z:()=>r})},87462(e,t,n){"use strict";function r(){return(r=Object.assign?Object.assign.bind():function(e){for(var t=1;tr})},51721(e,t,n){"use strict";function r(e,t){return(r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e})(e,t)}function i(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)}n.d(t,{Z:()=>i})},63366(e,t,n){"use strict";function r(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}n.d(t,{Z:()=>r})},25821(e,t,n){"use strict";n.d(t,{Z:()=>s});var r=n(45695);function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var a=10,o=2;function s(e){return u(e,[])}function u(e,t){switch(i(e)){case"string":return JSON.stringify(e);case"function":return e.name?"[function ".concat(e.name,"]"):"[function]";case"object":if(null===e)return"null";return c(e,t);default:return String(e)}}function c(e,t){if(-1!==t.indexOf(e))return"[Circular]";var n=[].concat(t,[e]),r=d(e);if(void 0!==r){var i=r.call(e);if(i!==e)return"string"==typeof i?i:u(i,n)}else if(Array.isArray(e))return f(e,n);return l(e,n)}function l(e,t){var n=Object.keys(e);return 0===n.length?"{}":t.length>o?"["+h(e)+"]":"{ "+n.map(function(n){var r=u(e[n],t);return n+": "+r}).join(", ")+" }"}function f(e,t){if(0===e.length)return"[]";if(t.length>o)return"[Array]";for(var n=Math.min(a,e.length),r=e.length-n,i=[],s=0;s1&&i.push("... ".concat(r," more items")),"["+i.join(", ")+"]"}function d(e){var t=e[String(r.Z)];return"function"==typeof t?t:"function"==typeof e.inspect?e.inspect:void 0}function h(e){var t=Object.prototype.toString.call(e).replace(/^\[object /,"").replace(/]$/,"");if("Object"===t&&"function"==typeof e.constructor){var n=e.constructor.name;if("string"==typeof n&&""!==n)return n}return t}},45695(e,t,n){"use strict";n.d(t,{Z:()=>i});var r="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):void 0;let i=r},25217(e,t,n){"use strict";function r(e,t){if(!Boolean(e))throw Error(null!=t?t:"Unexpected invariant triggered.")}n.d(t,{Ye:()=>o,WU:()=>s,UG:()=>u});var i=n(45695);function a(e){var t=e.prototype.toJSON;"function"==typeof t||r(0),e.prototype.inspect=t,i.Z&&(e.prototype[i.Z]=t)}var o=function(){function e(e,t,n){this.start=e.start,this.end=t.end,this.startToken=e,this.endToken=t,this.source=n}return e.prototype.toJSON=function(){return{start:this.start,end:this.end}},e}();a(o);var s=function(){function e(e,t,n,r,i,a,o){this.kind=e,this.start=t,this.end=n,this.line=r,this.column=i,this.value=o,this.prev=a,this.next=null}return e.prototype.toJSON=function(){return{kind:this.kind,value:this.value,line:this.line,column:this.column}},e}();function u(e){return null!=e&&"string"==typeof e.kind}a(s)},87392(e,t,n){"use strict";function r(e){var t=e.split(/\r\n|[\n\r]/g),n=a(e);if(0!==n)for(var r=1;ro&&i(t[s-1]);)--s;return t.slice(o,s).join("\n")}function i(e){for(var t=0;t1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=-1===e.indexOf("\n"),i=" "===e[0]||" "===e[0],a='"'===e[e.length-1],o="\\"===e[e.length-1],s=!r||a||o||n,u="";return s&&!(r&&i)&&(u+="\n"+t),u+=t?e.replace(/\n/g,"\n"+t):e,s&&(u+="\n"),'"""'+u.replace(/"""/g,'\\"""')+'"""'}n.d(t,{LZ:()=>o,W7:()=>r})},97359(e,t,n){"use strict";n.d(t,{h:()=>r});var r=Object.freeze({NAME:"Name",DOCUMENT:"Document",OPERATION_DEFINITION:"OperationDefinition",VARIABLE_DEFINITION:"VariableDefinition",SELECTION_SET:"SelectionSet",FIELD:"Field",ARGUMENT:"Argument",FRAGMENT_SPREAD:"FragmentSpread",INLINE_FRAGMENT:"InlineFragment",FRAGMENT_DEFINITION:"FragmentDefinition",VARIABLE:"Variable",INT:"IntValue",FLOAT:"FloatValue",STRING:"StringValue",BOOLEAN:"BooleanValue",NULL:"NullValue",ENUM:"EnumValue",LIST:"ListValue",OBJECT:"ObjectValue",OBJECT_FIELD:"ObjectField",DIRECTIVE:"Directive",NAMED_TYPE:"NamedType",LIST_TYPE:"ListType",NON_NULL_TYPE:"NonNullType",SCHEMA_DEFINITION:"SchemaDefinition",OPERATION_TYPE_DEFINITION:"OperationTypeDefinition",SCALAR_TYPE_DEFINITION:"ScalarTypeDefinition",OBJECT_TYPE_DEFINITION:"ObjectTypeDefinition",FIELD_DEFINITION:"FieldDefinition",INPUT_VALUE_DEFINITION:"InputValueDefinition",INTERFACE_TYPE_DEFINITION:"InterfaceTypeDefinition",UNION_TYPE_DEFINITION:"UnionTypeDefinition",ENUM_TYPE_DEFINITION:"EnumTypeDefinition",ENUM_VALUE_DEFINITION:"EnumValueDefinition",INPUT_OBJECT_TYPE_DEFINITION:"InputObjectTypeDefinition",DIRECTIVE_DEFINITION:"DirectiveDefinition",SCHEMA_EXTENSION:"SchemaExtension",SCALAR_TYPE_EXTENSION:"ScalarTypeExtension",OBJECT_TYPE_EXTENSION:"ObjectTypeExtension",INTERFACE_TYPE_EXTENSION:"InterfaceTypeExtension",UNION_TYPE_EXTENSION:"UnionTypeExtension",ENUM_TYPE_EXTENSION:"EnumTypeExtension",INPUT_OBJECT_TYPE_EXTENSION:"InputObjectTypeExtension"})},10143(e,t,n){"use strict";n.d(t,{H:()=>c,T:()=>l});var r=n(99763),i=n(25821);function a(e,t){if(!Boolean(e))throw Error(t)}let o=function(e,t){return e instanceof t};function s(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:"GraphQL request",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{line:1,column:1};"string"==typeof e||a(0,"Body must be a string. Received: ".concat((0,i.Z)(e),".")),this.body=e,this.name=t,this.locationOffset=n,this.locationOffset.line>0||a(0,"line in locationOffset is 1-indexed and must be positive."),this.locationOffset.column>0||a(0,"column in locationOffset is 1-indexed and must be positive.")}return u(e,[{key:r.YF,get:function(){return"Source"}}]),e}();function l(e){return o(e,c)}},99763(e,t,n){"use strict";n.d(t,{YF:()=>r});var r="function"==typeof Symbol&&null!=Symbol.toStringTag?Symbol.toStringTag:"@@toStringTag"},37452(e){"use strict";e.exports=JSON.parse('{"AElig":"\xc6","AMP":"&","Aacute":"\xc1","Acirc":"\xc2","Agrave":"\xc0","Aring":"\xc5","Atilde":"\xc3","Auml":"\xc4","COPY":"\xa9","Ccedil":"\xc7","ETH":"\xd0","Eacute":"\xc9","Ecirc":"\xca","Egrave":"\xc8","Euml":"\xcb","GT":">","Iacute":"\xcd","Icirc":"\xce","Igrave":"\xcc","Iuml":"\xcf","LT":"<","Ntilde":"\xd1","Oacute":"\xd3","Ocirc":"\xd4","Ograve":"\xd2","Oslash":"\xd8","Otilde":"\xd5","Ouml":"\xd6","QUOT":"\\"","REG":"\xae","THORN":"\xde","Uacute":"\xda","Ucirc":"\xdb","Ugrave":"\xd9","Uuml":"\xdc","Yacute":"\xdd","aacute":"\xe1","acirc":"\xe2","acute":"\xb4","aelig":"\xe6","agrave":"\xe0","amp":"&","aring":"\xe5","atilde":"\xe3","auml":"\xe4","brvbar":"\xa6","ccedil":"\xe7","cedil":"\xb8","cent":"\xa2","copy":"\xa9","curren":"\xa4","deg":"\xb0","divide":"\xf7","eacute":"\xe9","ecirc":"\xea","egrave":"\xe8","eth":"\xf0","euml":"\xeb","frac12":"\xbd","frac14":"\xbc","frac34":"\xbe","gt":">","iacute":"\xed","icirc":"\xee","iexcl":"\xa1","igrave":"\xec","iquest":"\xbf","iuml":"\xef","laquo":"\xab","lt":"<","macr":"\xaf","micro":"\xb5","middot":"\xb7","nbsp":"\xa0","not":"\xac","ntilde":"\xf1","oacute":"\xf3","ocirc":"\xf4","ograve":"\xf2","ordf":"\xaa","ordm":"\xba","oslash":"\xf8","otilde":"\xf5","ouml":"\xf6","para":"\xb6","plusmn":"\xb1","pound":"\xa3","quot":"\\"","raquo":"\xbb","reg":"\xae","sect":"\xa7","shy":"\xad","sup1":"\xb9","sup2":"\xb2","sup3":"\xb3","szlig":"\xdf","thorn":"\xfe","times":"\xd7","uacute":"\xfa","ucirc":"\xfb","ugrave":"\xf9","uml":"\xa8","uuml":"\xfc","yacute":"\xfd","yen":"\xa5","yuml":"\xff"}')},93580(e){"use strict";e.exports=JSON.parse('{"0":"�","128":"€","130":"‚","131":"ƒ","132":"„","133":"…","134":"†","135":"‡","136":"ˆ","137":"‰","138":"Š","139":"‹","140":"Œ","142":"Ž","145":"‘","146":"’","147":"“","148":"”","149":"•","150":"–","151":"—","152":"˜","153":"™","154":"š","155":"›","156":"œ","158":"ž","159":"Ÿ"}')},67946(e){"use strict";e.exports=JSON.parse('{"locale":"en","long":{"year":{"previous":"last year","current":"this year","next":"next year","past":{"one":"{0} year ago","other":"{0} years ago"},"future":{"one":"in {0} year","other":"in {0} years"}},"quarter":{"previous":"last quarter","current":"this quarter","next":"next quarter","past":{"one":"{0} quarter ago","other":"{0} quarters ago"},"future":{"one":"in {0} quarter","other":"in {0} quarters"}},"month":{"previous":"last month","current":"this month","next":"next month","past":{"one":"{0} month ago","other":"{0} months ago"},"future":{"one":"in {0} month","other":"in {0} months"}},"week":{"previous":"last week","current":"this week","next":"next week","past":{"one":"{0} week ago","other":"{0} weeks ago"},"future":{"one":"in {0} week","other":"in {0} weeks"}},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":{"one":"{0} hour ago","other":"{0} hours ago"},"future":{"one":"in {0} hour","other":"in {0} hours"}},"minute":{"current":"this minute","past":{"one":"{0} minute ago","other":"{0} minutes ago"},"future":{"one":"in {0} minute","other":"in {0} minutes"}},"second":{"current":"now","past":{"one":"{0} second ago","other":"{0} seconds ago"},"future":{"one":"in {0} second","other":"in {0} seconds"}}},"short":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"narrow":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"now":{"now":{"current":"now","future":"in a moment","past":"just now"}},"mini":{"year":"{0}yr","month":"{0}mo","week":"{0}wk","day":"{0}d","hour":"{0}h","minute":"{0}m","second":"{0}s","now":"now"},"short-time":{"year":"{0} yr.","month":"{0} mo.","week":"{0} wk.","day":{"one":"{0} day","other":"{0} days"},"hour":"{0} hr.","minute":"{0} min.","second":"{0} sec."},"long-time":{"year":{"one":"{0} year","other":"{0} years"},"month":{"one":"{0} month","other":"{0} months"},"week":{"one":"{0} week","other":"{0} weeks"},"day":{"one":"{0} day","other":"{0} days"},"hour":{"one":"{0} hour","other":"{0} hours"},"minute":{"one":"{0} minute","other":"{0} minutes"},"second":{"one":"{0} second","other":"{0} seconds"}}}')}},__webpack_module_cache__={};function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[e]={id:e,loaded:!1,exports:{}};return __webpack_modules__[e].call(n.exports,n,n.exports,__webpack_require__),n.loaded=!0,n.exports}__webpack_require__.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(t,{a:t}),t},(()=>{var e,t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__;__webpack_require__.t=function(n,r){if(1&r&&(n=this(n)),8&r||"object"==typeof n&&n&&(4&r&&n.__esModule||16&r&&"function"==typeof n.then))return n;var i=Object.create(null);__webpack_require__.r(i);var a={};e=e||[null,t({}),t([]),t(t)];for(var o=2&r&&n;"object"==typeof o&&!~e.indexOf(o);o=t(o))Object.getOwnPropertyNames(o).forEach(e=>a[e]=()=>n[e]);return a.default=()=>n,__webpack_require__.d(i,a),i}})(),__webpack_require__.d=(e,t)=>{for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.hmd=e=>((e=Object.create(e)).children||(e.children=[]),Object.defineProperty(e,"exports",{enumerable:!0,set(){throw Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+e.id)}}),e),__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},__webpack_require__.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),__webpack_require__.p="/assets/",__webpack_require__.nc=void 0;var __webpack_exports__={};(()=>{"use strict";var e,t,n,r,i=__webpack_require__(32316),a=__webpack_require__(8126),o=__webpack_require__(5690),s=__webpack_require__(30381),u=__webpack_require__.n(s),c=__webpack_require__(67294),l=__webpack_require__(73935),f=__webpack_require__.n(l),d=__webpack_require__(57209),h=__webpack_require__(37703),p=__webpack_require__(97779),b=__webpack_require__(28500);function m(e){return function(t){var n=t.dispatch,r=t.getState;return function(t){return function(i){return"function"==typeof i?i(n,r,e):t(i)}}}}var g=m();g.withExtraArgument=m;let v=g;var y=__webpack_require__(76489);function w(e){return function(t){return function(n){return function(r){n(r);var i=e||document&&document.cookie||"",a=t.getState();if("MATCH_ROUTE"===r.type&&"/signin"!==a.notifications.currentUrl){var o=(0,y.Q)(i);if(o.explorer)try{var s=JSON.parse(o.explorer);if("error"===s.status){var u=_(s.url);n({type:"NOTIFY_ERROR_MSG",msg:u})}}catch(c){n({type:"NOTIFY_ERROR_MSG",msg:"Invalid explorer status"})}}}}}}function _(e){var t="Can't connect to explorer: ".concat(e);return e.match(/^wss?:.+/)?t:"".concat(t,". You must use a websocket.")}var E=__webpack_require__(16353);function S(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function ei(e,t){if(e){if("string"==typeof e)return ea(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return ea(e,t)}}function ea(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1,i=!1,a=arguments[1],o=a;return new n(function(n){return t.subscribe({next:function(t){var a=!i;if(i=!0,!a||r)try{o=e(o,t)}catch(s){return n.error(s)}else o=t},error:function(e){n.error(e)},complete:function(){if(!i&&!r)return n.error(TypeError("Cannot reduce an empty sequence"));n.next(o),n.complete()}})})},t.concat=function(){for(var e=this,t=arguments.length,n=Array(t),r=0;r=0&&i.splice(e,1),o()}});i.push(s)},error:function(e){r.error(e)},complete:function(){o()}});function o(){a.closed&&0===i.length&&r.complete()}return function(){i.forEach(function(e){return e.unsubscribe()}),a.unsubscribe()}})},t[ed]=function(){return this},e.from=function(t){var n="function"==typeof this?this:e;if(null==t)throw TypeError(t+" is not an object");var r=ep(t,ed);if(r){var i=r.call(t);if(Object(i)!==i)throw TypeError(i+" is not an object");return em(i)&&i.constructor===n?i:new n(function(e){return i.subscribe(e)})}if(ec("iterator")&&(r=ep(t,ef)))return new n(function(e){ev(function(){if(!e.closed){for(var n,i=er(r.call(t));!(n=i()).done;){var a=n.value;if(e.next(a),e.closed)return}e.complete()}})});if(Array.isArray(t))return new n(function(e){ev(function(){if(!e.closed){for(var n=0;n0))return n.connection.key;var r=n.connection.filter?n.connection.filter:[];r.sort();var i={};return r.forEach(function(e){i[e]=t[e]}),"".concat(n.connection.key,"(").concat(eV(i),")")}var a=e;if(t){var o=eV(t);a+="(".concat(o,")")}return n&&Object.keys(n).forEach(function(e){-1===eW.indexOf(e)&&(n[e]&&Object.keys(n[e]).length?a+="@".concat(e,"(").concat(eV(n[e]),")"):a+="@".concat(e))}),a},{setStringify:function(e){var t=eV;return eV=e,t}}),eV=function(e){return JSON.stringify(e,eq)};function eq(e,t){return(0,eO.s)(t)&&!Array.isArray(t)&&(t=Object.keys(t).sort().reduce(function(e,n){return e[n]=t[n],e},{})),t}function eZ(e,t){if(e.arguments&&e.arguments.length){var n={};return e.arguments.forEach(function(e){var r;return ez(n,e.name,e.value,t)}),n}return null}function eX(e){return e.alias?e.alias.value:e.name.value}function eJ(e,t,n){for(var r,i=0,a=t.selections;it.indexOf(i))throw __DEV__?new Q.ej("illegal argument: ".concat(i)):new Q.ej(27)}return e}function tt(e,t){return t?t(e):eT.of()}function tn(e){return"function"==typeof e?new ta(e):e}function tr(e){return e.request.length<=1}var ti=function(e){function t(t,n){var r=e.call(this,t)||this;return r.link=n,r}return(0,en.ZT)(t,e),t}(Error),ta=function(){function e(e){e&&(this.request=e)}return e.empty=function(){return new e(function(){return eT.of()})},e.from=function(t){return 0===t.length?e.empty():t.map(tn).reduce(function(e,t){return e.concat(t)})},e.split=function(t,n,r){var i=tn(n),a=tn(r||new e(tt));return new e(tr(i)&&tr(a)?function(e){return t(e)?i.request(e)||eT.of():a.request(e)||eT.of()}:function(e,n){return t(e)?i.request(e,n)||eT.of():a.request(e,n)||eT.of()})},e.execute=function(e,t){return e.request(eM(t.context,e7(te(t))))||eT.of()},e.concat=function(t,n){var r=tn(t);if(tr(r))return __DEV__&&Q.kG.warn(new ti("You are calling concat on a terminating link, which will have no effect",r)),r;var i=tn(n);return new e(tr(i)?function(e){return r.request(e,function(e){return i.request(e)||eT.of()})||eT.of()}:function(e,t){return r.request(e,function(e){return i.request(e,t)||eT.of()})||eT.of()})},e.prototype.split=function(t,n,r){return this.concat(e.split(t,n,r||new e(tt)))},e.prototype.concat=function(t){return e.concat(this,t)},e.prototype.request=function(e,t){throw __DEV__?new Q.ej("request is not implemented"):new Q.ej(22)},e.prototype.onError=function(e,t){if(t&&t.error)return t.error(e),!1;throw e},e.prototype.setOnError=function(e){return this.onError=e,this},e}(),to=__webpack_require__(25821),ts=__webpack_require__(25217),tu={Name:[],Document:["definitions"],OperationDefinition:["name","variableDefinitions","directives","selectionSet"],VariableDefinition:["variable","type","defaultValue","directives"],Variable:["name"],SelectionSet:["selections"],Field:["alias","name","arguments","directives","selectionSet"],Argument:["name","value"],FragmentSpread:["name","directives"],InlineFragment:["typeCondition","directives","selectionSet"],FragmentDefinition:["name","variableDefinitions","typeCondition","directives","selectionSet"],IntValue:[],FloatValue:[],StringValue:[],BooleanValue:[],NullValue:[],EnumValue:[],ListValue:["values"],ObjectValue:["fields"],ObjectField:["name","value"],Directive:["name","arguments"],NamedType:["name"],ListType:["type"],NonNullType:["type"],SchemaDefinition:["description","directives","operationTypes"],OperationTypeDefinition:["type"],ScalarTypeDefinition:["description","name","directives"],ObjectTypeDefinition:["description","name","interfaces","directives","fields"],FieldDefinition:["description","name","arguments","type","directives"],InputValueDefinition:["description","name","type","defaultValue","directives"],InterfaceTypeDefinition:["description","name","interfaces","directives","fields"],UnionTypeDefinition:["description","name","directives","types"],EnumTypeDefinition:["description","name","directives","values"],EnumValueDefinition:["description","name","directives"],InputObjectTypeDefinition:["description","name","directives","fields"],DirectiveDefinition:["description","name","arguments","locations"],SchemaExtension:["directives","operationTypes"],ScalarTypeExtension:["name","directives"],ObjectTypeExtension:["name","interfaces","directives","fields"],InterfaceTypeExtension:["name","interfaces","directives","fields"],UnionTypeExtension:["name","directives","types"],EnumTypeExtension:["name","directives","values"],InputObjectTypeExtension:["name","directives","fields"]},tc=Object.freeze({});function tl(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:tu,r=void 0,i=Array.isArray(e),a=[e],o=-1,s=[],u=void 0,c=void 0,l=void 0,f=[],d=[],h=e;do{var p,b=++o===a.length,m=b&&0!==s.length;if(b){if(c=0===d.length?void 0:f[f.length-1],u=l,l=d.pop(),m){if(i)u=u.slice();else{for(var g={},v=0,y=Object.keys(u);v1)for(var r=new tB,i=1;i=0;--a){var o=i[a],s=isNaN(+o)?{}:[];s[o]=t,t=s}n=r.merge(n,t)}),n}var tW=Object.prototype.hasOwnProperty;function tK(e,t){var n,r,i,a,o;return(0,en.mG)(this,void 0,void 0,function(){var s,u,c,l,f,d,h,p,b,m,g,v,y,w,_,E,S,k,x,T,M,O,A;return(0,en.Jh)(this,function(L){switch(L.label){case 0:if(void 0===TextDecoder)throw Error("TextDecoder must be defined in the environment: please import a polyfill.");s=new TextDecoder("utf-8"),u=null===(n=e.headers)||void 0===n?void 0:n.get("content-type"),c="boundary=",l=(null==u?void 0:u.includes(c))?null==u?void 0:u.substring((null==u?void 0:u.indexOf(c))+c.length).replace(/['"]/g,"").replace(/\;(.*)/gm,"").trim():"-",f="\r\n--".concat(l),d="",h=tI(e),p=!0,L.label=1;case 1:if(!p)return[3,3];return[4,h.next()];case 2:for(m=(b=L.sent()).value,g=b.done,v="string"==typeof m?m:s.decode(m),y=d.length-f.length+1,p=!g,d+=v,w=d.indexOf(f,y);w>-1;){if(_=void 0,_=(O=[d.slice(0,w),d.slice(w+f.length),])[0],d=O[1],E=_.indexOf("\r\n\r\n"),(k=(S=tV(_.slice(0,E)))["content-type"])&&-1===k.toLowerCase().indexOf("application/json"))throw Error("Unsupported patch content type: application/json is required.");if(x=_.slice(E))try{T=tq(e,x),Object.keys(T).length>1||"data"in T||"incremental"in T||"errors"in T||"payload"in T?tz(T)?(M={},"payload"in T&&(M=(0,en.pi)({},T.payload)),"errors"in T&&(M=(0,en.pi)((0,en.pi)({},M),{extensions:(0,en.pi)((0,en.pi)({},"extensions"in M?M.extensions:null),((A={})[tN.YG]=T.errors,A))})),null===(r=t.next)||void 0===r||r.call(t,M)):null===(i=t.next)||void 0===i||i.call(t,T):1===Object.keys(T).length&&"hasNext"in T&&!T.hasNext&&(null===(a=t.complete)||void 0===a||a.call(t))}catch(C){tZ(C,t)}w=d.indexOf(f)}return[3,1];case 3:return null===(o=t.complete)||void 0===o||o.call(t),[2]}})})}function tV(e){var t={};return e.split("\n").forEach(function(e){var n=e.indexOf(":");if(n>-1){var r=e.slice(0,n).trim().toLowerCase(),i=e.slice(n+1).trim();t[r]=i}}),t}function tq(e,t){e.status>=300&&tD(e,function(){try{return JSON.parse(t)}catch(e){return t}}(),"Response not successful: Received status code ".concat(e.status));try{return JSON.parse(t)}catch(n){var r=n;throw r.name="ServerParseError",r.response=e,r.statusCode=e.status,r.bodyText=t,r}}function tZ(e,t){var n,r;"AbortError"!==e.name&&(e.result&&e.result.errors&&e.result.data&&(null===(n=t.next)||void 0===n||n.call(t,e.result)),null===(r=t.error)||void 0===r||r.call(t,e))}function tX(e,t,n){tJ(t)(e).then(function(e){var t,r;null===(t=n.next)||void 0===t||t.call(n,e),null===(r=n.complete)||void 0===r||r.call(n)}).catch(function(e){return tZ(e,n)})}function tJ(e){return function(t){return t.text().then(function(e){return tq(t,e)}).then(function(n){return t.status>=300&&tD(t,n,"Response not successful: Received status code ".concat(t.status)),Array.isArray(n)||tW.call(n,"data")||tW.call(n,"errors")||tD(t,n,"Server response was missing for query '".concat(Array.isArray(e)?e.map(function(e){return e.operationName}):e.operationName,"'.")),n})}}var tQ=function(e){if(!e&&"undefined"==typeof fetch)throw __DEV__?new Q.ej("\n\"fetch\" has not been found globally and no fetcher has been configured. To fix this, install a fetch package (like https://www.npmjs.com/package/cross-fetch), instantiate the fetcher, and pass it into your HttpLink constructor. For example:\n\nimport fetch from 'cross-fetch';\nimport { ApolloClient, HttpLink } from '@apollo/client';\nconst client = new ApolloClient({\n link: new HttpLink({ uri: '/graphql', fetch })\n});\n "):new Q.ej(23)},t1=__webpack_require__(87392);function t0(e){return tl(e,{leave:t3})}var t2=80,t3={Name:function(e){return e.value},Variable:function(e){return"$"+e.name},Document:function(e){return t6(e.definitions,"\n\n")+"\n"},OperationDefinition:function(e){var t=e.operation,n=e.name,r=t8("(",t6(e.variableDefinitions,", "),")"),i=t6(e.directives," "),a=e.selectionSet;return n||i||r||"query"!==t?t6([t,t6([n,r]),i,a]," "):a},VariableDefinition:function(e){var t=e.variable,n=e.type,r=e.defaultValue,i=e.directives;return t+": "+n+t8(" = ",r)+t8(" ",t6(i," "))},SelectionSet:function(e){return t5(e.selections)},Field:function(e){var t=e.alias,n=e.name,r=e.arguments,i=e.directives,a=e.selectionSet,o=t8("",t,": ")+n,s=o+t8("(",t6(r,", "),")");return s.length>t2&&(s=o+t8("(\n",t9(t6(r,"\n")),"\n)")),t6([s,t6(i," "),a]," ")},Argument:function(e){var t;return e.name+": "+e.value},FragmentSpread:function(e){var t;return"..."+e.name+t8(" ",t6(e.directives," "))},InlineFragment:function(e){var t=e.typeCondition,n=e.directives,r=e.selectionSet;return t6(["...",t8("on ",t),t6(n," "),r]," ")},FragmentDefinition:function(e){var t=e.name,n=e.typeCondition,r=e.variableDefinitions,i=e.directives,a=e.selectionSet;return"fragment ".concat(t).concat(t8("(",t6(r,", "),")")," ")+"on ".concat(n," ").concat(t8("",t6(i," ")," "))+a},IntValue:function(e){return e.value},FloatValue:function(e){return e.value},StringValue:function(e,t){var n=e.value;return e.block?(0,t1.LZ)(n,"description"===t?"":" "):JSON.stringify(n)},BooleanValue:function(e){return e.value?"true":"false"},NullValue:function(){return"null"},EnumValue:function(e){return e.value},ListValue:function(e){return"["+t6(e.values,", ")+"]"},ObjectValue:function(e){return"{"+t6(e.fields,", ")+"}"},ObjectField:function(e){var t;return e.name+": "+e.value},Directive:function(e){var t;return"@"+e.name+t8("(",t6(e.arguments,", "),")")},NamedType:function(e){return e.name},ListType:function(e){return"["+e.type+"]"},NonNullType:function(e){return e.type+"!"},SchemaDefinition:t4(function(e){var t=e.directives,n=e.operationTypes;return t6(["schema",t6(t," "),t5(n)]," ")}),OperationTypeDefinition:function(e){var t;return e.operation+": "+e.type},ScalarTypeDefinition:t4(function(e){var t;return t6(["scalar",e.name,t6(e.directives," ")]," ")}),ObjectTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["type",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")}),FieldDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.type,i=e.directives;return t+(ne(n)?t8("(\n",t9(t6(n,"\n")),"\n)"):t8("(",t6(n,", "),")"))+": "+r+t8(" ",t6(i," "))}),InputValueDefinition:t4(function(e){var t=e.name,n=e.type,r=e.defaultValue,i=e.directives;return t6([t+": "+n,t8("= ",r),t6(i," ")]," ")}),InterfaceTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["interface",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")}),UnionTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.types;return t6(["union",t,t6(n," "),r&&0!==r.length?"= "+t6(r," | "):""]," ")}),EnumTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.values;return t6(["enum",t,t6(n," "),t5(r)]," ")}),EnumValueDefinition:t4(function(e){var t;return t6([e.name,t6(e.directives," ")]," ")}),InputObjectTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.fields;return t6(["input",t,t6(n," "),t5(r)]," ")}),DirectiveDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.repeatable,i=e.locations;return"directive @"+t+(ne(n)?t8("(\n",t9(t6(n,"\n")),"\n)"):t8("(",t6(n,", "),")"))+(r?" repeatable":"")+" on "+t6(i," | ")}),SchemaExtension:function(e){var t=e.directives,n=e.operationTypes;return t6(["extend schema",t6(t," "),t5(n)]," ")},ScalarTypeExtension:function(e){var t;return t6(["extend scalar",e.name,t6(e.directives," ")]," ")},ObjectTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["extend type",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")},InterfaceTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["extend interface",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")},UnionTypeExtension:function(e){var t=e.name,n=e.directives,r=e.types;return t6(["extend union",t,t6(n," "),r&&0!==r.length?"= "+t6(r," | "):""]," ")},EnumTypeExtension:function(e){var t=e.name,n=e.directives,r=e.values;return t6(["extend enum",t,t6(n," "),t5(r)]," ")},InputObjectTypeExtension:function(e){var t=e.name,n=e.directives,r=e.fields;return t6(["extend input",t,t6(n," "),t5(r)]," ")}};function t4(e){return function(t){return t6([t.description,e(t)],"\n")}}function t6(e){var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return null!==(t=null==e?void 0:e.filter(function(e){return e}).join(n))&&void 0!==t?t:""}function t5(e){return t8("{\n",t9(t6(e,"\n")),"\n}")}function t8(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";return null!=t&&""!==t?e+t+n:""}function t9(e){return t8(" ",e.replace(/\n/g,"\n "))}function t7(e){return -1!==e.indexOf("\n")}function ne(e){return null!=e&&e.some(t7)}var nt,nn,nr,ni={http:{includeQuery:!0,includeExtensions:!1,preserveHeaderCase:!1},headers:{accept:"*/*","content-type":"application/json"},options:{method:"POST"}},na=function(e,t){return t(e)};function no(e,t){for(var n=[],r=2;rObject.create(null),{forEach:nv,slice:ny}=Array.prototype,{hasOwnProperty:nw}=Object.prototype;class n_{constructor(e=!0,t=ng){this.weakness=e,this.makeData=t}lookup(...e){return this.lookupArray(e)}lookupArray(e){let t=this;return nv.call(e,e=>t=t.getChildTrie(e)),nw.call(t,"data")?t.data:t.data=this.makeData(ny.call(e))}peek(...e){return this.peekArray(e)}peekArray(e){let t=this;for(let n=0,r=e.length;t&&n=0;--o)t.definitions[o].kind===nL.h.OPERATION_DEFINITION&&++a;var s=nN(e),u=e.some(function(e){return e.remove}),c=function(e){return u&&e&&e.some(s)},l=new Map,f=!1,d={enter:function(e){if(c(e.directives))return f=!0,null}},h=tl(t,{Field:d,InlineFragment:d,VariableDefinition:{enter:function(){return!1}},Variable:{enter:function(e,t,n,r,a){var o=i(a);o&&o.variables.add(e.name.value)}},FragmentSpread:{enter:function(e,t,n,r,a){if(c(e.directives))return f=!0,null;var o=i(a);o&&o.fragmentSpreads.add(e.name.value)}},FragmentDefinition:{enter:function(e,t,n,r){l.set(JSON.stringify(r),e)},leave:function(e,t,n,i){return e===l.get(JSON.stringify(i))?e:a>0&&e.selectionSet.selections.every(function(e){return e.kind===nL.h.FIELD&&"__typename"===e.name.value})?(r(e.name.value).removed=!0,f=!0,null):void 0}},Directive:{leave:function(e){if(s(e))return f=!0,null}}});if(!f)return t;var p=function(e){return e.transitiveVars||(e.transitiveVars=new Set(e.variables),e.removed||e.fragmentSpreads.forEach(function(t){p(r(t)).transitiveVars.forEach(function(t){e.transitiveVars.add(t)})})),e},b=new Set;h.definitions.forEach(function(e){e.kind===nL.h.OPERATION_DEFINITION?p(n(e.name&&e.name.value)).fragmentSpreads.forEach(function(e){b.add(e)}):e.kind!==nL.h.FRAGMENT_DEFINITION||0!==a||r(e.name.value).removed||b.add(e.name.value)}),b.forEach(function(e){p(r(e)).fragmentSpreads.forEach(function(e){b.add(e)})});var m=function(e){return!!(!b.has(e)||r(e).removed)},g={enter:function(e){if(m(e.name.value))return null}};return nD(tl(h,{FragmentSpread:g,FragmentDefinition:g,OperationDefinition:{leave:function(e){if(e.variableDefinitions){var t=p(n(e.name&&e.name.value)).transitiveVars;if(t.size0},t.prototype.tearDownQuery=function(){this.isTornDown||(this.concast&&this.observer&&(this.concast.removeObserver(this.observer),delete this.concast,delete this.observer),this.stopPolling(),this.subscriptions.forEach(function(e){return e.unsubscribe()}),this.subscriptions.clear(),this.queryManager.stopQuery(this.queryId),this.observers.clear(),this.isTornDown=!0)},t}(eT);function n4(e){var t=e.options,n=t.fetchPolicy,r=t.nextFetchPolicy;return"cache-and-network"===n||"network-only"===n?e.reobserve({fetchPolicy:"cache-first",nextFetchPolicy:function(){return(this.nextFetchPolicy=r,"function"==typeof r)?r.apply(this,arguments):n}}):e.reobserve()}function n6(e){__DEV__&&Q.kG.error("Unhandled error",e.message,e.stack)}function n5(e){__DEV__&&e&&__DEV__&&Q.kG.debug("Missing cache result fields: ".concat(JSON.stringify(e)),e)}function n8(e){return"network-only"===e||"no-cache"===e||"standby"===e}nK(n3);function n9(e){return e.kind===nL.h.FIELD||e.kind===nL.h.FRAGMENT_SPREAD||e.kind===nL.h.INLINE_FRAGMENT}function n7(e){return e.kind===Kind.SCALAR_TYPE_DEFINITION||e.kind===Kind.OBJECT_TYPE_DEFINITION||e.kind===Kind.INTERFACE_TYPE_DEFINITION||e.kind===Kind.UNION_TYPE_DEFINITION||e.kind===Kind.ENUM_TYPE_DEFINITION||e.kind===Kind.INPUT_OBJECT_TYPE_DEFINITION}function re(e){return e.kind===Kind.SCALAR_TYPE_EXTENSION||e.kind===Kind.OBJECT_TYPE_EXTENSION||e.kind===Kind.INTERFACE_TYPE_EXTENSION||e.kind===Kind.UNION_TYPE_EXTENSION||e.kind===Kind.ENUM_TYPE_EXTENSION||e.kind===Kind.INPUT_OBJECT_TYPE_EXTENSION}var rt=function(){return Object.create(null)},rn=Array.prototype,rr=rn.forEach,ri=rn.slice,ra=function(){function e(e,t){void 0===e&&(e=!0),void 0===t&&(t=rt),this.weakness=e,this.makeData=t}return e.prototype.lookup=function(){for(var e=[],t=0;tclass{constructor(){this.id=["slot",rc++,Date.now(),Math.random().toString(36).slice(2),].join(":")}hasValue(){for(let e=rs;e;e=e.parent)if(this.id in e.slots){let t=e.slots[this.id];if(t===ru)break;return e!==rs&&(rs.slots[this.id]=t),!0}return rs&&(rs.slots[this.id]=ru),!1}getValue(){if(this.hasValue())return rs.slots[this.id]}withValue(e,t,n,r){let i={__proto__:null,[this.id]:e},a=rs;rs={parent:a,slots:i};try{return t.apply(r,n)}finally{rs=a}}static bind(e){let t=rs;return function(){let n=rs;try{return rs=t,e.apply(this,arguments)}finally{rs=n}}}static noContext(e,t,n){if(!rs)return e.apply(n,t);{let r=rs;try{return rs=null,e.apply(n,t)}finally{rs=r}}}};function rf(e){try{return e()}catch(t){}}let rd="@wry/context:Slot",rh=rf(()=>globalThis)||rf(()=>global)||Object.create(null),rp=rh,rb=rp[rd]||Array[rd]||function(e){try{Object.defineProperty(rp,rd,{value:e,enumerable:!1,writable:!1,configurable:!0})}finally{return e}}(rl()),{bind:rm,noContext:rg}=rb;function rv(){}var ry=function(){function e(e,t){void 0===e&&(e=1/0),void 0===t&&(t=rv),this.max=e,this.dispose=t,this.map=new Map,this.newest=null,this.oldest=null}return e.prototype.has=function(e){return this.map.has(e)},e.prototype.get=function(e){var t=this.getNode(e);return t&&t.value},e.prototype.getNode=function(e){var t=this.map.get(e);if(t&&t!==this.newest){var n=t.older,r=t.newer;r&&(r.older=n),n&&(n.newer=r),t.older=this.newest,t.older.newer=t,t.newer=null,this.newest=t,t===this.oldest&&(this.oldest=r)}return t},e.prototype.set=function(e,t){var n=this.getNode(e);return n?n.value=t:(n={key:e,value:t,newer:null,older:this.newest},this.newest&&(this.newest.newer=n),this.newest=n,this.oldest=this.oldest||n,this.map.set(e,n),n.value)},e.prototype.clean=function(){for(;this.oldest&&this.map.size>this.max;)this.delete(this.oldest.key)},e.prototype.delete=function(e){var t=this.map.get(e);return!!t&&(t===this.newest&&(this.newest=t.older),t===this.oldest&&(this.oldest=t.newer),t.newer&&(t.newer.older=t.older),t.older&&(t.older.newer=t.newer),this.map.delete(e),this.dispose(t.value,e),!0)},e}(),rw=new rb,r_=Object.prototype.hasOwnProperty,rE=void 0===(n=Array.from)?function(e){var t=[];return e.forEach(function(e){return t.push(e)}),t}:n;function rS(e){var t=e.unsubscribe;"function"==typeof t&&(e.unsubscribe=void 0,t())}var rk=[],rx=100;function rT(e,t){if(!e)throw Error(t||"assertion failure")}function rM(e,t){var n=e.length;return n>0&&n===t.length&&e[n-1]===t[n-1]}function rO(e){switch(e.length){case 0:throw Error("unknown value");case 1:return e[0];case 2:throw e[1]}}function rA(e){return e.slice(0)}var rL=function(){function e(t){this.fn=t,this.parents=new Set,this.childValues=new Map,this.dirtyChildren=null,this.dirty=!0,this.recomputing=!1,this.value=[],this.deps=null,++e.count}return e.prototype.peek=function(){if(1===this.value.length&&!rN(this))return rC(this),this.value[0]},e.prototype.recompute=function(e){return rT(!this.recomputing,"already recomputing"),rC(this),rN(this)?rI(this,e):rO(this.value)},e.prototype.setDirty=function(){this.dirty||(this.dirty=!0,this.value.length=0,rR(this),rS(this))},e.prototype.dispose=function(){var e=this;this.setDirty(),rH(this),rF(this,function(t,n){t.setDirty(),r$(t,e)})},e.prototype.forget=function(){this.dispose()},e.prototype.dependOn=function(e){e.add(this),this.deps||(this.deps=rk.pop()||new Set),this.deps.add(e)},e.prototype.forgetDeps=function(){var e=this;this.deps&&(rE(this.deps).forEach(function(t){return t.delete(e)}),this.deps.clear(),rk.push(this.deps),this.deps=null)},e.count=0,e}();function rC(e){var t=rw.getValue();if(t)return e.parents.add(t),t.childValues.has(e)||t.childValues.set(e,[]),rN(e)?rY(t,e):rB(t,e),t}function rI(e,t){return rH(e),rw.withValue(e,rD,[e,t]),rz(e,t)&&rP(e),rO(e.value)}function rD(e,t){e.recomputing=!0,e.value.length=0;try{e.value[0]=e.fn.apply(null,t)}catch(n){e.value[1]=n}e.recomputing=!1}function rN(e){return e.dirty||!!(e.dirtyChildren&&e.dirtyChildren.size)}function rP(e){e.dirty=!1,!rN(e)&&rj(e)}function rR(e){rF(e,rY)}function rj(e){rF(e,rB)}function rF(e,t){var n=e.parents.size;if(n)for(var r=rE(e.parents),i=0;i0&&e.childValues.forEach(function(t,n){r$(e,n)}),e.forgetDeps(),rT(null===e.dirtyChildren)}function r$(e,t){t.parents.delete(e),e.childValues.delete(t),rU(e,t)}function rz(e,t){if("function"==typeof e.subscribe)try{rS(e),e.unsubscribe=e.subscribe.apply(null,t)}catch(n){return e.setDirty(),!1}return!0}var rG={setDirty:!0,dispose:!0,forget:!0};function rW(e){var t=new Map,n=e&&e.subscribe;function r(e){var r=rw.getValue();if(r){var i=t.get(e);i||t.set(e,i=new Set),r.dependOn(i),"function"==typeof n&&(rS(i),i.unsubscribe=n(e))}}return r.dirty=function(e,n){var r=t.get(e);if(r){var i=n&&r_.call(rG,n)?n:"setDirty";rE(r).forEach(function(e){return e[i]()}),t.delete(e),rS(r)}},r}function rK(){var e=new ra("function"==typeof WeakMap);return function(){return e.lookupArray(arguments)}}var rV=rK(),rq=new Set;function rZ(e,t){void 0===t&&(t=Object.create(null));var n=new ry(t.max||65536,function(e){return e.dispose()}),r=t.keyArgs,i=t.makeCacheKey||rK(),a=function(){var a=i.apply(null,r?r.apply(null,arguments):arguments);if(void 0===a)return e.apply(null,arguments);var o=n.get(a);o||(n.set(a,o=new rL(e)),o.subscribe=t.subscribe,o.forget=function(){return n.delete(a)});var s=o.recompute(Array.prototype.slice.call(arguments));return n.set(a,o),rq.add(n),rw.hasValue()||(rq.forEach(function(e){return e.clean()}),rq.clear()),s};function o(e){var t=n.get(e);t&&t.setDirty()}function s(e){var t=n.get(e);if(t)return t.peek()}function u(e){return n.delete(e)}return Object.defineProperty(a,"size",{get:function(){return n.map.size},configurable:!1,enumerable:!1}),a.dirtyKey=o,a.dirty=function(){o(i.apply(null,arguments))},a.peekKey=s,a.peek=function(){return s(i.apply(null,arguments))},a.forgetKey=u,a.forget=function(){return u(i.apply(null,arguments))},a.makeCacheKey=i,a.getKey=r?function(){return i.apply(null,r.apply(null,arguments))}:i,Object.freeze(a)}var rX=new rb,rJ=new WeakMap;function rQ(e){var t=rJ.get(e);return t||rJ.set(e,t={vars:new Set,dep:rW()}),t}function r1(e){rQ(e).vars.forEach(function(t){return t.forgetCache(e)})}function r0(e){rQ(e).vars.forEach(function(t){return t.attachCache(e)})}function r2(e){var t=new Set,n=new Set,r=function(a){if(arguments.length>0){if(e!==a){e=a,t.forEach(function(e){rQ(e).dep.dirty(r),r3(e)});var o=Array.from(n);n.clear(),o.forEach(function(t){return t(e)})}}else{var s=rX.getValue();s&&(i(s),rQ(s).dep(r))}return e};r.onNextChange=function(e){return n.add(e),function(){n.delete(e)}};var i=r.attachCache=function(e){return t.add(e),rQ(e).vars.add(r),r};return r.forgetCache=function(e){return t.delete(e)},r}function r3(e){e.broadcastWatches&&e.broadcastWatches()}var r4=function(){function e(e){var t=e.cache,n=e.client,r=e.resolvers,i=e.fragmentMatcher;this.selectionsToResolveCache=new WeakMap,this.cache=t,n&&(this.client=n),r&&this.addResolvers(r),i&&this.setFragmentMatcher(i)}return e.prototype.addResolvers=function(e){var t=this;this.resolvers=this.resolvers||{},Array.isArray(e)?e.forEach(function(e){t.resolvers=tj(t.resolvers,e)}):this.resolvers=tj(this.resolvers,e)},e.prototype.setResolvers=function(e){this.resolvers={},this.addResolvers(e)},e.prototype.getResolvers=function(){return this.resolvers||{}},e.prototype.runResolvers=function(e){var t=e.document,n=e.remoteResult,r=e.context,i=e.variables,a=e.onlyRunForcedResolvers,o=void 0!==a&&a;return(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(e){return t?[2,this.resolveDocument(t,n.data,r,i,this.fragmentMatcher,o).then(function(e){return(0,en.pi)((0,en.pi)({},n),{data:e.result})})]:[2,n]})})},e.prototype.setFragmentMatcher=function(e){this.fragmentMatcher=e},e.prototype.getFragmentMatcher=function(){return this.fragmentMatcher},e.prototype.clientQuery=function(e){return tb(["client"],e)&&this.resolvers?e:null},e.prototype.serverQuery=function(e){return n$(e)},e.prototype.prepareContext=function(e){var t=this.cache;return(0,en.pi)((0,en.pi)({},e),{cache:t,getCacheKey:function(e){return t.identify(e)}})},e.prototype.addExportedVariables=function(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(r){return e?[2,this.resolveDocument(e,this.buildRootValueFromCache(e,t)||{},this.prepareContext(n),t).then(function(e){return(0,en.pi)((0,en.pi)({},t),e.exportedVariables)})]:[2,(0,en.pi)({},t)]})})},e.prototype.shouldForceResolvers=function(e){var t=!1;return tl(e,{Directive:{enter:function(e){if("client"===e.name.value&&e.arguments&&(t=e.arguments.some(function(e){return"always"===e.name.value&&"BooleanValue"===e.value.kind&&!0===e.value.value})))return tc}}}),t},e.prototype.buildRootValueFromCache=function(e,t){return this.cache.diff({query:nH(e),variables:t,returnPartialData:!0,optimistic:!1}).result},e.prototype.resolveDocument=function(e,t,n,r,i,a){return void 0===n&&(n={}),void 0===r&&(r={}),void 0===i&&(i=function(){return!0}),void 0===a&&(a=!1),(0,en.mG)(this,void 0,void 0,function(){var o,s,u,c,l,f,d,h,p,b,m;return(0,en.Jh)(this,function(g){return o=e8(e),s=e4(e),u=eL(s),c=this.collectSelectionsToResolve(o,u),f=(l=o.operation)?l.charAt(0).toUpperCase()+l.slice(1):"Query",d=this,h=d.cache,p=d.client,b={fragmentMap:u,context:(0,en.pi)((0,en.pi)({},n),{cache:h,client:p}),variables:r,fragmentMatcher:i,defaultOperationType:f,exportedVariables:{},selectionsToResolve:c,onlyRunForcedResolvers:a},m=!1,[2,this.resolveSelectionSet(o.selectionSet,m,t,b).then(function(e){return{result:e,exportedVariables:b.exportedVariables}})]})})},e.prototype.resolveSelectionSet=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c=this;return(0,en.Jh)(this,function(l){return i=r.fragmentMap,a=r.context,o=r.variables,s=[n],u=function(e){return(0,en.mG)(c,void 0,void 0,function(){var u,c;return(0,en.Jh)(this,function(l){return(t||r.selectionsToResolve.has(e))&&td(e,o)?eQ(e)?[2,this.resolveField(e,t,n,r).then(function(t){var n;void 0!==t&&s.push(((n={})[eX(e)]=t,n))})]:(e1(e)?u=e:(u=i[e.name.value],__DEV__?(0,Q.kG)(u,"No fragment named ".concat(e.name.value)):(0,Q.kG)(u,11)),u&&u.typeCondition&&(c=u.typeCondition.name.value,r.fragmentMatcher(n,c,a)))?[2,this.resolveSelectionSet(u.selectionSet,t,n,r).then(function(e){s.push(e)})]:[2]:[2]})})},[2,Promise.all(e.selections.map(u)).then(function(){return tF(s)})]})})},e.prototype.resolveField=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c,l,f,d,h=this;return(0,en.Jh)(this,function(p){return n?(i=r.variables,a=e.name.value,o=eX(e),s=a!==o,c=Promise.resolve(u=n[o]||n[a]),(!r.onlyRunForcedResolvers||this.shouldForceResolvers(e))&&(l=n.__typename||r.defaultOperationType,(f=this.resolvers&&this.resolvers[l])&&(d=f[s?a:o])&&(c=Promise.resolve(rX.withValue(this.cache,d,[n,eZ(e,i),r.context,{field:e,fragmentMap:r.fragmentMap},])))),[2,c.then(function(n){if(void 0===n&&(n=u),e.directives&&e.directives.forEach(function(e){"export"===e.name.value&&e.arguments&&e.arguments.forEach(function(e){"as"===e.name.value&&"StringValue"===e.value.kind&&(r.exportedVariables[e.value.value]=n)})}),!e.selectionSet||null==n)return n;var i,a,o=null!==(a=null===(i=e.directives)||void 0===i?void 0:i.some(function(e){return"client"===e.name.value}))&&void 0!==a&&a;return Array.isArray(n)?h.resolveSubSelectedArray(e,t||o,n,r):e.selectionSet?h.resolveSelectionSet(e.selectionSet,t||o,n,r):void 0})]):[2,null]})})},e.prototype.resolveSubSelectedArray=function(e,t,n,r){var i=this;return Promise.all(n.map(function(n){return null===n?null:Array.isArray(n)?i.resolveSubSelectedArray(e,t,n,r):e.selectionSet?i.resolveSelectionSet(e.selectionSet,t,n,r):void 0}))},e.prototype.collectSelectionsToResolve=function(e,t){var n=function(e){return!Array.isArray(e)},r=this.selectionsToResolveCache;function i(e){if(!r.has(e)){var a=new Set;r.set(e,a),tl(e,{Directive:function(e,t,r,i,o){"client"===e.name.value&&o.forEach(function(e){n(e)&&n9(e)&&a.add(e)})},FragmentSpread:function(e,r,o,s,u){var c=t[e.name.value];__DEV__?(0,Q.kG)(c,"No fragment named ".concat(e.name.value)):(0,Q.kG)(c,12);var l=i(c);l.size>0&&(u.forEach(function(e){n(e)&&n9(e)&&a.add(e)}),a.add(e),l.forEach(function(e){a.add(e)}))}})}return r.get(e)}return i(e)},e}(),r6=new(t_.mr?WeakMap:Map);function r5(e,t){var n=e[t];"function"==typeof n&&(e[t]=function(){return r6.set(e,(r6.get(e)+1)%1e15),n.apply(this,arguments)})}function r8(e){e.notifyTimeout&&(clearTimeout(e.notifyTimeout),e.notifyTimeout=void 0)}var r9=function(){function e(e,t){void 0===t&&(t=e.generateQueryId()),this.queryId=t,this.listeners=new Set,this.document=null,this.lastRequestId=1,this.subscriptions=new Set,this.stopped=!1,this.dirty=!1,this.observableQuery=null;var n=this.cache=e.cache;r6.has(n)||(r6.set(n,0),r5(n,"evict"),r5(n,"modify"),r5(n,"reset"))}return e.prototype.init=function(e){var t=e.networkStatus||nZ.I.loading;return this.variables&&this.networkStatus!==nZ.I.loading&&!(0,nm.D)(this.variables,e.variables)&&(t=nZ.I.setVariables),(0,nm.D)(e.variables,this.variables)||(this.lastDiff=void 0),Object.assign(this,{document:e.document,variables:e.variables,networkError:null,graphQLErrors:this.graphQLErrors||[],networkStatus:t}),e.observableQuery&&this.setObservableQuery(e.observableQuery),e.lastRequestId&&(this.lastRequestId=e.lastRequestId),this},e.prototype.reset=function(){r8(this),this.dirty=!1},e.prototype.getDiff=function(e){void 0===e&&(e=this.variables);var t=this.getDiffOptions(e);if(this.lastDiff&&(0,nm.D)(t,this.lastDiff.options))return this.lastDiff.diff;this.updateWatch(this.variables=e);var n=this.observableQuery;if(n&&"no-cache"===n.options.fetchPolicy)return{complete:!1};var r=this.cache.diff(t);return this.updateLastDiff(r,t),r},e.prototype.updateLastDiff=function(e,t){this.lastDiff=e?{diff:e,options:t||this.getDiffOptions()}:void 0},e.prototype.getDiffOptions=function(e){var t;return void 0===e&&(e=this.variables),{query:this.document,variables:e,returnPartialData:!0,optimistic:!0,canonizeResults:null===(t=this.observableQuery)||void 0===t?void 0:t.options.canonizeResults}},e.prototype.setDiff=function(e){var t=this,n=this.lastDiff&&this.lastDiff.diff;this.updateLastDiff(e),this.dirty||(0,nm.D)(n&&n.result,e&&e.result)||(this.dirty=!0,this.notifyTimeout||(this.notifyTimeout=setTimeout(function(){return t.notify()},0)))},e.prototype.setObservableQuery=function(e){var t=this;e!==this.observableQuery&&(this.oqListener&&this.listeners.delete(this.oqListener),this.observableQuery=e,e?(e.queryInfo=this,this.listeners.add(this.oqListener=function(){t.getDiff().fromOptimisticTransaction?e.observe():n4(e)})):delete this.oqListener)},e.prototype.notify=function(){var e=this;r8(this),this.shouldNotify()&&this.listeners.forEach(function(t){return t(e)}),this.dirty=!1},e.prototype.shouldNotify=function(){if(!this.dirty||!this.listeners.size)return!1;if((0,nZ.O)(this.networkStatus)&&this.observableQuery){var e=this.observableQuery.options.fetchPolicy;if("cache-only"!==e&&"cache-and-network"!==e)return!1}return!0},e.prototype.stop=function(){if(!this.stopped){this.stopped=!0,this.reset(),this.cancel(),this.cancel=e.prototype.cancel,this.subscriptions.forEach(function(e){return e.unsubscribe()});var t=this.observableQuery;t&&t.stopPolling()}},e.prototype.cancel=function(){},e.prototype.updateWatch=function(e){var t=this;void 0===e&&(e=this.variables);var n=this.observableQuery;if(!n||"no-cache"!==n.options.fetchPolicy){var r=(0,en.pi)((0,en.pi)({},this.getDiffOptions(e)),{watcher:this,callback:function(e){return t.setDiff(e)}});this.lastWatch&&(0,nm.D)(r,this.lastWatch)||(this.cancel(),this.cancel=this.cache.watch(this.lastWatch=r))}},e.prototype.resetLastWrite=function(){this.lastWrite=void 0},e.prototype.shouldWrite=function(e,t){var n=this.lastWrite;return!(n&&n.dmCount===r6.get(this.cache)&&(0,nm.D)(t,n.variables)&&(0,nm.D)(e.data,n.result.data))},e.prototype.markResult=function(e,t,n,r){var i=this,a=new tB,o=(0,tP.O)(e.errors)?e.errors.slice(0):[];if(this.reset(),"incremental"in e&&(0,tP.O)(e.incremental)){var s=tG(this.getDiff().result,e);e.data=s}else if("hasNext"in e&&e.hasNext){var u=this.getDiff();e.data=a.merge(u.result,e.data)}this.graphQLErrors=o,"no-cache"===n.fetchPolicy?this.updateLastDiff({result:e.data,complete:!0},this.getDiffOptions(n.variables)):0!==r&&(r7(e,n.errorPolicy)?this.cache.performTransaction(function(a){if(i.shouldWrite(e,n.variables))a.writeQuery({query:t,data:e.data,variables:n.variables,overwrite:1===r}),i.lastWrite={result:e,variables:n.variables,dmCount:r6.get(i.cache)};else if(i.lastDiff&&i.lastDiff.diff.complete){e.data=i.lastDiff.diff.result;return}var o=i.getDiffOptions(n.variables),s=a.diff(o);i.stopped||i.updateWatch(n.variables),i.updateLastDiff(s,o),s.complete&&(e.data=s.result)}):this.lastWrite=void 0)},e.prototype.markReady=function(){return this.networkError=null,this.networkStatus=nZ.I.ready},e.prototype.markError=function(e){return this.networkStatus=nZ.I.error,this.lastWrite=void 0,this.reset(),e.graphQLErrors&&(this.graphQLErrors=e.graphQLErrors),e.networkError&&(this.networkError=e.networkError),e},e}();function r7(e,t){void 0===t&&(t="none");var n="ignore"===t||"all"===t,r=!nO(e);return!r&&n&&e.data&&(r=!0),r}var ie=Object.prototype.hasOwnProperty,it=function(){function e(e){var t=e.cache,n=e.link,r=e.defaultOptions,i=e.queryDeduplication,a=void 0!==i&&i,o=e.onBroadcast,s=e.ssrMode,u=void 0!==s&&s,c=e.clientAwareness,l=void 0===c?{}:c,f=e.localState,d=e.assumeImmutableResults;this.clientAwareness={},this.queries=new Map,this.fetchCancelFns=new Map,this.transformCache=new(t_.mr?WeakMap:Map),this.queryIdCounter=1,this.requestIdCounter=1,this.mutationIdCounter=1,this.inFlightLinkObservables=new Map,this.cache=t,this.link=n,this.defaultOptions=r||Object.create(null),this.queryDeduplication=a,this.clientAwareness=l,this.localState=f||new r4({cache:t}),this.ssrMode=u,this.assumeImmutableResults=!!d,(this.onBroadcast=o)&&(this.mutationStore=Object.create(null))}return e.prototype.stop=function(){var e=this;this.queries.forEach(function(t,n){e.stopQueryNoBroadcast(n)}),this.cancelPendingFetches(__DEV__?new Q.ej("QueryManager stopped while query was in flight"):new Q.ej(14))},e.prototype.cancelPendingFetches=function(e){this.fetchCancelFns.forEach(function(t){return t(e)}),this.fetchCancelFns.clear()},e.prototype.mutate=function(e){var t,n,r=e.mutation,i=e.variables,a=e.optimisticResponse,o=e.updateQueries,s=e.refetchQueries,u=void 0===s?[]:s,c=e.awaitRefetchQueries,l=void 0!==c&&c,f=e.update,d=e.onQueryUpdated,h=e.fetchPolicy,p=void 0===h?(null===(t=this.defaultOptions.mutate)||void 0===t?void 0:t.fetchPolicy)||"network-only":h,b=e.errorPolicy,m=void 0===b?(null===(n=this.defaultOptions.mutate)||void 0===n?void 0:n.errorPolicy)||"none":b,g=e.keepRootFields,v=e.context;return(0,en.mG)(this,void 0,void 0,function(){var e,t,n,s,c,h;return(0,en.Jh)(this,function(b){switch(b.label){case 0:if(__DEV__?(0,Q.kG)(r,"mutation option is required. You must specify your GraphQL document in the mutation option."):(0,Q.kG)(r,15),__DEV__?(0,Q.kG)("network-only"===p||"no-cache"===p,"Mutations support only 'network-only' or 'no-cache' fetchPolicy strings. The default `network-only` behavior automatically writes mutation results to the cache. Passing `no-cache` skips the cache write."):(0,Q.kG)("network-only"===p||"no-cache"===p,16),e=this.generateMutationId(),n=(t=this.transform(r)).document,s=t.hasClientExports,r=this.cache.transformForLink(n),i=this.getVariables(r,i),!s)return[3,2];return[4,this.localState.addExportedVariables(r,i,v)];case 1:i=b.sent(),b.label=2;case 2:return c=this.mutationStore&&(this.mutationStore[e]={mutation:r,variables:i,loading:!0,error:null}),a&&this.markMutationOptimistic(a,{mutationId:e,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,updateQueries:o,update:f,keepRootFields:g}),this.broadcastQueries(),h=this,[2,new Promise(function(t,n){return nM(h.getObservableFromLink(r,(0,en.pi)((0,en.pi)({},v),{optimisticResponse:a}),i,!1),function(t){if(nO(t)&&"none"===m)throw new tN.cA({graphQLErrors:nA(t)});c&&(c.loading=!1,c.error=null);var n=(0,en.pi)({},t);return"function"==typeof u&&(u=u(n)),"ignore"===m&&nO(n)&&delete n.errors,h.markMutationResult({mutationId:e,result:n,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,update:f,updateQueries:o,awaitRefetchQueries:l,refetchQueries:u,removeOptimistic:a?e:void 0,onQueryUpdated:d,keepRootFields:g})}).subscribe({next:function(e){h.broadcastQueries(),"hasNext"in e&&!1!==e.hasNext||t(e)},error:function(t){c&&(c.loading=!1,c.error=t),a&&h.cache.removeOptimistic(e),h.broadcastQueries(),n(t instanceof tN.cA?t:new tN.cA({networkError:t}))}})})]}})})},e.prototype.markMutationResult=function(e,t){var n=this;void 0===t&&(t=this.cache);var r=e.result,i=[],a="no-cache"===e.fetchPolicy;if(!a&&r7(r,e.errorPolicy)){if(tU(r)||i.push({result:r.data,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}),tU(r)&&(0,tP.O)(r.incremental)){var o=t.diff({id:"ROOT_MUTATION",query:this.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0}),s=void 0;o.result&&(s=tG(o.result,r)),void 0!==s&&(r.data=s,i.push({result:s,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}))}var u=e.updateQueries;u&&this.queries.forEach(function(e,a){var o=e.observableQuery,s=o&&o.queryName;if(s&&ie.call(u,s)){var c,l=u[s],f=n.queries.get(a),d=f.document,h=f.variables,p=t.diff({query:d,variables:h,returnPartialData:!0,optimistic:!1}),b=p.result;if(p.complete&&b){var m=l(b,{mutationResult:r,queryName:d&&e3(d)||void 0,queryVariables:h});m&&i.push({result:m,dataId:"ROOT_QUERY",query:d,variables:h})}}})}if(i.length>0||e.refetchQueries||e.update||e.onQueryUpdated||e.removeOptimistic){var c=[];if(this.refetchQueries({updateCache:function(t){a||i.forEach(function(e){return t.write(e)});var o=e.update,s=!t$(r)||tU(r)&&!r.hasNext;if(o){if(!a){var u=t.diff({id:"ROOT_MUTATION",query:n.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0});u.complete&&("incremental"in(r=(0,en.pi)((0,en.pi)({},r),{data:u.result}))&&delete r.incremental,"hasNext"in r&&delete r.hasNext)}s&&o(t,r,{context:e.context,variables:e.variables})}a||e.keepRootFields||!s||t.modify({id:"ROOT_MUTATION",fields:function(e,t){var n=t.fieldName,r=t.DELETE;return"__typename"===n?e:r}})},include:e.refetchQueries,optimistic:!1,removeOptimistic:e.removeOptimistic,onQueryUpdated:e.onQueryUpdated||null}).forEach(function(e){return c.push(e)}),e.awaitRefetchQueries||e.onQueryUpdated)return Promise.all(c).then(function(){return r})}return Promise.resolve(r)},e.prototype.markMutationOptimistic=function(e,t){var n=this,r="function"==typeof e?e(t.variables):e;return this.cache.recordOptimisticTransaction(function(e){try{n.markMutationResult((0,en.pi)((0,en.pi)({},t),{result:{data:r}}),e)}catch(i){__DEV__&&Q.kG.error(i)}},t.mutationId)},e.prototype.fetchQuery=function(e,t,n){return this.fetchQueryObservable(e,t,n).promise},e.prototype.getQueryStore=function(){var e=Object.create(null);return this.queries.forEach(function(t,n){e[n]={variables:t.variables,networkStatus:t.networkStatus,networkError:t.networkError,graphQLErrors:t.graphQLErrors}}),e},e.prototype.resetErrors=function(e){var t=this.queries.get(e);t&&(t.networkError=void 0,t.graphQLErrors=[])},e.prototype.transform=function(e){var t=this.transformCache;if(!t.has(e)){var n=this.cache.transformDocument(e),r=nY(n),i=this.localState.clientQuery(n),a=r&&this.localState.serverQuery(r),o={document:n,hasClientExports:tm(n),hasForcedResolvers:this.localState.shouldForceResolvers(n),clientQuery:i,serverQuery:a,defaultVars:e9(e2(n)),asQuery:(0,en.pi)((0,en.pi)({},n),{definitions:n.definitions.map(function(e){return"OperationDefinition"===e.kind&&"query"!==e.operation?(0,en.pi)((0,en.pi)({},e),{operation:"query"}):e})})},s=function(e){e&&!t.has(e)&&t.set(e,o)};s(e),s(n),s(i),s(a)}return t.get(e)},e.prototype.getVariables=function(e,t){return(0,en.pi)((0,en.pi)({},this.transform(e).defaultVars),t)},e.prototype.watchQuery=function(e){void 0===(e=(0,en.pi)((0,en.pi)({},e),{variables:this.getVariables(e.query,e.variables)})).notifyOnNetworkStatusChange&&(e.notifyOnNetworkStatusChange=!1);var t=new r9(this),n=new n3({queryManager:this,queryInfo:t,options:e});return this.queries.set(n.queryId,t),t.init({document:n.query,observableQuery:n,variables:n.variables}),n},e.prototype.query=function(e,t){var n=this;return void 0===t&&(t=this.generateQueryId()),__DEV__?(0,Q.kG)(e.query,"query option is required. You must specify your GraphQL document in the query option."):(0,Q.kG)(e.query,17),__DEV__?(0,Q.kG)("Document"===e.query.kind,'You must wrap the query string in a "gql" tag.'):(0,Q.kG)("Document"===e.query.kind,18),__DEV__?(0,Q.kG)(!e.returnPartialData,"returnPartialData option only supported on watchQuery."):(0,Q.kG)(!e.returnPartialData,19),__DEV__?(0,Q.kG)(!e.pollInterval,"pollInterval option only supported on watchQuery."):(0,Q.kG)(!e.pollInterval,20),this.fetchQuery(t,e).finally(function(){return n.stopQuery(t)})},e.prototype.generateQueryId=function(){return String(this.queryIdCounter++)},e.prototype.generateRequestId=function(){return this.requestIdCounter++},e.prototype.generateMutationId=function(){return String(this.mutationIdCounter++)},e.prototype.stopQueryInStore=function(e){this.stopQueryInStoreNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryInStoreNoBroadcast=function(e){var t=this.queries.get(e);t&&t.stop()},e.prototype.clearStore=function(e){return void 0===e&&(e={discardWatches:!0}),this.cancelPendingFetches(__DEV__?new Q.ej("Store reset while query was in flight (not completed in link chain)"):new Q.ej(21)),this.queries.forEach(function(e){e.observableQuery?e.networkStatus=nZ.I.loading:e.stop()}),this.mutationStore&&(this.mutationStore=Object.create(null)),this.cache.reset(e)},e.prototype.getObservableQueries=function(e){var t=this;void 0===e&&(e="active");var n=new Map,r=new Map,i=new Set;return Array.isArray(e)&&e.forEach(function(e){"string"==typeof e?r.set(e,!1):eN(e)?r.set(t.transform(e).document,!1):(0,eO.s)(e)&&e.query&&i.add(e)}),this.queries.forEach(function(t,i){var a=t.observableQuery,o=t.document;if(a){if("all"===e){n.set(i,a);return}var s=a.queryName;if("standby"===a.options.fetchPolicy||"active"===e&&!a.hasObservers())return;("active"===e||s&&r.has(s)||o&&r.has(o))&&(n.set(i,a),s&&r.set(s,!0),o&&r.set(o,!0))}}),i.size&&i.forEach(function(e){var r=nG("legacyOneTimeQuery"),i=t.getQuery(r).init({document:e.query,variables:e.variables}),a=new n3({queryManager:t,queryInfo:i,options:(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"network-only"})});(0,Q.kG)(a.queryId===r),i.setObservableQuery(a),n.set(r,a)}),__DEV__&&r.size&&r.forEach(function(e,t){!e&&__DEV__&&Q.kG.warn("Unknown query ".concat("string"==typeof t?"named ":"").concat(JSON.stringify(t,null,2)," requested in refetchQueries options.include array"))}),n},e.prototype.reFetchObservableQueries=function(e){var t=this;void 0===e&&(e=!1);var n=[];return this.getObservableQueries(e?"all":"active").forEach(function(r,i){var a=r.options.fetchPolicy;r.resetLastResults(),(e||"standby"!==a&&"cache-only"!==a)&&n.push(r.refetch()),t.getQuery(i).setDiff(null)}),this.broadcastQueries(),Promise.all(n)},e.prototype.setObservableQuery=function(e){this.getQuery(e.queryId).setObservableQuery(e)},e.prototype.startGraphQLSubscription=function(e){var t=this,n=e.query,r=e.fetchPolicy,i=e.errorPolicy,a=e.variables,o=e.context,s=void 0===o?{}:o;n=this.transform(n).document,a=this.getVariables(n,a);var u=function(e){return t.getObservableFromLink(n,s,e).map(function(a){"no-cache"!==r&&(r7(a,i)&&t.cache.write({query:n,result:a.data,dataId:"ROOT_SUBSCRIPTION",variables:e}),t.broadcastQueries());var o=nO(a),s=(0,tN.ls)(a);if(o||s){var u={};throw o&&(u.graphQLErrors=a.errors),s&&(u.protocolErrors=a.extensions[tN.YG]),new tN.cA(u)}return a})};if(this.transform(n).hasClientExports){var c=this.localState.addExportedVariables(n,a,s).then(u);return new eT(function(e){var t=null;return c.then(function(n){return t=n.subscribe(e)},e.error),function(){return t&&t.unsubscribe()}})}return u(a)},e.prototype.stopQuery=function(e){this.stopQueryNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryNoBroadcast=function(e){this.stopQueryInStoreNoBroadcast(e),this.removeQuery(e)},e.prototype.removeQuery=function(e){this.fetchCancelFns.delete(e),this.queries.has(e)&&(this.getQuery(e).stop(),this.queries.delete(e))},e.prototype.broadcastQueries=function(){this.onBroadcast&&this.onBroadcast(),this.queries.forEach(function(e){return e.notify()})},e.prototype.getLocalState=function(){return this.localState},e.prototype.getObservableFromLink=function(e,t,n,r){var i,a,o=this;void 0===r&&(r=null!==(i=null==t?void 0:t.queryDeduplication)&&void 0!==i?i:this.queryDeduplication);var s=this.transform(e).serverQuery;if(s){var u=this,c=u.inFlightLinkObservables,l=u.link,f={query:s,variables:n,operationName:e3(s)||void 0,context:this.prepareContext((0,en.pi)((0,en.pi)({},t),{forceFetch:!r}))};if(t=f.context,r){var d=c.get(s)||new Map;c.set(s,d);var h=nx(n);if(!(a=d.get(h))){var p=new nq([np(l,f)]);d.set(h,a=p),p.beforeNext(function(){d.delete(h)&&d.size<1&&c.delete(s)})}}else a=new nq([np(l,f)])}else a=new nq([eT.of({data:{}})]),t=this.prepareContext(t);var b=this.transform(e).clientQuery;return b&&(a=nM(a,function(e){return o.localState.runResolvers({document:b,remoteResult:e,context:t,variables:n})})),a},e.prototype.getResultsFromLink=function(e,t,n){var r=e.lastRequestId=this.generateRequestId(),i=this.cache.transformForLink(this.transform(e.document).document);return nM(this.getObservableFromLink(i,n.context,n.variables),function(a){var o=nA(a),s=o.length>0;if(r>=e.lastRequestId){if(s&&"none"===n.errorPolicy)throw e.markError(new tN.cA({graphQLErrors:o}));e.markResult(a,i,n,t),e.markReady()}var u={data:a.data,loading:!1,networkStatus:nZ.I.ready};return s&&"ignore"!==n.errorPolicy&&(u.errors=o,u.networkStatus=nZ.I.error),u},function(t){var n=(0,tN.MS)(t)?t:new tN.cA({networkError:t});throw r>=e.lastRequestId&&e.markError(n),n})},e.prototype.fetchQueryObservable=function(e,t,n){return this.fetchConcastWithInfo(e,t,n).concast},e.prototype.fetchConcastWithInfo=function(e,t,n){var r,i,a=this;void 0===n&&(n=nZ.I.loading);var o=this.transform(t.query).document,s=this.getVariables(o,t.variables),u=this.getQuery(e),c=this.defaultOptions.watchQuery,l=t.fetchPolicy,f=void 0===l?c&&c.fetchPolicy||"cache-first":l,d=t.errorPolicy,h=void 0===d?c&&c.errorPolicy||"none":d,p=t.returnPartialData,b=void 0!==p&&p,m=t.notifyOnNetworkStatusChange,g=void 0!==m&&m,v=t.context,y=void 0===v?{}:v,w=Object.assign({},t,{query:o,variables:s,fetchPolicy:f,errorPolicy:h,returnPartialData:b,notifyOnNetworkStatusChange:g,context:y}),_=function(e){w.variables=e;var r=a.fetchQueryByPolicy(u,w,n);return"standby"!==w.fetchPolicy&&r.sources.length>0&&u.observableQuery&&u.observableQuery.applyNextFetchPolicy("after-fetch",t),r},E=function(){return a.fetchCancelFns.delete(e)};if(this.fetchCancelFns.set(e,function(e){E(),setTimeout(function(){return r.cancel(e)})}),this.transform(w.query).hasClientExports)r=new nq(this.localState.addExportedVariables(w.query,w.variables,w.context).then(_).then(function(e){return e.sources})),i=!0;else{var S=_(w.variables);i=S.fromLink,r=new nq(S.sources)}return r.promise.then(E,E),{concast:r,fromLink:i}},e.prototype.refetchQueries=function(e){var t=this,n=e.updateCache,r=e.include,i=e.optimistic,a=void 0!==i&&i,o=e.removeOptimistic,s=void 0===o?a?nG("refetchQueries"):void 0:o,u=e.onQueryUpdated,c=new Map;r&&this.getObservableQueries(r).forEach(function(e,n){c.set(n,{oq:e,lastDiff:t.getQuery(n).getDiff()})});var l=new Map;return n&&this.cache.batch({update:n,optimistic:a&&s||!1,removeOptimistic:s,onWatchUpdated:function(e,t,n){var r=e.watcher instanceof r9&&e.watcher.observableQuery;if(r){if(u){c.delete(r.queryId);var i=u(r,t,n);return!0===i&&(i=r.refetch()),!1!==i&&l.set(r,i),i}null!==u&&c.set(r.queryId,{oq:r,lastDiff:n,diff:t})}}}),c.size&&c.forEach(function(e,n){var r,i=e.oq,a=e.lastDiff,o=e.diff;if(u){if(!o){var s=i.queryInfo;s.reset(),o=s.getDiff()}r=u(i,o,a)}u&&!0!==r||(r=i.refetch()),!1!==r&&l.set(i,r),n.indexOf("legacyOneTimeQuery")>=0&&t.stopQueryNoBroadcast(n)}),s&&this.cache.removeOptimistic(s),l},e.prototype.fetchQueryByPolicy=function(e,t,n){var r=this,i=t.query,a=t.variables,o=t.fetchPolicy,s=t.refetchWritePolicy,u=t.errorPolicy,c=t.returnPartialData,l=t.context,f=t.notifyOnNetworkStatusChange,d=e.networkStatus;e.init({document:this.transform(i).document,variables:a,networkStatus:n});var h=function(){return e.getDiff(a)},p=function(t,n){void 0===n&&(n=e.networkStatus||nZ.I.loading);var o=t.result;!__DEV__||c||(0,nm.D)(o,{})||n5(t.missing);var s=function(e){return eT.of((0,en.pi)({data:e,loading:(0,nZ.O)(n),networkStatus:n},t.complete?null:{partial:!0}))};return o&&r.transform(i).hasForcedResolvers?r.localState.runResolvers({document:i,remoteResult:{data:o},context:l,variables:a,onlyRunForcedResolvers:!0}).then(function(e){return s(e.data||void 0)}):"none"===u&&n===nZ.I.refetch&&Array.isArray(t.missing)?s(void 0):s(o)},b="no-cache"===o?0:n===nZ.I.refetch&&"merge"!==s?1:2,m=function(){return r.getResultsFromLink(e,b,{variables:a,context:l,fetchPolicy:o,errorPolicy:u})},g=f&&"number"==typeof d&&d!==n&&(0,nZ.O)(n);switch(o){default:case"cache-first":var v=h();if(v.complete)return{fromLink:!1,sources:[p(v,e.markReady())]};if(c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-and-network":var v=h();if(v.complete||c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-only":return{fromLink:!1,sources:[p(h(),e.markReady())]};case"network-only":if(g)return{fromLink:!0,sources:[p(h()),m()]};return{fromLink:!0,sources:[m()]};case"no-cache":if(g)return{fromLink:!0,sources:[p(e.getDiff()),m(),]};return{fromLink:!0,sources:[m()]};case"standby":return{fromLink:!1,sources:[]}}},e.prototype.getQuery=function(e){return e&&!this.queries.has(e)&&this.queries.set(e,new r9(this,e)),this.queries.get(e)},e.prototype.prepareContext=function(e){void 0===e&&(e={});var t=this.localState.prepareContext(e);return(0,en.pi)((0,en.pi)({},t),{clientAwareness:this.clientAwareness})},e}(),ir=__webpack_require__(14012),ii=!1,ia=function(){function e(e){var t=this;this.resetStoreCallbacks=[],this.clearStoreCallbacks=[];var n=e.uri,r=e.credentials,i=e.headers,a=e.cache,o=e.ssrMode,s=void 0!==o&&o,u=e.ssrForceFetchDelay,c=void 0===u?0:u,l=e.connectToDevTools,f=void 0===l?"object"==typeof window&&!window.__APOLLO_CLIENT__&&__DEV__:l,d=e.queryDeduplication,h=void 0===d||d,p=e.defaultOptions,b=e.assumeImmutableResults,m=void 0!==b&&b,g=e.resolvers,v=e.typeDefs,y=e.fragmentMatcher,w=e.name,_=e.version,E=e.link;if(E||(E=n?new nh({uri:n,credentials:r,headers:i}):ta.empty()),!a)throw __DEV__?new Q.ej("To initialize Apollo Client, you must specify a 'cache' property in the options object. \nFor more information, please visit: https://go.apollo.dev/c/docs"):new Q.ej(9);if(this.link=E,this.cache=a,this.disableNetworkFetches=s||c>0,this.queryDeduplication=h,this.defaultOptions=p||Object.create(null),this.typeDefs=v,c&&setTimeout(function(){return t.disableNetworkFetches=!1},c),this.watchQuery=this.watchQuery.bind(this),this.query=this.query.bind(this),this.mutate=this.mutate.bind(this),this.resetStore=this.resetStore.bind(this),this.reFetchObservableQueries=this.reFetchObservableQueries.bind(this),f&&"object"==typeof window&&(window.__APOLLO_CLIENT__=this),!ii&&f&&__DEV__&&(ii=!0,"undefined"!=typeof window&&window.document&&window.top===window.self&&!window.__APOLLO_DEVTOOLS_GLOBAL_HOOK__)){var S=window.navigator,k=S&&S.userAgent,x=void 0;"string"==typeof k&&(k.indexOf("Chrome/")>-1?x="https://chrome.google.com/webstore/detail/apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm":k.indexOf("Firefox/")>-1&&(x="https://addons.mozilla.org/en-US/firefox/addon/apollo-developer-tools/")),x&&__DEV__&&Q.kG.log("Download the Apollo DevTools for a better development experience: "+x)}this.version=nb,this.localState=new r4({cache:a,client:this,resolvers:g,fragmentMatcher:y}),this.queryManager=new it({cache:this.cache,link:this.link,defaultOptions:this.defaultOptions,queryDeduplication:h,ssrMode:s,clientAwareness:{name:w,version:_},localState:this.localState,assumeImmutableResults:m,onBroadcast:f?function(){t.devToolsHookCb&&t.devToolsHookCb({action:{},state:{queries:t.queryManager.getQueryStore(),mutations:t.queryManager.mutationStore||{}},dataWithOptimisticResults:t.cache.extract(!0)})}:void 0})}return e.prototype.stop=function(){this.queryManager.stop()},e.prototype.watchQuery=function(e){return this.defaultOptions.watchQuery&&(e=(0,ir.J)(this.defaultOptions.watchQuery,e)),this.disableNetworkFetches&&("network-only"===e.fetchPolicy||"cache-and-network"===e.fetchPolicy)&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.watchQuery(e)},e.prototype.query=function(e){return this.defaultOptions.query&&(e=(0,ir.J)(this.defaultOptions.query,e)),__DEV__?(0,Q.kG)("cache-and-network"!==e.fetchPolicy,"The cache-and-network fetchPolicy does not work with client.query, because client.query can only return a single result. Please use client.watchQuery to receive multiple results from the cache and the network, or consider using a different fetchPolicy, such as cache-first or network-only."):(0,Q.kG)("cache-and-network"!==e.fetchPolicy,10),this.disableNetworkFetches&&"network-only"===e.fetchPolicy&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.query(e)},e.prototype.mutate=function(e){return this.defaultOptions.mutate&&(e=(0,ir.J)(this.defaultOptions.mutate,e)),this.queryManager.mutate(e)},e.prototype.subscribe=function(e){return this.queryManager.startGraphQLSubscription(e)},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!1),this.cache.readQuery(e,t)},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!1),this.cache.readFragment(e,t)},e.prototype.writeQuery=function(e){var t=this.cache.writeQuery(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.writeFragment=function(e){var t=this.cache.writeFragment(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.__actionHookForDevTools=function(e){this.devToolsHookCb=e},e.prototype.__requestRaw=function(e){return np(this.link,e)},e.prototype.resetStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!1})}).then(function(){return Promise.all(e.resetStoreCallbacks.map(function(e){return e()}))}).then(function(){return e.reFetchObservableQueries()})},e.prototype.clearStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!0})}).then(function(){return Promise.all(e.clearStoreCallbacks.map(function(e){return e()}))})},e.prototype.onResetStore=function(e){var t=this;return this.resetStoreCallbacks.push(e),function(){t.resetStoreCallbacks=t.resetStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.onClearStore=function(e){var t=this;return this.clearStoreCallbacks.push(e),function(){t.clearStoreCallbacks=t.clearStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.reFetchObservableQueries=function(e){return this.queryManager.reFetchObservableQueries(e)},e.prototype.refetchQueries=function(e){var t=this.queryManager.refetchQueries(e),n=[],r=[];t.forEach(function(e,t){n.push(t),r.push(e)});var i=Promise.all(r);return i.queries=n,i.results=r,i.catch(function(e){__DEV__&&Q.kG.debug("In client.refetchQueries, Promise.all promise rejected with error ".concat(e))}),i},e.prototype.getObservableQueries=function(e){return void 0===e&&(e="active"),this.queryManager.getObservableQueries(e)},e.prototype.extract=function(e){return this.cache.extract(e)},e.prototype.restore=function(e){return this.cache.restore(e)},e.prototype.addResolvers=function(e){this.localState.addResolvers(e)},e.prototype.setResolvers=function(e){this.localState.setResolvers(e)},e.prototype.getResolvers=function(){return this.localState.getResolvers()},e.prototype.setLocalStateFragmentMatcher=function(e){this.localState.setFragmentMatcher(e)},e.prototype.setLink=function(e){this.link=this.queryManager.link=e},e}(),io=function(){function e(){this.getFragmentDoc=rZ(eA)}return e.prototype.batch=function(e){var t,n=this,r="string"==typeof e.optimistic?e.optimistic:!1===e.optimistic?null:void 0;return this.performTransaction(function(){return t=e.update(n)},r),t},e.prototype.recordOptimisticTransaction=function(e,t){this.performTransaction(e,t)},e.prototype.transformDocument=function(e){return e},e.prototype.transformForLink=function(e){return e},e.prototype.identify=function(e){},e.prototype.gc=function(){return[]},e.prototype.modify=function(e){return!1},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{rootId:e.id||"ROOT_QUERY",optimistic:t}))},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{query:this.getFragmentDoc(e.fragment,e.fragmentName),rootId:e.id,optimistic:t}))},e.prototype.writeQuery=function(e){var t=e.id,n=e.data,r=(0,en._T)(e,["id","data"]);return this.write(Object.assign(r,{dataId:t||"ROOT_QUERY",result:n}))},e.prototype.writeFragment=function(e){var t=e.id,n=e.data,r=e.fragment,i=e.fragmentName,a=(0,en._T)(e,["id","data","fragment","fragmentName"]);return this.write(Object.assign(a,{query:this.getFragmentDoc(r,i),dataId:t,result:n}))},e.prototype.updateQuery=function(e,t){return this.batch({update:function(n){var r=n.readQuery(e),i=t(r);return null==i?r:(n.writeQuery((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e.prototype.updateFragment=function(e,t){return this.batch({update:function(n){var r=n.readFragment(e),i=t(r);return null==i?r:(n.writeFragment((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e}(),is=function(e){function t(n,r,i,a){var o,s=e.call(this,n)||this;if(s.message=n,s.path=r,s.query=i,s.variables=a,Array.isArray(s.path)){s.missing=s.message;for(var u=s.path.length-1;u>=0;--u)s.missing=((o={})[s.path[u]]=s.missing,o)}else s.missing=s.path;return s.__proto__=t.prototype,s}return(0,en.ZT)(t,e),t}(Error),iu=__webpack_require__(10542),ic=Object.prototype.hasOwnProperty;function il(e){return null==e}function id(e,t){var n=e.__typename,r=e.id,i=e._id;if("string"==typeof n&&(t&&(t.keyObject=il(r)?il(i)?void 0:{_id:i}:{id:r}),il(r)&&!il(i)&&(r=i),!il(r)))return"".concat(n,":").concat("number"==typeof r||"string"==typeof r?r:JSON.stringify(r))}var ih={dataIdFromObject:id,addTypename:!0,resultCaching:!0,canonizeResults:!1};function ip(e){return(0,n1.o)(ih,e)}function ib(e){var t=e.canonizeResults;return void 0===t?ih.canonizeResults:t}function im(e,t){return eD(t)?e.get(t.__ref,"__typename"):t&&t.__typename}var ig=/^[_a-z][_0-9a-z]*/i;function iv(e){var t=e.match(ig);return t?t[0]:e}function iy(e,t,n){return!!(0,eO.s)(t)&&((0,tP.k)(t)?t.every(function(t){return iy(e,t,n)}):e.selections.every(function(e){if(eQ(e)&&td(e,n)){var r=eX(e);return ic.call(t,r)&&(!e.selectionSet||iy(e.selectionSet,t[r],n))}return!0}))}function iw(e){return(0,eO.s)(e)&&!eD(e)&&!(0,tP.k)(e)}function i_(){return new tB}function iE(e,t){var n=eL(e4(e));return{fragmentMap:n,lookupFragment:function(e){var r=n[e];return!r&&t&&(r=t.lookup(e)),r||null}}}var iS=Object.create(null),ik=function(){return iS},ix=Object.create(null),iT=function(){function e(e,t){var n=this;this.policies=e,this.group=t,this.data=Object.create(null),this.rootIds=Object.create(null),this.refs=Object.create(null),this.getFieldValue=function(e,t){return(0,iu.J)(eD(e)?n.get(e.__ref,t):e&&e[t])},this.canRead=function(e){return eD(e)?n.has(e.__ref):"object"==typeof e},this.toReference=function(e,t){if("string"==typeof e)return eI(e);if(eD(e))return e;var r=n.policies.identify(e)[0];if(r){var i=eI(r);return t&&n.merge(r,e),i}}}return e.prototype.toObject=function(){return(0,en.pi)({},this.data)},e.prototype.has=function(e){return void 0!==this.lookup(e,!0)},e.prototype.get=function(e,t){if(this.group.depend(e,t),ic.call(this.data,e)){var n=this.data[e];if(n&&ic.call(n,t))return n[t]}return"__typename"===t&&ic.call(this.policies.rootTypenamesById,e)?this.policies.rootTypenamesById[e]:this instanceof iL?this.parent.get(e,t):void 0},e.prototype.lookup=function(e,t){return(t&&this.group.depend(e,"__exists"),ic.call(this.data,e))?this.data[e]:this instanceof iL?this.parent.lookup(e,t):this.policies.rootTypenamesById[e]?Object.create(null):void 0},e.prototype.merge=function(e,t){var n,r=this;eD(e)&&(e=e.__ref),eD(t)&&(t=t.__ref);var i="string"==typeof e?this.lookup(n=e):e,a="string"==typeof t?this.lookup(n=t):t;if(a){__DEV__?(0,Q.kG)("string"==typeof n,"store.merge expects a string ID"):(0,Q.kG)("string"==typeof n,1);var o=new tB(iI).merge(i,a);if(this.data[n]=o,o!==i&&(delete this.refs[n],this.group.caching)){var s=Object.create(null);i||(s.__exists=1),Object.keys(a).forEach(function(e){if(!i||i[e]!==o[e]){s[e]=1;var t=iv(e);t===e||r.policies.hasKeyArgs(o.__typename,t)||(s[t]=1),void 0!==o[e]||r instanceof iL||delete o[e]}}),s.__typename&&!(i&&i.__typename)&&this.policies.rootTypenamesById[n]===o.__typename&&delete s.__typename,Object.keys(s).forEach(function(e){return r.group.dirty(n,e)})}}},e.prototype.modify=function(e,t){var n=this,r=this.lookup(e);if(r){var i=Object.create(null),a=!1,o=!0,s={DELETE:iS,INVALIDATE:ix,isReference:eD,toReference:this.toReference,canRead:this.canRead,readField:function(t,r){return n.policies.readField("string"==typeof t?{fieldName:t,from:r||eI(e)}:t,{store:n})}};if(Object.keys(r).forEach(function(u){var c=iv(u),l=r[u];if(void 0!==l){var f="function"==typeof t?t:t[u]||t[c];if(f){var d=f===ik?iS:f((0,iu.J)(l),(0,en.pi)((0,en.pi)({},s),{fieldName:c,storeFieldName:u,storage:n.getStorage(e,u)}));d===ix?n.group.dirty(e,u):(d===iS&&(d=void 0),d!==l&&(i[u]=d,a=!0,l=d))}void 0!==l&&(o=!1)}}),a)return this.merge(e,i),o&&(this instanceof iL?this.data[e]=void 0:delete this.data[e],this.group.dirty(e,"__exists")),!0}return!1},e.prototype.delete=function(e,t,n){var r,i=this.lookup(e);if(i){var a=this.getFieldValue(i,"__typename"),o=t&&n?this.policies.getStoreFieldName({typename:a,fieldName:t,args:n}):t;return this.modify(e,o?((r={})[o]=ik,r):ik)}return!1},e.prototype.evict=function(e,t){var n=!1;return e.id&&(ic.call(this.data,e.id)&&(n=this.delete(e.id,e.fieldName,e.args)),this instanceof iL&&this!==t&&(n=this.parent.evict(e,t)||n),(e.fieldName||n)&&this.group.dirty(e.id,e.fieldName||"__exists")),n},e.prototype.clear=function(){this.replace(null)},e.prototype.extract=function(){var e=this,t=this.toObject(),n=[];return this.getRootIdSet().forEach(function(t){ic.call(e.policies.rootTypenamesById,t)||n.push(t)}),n.length&&(t.__META={extraRootIds:n.sort()}),t},e.prototype.replace=function(e){var t=this;if(Object.keys(this.data).forEach(function(n){e&&ic.call(e,n)||t.delete(n)}),e){var n=e.__META,r=(0,en._T)(e,["__META"]);Object.keys(r).forEach(function(e){t.merge(e,r[e])}),n&&n.extraRootIds.forEach(this.retain,this)}},e.prototype.retain=function(e){return this.rootIds[e]=(this.rootIds[e]||0)+1},e.prototype.release=function(e){if(this.rootIds[e]>0){var t=--this.rootIds[e];return t||delete this.rootIds[e],t}return 0},e.prototype.getRootIdSet=function(e){return void 0===e&&(e=new Set),Object.keys(this.rootIds).forEach(e.add,e),this instanceof iL?this.parent.getRootIdSet(e):Object.keys(this.policies.rootTypenamesById).forEach(e.add,e),e},e.prototype.gc=function(){var e=this,t=this.getRootIdSet(),n=this.toObject();t.forEach(function(r){ic.call(n,r)&&(Object.keys(e.findChildRefIds(r)).forEach(t.add,t),delete n[r])});var r=Object.keys(n);if(r.length){for(var i=this;i instanceof iL;)i=i.parent;r.forEach(function(e){return i.delete(e)})}return r},e.prototype.findChildRefIds=function(e){if(!ic.call(this.refs,e)){var t=this.refs[e]=Object.create(null),n=this.data[e];if(!n)return t;var r=new Set([n]);r.forEach(function(e){eD(e)&&(t[e.__ref]=!0),(0,eO.s)(e)&&Object.keys(e).forEach(function(t){var n=e[t];(0,eO.s)(n)&&r.add(n)})})}return this.refs[e]},e.prototype.makeCacheKey=function(){return this.group.keyMaker.lookupArray(arguments)},e}(),iM=function(){function e(e,t){void 0===t&&(t=null),this.caching=e,this.parent=t,this.d=null,this.resetCaching()}return e.prototype.resetCaching=function(){this.d=this.caching?rW():null,this.keyMaker=new n_(t_.mr)},e.prototype.depend=function(e,t){if(this.d){this.d(iO(e,t));var n=iv(t);n!==t&&this.d(iO(e,n)),this.parent&&this.parent.depend(e,t)}},e.prototype.dirty=function(e,t){this.d&&this.d.dirty(iO(e,t),"__exists"===t?"forget":"setDirty")},e}();function iO(e,t){return t+"#"+e}function iA(e,t){iD(e)&&e.group.depend(t,"__exists")}!function(e){var t=function(e){function t(t){var n=t.policies,r=t.resultCaching,i=void 0===r||r,a=t.seed,o=e.call(this,n,new iM(i))||this;return o.stump=new iC(o),o.storageTrie=new n_(t_.mr),a&&o.replace(a),o}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,t){return this.stump.addLayer(e,t)},t.prototype.removeLayer=function(){return this},t.prototype.getStorage=function(){return this.storageTrie.lookupArray(arguments)},t}(e);e.Root=t}(iT||(iT={}));var iL=function(e){function t(t,n,r,i){var a=e.call(this,n.policies,i)||this;return a.id=t,a.parent=n,a.replay=r,a.group=i,r(a),a}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,n){return new t(e,this,n,this.group)},t.prototype.removeLayer=function(e){var t=this,n=this.parent.removeLayer(e);return e===this.id?(this.group.caching&&Object.keys(this.data).forEach(function(e){var r=t.data[e],i=n.lookup(e);i?r?r!==i&&Object.keys(r).forEach(function(n){(0,nm.D)(r[n],i[n])||t.group.dirty(e,n)}):(t.group.dirty(e,"__exists"),Object.keys(i).forEach(function(n){t.group.dirty(e,n)})):t.delete(e)}),n):n===this.parent?this:n.addLayer(this.id,this.replay)},t.prototype.toObject=function(){return(0,en.pi)((0,en.pi)({},this.parent.toObject()),this.data)},t.prototype.findChildRefIds=function(t){var n=this.parent.findChildRefIds(t);return ic.call(this.data,t)?(0,en.pi)((0,en.pi)({},n),e.prototype.findChildRefIds.call(this,t)):n},t.prototype.getStorage=function(){for(var e=this.parent;e.parent;)e=e.parent;return e.getStorage.apply(e,arguments)},t}(iT),iC=function(e){function t(t){return e.call(this,"EntityStore.Stump",t,function(){},new iM(t.group.caching,t.group))||this}return(0,en.ZT)(t,e),t.prototype.removeLayer=function(){return this},t.prototype.merge=function(){return this.parent.merge.apply(this.parent,arguments)},t}(iL);function iI(e,t,n){var r=e[n],i=t[n];return(0,nm.D)(r,i)?r:i}function iD(e){return!!(e instanceof iT&&e.group.caching)}function iN(e){return[e.selectionSet,e.objectOrReference,e.context,e.context.canonizeResults,]}var iP=function(){function e(e){var t=this;this.knownResults=new(t_.mr?WeakMap:Map),this.config=(0,n1.o)(e,{addTypename:!1!==e.addTypename,canonizeResults:ib(e)}),this.canon=e.canon||new nk,this.executeSelectionSet=rZ(function(e){var n,r=e.context.canonizeResults,i=iN(e);i[3]=!r;var a=(n=t.executeSelectionSet).peek.apply(n,i);return a?r?(0,en.pi)((0,en.pi)({},a),{result:t.canon.admit(a.result)}):a:(iA(e.context.store,e.enclosingRef.__ref),t.execSelectionSetImpl(e))},{max:this.config.resultCacheMaxSize,keyArgs:iN,makeCacheKey:function(e,t,n,r){if(iD(n.store))return n.store.makeCacheKey(e,eD(t)?t.__ref:t,n.varString,r)}}),this.executeSubSelectedArray=rZ(function(e){return iA(e.context.store,e.enclosingRef.__ref),t.execSubSelectedArrayImpl(e)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var t=e.field,n=e.array,r=e.context;if(iD(r.store))return r.store.makeCacheKey(t,n,r.varString)}})}return e.prototype.resetCanon=function(){this.canon=new nk},e.prototype.diffQueryAgainstStore=function(e){var t,n=e.store,r=e.query,i=e.rootId,a=void 0===i?"ROOT_QUERY":i,o=e.variables,s=e.returnPartialData,u=void 0===s||s,c=e.canonizeResults,l=void 0===c?this.config.canonizeResults:c,f=this.config.cache.policies;o=(0,en.pi)((0,en.pi)({},e9(e6(r))),o);var d=eI(a),h=this.executeSelectionSet({selectionSet:e8(r).selectionSet,objectOrReference:d,enclosingRef:d,context:(0,en.pi)({store:n,query:r,policies:f,variables:o,varString:nx(o),canonizeResults:l},iE(r,this.config.fragments))});if(h.missing&&(t=[new is(iR(h.missing),h.missing,r,o)],!u))throw t[0];return{result:h.result,complete:!t,missing:t}},e.prototype.isFresh=function(e,t,n,r){if(iD(r.store)&&this.knownResults.get(e)===n){var i=this.executeSelectionSet.peek(n,t,r,this.canon.isKnown(e));if(i&&e===i.result)return!0}return!1},e.prototype.execSelectionSetImpl=function(e){var t,n=this,r=e.selectionSet,i=e.objectOrReference,a=e.enclosingRef,o=e.context;if(eD(i)&&!o.policies.rootTypenamesById[i.__ref]&&!o.store.has(i.__ref))return{result:this.canon.empty,missing:"Dangling reference to missing ".concat(i.__ref," object")};var s=o.variables,u=o.policies,c=o.store.getFieldValue(i,"__typename"),l=[],f=new tB;function d(e,n){var r;return e.missing&&(t=f.merge(t,((r={})[n]=e.missing,r))),e.result}this.config.addTypename&&"string"==typeof c&&!u.rootIdsByTypename[c]&&l.push({__typename:c});var h=new Set(r.selections);h.forEach(function(e){var r,p;if(td(e,s)){if(eQ(e)){var b=u.readField({fieldName:e.name.value,field:e,variables:o.variables,from:i},o),m=eX(e);void 0===b?nj.added(e)||(t=f.merge(t,((r={})[m]="Can't find field '".concat(e.name.value,"' on ").concat(eD(i)?i.__ref+" object":"object "+JSON.stringify(i,null,2)),r))):(0,tP.k)(b)?b=d(n.executeSubSelectedArray({field:e,array:b,enclosingRef:a,context:o}),m):e.selectionSet?null!=b&&(b=d(n.executeSelectionSet({selectionSet:e.selectionSet,objectOrReference:b,enclosingRef:eD(b)?b:a,context:o}),m)):o.canonizeResults&&(b=n.canon.pass(b)),void 0!==b&&l.push(((p={})[m]=b,p))}else{var g=eC(e,o.lookupFragment);if(!g&&e.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(e.name.value)):new Q.ej(5);g&&u.fragmentMatches(g,c)&&g.selectionSet.selections.forEach(h.add,h)}}});var p={result:tF(l),missing:t},b=o.canonizeResults?this.canon.admit(p):(0,iu.J)(p);return b.result&&this.knownResults.set(b.result,r),b},e.prototype.execSubSelectedArrayImpl=function(e){var t,n=this,r=e.field,i=e.array,a=e.enclosingRef,o=e.context,s=new tB;function u(e,n){var r;return e.missing&&(t=s.merge(t,((r={})[n]=e.missing,r))),e.result}return r.selectionSet&&(i=i.filter(o.store.canRead)),i=i.map(function(e,t){return null===e?null:(0,tP.k)(e)?u(n.executeSubSelectedArray({field:r,array:e,enclosingRef:a,context:o}),t):r.selectionSet?u(n.executeSelectionSet({selectionSet:r.selectionSet,objectOrReference:e,enclosingRef:eD(e)?e:a,context:o}),t):(__DEV__&&ij(o.store,r,e),e)}),{result:o.canonizeResults?this.canon.admit(i):i,missing:t}},e}();function iR(e){try{JSON.stringify(e,function(e,t){if("string"==typeof t)throw t;return t})}catch(t){return t}}function ij(e,t,n){if(!t.selectionSet){var r=new Set([n]);r.forEach(function(n){(0,eO.s)(n)&&(__DEV__?(0,Q.kG)(!eD(n),"Missing selection set for object of type ".concat(im(e,n)," returned for query field ").concat(t.name.value)):(0,Q.kG)(!eD(n),6),Object.values(n).forEach(r.add,r))})}}function iF(e){var t=nG("stringifyForDisplay");return JSON.stringify(e,function(e,n){return void 0===n?t:n}).split(JSON.stringify(t)).join("")}var iY=Object.create(null);function iB(e){var t=JSON.stringify(e);return iY[t]||(iY[t]=Object.create(null))}function iU(e){var t=iB(e);return t.keyFieldsFn||(t.keyFieldsFn=function(t,n){var r=function(e,t){return n.readField(t,e)},i=n.keyObject=i$(e,function(e){var i=iW(n.storeObject,e,r);return void 0===i&&t!==n.storeObject&&ic.call(t,e[0])&&(i=iW(t,e,iG)),__DEV__?(0,Q.kG)(void 0!==i,"Missing field '".concat(e.join("."),"' while extracting keyFields from ").concat(JSON.stringify(t))):(0,Q.kG)(void 0!==i,2),i});return"".concat(n.typename,":").concat(JSON.stringify(i))})}function iH(e){var t=iB(e);return t.keyArgsFn||(t.keyArgsFn=function(t,n){var r=n.field,i=n.variables,a=n.fieldName,o=JSON.stringify(i$(e,function(e){var n=e[0],a=n.charAt(0);if("@"===a){if(r&&(0,tP.O)(r.directives)){var o=n.slice(1),s=r.directives.find(function(e){return e.name.value===o}),u=s&&eZ(s,i);return u&&iW(u,e.slice(1))}return}if("$"===a){var c=n.slice(1);if(i&&ic.call(i,c)){var l=e.slice(0);return l[0]=c,iW(i,l)}return}if(t)return iW(t,e)}));return(t||"{}"!==o)&&(a+=":"+o),a})}function i$(e,t){var n=new tB;return iz(e).reduce(function(e,r){var i,a=t(r);if(void 0!==a){for(var o=r.length-1;o>=0;--o)a=((i={})[r[o]]=a,i);e=n.merge(e,a)}return e},Object.create(null))}function iz(e){var t=iB(e);if(!t.paths){var n=t.paths=[],r=[];e.forEach(function(t,i){(0,tP.k)(t)?(iz(t).forEach(function(e){return n.push(r.concat(e))}),r.length=0):(r.push(t),(0,tP.k)(e[i+1])||(n.push(r.slice(0)),r.length=0))})}return t.paths}function iG(e,t){return e[t]}function iW(e,t,n){return n=n||iG,iK(t.reduce(function e(t,r){return(0,tP.k)(t)?t.map(function(t){return e(t,r)}):t&&n(t,r)},e))}function iK(e){return(0,eO.s)(e)?(0,tP.k)(e)?e.map(iK):i$(Object.keys(e).sort(),function(t){return iW(e,t)}):e}function iV(e){return void 0!==e.args?e.args:e.field?eZ(e.field,e.variables):null}eK.setStringify(nx);var iq=function(){},iZ=function(e,t){return t.fieldName},iX=function(e,t,n){return(0,n.mergeObjects)(e,t)},iJ=function(e,t){return t},iQ=function(){function e(e){this.config=e,this.typePolicies=Object.create(null),this.toBeAdded=Object.create(null),this.supertypeMap=new Map,this.fuzzySubtypes=new Map,this.rootIdsByTypename=Object.create(null),this.rootTypenamesById=Object.create(null),this.usingPossibleTypes=!1,this.config=(0,en.pi)({dataIdFromObject:id},e),this.cache=this.config.cache,this.setRootTypename("Query"),this.setRootTypename("Mutation"),this.setRootTypename("Subscription"),e.possibleTypes&&this.addPossibleTypes(e.possibleTypes),e.typePolicies&&this.addTypePolicies(e.typePolicies)}return e.prototype.identify=function(e,t){var n,r,i=this,a=t&&(t.typename||(null===(n=t.storeObject)||void 0===n?void 0:n.__typename))||e.__typename;if(a===this.rootTypenamesById.ROOT_QUERY)return["ROOT_QUERY"];for(var o=t&&t.storeObject||e,s=(0,en.pi)((0,en.pi)({},t),{typename:a,storeObject:o,readField:t&&t.readField||function(){var e=i0(arguments,o);return i.readField(e,{store:i.cache.data,variables:e.variables})}}),u=a&&this.getTypePolicy(a),c=u&&u.keyFn||this.config.dataIdFromObject;c;){var l=c((0,en.pi)((0,en.pi)({},e),o),s);if((0,tP.k)(l))c=iU(l);else{r=l;break}}return r=r?String(r):void 0,s.keyObject?[r,s.keyObject]:[r]},e.prototype.addTypePolicies=function(e){var t=this;Object.keys(e).forEach(function(n){var r=e[n],i=r.queryType,a=r.mutationType,o=r.subscriptionType,s=(0,en._T)(r,["queryType","mutationType","subscriptionType"]);i&&t.setRootTypename("Query",n),a&&t.setRootTypename("Mutation",n),o&&t.setRootTypename("Subscription",n),ic.call(t.toBeAdded,n)?t.toBeAdded[n].push(s):t.toBeAdded[n]=[s]})},e.prototype.updateTypePolicy=function(e,t){var n=this,r=this.getTypePolicy(e),i=t.keyFields,a=t.fields;function o(e,t){e.merge="function"==typeof t?t:!0===t?iX:!1===t?iJ:e.merge}o(r,t.merge),r.keyFn=!1===i?iq:(0,tP.k)(i)?iU(i):"function"==typeof i?i:r.keyFn,a&&Object.keys(a).forEach(function(t){var r=n.getFieldPolicy(e,t,!0),i=a[t];if("function"==typeof i)r.read=i;else{var s=i.keyArgs,u=i.read,c=i.merge;r.keyFn=!1===s?iZ:(0,tP.k)(s)?iH(s):"function"==typeof s?s:r.keyFn,"function"==typeof u&&(r.read=u),o(r,c)}r.read&&r.merge&&(r.keyFn=r.keyFn||iZ)})},e.prototype.setRootTypename=function(e,t){void 0===t&&(t=e);var n="ROOT_"+e.toUpperCase(),r=this.rootTypenamesById[n];t!==r&&(__DEV__?(0,Q.kG)(!r||r===e,"Cannot change root ".concat(e," __typename more than once")):(0,Q.kG)(!r||r===e,3),r&&delete this.rootIdsByTypename[r],this.rootIdsByTypename[t]=n,this.rootTypenamesById[n]=t)},e.prototype.addPossibleTypes=function(e){var t=this;this.usingPossibleTypes=!0,Object.keys(e).forEach(function(n){t.getSupertypeSet(n,!0),e[n].forEach(function(e){t.getSupertypeSet(e,!0).add(n);var r=e.match(ig);r&&r[0]===e||t.fuzzySubtypes.set(e,RegExp(e))})})},e.prototype.getTypePolicy=function(e){var t=this;if(!ic.call(this.typePolicies,e)){var n=this.typePolicies[e]=Object.create(null);n.fields=Object.create(null);var r=this.supertypeMap.get(e);r&&r.size&&r.forEach(function(e){var r=t.getTypePolicy(e),i=r.fields;Object.assign(n,(0,en._T)(r,["fields"])),Object.assign(n.fields,i)})}var i=this.toBeAdded[e];return i&&i.length&&i.splice(0).forEach(function(n){t.updateTypePolicy(e,n)}),this.typePolicies[e]},e.prototype.getFieldPolicy=function(e,t,n){if(e){var r=this.getTypePolicy(e).fields;return r[t]||n&&(r[t]=Object.create(null))}},e.prototype.getSupertypeSet=function(e,t){var n=this.supertypeMap.get(e);return!n&&t&&this.supertypeMap.set(e,n=new Set),n},e.prototype.fragmentMatches=function(e,t,n,r){var i=this;if(!e.typeCondition)return!0;if(!t)return!1;var a=e.typeCondition.name.value;if(t===a)return!0;if(this.usingPossibleTypes&&this.supertypeMap.has(a))for(var o=this.getSupertypeSet(t,!0),s=[o],u=function(e){var t=i.getSupertypeSet(e,!1);t&&t.size&&0>s.indexOf(t)&&s.push(t)},c=!!(n&&this.fuzzySubtypes.size),l=!1,f=0;f1?a:t}:(r=(0,en.pi)({},i),ic.call(r,"from")||(r.from=t)),__DEV__&&void 0===r.from&&__DEV__&&Q.kG.warn("Undefined 'from' passed to readField with arguments ".concat(iF(Array.from(e)))),void 0===r.variables&&(r.variables=n),r}function i2(e){return function(t,n){if((0,tP.k)(t)||(0,tP.k)(n))throw __DEV__?new Q.ej("Cannot automatically merge arrays"):new Q.ej(4);if((0,eO.s)(t)&&(0,eO.s)(n)){var r=e.getFieldValue(t,"__typename"),i=e.getFieldValue(n,"__typename");if(r&&i&&r!==i)return n;if(eD(t)&&iw(n))return e.merge(t.__ref,n),t;if(iw(t)&&eD(n))return e.merge(t,n.__ref),n;if(iw(t)&&iw(n))return(0,en.pi)((0,en.pi)({},t),n)}return n}}function i3(e,t,n){var r="".concat(t).concat(n),i=e.flavors.get(r);return i||e.flavors.set(r,i=e.clientOnly===t&&e.deferred===n?e:(0,en.pi)((0,en.pi)({},e),{clientOnly:t,deferred:n})),i}var i4=function(){function e(e,t,n){this.cache=e,this.reader=t,this.fragments=n}return e.prototype.writeToStore=function(e,t){var n=this,r=t.query,i=t.result,a=t.dataId,o=t.variables,s=t.overwrite,u=e2(r),c=i_();o=(0,en.pi)((0,en.pi)({},e9(u)),o);var l=(0,en.pi)((0,en.pi)({store:e,written:Object.create(null),merge:function(e,t){return c.merge(e,t)},variables:o,varString:nx(o)},iE(r,this.fragments)),{overwrite:!!s,incomingById:new Map,clientOnly:!1,deferred:!1,flavors:new Map}),f=this.processSelectionSet({result:i||Object.create(null),dataId:a,selectionSet:u.selectionSet,mergeTree:{map:new Map},context:l});if(!eD(f))throw __DEV__?new Q.ej("Could not identify object ".concat(JSON.stringify(i))):new Q.ej(7);return l.incomingById.forEach(function(t,r){var i=t.storeObject,a=t.mergeTree,o=t.fieldNodeSet,s=eI(r);if(a&&a.map.size){var u=n.applyMerges(a,s,i,l);if(eD(u))return;i=u}if(__DEV__&&!l.overwrite){var c=Object.create(null);o.forEach(function(e){e.selectionSet&&(c[e.name.value]=!0)});var f=function(e){return!0===c[iv(e)]},d=function(e){var t=a&&a.map.get(e);return Boolean(t&&t.info&&t.info.merge)};Object.keys(i).forEach(function(e){f(e)&&!d(e)&&at(s,i,e,l.store)})}e.merge(r,i)}),e.retain(f.__ref),f},e.prototype.processSelectionSet=function(e){var t=this,n=e.dataId,r=e.result,i=e.selectionSet,a=e.context,o=e.mergeTree,s=this.cache.policies,u=Object.create(null),c=n&&s.rootTypenamesById[n]||eJ(r,i,a.fragmentMap)||n&&a.store.get(n,"__typename");"string"==typeof c&&(u.__typename=c);var l=function(){var e=i0(arguments,u,a.variables);if(eD(e.from)){var t=a.incomingById.get(e.from.__ref);if(t){var n=s.readField((0,en.pi)((0,en.pi)({},e),{from:t.storeObject}),a);if(void 0!==n)return n}}return s.readField(e,a)},f=new Set;this.flattenFields(i,r,a,c).forEach(function(e,n){var i,a=r[eX(n)];if(f.add(n),void 0!==a){var d=s.getStoreFieldName({typename:c,fieldName:n.name.value,field:n,variables:e.variables}),h=i5(o,d),p=t.processFieldValue(a,n,n.selectionSet?i3(e,!1,!1):e,h),b=void 0;n.selectionSet&&(eD(p)||iw(p))&&(b=l("__typename",p));var m=s.getMergeFunction(c,n.name.value,b);m?h.info={field:n,typename:c,merge:m}:i7(o,d),u=e.merge(u,((i={})[d]=p,i))}else __DEV__&&!e.clientOnly&&!e.deferred&&!nj.added(n)&&!s.getReadFunction(c,n.name.value)&&__DEV__&&Q.kG.error("Missing field '".concat(eX(n),"' while writing result ").concat(JSON.stringify(r,null,2)).substring(0,1e3))});try{var d=s.identify(r,{typename:c,selectionSet:i,fragmentMap:a.fragmentMap,storeObject:u,readField:l}),h=d[0],p=d[1];n=n||h,p&&(u=a.merge(u,p))}catch(b){if(!n)throw b}if("string"==typeof n){var m=eI(n),g=a.written[n]||(a.written[n]=[]);if(g.indexOf(i)>=0||(g.push(i),this.reader&&this.reader.isFresh(r,m,i,a)))return m;var v=a.incomingById.get(n);return v?(v.storeObject=a.merge(v.storeObject,u),v.mergeTree=i8(v.mergeTree,o),f.forEach(function(e){return v.fieldNodeSet.add(e)})):a.incomingById.set(n,{storeObject:u,mergeTree:i9(o)?void 0:o,fieldNodeSet:f}),m}return u},e.prototype.processFieldValue=function(e,t,n,r){var i=this;return t.selectionSet&&null!==e?(0,tP.k)(e)?e.map(function(e,a){var o=i.processFieldValue(e,t,n,i5(r,a));return i7(r,a),o}):this.processSelectionSet({result:e,selectionSet:t.selectionSet,context:n,mergeTree:r}):__DEV__?nJ(e):e},e.prototype.flattenFields=function(e,t,n,r){void 0===r&&(r=eJ(t,e,n.fragmentMap));var i=new Map,a=this.cache.policies,o=new n_(!1);return function e(s,u){var c=o.lookup(s,u.clientOnly,u.deferred);c.visited||(c.visited=!0,s.selections.forEach(function(o){if(td(o,n.variables)){var s=u.clientOnly,c=u.deferred;if(!(s&&c)&&(0,tP.O)(o.directives)&&o.directives.forEach(function(e){var t=e.name.value;if("client"===t&&(s=!0),"defer"===t){var r=eZ(e,n.variables);r&&!1===r.if||(c=!0)}}),eQ(o)){var l=i.get(o);l&&(s=s&&l.clientOnly,c=c&&l.deferred),i.set(o,i3(n,s,c))}else{var f=eC(o,n.lookupFragment);if(!f&&o.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(o.name.value)):new Q.ej(8);f&&a.fragmentMatches(f,r,t,n.variables)&&e(f.selectionSet,i3(n,s,c))}}}))}(e,n),i},e.prototype.applyMerges=function(e,t,n,r,i){var a=this;if(e.map.size&&!eD(n)){var o,s,u=!(0,tP.k)(n)&&(eD(t)||iw(t))?t:void 0,c=n;u&&!i&&(i=[eD(u)?u.__ref:u]);var l=function(e,t){return(0,tP.k)(e)?"number"==typeof t?e[t]:void 0:r.store.getFieldValue(e,String(t))};e.map.forEach(function(e,t){var n=l(u,t),o=l(c,t);if(void 0!==o){i&&i.push(t);var f=a.applyMerges(e,n,o,r,i);f!==o&&(s=s||new Map).set(t,f),i&&(0,Q.kG)(i.pop()===t)}}),s&&(n=(0,tP.k)(c)?c.slice(0):(0,en.pi)({},c),s.forEach(function(e,t){n[t]=e}))}return e.info?this.cache.policies.runMergeFunction(t,n,e.info,r,i&&(o=r.store).getStorage.apply(o,i)):n},e}(),i6=[];function i5(e,t){var n=e.map;return n.has(t)||n.set(t,i6.pop()||{map:new Map}),n.get(t)}function i8(e,t){if(e===t||!t||i9(t))return e;if(!e||i9(e))return t;var n=e.info&&t.info?(0,en.pi)((0,en.pi)({},e.info),t.info):e.info||t.info,r=e.map.size&&t.map.size,i=r?new Map:e.map.size?e.map:t.map,a={info:n,map:i};if(r){var o=new Set(t.map.keys());e.map.forEach(function(e,n){a.map.set(n,i8(e,t.map.get(n))),o.delete(n)}),o.forEach(function(n){a.map.set(n,i8(t.map.get(n),e.map.get(n)))})}return a}function i9(e){return!e||!(e.info||e.map.size)}function i7(e,t){var n=e.map,r=n.get(t);r&&i9(r)&&(i6.push(r),n.delete(t))}var ae=new Set;function at(e,t,n,r){var i=function(e){var t=r.getFieldValue(e,n);return"object"==typeof t&&t},a=i(e);if(a){var o=i(t);if(!(!o||eD(a)||(0,nm.D)(a,o)||Object.keys(a).every(function(e){return void 0!==r.getFieldValue(o,e)}))){var s=r.getFieldValue(e,"__typename")||r.getFieldValue(t,"__typename"),u=iv(n),c="".concat(s,".").concat(u);if(!ae.has(c)){ae.add(c);var l=[];(0,tP.k)(a)||(0,tP.k)(o)||[a,o].forEach(function(e){var t=r.getFieldValue(e,"__typename");"string"!=typeof t||l.includes(t)||l.push(t)}),__DEV__&&Q.kG.warn("Cache data may be lost when replacing the ".concat(u," field of a ").concat(s," object.\n\nThis could cause additional (usually avoidable) network requests to fetch data that were otherwise cached.\n\nTo address this problem (which is not a bug in Apollo Client), ").concat(l.length?"either ensure all objects of type "+l.join(" and ")+" have an ID or a custom merge function, or ":"","define a custom merge function for the ").concat(c," field, so InMemoryCache can safely merge these objects:\n\n existing: ").concat(JSON.stringify(a).slice(0,1e3),"\n incoming: ").concat(JSON.stringify(o).slice(0,1e3),"\n\nFor more information about these options, please refer to the documentation:\n\n * Ensuring entity objects have IDs: https://go.apollo.dev/c/generating-unique-identifiers\n * Defining custom merge functions: https://go.apollo.dev/c/merging-non-normalized-objects\n"))}}}}var an=function(e){function t(t){void 0===t&&(t={});var n=e.call(this)||this;return n.watches=new Set,n.typenameDocumentCache=new Map,n.makeVar=r2,n.txCount=0,n.config=ip(t),n.addTypename=!!n.config.addTypename,n.policies=new iQ({cache:n,dataIdFromObject:n.config.dataIdFromObject,possibleTypes:n.config.possibleTypes,typePolicies:n.config.typePolicies}),n.init(),n}return(0,en.ZT)(t,e),t.prototype.init=function(){var e=this.data=new iT.Root({policies:this.policies,resultCaching:this.config.resultCaching});this.optimisticData=e.stump,this.resetResultCache()},t.prototype.resetResultCache=function(e){var t=this,n=this.storeReader,r=this.config.fragments;this.storeWriter=new i4(this,this.storeReader=new iP({cache:this,addTypename:this.addTypename,resultCacheMaxSize:this.config.resultCacheMaxSize,canonizeResults:ib(this.config),canon:e?void 0:n&&n.canon,fragments:r}),r),this.maybeBroadcastWatch=rZ(function(e,n){return t.broadcastWatch(e,n)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var n=e.optimistic?t.optimisticData:t.data;if(iD(n)){var r=e.optimistic,i=e.id,a=e.variables;return n.makeCacheKey(e.query,e.callback,nx({optimistic:r,id:i,variables:a}))}}}),new Set([this.data.group,this.optimisticData.group,]).forEach(function(e){return e.resetCaching()})},t.prototype.restore=function(e){return this.init(),e&&this.data.replace(e),this},t.prototype.extract=function(e){return void 0===e&&(e=!1),(e?this.optimisticData:this.data).extract()},t.prototype.read=function(e){var t=e.returnPartialData,n=void 0!==t&&t;try{return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,config:this.config,returnPartialData:n})).result||null}catch(r){if(r instanceof is)return null;throw r}},t.prototype.write=function(e){try{return++this.txCount,this.storeWriter.writeToStore(this.data,e)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.modify=function(e){if(ic.call(e,"id")&&!e.id)return!1;var t=e.optimistic?this.optimisticData:this.data;try{return++this.txCount,t.modify(e.id||"ROOT_QUERY",e.fields)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.diff=function(e){return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,rootId:e.id||"ROOT_QUERY",config:this.config}))},t.prototype.watch=function(e){var t=this;return this.watches.size||r0(this),this.watches.add(e),e.immediate&&this.maybeBroadcastWatch(e),function(){t.watches.delete(e)&&!t.watches.size&&r1(t),t.maybeBroadcastWatch.forget(e)}},t.prototype.gc=function(e){nx.reset();var t=this.optimisticData.gc();return e&&!this.txCount&&(e.resetResultCache?this.resetResultCache(e.resetResultIdentities):e.resetResultIdentities&&this.storeReader.resetCanon()),t},t.prototype.retain=function(e,t){return(t?this.optimisticData:this.data).retain(e)},t.prototype.release=function(e,t){return(t?this.optimisticData:this.data).release(e)},t.prototype.identify=function(e){if(eD(e))return e.__ref;try{return this.policies.identify(e)[0]}catch(t){__DEV__&&Q.kG.warn(t)}},t.prototype.evict=function(e){if(!e.id){if(ic.call(e,"id"))return!1;e=(0,en.pi)((0,en.pi)({},e),{id:"ROOT_QUERY"})}try{return++this.txCount,this.optimisticData.evict(e,this.data)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.reset=function(e){var t=this;return this.init(),nx.reset(),e&&e.discardWatches?(this.watches.forEach(function(e){return t.maybeBroadcastWatch.forget(e)}),this.watches.clear(),r1(this)):this.broadcastWatches(),Promise.resolve()},t.prototype.removeOptimistic=function(e){var t=this.optimisticData.removeLayer(e);t!==this.optimisticData&&(this.optimisticData=t,this.broadcastWatches())},t.prototype.batch=function(e){var t,n=this,r=e.update,i=e.optimistic,a=void 0===i||i,o=e.removeOptimistic,s=e.onWatchUpdated,u=function(e){var i=n,a=i.data,o=i.optimisticData;++n.txCount,e&&(n.data=n.optimisticData=e);try{return t=r(n)}finally{--n.txCount,n.data=a,n.optimisticData=o}},c=new Set;return s&&!this.txCount&&this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e){return c.add(e),!1}})),"string"==typeof a?this.optimisticData=this.optimisticData.addLayer(a,u):!1===a?u(this.data):u(),"string"==typeof o&&(this.optimisticData=this.optimisticData.removeLayer(o)),s&&c.size?(this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e,t){var n=s.call(this,e,t);return!1!==n&&c.delete(e),n}})),c.size&&c.forEach(function(e){return n.maybeBroadcastWatch.dirty(e)})):this.broadcastWatches(e),t},t.prototype.performTransaction=function(e,t){return this.batch({update:e,optimistic:t||null!==t})},t.prototype.transformDocument=function(e){if(this.addTypename){var t=this.typenameDocumentCache.get(e);return t||(t=nj(e),this.typenameDocumentCache.set(e,t),this.typenameDocumentCache.set(t,t)),t}return e},t.prototype.transformForLink=function(e){var t=this.config.fragments;return t?t.transform(e):e},t.prototype.broadcastWatches=function(e){var t=this;this.txCount||this.watches.forEach(function(n){return t.maybeBroadcastWatch(n,e)})},t.prototype.broadcastWatch=function(e,t){var n=e.lastDiff,r=this.diff(e);(!t||(e.optimistic&&"string"==typeof t.optimistic&&(r.fromOptimisticTransaction=!0),!t.onWatchUpdated||!1!==t.onWatchUpdated.call(this,e,r,n)))&&(n&&(0,nm.D)(n.result,r.result)||e.callback(e.lastDiff=r,n))},t}(io),ar={possibleTypes:{ApproveJobProposalSpecPayload:["ApproveJobProposalSpecSuccess","JobAlreadyExistsError","NotFoundError"],BridgePayload:["Bridge","NotFoundError"],CancelJobProposalSpecPayload:["CancelJobProposalSpecSuccess","NotFoundError"],ChainPayload:["Chain","NotFoundError"],CreateAPITokenPayload:["CreateAPITokenSuccess","InputErrors"],CreateBridgePayload:["CreateBridgeSuccess"],CreateCSAKeyPayload:["CSAKeyExistsError","CreateCSAKeySuccess"],CreateFeedsManagerChainConfigPayload:["CreateFeedsManagerChainConfigSuccess","InputErrors","NotFoundError"],CreateFeedsManagerPayload:["CreateFeedsManagerSuccess","DuplicateFeedsManagerError","InputErrors","NotFoundError","SingleFeedsManagerError"],CreateJobPayload:["CreateJobSuccess","InputErrors"],CreateOCR2KeyBundlePayload:["CreateOCR2KeyBundleSuccess"],CreateOCRKeyBundlePayload:["CreateOCRKeyBundleSuccess"],CreateP2PKeyPayload:["CreateP2PKeySuccess"],DeleteAPITokenPayload:["DeleteAPITokenSuccess","InputErrors"],DeleteBridgePayload:["DeleteBridgeConflictError","DeleteBridgeInvalidNameError","DeleteBridgeSuccess","NotFoundError"],DeleteCSAKeyPayload:["DeleteCSAKeySuccess","NotFoundError"],DeleteFeedsManagerChainConfigPayload:["DeleteFeedsManagerChainConfigSuccess","NotFoundError"],DeleteJobPayload:["DeleteJobSuccess","NotFoundError"],DeleteOCR2KeyBundlePayload:["DeleteOCR2KeyBundleSuccess","NotFoundError"],DeleteOCRKeyBundlePayload:["DeleteOCRKeyBundleSuccess","NotFoundError"],DeleteP2PKeyPayload:["DeleteP2PKeySuccess","NotFoundError"],DeleteVRFKeyPayload:["DeleteVRFKeySuccess","NotFoundError"],DisableFeedsManagerPayload:["DisableFeedsManagerSuccess","NotFoundError"],DismissJobErrorPayload:["DismissJobErrorSuccess","NotFoundError"],EnableFeedsManagerPayload:["EnableFeedsManagerSuccess","NotFoundError"],Error:["CSAKeyExistsError","DeleteBridgeConflictError","DeleteBridgeInvalidNameError","DuplicateFeedsManagerError","InputError","JobAlreadyExistsError","NotFoundError","RunJobCannotRunError","SingleFeedsManagerError"],EthTransactionPayload:["EthTransaction","NotFoundError"],FeaturesPayload:["Features"],FeedsManagerPayload:["FeedsManager","NotFoundError"],GetSQLLoggingPayload:["SQLLogging"],GlobalLogLevelPayload:["GlobalLogLevel"],JobPayload:["Job","NotFoundError"],JobProposalPayload:["JobProposal","NotFoundError"],JobRunPayload:["JobRun","NotFoundError"],JobSpec:["BlockHeaderFeederSpec","BlockhashStoreSpec","BootstrapSpec","CronSpec","DirectRequestSpec","FluxMonitorSpec","GatewaySpec","KeeperSpec","OCR2Spec","OCRSpec","StandardCapabilitiesSpec","StreamSpec","VRFSpec","WebhookSpec","WorkflowSpec"],NodePayload:["Node","NotFoundError"],PaginatedPayload:["BridgesPayload","ChainsPayload","EthTransactionAttemptsPayload","EthTransactionsPayload","JobRunsPayload","JobsPayload","NodesPayload"],RejectJobProposalSpecPayload:["NotFoundError","RejectJobProposalSpecSuccess"],RunJobPayload:["NotFoundError","RunJobCannotRunError","RunJobSuccess"],SetGlobalLogLevelPayload:["InputErrors","SetGlobalLogLevelSuccess"],SetSQLLoggingPayload:["SetSQLLoggingSuccess"],SetServicesLogLevelsPayload:["InputErrors","SetServicesLogLevelsSuccess"],UpdateBridgePayload:["NotFoundError","UpdateBridgeSuccess"],UpdateFeedsManagerChainConfigPayload:["InputErrors","NotFoundError","UpdateFeedsManagerChainConfigSuccess"],UpdateFeedsManagerPayload:["InputErrors","NotFoundError","UpdateFeedsManagerSuccess"],UpdateJobProposalSpecDefinitionPayload:["NotFoundError","UpdateJobProposalSpecDefinitionSuccess"],UpdatePasswordPayload:["InputErrors","UpdatePasswordSuccess"],VRFKeyPayload:["NotFoundError","VRFKeySuccess"]}};let ai=ar;var aa=(r=void 0,location.origin),ao=new nh({uri:"".concat(aa,"/query"),credentials:"include"}),as=new ia({cache:new an({possibleTypes:ai.possibleTypes}),link:ao});if(a.Z.locale(o),u().defaultFormat="YYYY-MM-DD h:mm:ss A","undefined"!=typeof document){var au,ac,al=f().hydrate;ac=X,al(c.createElement(et,{client:as},c.createElement(d.zj,null,c.createElement(i.MuiThemeProvider,{theme:J.r},c.createElement(ac,null)))),document.getElementById("root"))}})()})(); \ No newline at end of file +`+(a!==i?`result of cast: ${a}`:""))}return r}_cast(e,t){let n=void 0===e?e:this.transforms.reduce((t,n)=>n.call(this,t,e,this),e);return void 0===n&&(n=this.getDefault()),n}_validate(e,t={},n){let{sync:r,path:i,from:a=[],originalValue:o=e,strict:s=this.spec.strict,abortEarly:u=this.spec.abortEarly}=t,c=e;s||(c=this._cast(c,pB({assert:!1},t)));let l={value:c,path:i,options:t,originalValue:o,schema:this,label:this.spec.label,sync:r,from:a},f=[];this._typeError&&f.push(this._typeError),this._whitelistError&&f.push(this._whitelistError),this._blacklistError&&f.push(this._blacklistError),pO({args:l,value:c,path:i,sync:r,tests:f,endEarly:u},e=>{if(e)return void n(e,c);pO({tests:this.tests,args:l,path:i,sync:r,value:c,endEarly:u},n)})}validate(e,t,n){let r=this.resolve(pB({},t,{value:e}));return"function"==typeof n?r._validate(e,t,n):new Promise((n,i)=>r._validate(e,t,(e,t)=>{e?i(e):n(t)}))}validateSync(e,t){let n;return this.resolve(pB({},t,{value:e}))._validate(e,pB({},t,{sync:!0}),(e,t)=>{if(e)throw e;n=t}),n}isValid(e,t){return this.validate(e,t).then(()=>!0,e=>{if(pT.isError(e))return!1;throw e})}isValidSync(e,t){try{return this.validateSync(e,t),!0}catch(n){if(pT.isError(n))return!1;throw n}}_getDefault(){let e=this.spec.default;return null==e?e:"function"==typeof e?e.call(this):pn(e)}getDefault(e){return this.resolve(e||{})._getDefault()}default(e){return 0===arguments.length?this._getDefault():this.clone({default:e})}strict(e=!0){var t=this.clone();return t.spec.strict=e,t}_isPresent(e){return null!=e}defined(e=pf.defined){return this.test({message:e,name:"defined",exclusive:!0,test:e=>void 0!==e})}required(e=pf.required){return this.clone({presence:"required"}).withMutation(t=>t.test({message:e,name:"required",exclusive:!0,test(e){return this.schema._isPresent(e)}}))}notRequired(){var e=this.clone({presence:"optional"});return e.tests=e.tests.filter(e=>"required"!==e.OPTIONS.name),e}nullable(e=!0){return this.clone({nullable:!1!==e})}transform(e){var t=this.clone();return t.transforms.push(e),t}test(...e){let t;if(void 0===(t=1===e.length?"function"==typeof e[0]?{test:e[0]}:e[0]:2===e.length?{name:e[0],test:e[1]}:{name:e[0],message:e[1],test:e[2]}).message&&(t.message=pf.default),"function"!=typeof t.test)throw TypeError("`test` is a required parameters");let n=this.clone(),r=pR(t),i=t.exclusive||t.name&&!0===n.exclusiveTests[t.name];if(t.exclusive&&!t.name)throw TypeError("Exclusive tests must provide a unique `name` identifying the test");return t.name&&(n.exclusiveTests[t.name]=!!t.exclusive),n.tests=n.tests.filter(e=>e.OPTIONS.name!==t.name||!i&&e.OPTIONS.test!==r.OPTIONS.test),n.tests.push(r),n}when(e,t){Array.isArray(e)||"string"==typeof e||(t=e,e=".");let n=this.clone(),r=pS(e).map(e=>new pD(e));return r.forEach(e=>{e.isSibling&&n.deps.push(e.key)}),n.conditions.push(new pE(r,t)),n}typeError(e){var t=this.clone();return t._typeError=pR({message:e,name:"typeError",test(e){return!!(void 0===e||this.schema.isType(e))||this.createError({params:{type:this.schema._type}})}}),t}oneOf(e,t=pf.oneOf){var n=this.clone();return e.forEach(e=>{n._whitelist.add(e),n._blacklist.delete(e)}),n._whitelistError=pR({message:t,name:"oneOf",test(e){if(void 0===e)return!0;let t=this.schema._whitelist;return!!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}notOneOf(e,t=pf.notOneOf){var n=this.clone();return e.forEach(e=>{n._blacklist.add(e),n._whitelist.delete(e)}),n._blacklistError=pR({message:t,name:"notOneOf",test(e){let t=this.schema._blacklist;return!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}strip(e=!0){let t=this.clone();return t.spec.strip=e,t}describe(){let e=this.clone(),{label:t,meta:n}=e.spec,r={meta:n,label:t,type:e.type,oneOf:e._whitelist.describe(),notOneOf:e._blacklist.describe(),tests:e.tests.map(e=>({name:e.OPTIONS.name,params:e.OPTIONS.params})).filter((e,t,n)=>n.findIndex(t=>t.name===e.name)===t)};return r}}for(let pH of(pU.prototype.__isYupSchema__=!0,["validate","validateSync"]))pU.prototype[`${pH}At`]=function(e,t,n={}){let{parent:r,parentPath:i,schema:a}=pF(this,e,t,n.context);return a[pH](r&&r[i],pB({},n,{parent:r,path:e}))};for(let p$ of["equals","is"])pU.prototype[p$]=pU.prototype.oneOf;for(let pz of["not","nope"])pU.prototype[pz]=pU.prototype.notOneOf;pU.prototype.optional=pU.prototype.notRequired;let pG=pU;function pW(){return new pG}pW.prototype=pG.prototype;let pK=e=>null==e;function pV(){return new pq}class pq extends pU{constructor(){super({type:"boolean"}),this.withMutation(()=>{this.transform(function(e){if(!this.isType(e)){if(/^(true|1)$/i.test(String(e)))return!0;if(/^(false|0)$/i.test(String(e)))return!1}return e})})}_typeCheck(e){return e instanceof Boolean&&(e=e.valueOf()),"boolean"==typeof e}isTrue(e=pb.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"true"},test:e=>pK(e)||!0===e})}isFalse(e=pb.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"false"},test:e=>pK(e)||!1===e})}}pV.prototype=pq.prototype;let pZ=/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,pX=/^((https?|ftp):)?\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,pJ=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i,pQ=e=>pK(e)||e===e.trim(),p1=({}).toString();function p0(){return new p2}class p2 extends pU{constructor(){super({type:"string"}),this.withMutation(()=>{this.transform(function(e){if(this.isType(e)||Array.isArray(e))return e;let t=null!=e&&e.toString?e.toString():e;return t===p1?e:t})})}_typeCheck(e){return e instanceof String&&(e=e.valueOf()),"string"==typeof e}_isPresent(e){return super._isPresent(e)&&!!e.length}length(e,t=pd.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pK(t)||t.length===this.resolve(e)}})}min(e,t=pd.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t.length>=this.resolve(e)}})}max(e,t=pd.max){return this.test({name:"max",exclusive:!0,message:t,params:{max:e},test(t){return pK(t)||t.length<=this.resolve(e)}})}matches(e,t){let n=!1,r,i;return t&&("object"==typeof t?{excludeEmptyString:n=!1,message:r,name:i}=t:r=t),this.test({name:i||"matches",message:r||pd.matches,params:{regex:e},test:t=>pK(t)||""===t&&n||-1!==t.search(e)})}email(e=pd.email){return this.matches(pZ,{name:"email",message:e,excludeEmptyString:!0})}url(e=pd.url){return this.matches(pX,{name:"url",message:e,excludeEmptyString:!0})}uuid(e=pd.uuid){return this.matches(pJ,{name:"uuid",message:e,excludeEmptyString:!1})}ensure(){return this.default("").transform(e=>null===e?"":e)}trim(e=pd.trim){return this.transform(e=>null!=e?e.trim():e).test({message:e,name:"trim",test:pQ})}lowercase(e=pd.lowercase){return this.transform(e=>pK(e)?e:e.toLowerCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pK(e)||e===e.toLowerCase()})}uppercase(e=pd.uppercase){return this.transform(e=>pK(e)?e:e.toUpperCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pK(e)||e===e.toUpperCase()})}}p0.prototype=p2.prototype;let p3=e=>e!=+e;function p4(){return new p6}class p6 extends pU{constructor(){super({type:"number"}),this.withMutation(()=>{this.transform(function(e){let t=e;if("string"==typeof t){if(""===(t=t.replace(/\s/g,"")))return NaN;t=+t}return this.isType(t)?t:parseFloat(t)})})}_typeCheck(e){return e instanceof Number&&(e=e.valueOf()),"number"==typeof e&&!p3(e)}min(e,t=ph.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t>=this.resolve(e)}})}max(e,t=ph.max){return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pK(t)||t<=this.resolve(e)}})}lessThan(e,t=ph.lessThan){return this.test({message:t,name:"max",exclusive:!0,params:{less:e},test(t){return pK(t)||tthis.resolve(e)}})}positive(e=ph.positive){return this.moreThan(0,e)}negative(e=ph.negative){return this.lessThan(0,e)}integer(e=ph.integer){return this.test({name:"integer",message:e,test:e=>pK(e)||Number.isInteger(e)})}truncate(){return this.transform(e=>pK(e)?e:0|e)}round(e){var t,n=["ceil","floor","round","trunc"];if("trunc"===(e=(null==(t=e)?void 0:t.toLowerCase())||"round"))return this.truncate();if(-1===n.indexOf(e.toLowerCase()))throw TypeError("Only valid options for round() are: "+n.join(", "));return this.transform(t=>pK(t)?t:Math[e](t))}}p4.prototype=p6.prototype;var p5=/^(\d{4}|[+\-]\d{6})(?:-?(\d{2})(?:-?(\d{2}))?)?(?:[ T]?(\d{2}):?(\d{2})(?::?(\d{2})(?:[,\.](\d{1,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?)?)?$/;function p8(e){var t,n,r=[1,4,5,6,7,10,11],i=0;if(n=p5.exec(e)){for(var a,o=0;a=r[o];++o)n[a]=+n[a]||0;n[2]=(+n[2]||1)-1,n[3]=+n[3]||1,n[7]=n[7]?String(n[7]).substr(0,3):0,(void 0===n[8]||""===n[8])&&(void 0===n[9]||""===n[9])?t=+new Date(n[1],n[2],n[3],n[4],n[5],n[6],n[7]):("Z"!==n[8]&&void 0!==n[9]&&(i=60*n[10]+n[11],"+"===n[9]&&(i=0-i)),t=Date.UTC(n[1],n[2],n[3],n[4],n[5]+i,n[6],n[7]))}else t=Date.parse?Date.parse(e):NaN;return t}let p9=new Date(""),p7=e=>"[object Date]"===Object.prototype.toString.call(e);function be(){return new bt}class bt extends pU{constructor(){super({type:"date"}),this.withMutation(()=>{this.transform(function(e){return this.isType(e)?e:(e=p8(e),isNaN(e)?p9:new Date(e))})})}_typeCheck(e){return p7(e)&&!isNaN(e.getTime())}prepareParam(e,t){let n;if(pD.isRef(e))n=e;else{let r=this.cast(e);if(!this._typeCheck(r))throw TypeError(`\`${t}\` must be a Date or a value that can be \`cast()\` to a Date`);n=r}return n}min(e,t=pp.min){let n=this.prepareParam(e,"min");return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(e){return pK(e)||e>=this.resolve(n)}})}max(e,t=pp.max){var n=this.prepareParam(e,"max");return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(e){return pK(e)||e<=this.resolve(n)}})}}bt.INVALID_DATE=p9,be.prototype=bt.prototype,be.INVALID_DATE=p9;var bn=n(11865),br=n.n(bn),bi=n(68929),ba=n.n(bi),bo=n(67523),bs=n.n(bo),bu=n(94633),bc=n.n(bu);function bl(e,t=[]){let n=[],r=[];function i(e,i){var a=(0,pC.split)(e)[0];~r.indexOf(a)||r.push(a),~t.indexOf(`${i}-${a}`)||n.push([i,a])}for(let a in e)if(py()(e,a)){let o=e[a];~r.indexOf(a)||r.push(a),pD.isRef(o)&&o.isSibling?i(o.path,a):pw(o)&&"deps"in o&&o.deps.forEach(e=>i(e,a))}return bc().array(r,n).reverse()}function bf(e,t){let n=1/0;return e.some((e,r)=>{var i;if((null==(i=t.path)?void 0:i.indexOf(e))!==-1)return n=r,!0}),n}function bd(e){return(t,n)=>bf(e,t)-bf(e,n)}function bh(){return(bh=Object.assign||function(e){for(var t=1;t"[object Object]"===Object.prototype.toString.call(e);function bb(e,t){let n=Object.keys(e.fields);return Object.keys(t).filter(e=>-1===n.indexOf(e))}let bm=bd([]);class bg extends pU{constructor(e){super({type:"object"}),this.fields=Object.create(null),this._sortErrors=bm,this._nodes=[],this._excludedEdges=[],this.withMutation(()=>{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null}),e&&this.shape(e)})}_typeCheck(e){return bp(e)||"function"==typeof e}_cast(e,t={}){var n;let r=super._cast(e,t);if(void 0===r)return this.getDefault();if(!this._typeCheck(r))return r;let i=this.fields,a=null!=(n=t.stripUnknown)?n:this.spec.noUnknown,o=this._nodes.concat(Object.keys(r).filter(e=>-1===this._nodes.indexOf(e))),s={},u=bh({},t,{parent:s,__validating:t.__validating||!1}),c=!1;for(let l of o){let f=i[l],d=py()(r,l);if(f){let h,p=r[l];u.path=(t.path?`${t.path}.`:"")+l;let b="spec"in(f=f.resolve({value:p,context:t.context,parent:s}))?f.spec:void 0,m=null==b?void 0:b.strict;if(null==b?void 0:b.strip){c=c||l in r;continue}void 0!==(h=t.__validating&&m?r[l]:f.cast(r[l],u))&&(s[l]=h)}else d&&!a&&(s[l]=r[l]);s[l]!==r[l]&&(c=!0)}return c?s:r}_validate(e,t={},n){let r=[],{sync:i,from:a=[],originalValue:o=e,abortEarly:s=this.spec.abortEarly,recursive:u=this.spec.recursive}=t;a=[{schema:this,value:o},...a],t.__validating=!0,t.originalValue=o,t.from=a,super._validate(e,t,(e,c)=>{if(e){if(!pT.isError(e)||s)return void n(e,c);r.push(e)}if(!u||!bp(c)){n(r[0]||null,c);return}o=o||c;let l=this._nodes.map(e=>(n,r)=>{let i=-1===e.indexOf(".")?(t.path?`${t.path}.`:"")+e:`${t.path||""}["${e}"]`,s=this.fields[e];if(s&&"validate"in s){s.validate(c[e],bh({},t,{path:i,from:a,strict:!0,parent:c,originalValue:o[e]}),r);return}r(null)});pO({sync:i,tests:l,value:c,errors:r,endEarly:s,sort:this._sortErrors,path:t.path},n)})}clone(e){let t=super.clone(e);return t.fields=bh({},this.fields),t._nodes=this._nodes,t._excludedEdges=this._excludedEdges,t._sortErrors=this._sortErrors,t}concat(e){let t=super.concat(e),n=t.fields;for(let[r,i]of Object.entries(this.fields)){let a=n[r];void 0===a?n[r]=i:a instanceof pU&&i instanceof pU&&(n[r]=i.concat(a))}return t.withMutation(()=>t.shape(n))}getDefaultFromShape(){let e={};return this._nodes.forEach(t=>{let n=this.fields[t];e[t]="default"in n?n.getDefault():void 0}),e}_getDefault(){return"default"in this.spec?super._getDefault():this._nodes.length?this.getDefaultFromShape():void 0}shape(e,t=[]){let n=this.clone(),r=Object.assign(n.fields,e);if(n.fields=r,n._sortErrors=bd(Object.keys(r)),t.length){Array.isArray(t[0])||(t=[t]);let i=t.map(([e,t])=>`${e}-${t}`);n._excludedEdges=n._excludedEdges.concat(i)}return n._nodes=bl(r,n._excludedEdges),n}pick(e){let t={};for(let n of e)this.fields[n]&&(t[n]=this.fields[n]);return this.clone().withMutation(e=>(e.fields={},e.shape(t)))}omit(e){let t=this.clone(),n=t.fields;for(let r of(t.fields={},e))delete n[r];return t.withMutation(()=>t.shape(n))}from(e,t,n){let r=(0,pC.getter)(e,!0);return this.transform(i=>{if(null==i)return i;let a=i;return py()(i,e)&&(a=bh({},i),n||delete a[e],a[t]=r(i)),a})}noUnknown(e=!0,t=pm.noUnknown){"string"==typeof e&&(t=e,e=!0);let n=this.test({name:"noUnknown",exclusive:!0,message:t,test(t){if(null==t)return!0;let n=bb(this.schema,t);return!e||0===n.length||this.createError({params:{unknown:n.join(", ")}})}});return n.spec.noUnknown=e,n}unknown(e=!0,t=pm.noUnknown){return this.noUnknown(!e,t)}transformKeys(e){return this.transform(t=>t&&bs()(t,(t,n)=>e(n)))}camelCase(){return this.transformKeys(ba())}snakeCase(){return this.transformKeys(br())}constantCase(){return this.transformKeys(e=>br()(e).toUpperCase())}describe(){let e=super.describe();return e.fields=pL()(this.fields,e=>e.describe()),e}}function bv(e){return new bg(e)}function by(){return(by=Object.assign||function(e){for(var t=1;t{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null})})}_typeCheck(e){return Array.isArray(e)}get _subType(){return this.innerType}_cast(e,t){let n=super._cast(e,t);if(!this._typeCheck(n)||!this.innerType)return n;let r=!1,i=n.map((e,n)=>{let i=this.innerType.cast(e,by({},t,{path:`${t.path||""}[${n}]`}));return i!==e&&(r=!0),i});return r?i:n}_validate(e,t={},n){var r,i;let a=[],o=t.sync,s=t.path,u=this.innerType,c=null!=(r=t.abortEarly)?r:this.spec.abortEarly,l=null!=(i=t.recursive)?i:this.spec.recursive,f=null!=t.originalValue?t.originalValue:e;super._validate(e,t,(e,r)=>{if(e){if(!pT.isError(e)||c)return void n(e,r);a.push(e)}if(!l||!u||!this._typeCheck(r)){n(a[0]||null,r);return}f=f||r;let i=Array(r.length);for(let d=0;du.validate(h,b,t)}pO({sync:o,path:s,value:r,errors:a,endEarly:c,tests:i},n)})}clone(e){let t=super.clone(e);return t.innerType=this.innerType,t}concat(e){let t=super.concat(e);return t.innerType=this.innerType,e.innerType&&(t.innerType=t.innerType?t.innerType.concat(e.innerType):e.innerType),t}of(e){let t=this.clone();if(!pw(e))throw TypeError("`array.of()` sub-schema must be a valid yup schema not: "+pl(e));return t.innerType=e,t}length(e,t=pg.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pK(t)||t.length===this.resolve(e)}})}min(e,t){return t=t||pg.min,this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t.length>=this.resolve(e)}})}max(e,t){return t=t||pg.max,this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pK(t)||t.length<=this.resolve(e)}})}ensure(){return this.default(()=>[]).transform((e,t)=>this._typeCheck(e)?e:null==t?[]:[].concat(t))}compact(e){let t=e?(t,n,r)=>!e(t,n,r):e=>!!e;return this.transform(e=>null!=e?e.filter(t):e)}describe(){let e=super.describe();return this.innerType&&(e.innerType=this.innerType.describe()),e}nullable(e=!0){return super.nullable(e)}defined(){return super.defined()}required(e){return super.required(e)}}bw.prototype=b_.prototype;var bE=bv().shape({name:p0().required("Required"),url:p0().required("Required")}),bS=function(e){var t=e.initialValues,n=e.onSubmit,r=e.submitButtonText,i=e.nameDisabled,a=void 0!==i&&i;return l.createElement(hT,{initialValues:t,validationSchema:bE,onSubmit:n},function(e){var t=e.isSubmitting;return l.createElement(l.Fragment,null,l.createElement(hR,{"data-testid":"bridge-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hP,{component:hX,id:"name",name:"name",label:"Name",disabled:a,required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hP,{component:hX,id:"url",name:"url",label:"Bridge URL",placeholder:"https://",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"url-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:7},l.createElement(hP,{component:hX,id:"minimumContractPayment",name:"minimumContractPayment",label:"Minimum Contract Payment",placeholder:"0",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"minimumContractPayment-helper-text"}})),l.createElement(d.Z,{item:!0,xs:7},l.createElement(hP,{component:hX,id:"confirmations",name:"confirmations",label:"Confirmations",placeholder:"0",type:"number",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"confirmations-helper-text"}})))),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},r)))))})},bk=function(e){var t=e.bridge,n=e.onSubmit,r={name:t.name,url:t.url,minimumContractPayment:t.minimumContractPayment,confirmations:t.confirmations};return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:40},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Edit Bridge",action:l.createElement(aA.Z,{component:tz,href:"/bridges/".concat(t.id)},"Cancel")}),l.createElement(aW.Z,null,l.createElement(bS,{nameDisabled:!0,initialValues:r,onSubmit:n,submitButtonText:"Save Bridge"}))))))};function bx(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]&&arguments[0],t=e?function(){return l.createElement(x.default,{variant:"body1"},"Loading...")}:function(){return null};return{isLoading:e,LoadingPlaceholder:t}},mc=n(76023);function ml(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function mB(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=4?[e[0],e[1],e[2],e[3],"".concat(e[0],".").concat(e[1]),"".concat(e[0],".").concat(e[2]),"".concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[0]),"".concat(e[1],".").concat(e[2]),"".concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[1]),"".concat(e[2],".").concat(e[3]),"".concat(e[3],".").concat(e[0]),"".concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[0]),"".concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[1],".").concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[2],".").concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[3],".").concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[2],".").concat(e[1],".").concat(e[0])]:void 0}var mZ={};function mX(e){if(0===e.length||1===e.length)return e;var t=e.join(".");return mZ[t]||(mZ[t]=mq(e)),mZ[t]}function mJ(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0;return mX(e.filter(function(e){return"token"!==e})).reduce(function(e,t){return mK({},e,n[t])},t)}function mQ(e){return e.join(" ")}function m1(e,t){var n=0;return function(r){return n+=1,r.map(function(r,i){return m0({node:r,stylesheet:e,useInlineStyles:t,key:"code-segment-".concat(n,"-").concat(i)})})}}function m0(e){var t=e.node,n=e.stylesheet,r=e.style,i=void 0===r?{}:r,a=e.useInlineStyles,o=e.key,s=t.properties,u=t.type,c=t.tagName,f=t.value;if("text"===u)return f;if(c){var d,h=m1(n,a);if(a){var p=Object.keys(n).reduce(function(e,t){return t.split(".").forEach(function(t){e.includes(t)||e.push(t)}),e},[]),b=s.className&&s.className.includes("token")?["token"]:[],m=s.className&&b.concat(s.className.filter(function(e){return!p.includes(e)}));d=mK({},s,{className:mQ(m)||void 0,style:mJ(s.className,Object.assign({},s.style,i),n)})}else d=mK({},s,{className:mQ(s.className)});var g=h(t.children);return l.createElement(c,(0,mV.Z)({key:o},d),g)}}let m2=function(e,t){return -1!==e.listLanguages().indexOf(t)};var m3=/\n/g;function m4(e){return e.match(m3)}function m6(e){var t=e.lines,n=e.startingLineNumber,r=e.style;return t.map(function(e,t){var i=t+n;return l.createElement("span",{key:"line-".concat(t),className:"react-syntax-highlighter-line-number",style:"function"==typeof r?r(i):r},"".concat(i,"\n"))})}function m5(e){var t=e.codeString,n=e.codeStyle,r=e.containerStyle,i=void 0===r?{float:"left",paddingRight:"10px"}:r,a=e.numberStyle,o=void 0===a?{}:a,s=e.startingLineNumber;return l.createElement("code",{style:Object.assign({},n,i)},m6({lines:t.replace(/\n$/,"").split("\n"),style:o,startingLineNumber:s}))}function m8(e){return"".concat(e.toString().length,".25em")}function m9(e,t){return{type:"element",tagName:"span",properties:{key:"line-number--".concat(e),className:["comment","linenumber","react-syntax-highlighter-line-number"],style:t},children:[{type:"text",value:e}]}}function m7(e,t,n){var r,i={display:"inline-block",minWidth:m8(n),paddingRight:"1em",textAlign:"right",userSelect:"none"};return mK({},i,"function"==typeof e?e(t):e)}function ge(e){var t=e.children,n=e.lineNumber,r=e.lineNumberStyle,i=e.largestLineNumber,a=e.showInlineLineNumbers,o=e.lineProps,s=void 0===o?{}:o,u=e.className,c=void 0===u?[]:u,l=e.showLineNumbers,f=e.wrapLongLines,d="function"==typeof s?s(n):s;if(d.className=c,n&&a){var h=m7(r,n,i);t.unshift(m9(n,h))}return f&l&&(d.style=mK({},d.style,{display:"flex"})),{type:"element",tagName:"span",properties:d,children:t}}function gt(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],r=0;r2&&void 0!==arguments[2]?arguments[2]:[];return ge({children:e,lineNumber:t,lineNumberStyle:s,largestLineNumber:o,showInlineLineNumbers:i,lineProps:n,className:a,showLineNumbers:r,wrapLongLines:u})}function b(e,t){if(r&&t&&i){var n=m7(s,t,o);e.unshift(m9(t,n))}return e}function m(e,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];return t||r.length>0?p(e,n,r):b(e,n)}for(var g=function(){var e=l[h],t=e.children[0].value;if(m4(t)){var n=t.split("\n");n.forEach(function(t,i){var o=r&&f.length+a,s={type:"text",value:"".concat(t,"\n")};if(0===i){var u=l.slice(d+1,h).concat(ge({children:[s],className:e.properties.className})),c=m(u,o);f.push(c)}else if(i===n.length-1){if(l[h+1]&&l[h+1].children&&l[h+1].children[0]){var p={type:"text",value:"".concat(t)},b=ge({children:[p],className:e.properties.className});l.splice(h+1,0,b)}else{var g=[s],v=m(g,o,e.properties.className);f.push(v)}}else{var y=[s],w=m(y,o,e.properties.className);f.push(w)}}),d=h}h++};h code[class*="language-"]':{background:"#f5f2f0",padding:".1em",borderRadius:".3em",whiteSpace:"normal"},comment:{color:"slategray"},prolog:{color:"slategray"},doctype:{color:"slategray"},cdata:{color:"slategray"},punctuation:{color:"#999"},namespace:{Opacity:".7"},property:{color:"#905"},tag:{color:"#905"},boolean:{color:"#905"},number:{color:"#905"},constant:{color:"#905"},symbol:{color:"#905"},deleted:{color:"#905"},selector:{color:"#690"},"attr-name":{color:"#690"},string:{color:"#690"},char:{color:"#690"},builtin:{color:"#690"},inserted:{color:"#690"},operator:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},entity:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)",cursor:"help"},url:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".language-css .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".style .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},atrule:{color:"#07a"},"attr-value":{color:"#07a"},keyword:{color:"#07a"},function:{color:"#DD4A68"},"class-name":{color:"#DD4A68"},regex:{color:"#e90"},important:{color:"#e90",fontWeight:"bold"},variable:{color:"#e90"},bold:{fontWeight:"bold"},italic:{fontStyle:"italic"}};var gu=n(98695),gc=n.n(gu);let gl=["abap","abnf","actionscript","ada","agda","al","antlr4","apacheconf","apl","applescript","aql","arduino","arff","asciidoc","asm6502","aspnet","autohotkey","autoit","bash","basic","batch","bbcode","birb","bison","bnf","brainfuck","brightscript","bro","bsl","c","cil","clike","clojure","cmake","coffeescript","concurnas","cpp","crystal","csharp","csp","css-extras","css","cypher","d","dart","dax","dhall","diff","django","dns-zone-file","docker","ebnf","editorconfig","eiffel","ejs","elixir","elm","erb","erlang","etlua","excel-formula","factor","firestore-security-rules","flow","fortran","fsharp","ftl","gcode","gdscript","gedcom","gherkin","git","glsl","gml","go","graphql","groovy","haml","handlebars","haskell","haxe","hcl","hlsl","hpkp","hsts","http","ichigojam","icon","iecst","ignore","inform7","ini","io","j","java","javadoc","javadoclike","javascript","javastacktrace","jolie","jq","js-extras","js-templates","jsdoc","json","json5","jsonp","jsstacktrace","jsx","julia","keyman","kotlin","latex","latte","less","lilypond","liquid","lisp","livescript","llvm","lolcode","lua","makefile","markdown","markup-templating","markup","matlab","mel","mizar","mongodb","monkey","moonscript","n1ql","n4js","nand2tetris-hdl","naniscript","nasm","neon","nginx","nim","nix","nsis","objectivec","ocaml","opencl","oz","parigp","parser","pascal","pascaligo","pcaxis","peoplecode","perl","php-extras","php","phpdoc","plsql","powerquery","powershell","processing","prolog","properties","protobuf","pug","puppet","pure","purebasic","purescript","python","q","qml","qore","r","racket","reason","regex","renpy","rest","rip","roboconf","robotframework","ruby","rust","sas","sass","scala","scheme","scss","shell-session","smali","smalltalk","smarty","sml","solidity","solution-file","soy","sparql","splunk-spl","sqf","sql","stan","stylus","swift","t4-cs","t4-templating","t4-vb","tap","tcl","textile","toml","tsx","tt2","turtle","twig","typescript","typoscript","unrealscript","vala","vbnet","velocity","verilog","vhdl","vim","visual-basic","warpscript","wasm","wiki","xeora","xml-doc","xojo","xquery","yaml","yang","zig"];var gf=go(gc(),gs);gf.supportedLanguages=gl;let gd=gf;var gh=n(64566);function gp(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function gb(){var e=gp(["\n query FetchConfigV2 {\n configv2 {\n user\n effective\n }\n }\n"]);return gb=function(){return e},e}var gm=n0(gb()),gg=function(e){var t=e.children;return l.createElement(ir.Z,null,l.createElement(r7.default,{component:"th",scope:"row",colSpan:3},t))},gv=function(){return l.createElement(gg,null,"...")},gy=function(e){var t=e.children;return l.createElement(gg,null,t)},gw=function(e){var t=e.loading,n=e.toml,r=e.error,i=void 0===r?"":r,a=e.title,o=e.expanded;if(i)return l.createElement(gy,null,i);if(t)return l.createElement(gv,null);a||(a="TOML");var s={display:"block"};return l.createElement(x.default,null,l.createElement(mP.Z,{defaultExpanded:o},l.createElement(mR.Z,{expandIcon:l.createElement(gh.Z,null)},a),l.createElement(mj.Z,{style:s},l.createElement(gd,{language:"toml",style:gs},n))))},g_=function(){var e=rv(gm,{fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return(null==t?void 0:t.configv2.effective)=="N/A"?l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"TOML Configuration"}),l.createElement(gw,{title:"V2 config dump:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0})))):l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"TOML Configuration"}),l.createElement(gw,{title:"User specified:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0,expanded:!0}),l.createElement(gw,{title:"Effective (with defaults):",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.effective,showHead:!0})))))},gE=n(34823),gS=function(e){return(0,b.createStyles)({cell:{paddingTop:1.5*e.spacing.unit,paddingBottom:1.5*e.spacing.unit}})},gk=(0,b.withStyles)(gS)(function(e){var t=e.classes,n=(0,A.I0)();(0,l.useEffect)(function(){n((0,ty.DQ)())});var r=(0,A.v9)(gE.N,A.wU);return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Node"}),l.createElement(r8.Z,null,l.createElement(r9.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,{className:t.cell},l.createElement(x.default,null,"Version"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.version))),l.createElement(ir.Z,null,l.createElement(r7.default,{className:t.cell},l.createElement(x.default,null,"SHA"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.commitSHA))))))}),gx=function(){return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,sm:12,md:8},l.createElement(d.Z,{container:!0},l.createElement(g_,null))),l.createElement(d.Z,{item:!0,sm:12,md:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gk,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mN,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mE,null))))))},gT=function(){return l.createElement(gx,null)},gM=function(){return l.createElement(gT,null)},gO=n(44431),gA=1e18,gL=function(e){return new gO.BigNumber(e).dividedBy(gA).toFixed(8)},gC=function(e){var t=e.keys,n=e.chainID,r=e.hideHeaderTitle;return l.createElement(l.Fragment,null,l.createElement(sl.Z,{title:!r&&"Account Balances",subheader:"Chain ID "+n}),l.createElement(aW.Z,null,l.createElement(w.default,{dense:!1,disablePadding:!0},t&&t.map(function(e,r){return l.createElement(l.Fragment,null,l.createElement(_.default,{disableGutters:!0,key:["acc-balance",n.toString(),r.toString()].join("-")},l.createElement(E.Z,{primary:l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(op,{title:"Address"}),l.createElement(ob,{value:e.address})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(op,{title:"Native Token Balance"}),l.createElement(ob,{value:e.ethBalance||"--"})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(op,{title:"LINK Balance"}),l.createElement(ob,{value:e.linkBalance?gL(e.linkBalance):"--"}))))})),r+1s&&l.createElement(gB.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,{className:r.footer},l.createElement(aA.Z,{href:"/runs",component:tz},"View More"))))))});function vt(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vn(){var e=vt(["\n ","\n query FetchRecentJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...RecentJobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return vn=function(){return e},e}var vr=5,vi=n0(vn(),g9),va=function(){var e=rv(vi,{variables:{offset:0,limit:vr},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(ve,{data:t,errorMsg:null==r?void 0:r.message,loading:n,maxRunsSize:vr})},vo=function(e){return(0,b.createStyles)({style:{textAlign:"center",padding:2.5*e.spacing.unit,position:"fixed",left:"0",bottom:"0",width:"100%",borderRadius:0},bareAnchor:{color:e.palette.common.black,textDecoration:"none"}})},vs=(0,b.withStyles)(vo)(function(e){var t=e.classes,n=(0,A.v9)(gE.N,A.wU),r=(0,A.I0)();return(0,l.useEffect)(function(){r((0,ty.DQ)())}),l.createElement(ii.default,{className:t.style},l.createElement(x.default,null,"Chainlink Node ",n.version," at commit"," ",l.createElement("a",{target:"_blank",rel:"noopener noreferrer",href:"https://github.com/smartcontractkit/chainlink/commit/".concat(n.commitSHA),className:t.bareAnchor},n.commitSHA)))}),vu=function(e){return(0,b.createStyles)({cell:{borderColor:e.palette.divider,borderTop:"1px solid",borderBottom:"none",paddingTop:2*e.spacing.unit,paddingBottom:2*e.spacing.unit,paddingLeft:2*e.spacing.unit},block:{display:"block"},overflowEllipsis:{textOverflow:"ellipsis",overflow:"hidden"}})},vc=(0,b.withStyles)(vu)(function(e){var t=e.classes,n=e.job;return l.createElement(ir.Z,null,l.createElement(r7.default,{scope:"row",className:t.cell},l.createElement(d.Z,{container:!0,spacing:0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(ih,{href:"/jobs/".concat(n.id),classes:{linkContent:t.block}},l.createElement(x.default,{className:t.overflowEllipsis,variant:"body1",component:"span",color:"primary"},n.name||n.id))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,{variant:"body1",color:"textSecondary"},"Created ",l.createElement(aO,{tooltip:!0},n.createdAt))))))});function vl(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vf(){var e=vl(["\n fragment RecentJobsPayload_ResultsFields on Job {\n id\n name\n createdAt\n }\n"]);return vf=function(){return e},e}var vd=n0(vf()),vh=function(){return(0,b.createStyles)({cardHeader:{borderBottom:0},table:{tableLayout:"fixed"}})},vp=(0,b.withStyles)(vh)(function(e){var t,n,r=e.classes,i=e.data,a=e.errorMsg,o=e.loading;return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Recent Jobs",className:r.cardHeader}),l.createElement(r8.Z,{className:r.table},l.createElement(r9.Z,null,l.createElement(g$,{visible:o}),l.createElement(gz,{visible:(null===(t=null==i?void 0:i.jobs.results)||void 0===t?void 0:t.length)===0},"No recently created jobs"),l.createElement(gU,{msg:a}),null===(n=null==i?void 0:i.jobs.results)||void 0===n?void 0:n.map(function(e,t){return l.createElement(vc,{job:e,key:t})}))))});function vb(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vm(){var e=vb(["\n ","\n query FetchRecentJobs($offset: Int, $limit: Int) {\n jobs(offset: $offset, limit: $limit) {\n results {\n ...RecentJobsPayload_ResultsFields\n }\n }\n }\n"]);return vm=function(){return e},e}var vg=5,vv=n0(vm(),vd),vy=function(){var e=rv(vv,{variables:{offset:0,limit:vg},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(vp,{data:t,errorMsg:null==r?void 0:r.message,loading:n})},vw=function(){return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:8},l.createElement(va,null)),l.createElement(d.Z,{item:!0,xs:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gY,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(vy,null))))),l.createElement(vs,null))},v_=function(){return l.createElement(vw,null)},vE=function(){return l.createElement(v_,null)},vS=n(87239),vk=function(e){switch(e){case"DirectRequestSpec":return"Direct Request";case"FluxMonitorSpec":return"Flux Monitor";default:return e.replace(/Spec$/,"")}},vx=n(5022),vT=n(78718),vM=n.n(vT);function vO(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1?t-1:0),r=1;r1?t-1:0),r=1;re.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&n.map(function(e){return l.createElement(ir.Z,{key:e.id,style:{cursor:"pointer"},onClick:function(){return r.push("/runs/".concat(e.id))}},l.createElement(r7.default,{className:t.idCell,scope:"row"},l.createElement("div",{className:t.runDetails},l.createElement(x.default,{variant:"h5",color:"primary",component:"span"},e.id))),l.createElement(r7.default,{className:t.stampCell},l.createElement(x.default,{variant:"body1",color:"textSecondary",className:t.stamp},"Created ",l.createElement(aO,{tooltip:!0},e.createdAt))),l.createElement(r7.default,{className:t.statusCell,scope:"row"},l.createElement(x.default,{variant:"body1",className:O()(t.status,yh(t,e.status))},e.status.toLowerCase())))})))}),yb=n(16839),ym=n.n(yb);function yg(e){var t=e.replace(/\w+\s*=\s*<([^>]|[\r\n])*>/g,""),n=ym().read(t),r=n.edges();return n.nodes().map(function(e){var t={id:e,parentIds:r.filter(function(t){return t.w===e}).map(function(e){return e.v})};return Object.keys(n.node(e)).length>0&&(t.attributes=n.node(e)),t})}var yv=n(94164),yy=function(e){var t=e.data,n=[];return(null==t?void 0:t.attributes)&&Object.keys(t.attributes).forEach(function(e){var r;n.push(l.createElement("div",{key:e},l.createElement(x.default,{variant:"body1",color:"textSecondary",component:"div"},l.createElement("b",null,e,":")," ",null===(r=t.attributes)||void 0===r?void 0:r[e])))}),l.createElement("div",null,t&&l.createElement(x.default,{variant:"body1",color:"textPrimary"},l.createElement("b",null,t.id)),n)},yw=n(73343),y_=n(3379),yE=n.n(y_);function yS(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nwindow.innerWidth?u-r.getBoundingClientRect().width-a:u+a,n=c+r.getBoundingClientRect().height+i>window.innerHeight?c-r.getBoundingClientRect().height-a:c+a,r.style.opacity=String(1),r.style.top="".concat(n,"px"),r.style.left="".concat(t,"px"),r.style.zIndex=String(1)}},h=function(e){var t=document.getElementById("tooltip-d3-chart-".concat(e));t&&(t.style.opacity=String(0),t.style.zIndex=String(-1))};return l.createElement("div",{style:{fontFamily:"sans-serif",fontWeight:"normal"}},l.createElement(yv.kJ,{id:"task-list-graph-d3",data:i,config:s,onMouseOverNode:d,onMouseOutNode:h},"D3 chart"),n.map(function(e){return l.createElement("div",{key:"d3-tooltip-key-".concat(e.id),id:"tooltip-d3-chart-".concat(e.id),style:{position:"absolute",opacity:"0",border:"1px solid rgba(0, 0, 0, 0.1)",padding:yw.r.spacing.unit,background:"white",borderRadius:5,zIndex:-1,inlineSize:"min-content"}},l.createElement(yy,{data:e}))}))};function yL(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nyY&&l.createElement("div",{className:t.runDetails},l.createElement(aA.Z,{href:"/jobs/".concat(n.id,"/runs"),component:tz},"View more")))),l.createElement(d.Z,{item:!0,xs:12,sm:6},l.createElement(yF,{observationSource:n.observationSource})))});function yH(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]?arguments[0]:"";try{return vx.parse(e),!0}catch(t){return!1}})}),wW=function(e){var t=e.initialValues,n=e.onSubmit,r=e.onTOMLChange;return l.createElement(hT,{initialValues:t,validationSchema:wG,onSubmit:n},function(e){var t=e.isSubmitting,n=e.values;return r&&r(n.toml),l.createElement(hR,{"data-testid":"job-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"toml",name:"toml",label:"Job Spec (TOML)",required:!0,fullWidth:!0,multiline:!0,rows:10,rowsMax:25,variant:"outlined",autoComplete:"off",FormHelperTextProps:{"data-testid":"toml-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},"Create Job"))))})},wK=n(50109),wV="persistSpec";function wq(e){var t=e.query,n=new URLSearchParams(t).get("definition");return n?(wK.t8(wV,n),{toml:n}):{toml:wK.U2(wV)||""}}var wZ=function(e){var t=e.onSubmit,n=e.onTOMLChange,r=wq({query:(0,h.TH)().search}),i=function(e){var t=e.replace(/[\u200B-\u200D\uFEFF]/g,"");wK.t8("".concat(wV),t),n&&n(t)};return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"New Job"}),l.createElement(aW.Z,null,l.createElement(wW,{initialValues:r,onSubmit:t,onTOMLChange:i})))};function wX(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n1&&void 0!==arguments[1]?arguments[1]:{},n=t.start,r=void 0===n?6:n,i=t.end,a=void 0===i?4:i;return e.substring(0,r)+"..."+e.substring(e.length-a)}function _M(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(_W,e)},_V=function(){var e=_K({fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error,i=e.refetch;return l.createElement(_U,{loading:n,data:t,errorMsg:null==r?void 0:r.message,refetch:i})},_q=function(e){var t=e.csaKey;return l.createElement(ir.Z,{hover:!0},l.createElement(r7.default,null,l.createElement(x.default,{variant:"body1"},t.publicKey," ",l.createElement(_x,{data:t.publicKey}))))};function _Z(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function _X(){var e=_Z(["\n fragment CSAKeysPayload_ResultsFields on CSAKey {\n id\n publicKey\n }\n"]);return _X=function(){return e},e}var _J=n0(_X()),_Q=function(e){var t,n,r,i=e.data,a=e.errorMsg,o=e.loading,s=e.onCreate;return l.createElement(r5.Z,null,l.createElement(sl.Z,{action:(null===(t=null==i?void 0:i.csaKeys.results)||void 0===t?void 0:t.length)===0&&l.createElement(ok.default,{variant:"outlined",color:"primary",onClick:s},"New CSA Key"),title:"CSA Key",subheader:"Manage your CSA Key"}),l.createElement(r8.Z,null,l.createElement(ie.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,null,"Public Key"))),l.createElement(r9.Z,null,l.createElement(g$,{visible:o}),l.createElement(gz,{visible:(null===(n=null==i?void 0:i.csaKeys.results)||void 0===n?void 0:n.length)===0}),l.createElement(gU,{msg:a}),null===(r=null==i?void 0:i.csaKeys.results)||void 0===r?void 0:r.map(function(e,t){return l.createElement(_q,{csaKey:e,key:t})}))))};function _1(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(EM,e)};function EA(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(EJ,e)},E3=function(){return oo(EQ)},E4=function(){return oo(E1)},E6=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return rv(E0,e)};function E5(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(SK,e)};function Sq(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function kV(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}var kq=function(e){var t=e.run,n=l.useMemo(function(){var e=t.inputs,n=t.outputs,r=t.taskRuns,i=kK(t,["inputs","outputs","taskRuns"]),a={};try{a=JSON.parse(e)}catch(o){a={}}return kW(kz({},i),{inputs:a,outputs:n,taskRuns:r})},[t]);return l.createElement(r5.Z,null,l.createElement(aW.Z,null,l.createElement(kH,{object:n})))};function kZ(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function kX(e){for(var t=1;t0&&l.createElement(kr,{errors:t.allErrors})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(h.rs,null,l.createElement(h.AW,{path:"".concat(n,"/json")},l.createElement(kq,{run:t})),l.createElement(h.AW,{path:n},t.taskRuns.length>0&&l.createElement(kN,{taskRuns:t.taskRuns,observationSource:t.job.observationSource}))))))))};function k5(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function k8(){var e=k5(["\n ","\n query FetchJobRun($id: ID!) {\n jobRun(id: $id) {\n __typename\n ... on JobRun {\n ...JobRunPayload_Fields\n }\n ... on NotFoundError {\n message\n }\n }\n }\n"]);return k8=function(){return e},e}var k9=n0(k8(),k4),k7=function(){var e=rv(k9,{variables:{id:(0,h.UO)().id}}),t=e.data,n=e.loading,r=e.error;if(n)return l.createElement(iR,null);if(r)return l.createElement(iD,{error:r});var i=null==t?void 0:t.jobRun;switch(null==i?void 0:i.__typename){case"JobRun":return l.createElement(k6,{run:i});case"NotFoundError":return l.createElement(oa,null);default:return null}};function xe(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xt(){var e=xe(["\n fragment JobRunsPayload_ResultsFields on JobRun {\n id\n allErrors\n createdAt\n finishedAt\n status\n job {\n id\n }\n }\n"]);return xt=function(){return e},e}var xn=n0(xt()),xr=function(e){var t=e.loading,n=e.data,r=e.page,i=e.pageSize,a=(0,h.k6)(),o=l.useMemo(function(){return null==n?void 0:n.jobRuns.results.map(function(e){var t,n=e.allErrors,r=e.id,i=e.createdAt;return{id:r,createdAt:i,errors:n,finishedAt:e.finishedAt,status:e.status}})},[n]);return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(iy,null,"Job Runs")),t&&l.createElement(iR,null),n&&o&&l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(yp,{runs:o}),l.createElement(it.Z,{component:"div",count:n.jobRuns.metadata.total,rowsPerPage:i,rowsPerPageOptions:[i],page:r-1,onChangePage:function(e,t){a.push("/runs?page=".concat(t+1,"&per=").concat(i))},onChangeRowsPerPage:function(){},backIconButtonProps:{"aria-label":"prev-page"},nextIconButtonProps:{"aria-label":"next-page"}})))))};function xi(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xa(){var e=xi(["\n ","\n query FetchJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...JobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return xa=function(){return e},e}var xo=n0(xa(),xn),xs=function(){var e=ij(),t=parseInt(e.get("page")||"1",10),n=parseInt(e.get("per")||"25",10),r=rv(xo,{variables:{offset:(t-1)*n,limit:n},fetchPolicy:"cache-and-network"}),i=r.data,a=r.loading,o=r.error;return o?l.createElement(iD,{error:o}):l.createElement(xr,{loading:a,data:i,page:t,pageSize:n})},xu=function(){var e=(0,h.$B)().path;return l.createElement(h.rs,null,l.createElement(h.AW,{exact:!0,path:e},l.createElement(xs,null)),l.createElement(h.AW,{path:"".concat(e,"/:id")},l.createElement(k7,null)))};function xc(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xl(){var e=xc(["\n fragment FetchFeedsManagersPayload_ResultsFields on FeedsManager {\n __typename\n id\n name\n uri\n publicKey\n isConnectionActive\n createdAt\n disabledAt\n }\n query FetchFeedsManagers {\n feedsManagers {\n results {\n ...FetchFeedsManagersPayload_ResultsFields\n }\n }\n }\n"]);return xl=function(){return e},e}var xf=n0(xl()),xd=function(e){return rv(xf,e)},xh=n(47559),xp=n(83165),xb=n(47298),xm=n(81395),xg=function(){return(0,b.createStyles)({root:{display:"flex"},activeIcon:{color:xh.default[500]},inactiveIcon:{color:xp.default[500]},text:{marginLeft:4}})},xv=(0,b.withStyles)(xg)(function(e){var t=e.isActive,n=e.activeText,r=e.inactiveText,i=e.classes;return l.createElement("div",{className:i.root},t?l.createElement(xm.Z,{fontSize:"small",className:i.activeIcon}):l.createElement(xb.Z,{fontSize:"small",className:i.inactiveIcon}),l.createElement(x.default,{variant:"body1",inline:!0,className:i.text},t?n:r))}),xy=(0,b.withStyles)(iu)(function(e){var t=e.jobDistributor,n=e.classes;return l.createElement(ir.Z,{className:n.row,hover:!0},l.createElement(r7.default,{className:n.cell,component:"th",scope:"row"},l.createElement(ih,{className:n.link,href:"/job_distributors/".concat(t.id)},t.name)),l.createElement(r7.default,null,l.createElement(xv,{isActive:t.isConnectionActive,activeText:"Connected",inactiveText:"Disconnected"})),l.createElement(r7.default,null,l.createElement(xv,{isActive:!t.disabledAt,activeText:"Enabled",inactiveText:"Disabled"})),l.createElement(r7.default,null,_T(t.publicKey,{start:6,end:6}),l.createElement(_x,{data:t.publicKey})),l.createElement(r7.default,null,t.uri))}),xw=function(e){var t=e.jobDistributors;return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:9},l.createElement(iy,null,"Job Distributors")),l.createElement(d.Z,{item:!0,xs:3},l.createElement(d.Z,{container:!0,justify:"flex-end"},l.createElement(d.Z,{item:!0},l.createElement(aA.Z,{variant:"secondary",component:tz,href:"/job_distributors/new"},"New Job Distributor")))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(r8.Z,null,l.createElement(ie.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,null,"Name"),l.createElement(r7.default,null,"Connection Status"),l.createElement(r7.default,null,"Status"),l.createElement(r7.default,null,"CSA Public Key"),l.createElement(r7.default,null,"RPC URL"))),l.createElement(r9.Z,null,0===t.length&&l.createElement(ir.Z,null,l.createElement(r7.default,{component:"th",scope:"row",colSpan:3},"Job Distributors have not been registered")),t.map(function(e){return l.createElement(xy,{key:e.id,jobDistributor:e})})))))))},x_=function(){var e,t=xd({fetchPolicy:"cache-and-network"}),n=t.data,r=t.loading,i=t.error;return r?l.createElement(iR,null):i?l.createElement(iD,{error:i}):l.createElement(xw,{jobDistributors:null!==(e=null==n?void 0:n.feedsManagers.results)&&void 0!==e?e:[]})},xE=bv().shape({name:p0().required("Required"),uri:p0().required("Required"),publicKey:p0().required("Required")}),xS=function(e){var t=e.initialValues,n=e.onSubmit;return l.createElement(hT,{initialValues:t,validationSchema:xE,onSubmit:n},function(e){var t=e.isSubmitting,n=e.submitForm;return l.createElement(hR,{"data-testid":"feeds-manager-form"},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"name",name:"name",label:"Name",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:!1,md:6}),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"uri",name:"uri",label:"URI",required:!0,fullWidth:!0,helperText:"Provided by the Job Distributor operator",FormHelperTextProps:{"data-testid":"uri-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"publicKey",name:"publicKey",label:"Public Key",required:!0,fullWidth:!0,helperText:"Provided by the Job Distributor operator",FormHelperTextProps:{"data-testid":"publicKey-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(ok.default,{variant:"contained",color:"primary",disabled:t,onClick:n},"Submit"))))})},xk=function(e){var t=e.data,n=e.onSubmit,r={name:t.name,uri:t.uri,publicKey:t.publicKey};return l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Edit Job Distributor"}),l.createElement(aW.Z,null,l.createElement(xS,{initialValues:r,onSubmit:n})))))};function xx(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(xZ,e)},xJ=function(){return(0,b.createStyles)({root:{fontSize:24}})},xQ=(0,b.withStyles)(xJ)(function(e){var t=e.children,n=e.classes;return l.createElement(x.default,{variant:"h2",className:n.root},t)}),x1=n(9290),x0=n(74923);function x2(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function TT(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}function TM(e,t){return Tv(e)||TE(e,t)||TA(e,t)||TS()}function TO(e){return Ty(e)||T_(e)||TA(e)||Tk()}function TA(e,t){if(e){if("string"==typeof e)return Tg(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return Tg(e,t)}}var TL=function(e){return"SN_MAIN"===e||"SN_SEPOLIA"===e},TC=bv().shape({chainID:p0().required("Required"),chainType:p0().required("Required"),accountAddr:p0().required("Required"),accountAddrPubKey:p0().nullable(),adminAddr:p0(),ocr1Multiaddr:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&t},then:p0().required("Required").nullable()}).nullable(),ocr1P2PPeerID:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr1KeyBundleID:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2Multiaddr:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&t},then:p0().required("Required").nullable()}).nullable(),ocr2P2PPeerID:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2KeyBundleID:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2CommitPluginEnabled:pV().required("Required"),ocr2ExecutePluginEnabled:pV().required("Required"),ocr2MedianPluginEnabled:pV().required("Required"),ocr2MercuryPluginEnabled:pV().required("Required"),ocr2ForwarderAddress:p0().nullable()}),TI=function(e){return(0,b.createStyles)({supportedJobOptionsPaper:{padding:2*e.spacing.unit}})},TD=function(e){var t=e.addresses,n=Tx(e,["addresses"]),r=h_(),i=r.values,a=i.chainID,o=i.accountAddr,s=r.setFieldValue,u=TM(l.useState(!1),2),c=u[0],f=u[1],d=l.useRef();l.useEffect(function(){d.current=a},[a]),l.useEffect(function(){a!==d.current&&(s(n.name,""),f(!1))},[a,s,n.name]);var h=function(e){var t=e.target.value;"custom"===t?(f(!0),s(n.name,"")):(f(!1),s(n.name,t))};return l.createElement(l.Fragment,null,!TL(a)&&l.createElement(hP,Tw({},n,{select:!0,value:c?"custom":o,onChange:h}),t.map(function(e){return l.createElement(tE.default,{key:e,value:e},e)})),TL(a)&&l.createElement(hP,{component:hX,id:"accountAddr",name:"accountAddr",label:"Enter your account address",inputProps:{"data-testid":"customAccountAddr-input"},helperText:"The account address used for this chain",required:!0,fullWidth:!0}),TL(a)&&l.createElement("div",null,l.createElement(hP,{component:hX,id:"accountAddrPubKey",name:"accountAddrPubKey",label:"Account Address Public Key",required:!0,fullWidth:!0,helperText:"The public key for your account address",FormHelperTextProps:{"data-testid":"accountAddrPubKey-helper-text"}})))},TN=(0,b.withStyles)(TI)(function(e){var t=e.classes,n=e.editing,r=void 0!==n&&n,i=e.innerRef,a=e.initialValues,o=e.onSubmit,s=e.chains,u=void 0===s?[]:s,c=e.accountsEVM,f=void 0===c?[]:c,h=e.accountsNonEvm,p=e.p2pKeys,b=void 0===p?[]:p,m=e.ocrKeys,g=void 0===m?[]:m,v=e.ocr2Keys,y=void 0===v?[]:v,w=e.showSubmit,_=void 0!==w&&w,E=TO(y).sort(function(e,t){var n,r,i;return e.chainType===t.chainType?e.id.localeCompare(t.id):null!==(i=null===(n=e.chainType)||void 0===n?void 0:n.localeCompare(null!==(r=t.chainType)&&void 0!==r?r:""))&&void 0!==i?i:0});return l.createElement(hT,{innerRef:i,initialValues:a,validationSchema:TC,onSubmit:o},function(e){var n,i,a=e.values,o=[];switch(a.chainType){case Tm.EVM:o=f.filter(function(e){return e.chain.id==a.chainID&&!e.isDisabled}).map(function(e){return e.address});break;case Tm.APTOS:o=null!==(n=null==h?void 0:h.aptosKeys.results.map(function(e){return e.account}))&&void 0!==n?n:[];break;case Tm.SOLANA:o=null!==(i=null==h?void 0:h.solanaKeys.results.map(function(e){return e.id}))&&void 0!==i?i:[];break;default:o=[]}var s=u.filter(function(e){return e.network.toUpperCase()===a.chainType});return l.createElement(hR,{"data-testid":"feeds-manager-form",id:"chain-configuration-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"chainType",name:"chainType",label:"Chain Type",select:!0,required:!0,fullWidth:!0,disabled:r},l.createElement(tE.default,{key:Tm.EVM,value:Tm.EVM},"EVM"),l.createElement(tE.default,{key:Tm.APTOS,value:Tm.APTOS},"APTOS"),l.createElement(tE.default,{key:Tm.SOLANA,value:Tm.SOLANA},"SOLANA"))),l.createElement(d.Z,{item:!0,xs:12,md:6},s.length>0&&!r?l.createElement(hP,{component:hX,id:"chainID",name:"chainID",label:"Chain ID",required:!0,fullWidth:!0,select:!0,disabled:r,inputProps:{"data-testid":"chainID-input"},FormHelperTextProps:{"data-testid":"chainID-helper-text"}},s.map(function(e){return l.createElement(tE.default,{key:e.id,value:e.id},e.id)})):l.createElement(hP,{component:hX,id:"chainID",name:"chainID",label:"Chain ID",required:!0,fullWidth:!0,disabled:r,inputProps:{"data-testid":"chainID-manual-input"},FormHelperTextProps:{"data-testid":"chainID-helper-manual-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},o.length>0?l.createElement(TD,{component:hX,id:"accountAddr",name:"accountAddr",label:"Account Address",inputProps:{"data-testid":"accountAddr-input"},required:!0,fullWidth:!0,select:!0,helperText:"The account address used for this chain",addresses:o,FormHelperTextProps:{"data-testid":"accountAddr-helper-text"}}):l.createElement(hP,{component:hX,id:"accountAddr",name:"accountAddr",label:"Account Address",inputProps:{"data-testid":"accountAddr-manual-input"},required:!0,fullWidth:!0,helperText:"The account address used for this chain",FormHelperTextProps:{"data-testid":"accountAddr-helper-manual-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"adminAddr",name:"adminAddr",label:"Admin Address",fullWidth:!0,helperText:"The address used for LINK payments",FormHelperTextProps:{"data-testid":"adminAddr-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,null,"Supported Job Types")),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"fluxMonitorEnabled",type:"checkbox",Label:{label:"Flux Monitor"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr1Enabled",type:"checkbox",Label:{label:"OCR"}}),a.ocr1Enabled&&l.createElement(ii.default,{className:t.supportedJobOptionsPaper},l.createElement(d.Z,{container:!0,spacing:8},l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr1IsBootstrap",type:"checkbox",Label:{label:"Is this node running as a bootstrap peer?"}})),a.ocr1IsBootstrap?l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"ocr1Multiaddr",name:"ocr1Multiaddr",label:"Multiaddr",required:!0,fullWidth:!0,helperText:"The OCR Multiaddr which oracles use to query for network information",FormHelperTextProps:{"data-testid":"ocr1Multiaddr-helper-text"}})):l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr1P2PPeerID",name:"ocr1P2PPeerID",label:"Peer ID",select:!0,required:!0,fullWidth:!0,helperText:"The Peer ID used for this chain",FormHelperTextProps:{"data-testid":"ocr1P2PPeerID-helper-text"}},b.map(function(e){return l.createElement(tE.default,{key:e.peerID,value:e.peerID},e.peerID)}))),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr1KeyBundleID",name:"ocr1KeyBundleID",label:"Key Bundle ID",select:!0,required:!0,fullWidth:!0,helperText:"The OCR Key Bundle ID used for this chain",FormHelperTextProps:{"data-testid":"ocr1KeyBundleID-helper-text"}},g.map(function(e){return l.createElement(tE.default,{key:e.id,value:e.id},e.id)})))))))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr2Enabled",type:"checkbox",Label:{label:"OCR2"}}),a.ocr2Enabled&&l.createElement(ii.default,{className:t.supportedJobOptionsPaper},l.createElement(d.Z,{container:!0,spacing:8},l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr2IsBootstrap",type:"checkbox",Label:{label:"Is this node running as a bootstrap peer?"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr2P2PPeerID",name:"ocr2P2PPeerID",label:"Peer ID",select:!0,required:!a.ocr2IsBootstrap,fullWidth:!0,helperText:"The Peer ID used for this chain",FormHelperTextProps:{"data-testid":"ocr2P2PPeerID-helper-text"}},b.map(function(e){return l.createElement(tE.default,{key:e.peerID,value:e.peerID},e.peerID)}))),a.ocr2IsBootstrap?l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"ocr2Multiaddr",name:"ocr2Multiaddr",label:"Multiaddr",required:!0,fullWidth:!0,helperText:"The OCR2 Multiaddr which oracles use to query for network information",FormHelperTextProps:{"data-testid":"ocr2Multiaddr-helper-text"}})):l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr2KeyBundleID",name:"ocr2KeyBundleID",label:"Key Bundle ID",select:!0,required:!0,fullWidth:!0,helperText:"The OCR2 Key Bundle ID used for this chain",FormHelperTextProps:{"data-testid":"ocr2KeyBundleID-helper-text"}},E.map(function(e){return l.createElement(tE.default,{key:e.id,value:e.id},e.id," (",e.chainType,")")}))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,null,"Supported Plugins")),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2CommitPluginEnabled",type:"checkbox",Label:{label:"Commit"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2ExecutePluginEnabled",type:"checkbox",Label:{label:"Execute"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2RebalancerPluginEnabled",type:"checkbox",Label:{label:"Rebalancer"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2MedianPluginEnabled",type:"checkbox",Label:{label:"Median"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2MercuryPluginEnabled",type:"checkbox",Label:{label:"Mercury"}})),l.createElement(d.Z,{item:!0,xs:12,md:12},l.createElement(hP,{component:hX,id:"ocr2ForwarderAddress",name:"ocr2ForwarderAddress",label:"Forwarder Address (optional)",fullWidth:!0,helperText:"The forwarder address from the Operator Forwarder Contract",FormHelperTextProps:{"data-testid":"ocr2ForwarderAddress-helper-text"}}))))))),_&&l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",size:"large"},"Submit"))))})});function TP(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function TR(){var e=TP(["\n fragment AptosKeysPayload_ResultsFields on AptosKey {\n account\n id\n }\n"]);return TR=function(){return e},e}function Tj(){var e=TP(["\n fragment SolanaKeysPayload_ResultsFields on SolanaKey {\n id\n }\n"]);return Tj=function(){return e},e}function TF(){var e=TP(["\n ","\n ","\n query FetchNonEvmKeys {\n aptosKeys {\n results {\n ...AptosKeysPayload_ResultsFields\n }\n }\n solanaKeys {\n results {\n ...SolanaKeysPayload_ResultsFields\n }\n }\n }\n"]);return TF=function(){return e},e}var TY=n0(TR()),TB=n0(Tj()),TU=n0(TF(),TY,TB),TH=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return rv(TU,e)},T$=function(e){var t=e.onClose,n=e.open,r=e.onSubmit,i=l.useRef(),a=i$({fetchPolicy:"network-only"}).data,o=_K({fetchPolicy:"cache-and-network"}).data,s=TH({fetchPolicy:"cache-and-network"}).data,u=SV({fetchPolicy:"cache-and-network"}).data,c=EO({fetchPolicy:"cache-and-network"}).data,f=E2({fetchPolicy:"cache-and-network"}).data,d={chainID:"",chainType:Tm.EVM,accountAddr:"",adminAddr:"",accountAddrPubKey:"",fluxMonitorEnabled:!1,ocr1Enabled:!1,ocr1IsBootstrap:!1,ocr1Multiaddr:"",ocr1P2PPeerID:"",ocr1KeyBundleID:"",ocr2Enabled:!1,ocr2IsBootstrap:!1,ocr2Multiaddr:"",ocr2P2PPeerID:"",ocr2KeyBundleID:"",ocr2CommitPluginEnabled:!1,ocr2ExecutePluginEnabled:!1,ocr2MedianPluginEnabled:!1,ocr2MercuryPluginEnabled:!1,ocr2RebalancerPluginEnabled:!1,ocr2ForwarderAddress:""},h=a?a.chains.results:[],p=o?o.ethKeys.results:[],b=u?u.p2pKeys.results:[],m=c?c.ocrKeyBundles.results:[],g=f?f.ocr2KeyBundles.results:[];return l.createElement(aD.Z,{onClose:t,open:n,disableBackdropClick:!0},l.createElement(oO.Z,{disableTypography:!0},l.createElement(x.default,{variant:"body2"},"New Supported Chain")),l.createElement(oT.Z,null,l.createElement(TN,{innerRef:i,initialValues:d,onSubmit:r,chains:h,accountsEVM:p,accountsNonEvm:s,p2pKeys:b,ocrKeys:m,ocr2Keys:g})),l.createElement(ox.Z,null,l.createElement(ok.default,{onClick:t},"Cancel"),l.createElement(ok.default,{color:"primary",type:"submit",form:"chain-configuration-form",variant:"contained"},"Submit")))},Tz=function(e){var t=e.cfg,n=e.onClose,r=e.open,i=e.onSubmit,a=l.useRef(),o=i$({fetchPolicy:"network-only"}).data,s=_K({fetchPolicy:"cache-and-network"}).data,u=TH({fetchPolicy:"cache-and-network"}).data,c=SV({fetchPolicy:"cache-and-network"}).data,f=EO({fetchPolicy:"cache-and-network"}).data,d=E2({fetchPolicy:"cache-and-network"}).data;if(!t)return null;var h={chainID:t.chainID,chainType:t.chainType,accountAddr:t.accountAddr,adminAddr:t.adminAddr,accountAddrPubKey:t.accountAddrPubKey,fluxMonitorEnabled:t.fluxMonitorJobConfig.enabled,ocr1Enabled:t.ocr1JobConfig.enabled,ocr1IsBootstrap:t.ocr1JobConfig.isBootstrap,ocr1Multiaddr:t.ocr1JobConfig.multiaddr,ocr1P2PPeerID:t.ocr1JobConfig.p2pPeerID,ocr1KeyBundleID:t.ocr1JobConfig.keyBundleID,ocr2Enabled:t.ocr2JobConfig.enabled,ocr2IsBootstrap:t.ocr2JobConfig.isBootstrap,ocr2Multiaddr:t.ocr2JobConfig.multiaddr,ocr2P2PPeerID:t.ocr2JobConfig.p2pPeerID,ocr2KeyBundleID:t.ocr2JobConfig.keyBundleID,ocr2CommitPluginEnabled:t.ocr2JobConfig.plugins.commit,ocr2ExecutePluginEnabled:t.ocr2JobConfig.plugins.execute,ocr2MedianPluginEnabled:t.ocr2JobConfig.plugins.median,ocr2MercuryPluginEnabled:t.ocr2JobConfig.plugins.mercury,ocr2RebalancerPluginEnabled:t.ocr2JobConfig.plugins.rebalancer,ocr2ForwarderAddress:t.ocr2JobConfig.forwarderAddress},p=o?o.chains.results:[],b=s?s.ethKeys.results:[],m=c?c.p2pKeys.results:[],g=f?f.ocrKeyBundles.results:[],v=d?d.ocr2KeyBundles.results:[];return l.createElement(aD.Z,{onClose:n,open:r,disableBackdropClick:!0},l.createElement(oO.Z,{disableTypography:!0},l.createElement(x.default,{variant:"body2"},"Edit Supported Chain")),l.createElement(oT.Z,null,l.createElement(TN,{innerRef:a,initialValues:h,onSubmit:i,chains:p,accountsEVM:b,accountsNonEvm:u,p2pKeys:m,ocrKeys:g,ocr2Keys:v,editing:!0})),l.createElement(ox.Z,null,l.createElement(ok.default,{onClick:n},"Cancel"),l.createElement(ok.default,{color:"primary",type:"submit",form:"chain-configuration-form",variant:"contained"},"Submit")))};function TG(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);nt.version?e:t})},[o]),g=l.useMemo(function(){return M1(o).sort(function(e,t){return t.version-e.version})},[o]),v=function(e,t,n){switch(e){case"PENDING":return l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"text",color:"secondary",onClick:function(){return b("reject",t)}},"Reject"),m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status&&l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve"),m.id===t&&"DELETED"===n.status&&n.pendingUpdate&&l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("cancel",t)}},"Cancel"),l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs")));case"APPROVED":return l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"contained",onClick:function(){return b("cancel",t)}},"Cancel"),"DELETED"===n.status&&n.pendingUpdate&&l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs"));case"CANCELLED":if(m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status)return l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve");return null;default:return null}};return l.createElement("div",null,g.map(function(e,n){return l.createElement(mP.Z,{defaultExpanded:0===n,key:n},l.createElement(mR.Z,{expandIcon:l.createElement(gh.Z,null)},l.createElement(x.default,{className:t.versionText},"Version ",e.version),l.createElement(Es.Z,{label:e.status,color:"APPROVED"===e.status?"primary":"default",variant:"REJECTED"===e.status||"CANCELLED"===e.status?"outlined":"default"}),l.createElement("div",{className:t.proposedAtContainer},l.createElement(x.default,null,"Proposed ",l.createElement(aO,{tooltip:!0},e.createdAt)))),l.createElement(mj.Z,{className:t.expansionPanelDetails},l.createElement("div",{className:t.actions},l.createElement("div",{className:t.editContainer},0===n&&("PENDING"===e.status||"CANCELLED"===e.status)&&"DELETED"!==s.status&&"REVOKED"!==s.status&&l.createElement(ok.default,{variant:"contained",onClick:function(){return p(!0)}},"Edit")),l.createElement("div",{className:t.actionsContainer},v(e.status,e.id,s))),l.createElement(gd,{language:"toml",style:gs,"data-testid":"codeblock"},e.definition)))}),l.createElement(oC,{open:null!=c,title:c?M6[c.action].title:"",body:c?M6[c.action].body:"",onConfirm:function(){if(c){switch(c.action){case"approve":n(c.id);break;case"cancel":r(c.id);break;case"reject":i(c.id)}f(null)}},cancelButtonText:"Cancel",onCancel:function(){return f(null)}}),l.createElement(Mz,{open:h,onClose:function(){return p(!1)},initialValues:{definition:m.definition,id:m.id},onSubmit:a}))});function M8(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function M9(){var e=M8(["\n ","\n fragment JobProposalPayloadFields on JobProposal {\n id\n externalJobID\n remoteUUID\n jobID\n specs {\n ...JobProposal_SpecsFields\n }\n status\n pendingUpdate\n }\n"]);return M9=function(){return e},e}var M7=n0(M9(),M3),Oe=function(e){var t=e.onApprove,n=e.onCancel,r=e.onReject,i=e.onUpdateSpec,a=e.proposal;return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(iy,null,"Job Proposal #",a.id))),l.createElement(MF,{proposal:a}),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(xQ,null,"Specs"))),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(M5,{proposal:a,specs:a.specs,onReject:r,onApprove:t,onCancel:n,onUpdateSpec:i}))))};function Ot(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);nU,tA:()=>$,KL:()=>H,Iw:()=>V,DQ:()=>W,cB:()=>T,LO:()=>M,t5:()=>k,qt:()=>x,Jc:()=>C,L7:()=>Y,EO:()=>B});var r,i,a=n(66289),o=n(41800),s=n.n(o),u=n(67932);(i=r||(r={})).IN_PROGRESS="in_progress",i.PENDING_INCOMING_CONFIRMATIONS="pending_incoming_confirmations",i.PENDING_CONNECTION="pending_connection",i.PENDING_BRIDGE="pending_bridge",i.PENDING_SLEEP="pending_sleep",i.ERRORED="errored",i.COMPLETED="completed";var c=n(87013),l=n(19084),f=n(34823);function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]j,v2:()=>F});var r=n(66289);function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var a="/sessions",o="/sessions",s=function e(t){var n=this;i(this,e),this.api=t,this.createSession=function(e){return n.create(e)},this.destroySession=function(){return n.destroy()},this.create=this.api.createResource(a),this.destroy=this.api.deleteResource(o)};function u(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var c="/v2/bulk_delete_runs",l=function e(t){var n=this;u(this,e),this.api=t,this.bulkDeleteJobRuns=function(e){return n.destroy(e)},this.destroy=this.api.deleteResource(c)};function f(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var d="/v2/chains/evm",h="".concat(d,"/:id"),p=function e(t){var n=this;f(this,e),this.api=t,this.getChains=function(){return n.index()},this.createChain=function(e){return n.create(e)},this.destroyChain=function(e){return n.destroy(void 0,{id:e})},this.updateChain=function(e,t){return n.update(t,{id:e})},this.index=this.api.fetchResource(d),this.create=this.api.createResource(d),this.destroy=this.api.deleteResource(h),this.update=this.api.updateResource(h)};function b(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var m="/v2/keys/evm/chain",g=function e(t){var n=this;b(this,e),this.api=t,this.chain=function(e){var t=new URLSearchParams;t.append("address",e.address),t.append("evmChainID",e.evmChainID),null!==e.abandon&&t.append("abandon",String(e.abandon)),null!==e.enabled&&t.append("enabled",String(e.enabled));var r=m+"?"+t.toString();return n.api.createResource(r)()}};function v(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var y="/v2/jobs",w="".concat(y,"/:specId/runs"),_=function e(t){var n=this;v(this,e),this.api=t,this.createJobRunV2=function(e,t){return n.post(t,{specId:e})},this.post=this.api.createResource(w,!0)};function E(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var S="/v2/log",k=function e(t){var n=this;E(this,e),this.api=t,this.getLogConfig=function(){return n.show()},this.updateLogConfig=function(e){return n.update(e)},this.show=this.api.fetchResource(S),this.update=this.api.updateResource(S)};function x(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var T="/v2/nodes",M=function e(t){var n=this;x(this,e),this.api=t,this.getNodes=function(){return n.index()},this.createNode=function(e){return n.create(e)},this.index=this.api.fetchResource(T),this.create=this.api.createResource(T)};function O(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var A="/v2/enroll_webauthn",L=function e(t){var n=this;O(this,e),this.api=t,this.beginKeyRegistration=function(e){return n.create(e)},this.finishKeyRegistration=function(e){return n.put(e)},this.create=this.api.fetchResource(A),this.put=this.api.createResource(A)};function C(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var I="/v2/build_info",D=function e(t){var n=this;C(this,e),this.api=t,this.show=function(){return n.api.GET(I)()}};function N(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var P=function e(t){N(this,e),this.api=t,this.buildInfo=new D(this.api),this.bulkDeleteRuns=new l(this.api),this.chains=new p(this.api),this.logConfig=new k(this.api),this.nodes=new M(this.api),this.jobs=new _(this.api),this.webauthn=new L(this.api),this.evmKeys=new g(this.api)},R=new r.V0({base:void 0}),j=new s(R),F=new P(R)},1398(e,t,n){"use strict";n.d(t,{Z:()=>d});var r=n(67294),i=n(32316),a=n(83638),o=n(94184),s=n.n(o);function u(){return(u=Object.assign||function(e){for(var t=1;tc});var r=n(67294),i=n(32316);function a(){return(a=Object.assign||function(e){for(var t=1;tx,jK:()=>v});var r=n(67294),i=n(37703),a=n(45697),o=n.n(a),s=n(82204),u=n(71426),c=n(94184),l=n.n(c),f=n(32316),d=function(e){var t=e.palette.success||{},n=e.palette.warning||{};return{base:{paddingLeft:5*e.spacing.unit,paddingRight:5*e.spacing.unit},success:{backgroundColor:t.main,color:t.contrastText},error:{backgroundColor:e.palette.error.dark,color:e.palette.error.contrastText},warning:{backgroundColor:n.contrastText,color:n.main}}},h=function(e){var t,n=e.success,r=e.error,i=e.warning,a=e.classes,o=e.className;return n?t=a.success:r?t=a.error:i&&(t=a.warning),l()(a.base,o,t)},p=function(e){return r.createElement(s.Z,{className:h(e),square:!0},r.createElement(u.default,{variant:"body2",color:"inherit",component:"div"},e.children))};p.defaultProps={success:!1,error:!1,warning:!1},p.propTypes={success:o().bool,error:o().bool,warning:o().bool};let b=(0,f.withStyles)(d)(p);var m=function(){return r.createElement(r.Fragment,null,"Unhandled error. Please help us by opening a"," ",r.createElement("a",{href:"https://github.com/smartcontractkit/chainlink/issues/new"},"bug report"))};let g=m;function v(e){return"string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null)}function y(e,t){var n;return n="string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null),r.createElement("p",{key:t},n)}var w=function(e){var t=e.notifications;return r.createElement(b,{error:!0},t.map(y))},_=function(e){var t=e.notifications;return r.createElement(b,{success:!0},t.map(y))},E=function(e){var t=e.errors,n=e.successes;return r.createElement("div",null,(null==t?void 0:t.length)>0&&r.createElement(w,{notifications:t}),n.length>0&&r.createElement(_,{notifications:n}))},S=function(e){return{errors:e.notifications.errors,successes:e.notifications.successes}},k=(0,i.$j)(S)(E);let x=k},9409(e,t,n){"use strict";n.d(t,{ZP:()=>j});var r=n(67294),i=n(37703),a=n(5977),o=n(32316),s=n(1398),u=n(82204),c=n(30060),l=n(71426),f=n(60520),d=n(39814),h=n(57209),p=n(26842),b=n(3950),m=n(5536),g=n(45697),v=n.n(g);let y=n.p+"9f6d832ef97e8493764e.svg";function w(){return(w=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&_.map(function(e,t){return r.createElement(d.Z,{item:!0,xs:12,key:t},r.createElement(u.Z,{raised:!1,className:v.error},r.createElement(c.Z,null,r.createElement(l.default,{variant:"body1",className:v.errorText},(0,b.jK)(e)))))}),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"email",label:"Email",margin:"normal",value:n,onChange:m("email"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"password",label:"Password",type:"password",autoComplete:"password",margin:"normal",value:h,onChange:m("password"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(d.Z,{container:!0,spacing:0,justify:"center"},r.createElement(d.Z,{item:!0},r.createElement(s.Z,{type:"submit",variant:"primary"},"Access Account")))),y&&r.createElement(l.default,{variant:"body1",color:"textSecondary"},"Signing in...")))))))},P=function(e){return{fetching:e.authentication.fetching,authenticated:e.authentication.allowed,errors:e.notifications.errors}},R=(0,i.$j)(P,x({submitSignIn:p.L7}))(N);let j=(0,h.wU)(e)((0,o.withStyles)(D)(R))},16353(e,t,n){"use strict";n.d(t,{ZP:()=>H,rH:()=>U});var r,i=n(37703),a=n(97779),o=n(9541),s=n(19084);function u(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:h,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.Mk.RECEIVE_SIGNOUT_SUCCESS:case s.Mk.RECEIVE_SIGNIN_SUCCESS:var n={allowed:t.authenticated};return o.Ks(n),f(c({},e,n),{errors:[]});case s.Mk.RECEIVE_SIGNIN_FAIL:var r={allowed:!1};return o.Ks(r),f(c({},e,r),{errors:[]});case s.Mk.RECEIVE_SIGNIN_ERROR:case s.Mk.RECEIVE_SIGNOUT_ERROR:var i={allowed:!1};return o.Ks(i),f(c({},e,i),{errors:t.errors||[]});default:return e}};let b=p;function m(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function g(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:_,t=arguments.length>1?arguments[1]:void 0;return t.type?t.type.startsWith(r.REQUEST)?y(g({},e),{count:e.count+1}):t.type.startsWith(r.RECEIVE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type.startsWith(r.RESPONSE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type===s.di.REDIRECT?y(g({},e),{count:0}):e:e};let S=E;function k(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function x(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:O,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.MATCH_ROUTE:return M(x({},O),{currentUrl:t.pathname});case s.Ih.NOTIFY_SUCCESS:var n={component:t.component,props:t.props};return M(x({},e),{successes:[n],errors:[]});case s.Ih.NOTIFY_SUCCESS_MSG:return M(x({},e),{successes:[t.msg],errors:[]});case s.Ih.NOTIFY_ERROR:var r=t.error.errors,i=null==r?void 0:r.map(function(e){return L(t,e)});return M(x({},e),{successes:[],errors:i});case s.Ih.NOTIFY_ERROR_MSG:return M(x({},e),{successes:[],errors:[t.msg]});case s.Mk.RECEIVE_SIGNIN_FAIL:return M(x({},e),{successes:[],errors:["Your email or password is incorrect. Please try again"]});default:return e}};function L(e,t){return{component:e.component,props:{msg:t.detail}}}let C=A;function I(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function D(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:R,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.REDIRECT:return P(D({},e),{to:t.to});case s.di.MATCH_ROUTE:return P(D({},e),{to:void 0});default:return e}};let F=j;var Y=n(87013),B=(0,a.UY)({authentication:b,fetching:S,notifications:C,redirect:F,buildInfo:Y.Z});B(void 0,{type:"INITIAL_STATE"});var U=i.v9;let H=B},19084(e,t,n){"use strict";var r,i,a,o,s,u,c,l,f,d;n.d(t,{Ih:()=>i,Mk:()=>a,Y0:()=>s,di:()=>r,jp:()=>o}),n(67294),(u=r||(r={})).REDIRECT="REDIRECT",u.MATCH_ROUTE="MATCH_ROUTE",(c=i||(i={})).NOTIFY_SUCCESS="NOTIFY_SUCCESS",c.NOTIFY_SUCCESS_MSG="NOTIFY_SUCCESS_MSG",c.NOTIFY_ERROR="NOTIFY_ERROR",c.NOTIFY_ERROR_MSG="NOTIFY_ERROR_MSG",(l=a||(a={})).REQUEST_SIGNIN="REQUEST_SIGNIN",l.RECEIVE_SIGNIN_SUCCESS="RECEIVE_SIGNIN_SUCCESS",l.RECEIVE_SIGNIN_FAIL="RECEIVE_SIGNIN_FAIL",l.RECEIVE_SIGNIN_ERROR="RECEIVE_SIGNIN_ERROR",l.RECEIVE_SIGNOUT_SUCCESS="RECEIVE_SIGNOUT_SUCCESS",l.RECEIVE_SIGNOUT_ERROR="RECEIVE_SIGNOUT_ERROR",(f=o||(o={})).RECEIVE_CREATE_ERROR="RECEIVE_CREATE_ERROR",f.RECEIVE_CREATE_SUCCESS="RECEIVE_CREATE_SUCCESS",f.RECEIVE_DELETE_ERROR="RECEIVE_DELETE_ERROR",f.RECEIVE_DELETE_SUCCESS="RECEIVE_DELETE_SUCCESS",f.RECEIVE_UPDATE_ERROR="RECEIVE_UPDATE_ERROR",f.RECEIVE_UPDATE_SUCCESS="RECEIVE_UPDATE_SUCCESS",f.REQUEST_CREATE="REQUEST_CREATE",f.REQUEST_DELETE="REQUEST_DELETE",f.REQUEST_UPDATE="REQUEST_UPDATE",f.UPSERT_CONFIGURATION="UPSERT_CONFIGURATION",f.UPSERT_JOB_RUN="UPSERT_JOB_RUN",f.UPSERT_JOB_RUNS="UPSERT_JOB_RUNS",f.UPSERT_TRANSACTION="UPSERT_TRANSACTION",f.UPSERT_TRANSACTIONS="UPSERT_TRANSACTIONS",f.UPSERT_BUILD_INFO="UPSERT_BUILD_INFO",(d=s||(s={})).FETCH_BUILD_INFO_REQUESTED="FETCH_BUILD_INFO_REQUESTED",d.FETCH_BUILD_INFO_SUCCEEDED="FETCH_BUILD_INFO_SUCCEEDED",d.FETCH_BUILD_INFO_FAILED="FETCH_BUILD_INFO_FAILED"},87013(e,t,n){"use strict";n.d(t,{Y:()=>o,Z:()=>u});var r=n(19084);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:o,t=arguments.length>1?arguments[1]:void 0;return t.type===r.Y0.FETCH_BUILD_INFO_SUCCEEDED?a({},t.buildInfo):e};let u=s},34823(e,t,n){"use strict";n.d(t,{N:()=>r});var r=function(e){return e.buildInfo}},73343(e,t,n){"use strict";n.d(t,{r:()=>u});var r=n(19350),i=n(32316),a=n(59114),o=n(5324),s={props:{MuiGrid:{spacing:3*o.default.unit},MuiCardHeader:{titleTypographyProps:{color:"secondary"}}},palette:{action:{hoverOpacity:.3},primary:{light:"#E5F1FF",main:"#3c40c6",contrastText:"#fff"},secondary:{main:"#3d5170"},success:{light:"#e8faf1",main:r.ek.A700,dark:r.ek[700],contrastText:r.y0.white},warning:{light:"#FFFBF1",main:"#fff6b6",contrastText:"#fad27a"},error:{light:"#ffdada",main:"#f44336",dark:"#d32f2f",contrastText:"#fff"},background:{default:"#f5f6f8",appBar:"#3c40c6"},text:{primary:(0,a.darken)(r.BA.A700,.7),secondary:"#818ea3"},listPendingStatus:{background:"#fef7e5",color:"#fecb4c"},listCompletedStatus:{background:"#e9faf2",color:"#4ed495"}},shape:{borderRadius:o.default.unit},overrides:{MuiButton:{root:{borderRadius:o.default.unit/2,textTransform:"none"},sizeLarge:{padding:void 0,fontSize:void 0,paddingTop:o.default.unit,paddingBottom:o.default.unit,paddingLeft:5*o.default.unit,paddingRight:5*o.default.unit}},MuiTableCell:{body:{fontSize:"1rem"},head:{fontSize:"1rem",fontWeight:400}},MuiCardHeader:{root:{borderBottom:"1px solid rgba(0, 0, 0, 0.12)"},action:{marginTop:-2,marginRight:0,"& >*":{marginLeft:2*o.default.unit}},subheader:{marginTop:.5*o.default.unit}}},typography:{useNextVariants:!0,fontFamily:"-apple-system,BlinkMacSystemFont,Roboto,Helvetica,Arial,sans-serif",button:{textTransform:"none",fontSize:"1.2em"},body1:{fontSize:"1.0rem",fontWeight:400,lineHeight:"1.46429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body2:{fontSize:"1.0rem",fontWeight:500,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body1Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"1rem",lineHeight:1.5,letterSpacing:-.4},body2Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"0.875rem",lineHeight:1.5,letterSpacing:-.4},display1:{color:"#818ea3",fontSize:"2.125rem",fontWeight:400,lineHeight:"1.20588em",letterSpacing:-.4},display2:{color:"#818ea3",fontSize:"2.8125rem",fontWeight:400,lineHeight:"1.13333em",marginLeft:"-.02em",letterSpacing:-.4},display3:{color:"#818ea3",fontSize:"3.5rem",fontWeight:400,lineHeight:"1.30357em",marginLeft:"-.02em",letterSpacing:-.4},display4:{fontSize:14,fontWeightLight:300,fontWeightMedium:500,fontWeightRegular:400,letterSpacing:-.4},h1:{color:"rgb(29, 29, 29)",fontSize:"6rem",fontWeight:300,lineHeight:1},h2:{color:"rgb(29, 29, 29)",fontSize:"3.75rem",fontWeight:300,lineHeight:1},h3:{color:"rgb(29, 29, 29)",fontSize:"3rem",fontWeight:400,lineHeight:1.04},h4:{color:"rgb(29, 29, 29)",fontSize:"2.125rem",fontWeight:400,lineHeight:1.17},h5:{color:"rgb(29, 29, 29)",fontSize:"1.5rem",fontWeight:400,lineHeight:1.33,letterSpacing:-.4},h6:{fontSize:"0.8rem",fontWeight:450,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},subheading:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:"1.5em",letterSpacing:-.4},subtitle1:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:1.75,letterSpacing:-.4},subtitle2:{color:"rgb(29, 29, 29)",fontSize:"0.875rem",fontWeight:500,lineHeight:1.57,letterSpacing:-.4}},shadows:["none","0px 1px 3px 0px rgba(0, 0, 0, 0.1),0px 1px 1px 0px rgba(0, 0, 0, 0.04),0px 2px 1px -1px rgba(0, 0, 0, 0.02)","0px 1px 5px 0px rgba(0, 0, 0, 0.1),0px 2px 2px 0px rgba(0, 0, 0, 0.04),0px 3px 1px -2px rgba(0, 0, 0, 0.02)","0px 1px 8px 0px rgba(0, 0, 0, 0.1),0px 3px 4px 0px rgba(0, 0, 0, 0.04),0px 3px 3px -2px rgba(0, 0, 0, 0.02)","0px 2px 4px -1px rgba(0, 0, 0, 0.1),0px 4px 5px 0px rgba(0, 0, 0, 0.04),0px 1px 10px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 5px 8px 0px rgba(0, 0, 0, 0.04),0px 1px 14px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 6px 10px 0px rgba(0, 0, 0, 0.04),0px 1px 18px 0px rgba(0, 0, 0, 0.02)","0px 4px 5px -2px rgba(0, 0, 0, 0.1),0px 7px 10px 1px rgba(0, 0, 0, 0.04),0px 2px 16px 1px rgba(0, 0, 0, 0.02)","0px 5px 5px -3px rgba(0, 0, 0, 0.1),0px 8px 10px 1px rgba(0, 0, 0, 0.04),0px 3px 14px 2px rgba(0, 0, 0, 0.02)","0px 5px 6px -3px rgba(0, 0, 0, 0.1),0px 9px 12px 1px rgba(0, 0, 0, 0.04),0px 3px 16px 2px rgba(0, 0, 0, 0.02)","0px 6px 6px -3px rgba(0, 0, 0, 0.1),0px 10px 14px 1px rgba(0, 0, 0, 0.04),0px 4px 18px 3px rgba(0, 0, 0, 0.02)","0px 6px 7px -4px rgba(0, 0, 0, 0.1),0px 11px 15px 1px rgba(0, 0, 0, 0.04),0px 4px 20px 3px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 12px 17px 2px rgba(0, 0, 0, 0.04),0px 5px 22px 4px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 13px 19px 2px rgba(0, 0, 0, 0.04),0px 5px 24px 4px rgba(0, 0, 0, 0.02)","0px 7px 9px -4px rgba(0, 0, 0, 0.1),0px 14px 21px 2px rgba(0, 0, 0, 0.04),0px 5px 26px 4px rgba(0, 0, 0, 0.02)","0px 8px 9px -5px rgba(0, 0, 0, 0.1),0px 15px 22px 2px rgba(0, 0, 0, 0.04),0px 6px 28px 5px rgba(0, 0, 0, 0.02)","0px 8px 10px -5px rgba(0, 0, 0, 0.1),0px 16px 24px 2px rgba(0, 0, 0, 0.04),0px 6px 30px 5px rgba(0, 0, 0, 0.02)","0px 8px 11px -5px rgba(0, 0, 0, 0.1),0px 17px 26px 2px rgba(0, 0, 0, 0.04),0px 6px 32px 5px rgba(0, 0, 0, 0.02)","0px 9px 11px -5px rgba(0, 0, 0, 0.1),0px 18px 28px 2px rgba(0, 0, 0, 0.04),0px 7px 34px 6px rgba(0, 0, 0, 0.02)","0px 9px 12px -6px rgba(0, 0, 0, 0.1),0px 19px 29px 2px rgba(0, 0, 0, 0.04),0px 7px 36px 6px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 20px 31px 3px rgba(0, 0, 0, 0.04),0px 8px 38px 7px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 21px 33px 3px rgba(0, 0, 0, 0.04),0px 8px 40px 7px rgba(0, 0, 0, 0.02)","0px 10px 14px -6px rgba(0, 0, 0, 0.1),0px 22px 35px 3px rgba(0, 0, 0, 0.04),0px 8px 42px 7px rgba(0, 0, 0, 0.02)","0px 11px 14px -7px rgba(0, 0, 0, 0.1),0px 23px 36px 3px rgba(0, 0, 0, 0.04),0px 9px 44px 8px rgba(0, 0, 0, 0.02)","0px 11px 15px -7px rgba(0, 0, 0, 0.1),0px 24px 38px 3px rgba(0, 0, 0, 0.04),0px 9px 46px 8px rgba(0, 0, 0, 0.02)",]},u=(0,i.createMuiTheme)(s)},66289(e,t,n){"use strict";function r(e){if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}function a(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(e){return!1}}function o(e,t,n){return(o=a()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var i=new(Function.bind.apply(e,r));return n&&f(i,n.prototype),i}).apply(null,arguments)}function s(e){return(s=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function u(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&f(e,t)}function c(e){return -1!==Function.toString.call(e).indexOf("[native code]")}function l(e,t){return t&&("object"===p(t)||"function"==typeof t)?t:r(e)}function f(e,t){return(f=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}n.d(t,{V0:()=>B,_7:()=>v});var d,h,p=function(e){return e&&"undefined"!=typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};function b(e){var t="function"==typeof Map?new Map:void 0;return(b=function(e){if(null===e||!c(e))return e;if("function"!=typeof e)throw TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return o(e,arguments,s(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),f(n,e)})(e)}function m(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(e){return!1}}function g(e){var t=m();return function(){var n,r=s(e);if(t){var i=s(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return l(this,n)}}var v=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"AuthenticationError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e},],r}return n}(b(Error)),y=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"BadRequestError")).errors=a,r}return n}(b(Error)),w=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnprocessableEntityError")).errors=e,r}return n}(b(Error)),_=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"ServerError")).errors=e,r}return n}(b(Error)),E=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"ConflictError")).errors=a,r}return n}(b(Error)),S=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnknownResponseError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e.statusText},],r}return n}(b(Error));function k(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:2e4;return Promise.race([fetch(e,t),new Promise(function(e,t){return setTimeout(function(){return t(Error("timeout"))},n)}),])}function x(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=200&&e.status<300))return[3,2];return[2,e.json()];case 2:if(400!==e.status)return[3,3];return[2,e.json().then(function(e){throw new y(e)})];case 3:if(401!==e.status)return[3,4];throw new v(e);case 4:if(422!==e.status)return[3,6];return[4,$(e)];case 5:throw n=i.sent(),new w(n);case 6:if(409!==e.status)return[3,7];return[2,e.json().then(function(e){throw new E(e)})];case 7:if(!(e.status>=500))return[3,9];return[4,$(e)];case 8:throw r=i.sent(),new _(r);case 9:throw new S(e);case 10:return[2]}})})).apply(this,arguments)}function $(e){return z.apply(this,arguments)}function z(){return(z=j(function(e){return Y(this,function(t){return[2,e.json().then(function(t){return t.errors?t.errors.map(function(t){return{status:e.status,detail:t.detail}}):G(e)}).catch(function(){return G(e)})]})})).apply(this,arguments)}function G(e){return[{status:e.status,detail:e.statusText},]}},50109(e,t,n){"use strict";n.d(t,{LK:()=>o,U2:()=>i,eT:()=>s,t8:()=>a});var r=n(12795);function i(e){return r.ZP.getItem("chainlink.".concat(e))}function a(e,t){r.ZP.setItem("chainlink.".concat(e),t)}function o(e){var t=i(e),n={};if(t)try{return JSON.parse(t)}catch(r){}return n}function s(e,t){a(e,JSON.stringify(t))}},9541(e,t,n){"use strict";n.d(t,{Ks:()=>u,Tp:()=>a,iR:()=>o,pm:()=>s});var r=n(50109),i="persistURL";function a(){return r.U2(i)||""}function o(e){r.t8(i,e)}function s(){return r.LK("authentication")}function u(e){r.eT("authentication",e)}},67121(e,t,n){"use strict";function r(e){var t,n=e.Symbol;return"function"==typeof n?n.observable?t=n.observable:(t=n("observable"),n.observable=t):t="@@observable",t}n.r(t),n.d(t,{default:()=>o}),e=n.hmd(e),i="undefined"!=typeof self?self:"undefined"!=typeof window?window:void 0!==n.g?n.g:e;var i,a=r(i);let o=a},2177(e,t,n){"use strict";n.d(t,{Z:()=>o});var r=!0,i="Invariant failed";function a(e,t){if(!e){if(r)throw Error(i);throw Error(i+": "+(t||""))}}let o=a},11742(e){e.exports=function(){var e=document.getSelection();if(!e.rangeCount)return function(){};for(var t=document.activeElement,n=[],r=0;ru,ZT:()=>i,_T:()=>o,ev:()=>c,mG:()=>s,pi:()=>a});var r=function(e,t){return(r=Object.setPrototypeOf||({__proto__:[]})instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,t)};function i(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return(a=Object.assign||function(e){for(var t,n=1,r=arguments.length;nt.indexOf(r)&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,r=Object.getOwnPropertySymbols(e);it.indexOf(r[i])&&Object.prototype.propertyIsEnumerable.call(e,r[i])&&(n[r[i]]=e[r[i]]);return n}function s(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||(n=Promise))(function(n,a){function o(e){try{u(r.next(e))}catch(t){a(t)}}function s(e){try{u(r.throw(e))}catch(t){a(t)}}function u(e){e.done?n(e.value):i(e.value).then(o,s)}u((r=r.apply(e,t||[])).next())})}function u(e,t){var n,r,i,a,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(e){return function(t){return u([e,t])}}function u(a){if(n)throw TypeError("Generator is already executing.");for(;o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!(i=(i=o.trys).length>0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]r})},94927(e,t,n){function r(e,t){if(i("noDeprecation"))return e;var n=!1;function r(){if(!n){if(i("throwDeprecation"))throw Error(t);i("traceDeprecation")?console.trace(t):console.warn(t),n=!0}return e.apply(this,arguments)}return r}function i(e){try{if(!n.g.localStorage)return!1}catch(t){return!1}var r=n.g.localStorage[e];return null!=r&&"true"===String(r).toLowerCase()}e.exports=r},42473(e){"use strict";var t=function(){};e.exports=t},84763(e){e.exports=Worker},47529(e){e.exports=n;var t=Object.prototype.hasOwnProperty;function n(){for(var e={},n=0;ne.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}e.exports=i,e.exports.__esModule=!0,e.exports.default=e.exports},7071(e){function t(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},94993(e,t,n){var r=n(18698).default,i=n(66115);function a(e,t){if(t&&("object"===r(t)||"function"==typeof t))return t;if(void 0!==t)throw TypeError("Derived constructors may only return object or undefined");return i(e)}e.exports=a,e.exports.__esModule=!0,e.exports.default=e.exports},6015(e){function t(n,r){return e.exports=t=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},e.exports.__esModule=!0,e.exports.default=e.exports,t(n,r)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},861(e,t,n){var r=n(63405),i=n(79498),a=n(86116),o=n(42281);function s(e){return r(e)||i(e)||a(e)||o()}e.exports=s,e.exports.__esModule=!0,e.exports.default=e.exports},18698(e){function t(n){return e.exports=t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e.exports.__esModule=!0,e.exports.default=e.exports,t(n)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},86116(e,t,n){var r=n(73897);function i(e,t){if(e){if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return r(e,t)}}e.exports=i,e.exports.__esModule=!0,e.exports.default=e.exports},1644(e,t,n){"use strict";var r,i;function a(e){return!!e&&e<7}n.d(t,{I:()=>r,O:()=>a}),(i=r||(r={}))[i.loading=1]="loading",i[i.setVariables=2]="setVariables",i[i.fetchMore=3]="fetchMore",i[i.refetch=4]="refetch",i[i.poll=6]="poll",i[i.ready=7]="ready",i[i.error=8]="error"},30990(e,t,n){"use strict";n.d(t,{MS:()=>s,YG:()=>a,cA:()=>c,ls:()=>o});var r=n(70655);n(83952);var i=n(13154),a=Symbol();function o(e){return!!e.extensions&&Array.isArray(e.extensions[a])}function s(e){return e.hasOwnProperty("graphQLErrors")}var u=function(e){var t=(0,r.ev)((0,r.ev)((0,r.ev)([],e.graphQLErrors,!0),e.clientErrors,!0),e.protocolErrors,!0);return e.networkError&&t.push(e.networkError),t.map(function(e){return(0,i.s)(e)&&e.message||"Error message not found."}).join("\n")},c=function(e){function t(n){var r=n.graphQLErrors,i=n.protocolErrors,a=n.clientErrors,o=n.networkError,s=n.errorMessage,c=n.extraInfo,l=e.call(this,s)||this;return l.name="ApolloError",l.graphQLErrors=r||[],l.protocolErrors=i||[],l.clientErrors=a||[],l.networkError=o||null,l.message=s||u(l),l.extraInfo=c,l.__proto__=t.prototype,l}return(0,r.ZT)(t,e),t}(Error)},85317(e,t,n){"use strict";n.d(t,{K:()=>a});var r=n(67294),i=n(30320).aS?Symbol.for("__APOLLO_CONTEXT__"):"__APOLLO_CONTEXT__";function a(){var e=r.createContext[i];return e||(Object.defineProperty(r.createContext,i,{value:e=r.createContext({}),enumerable:!1,writable:!1,configurable:!0}),e.displayName="ApolloContext"),e}},21436(e,t,n){"use strict";n.d(t,{O:()=>i,k:()=>r});var r=Array.isArray;function i(e){return Array.isArray(e)&&e.length>0}},30320(e,t,n){"use strict";n.d(t,{DN:()=>s,JC:()=>l,aS:()=>o,mr:()=>i,sy:()=>a});var r=n(83952),i="function"==typeof WeakMap&&"ReactNative"!==(0,r.wY)(function(){return navigator.product}),a="function"==typeof WeakSet,o="function"==typeof Symbol&&"function"==typeof Symbol.for,s=o&&Symbol.asyncIterator,u="function"==typeof(0,r.wY)(function(){return window.document.createElement}),c=(0,r.wY)(function(){return navigator.userAgent.indexOf("jsdom")>=0})||!1,l=u&&!c},53712(e,t,n){"use strict";function r(){for(var e=[],t=0;tr})},10542(e,t,n){"use strict";n.d(t,{J:()=>o}),n(83952);var r=n(13154);function i(e){var t=new Set([e]);return t.forEach(function(e){(0,r.s)(e)&&a(e)===e&&Object.getOwnPropertyNames(e).forEach(function(n){(0,r.s)(e[n])&&t.add(e[n])})}),e}function a(e){if(__DEV__&&!Object.isFrozen(e))try{Object.freeze(e)}catch(t){if(t instanceof TypeError)return null;throw t}return e}function o(e){return __DEV__&&i(e),e}},14012(e,t,n){"use strict";n.d(t,{J:()=>a});var r=n(70655),i=n(53712);function a(e,t){return(0,i.o)(e,t,t.variables&&{variables:(0,r.pi)((0,r.pi)({},e&&e.variables),t.variables)})}},13154(e,t,n){"use strict";function r(e){return null!==e&&"object"==typeof e}n.d(t,{s:()=>r})},83952(e,t,n){"use strict";n.d(t,{ej:()=>u,kG:()=>c,wY:()=>h});var r,i=n(70655),a="Invariant Violation",o=Object.setPrototypeOf,s=void 0===o?function(e,t){return e.__proto__=t,e}:o,u=function(e){function t(n){void 0===n&&(n=a);var r=e.call(this,"number"==typeof n?a+": "+n+" (see https://github.com/apollographql/invariant-packages)":n)||this;return r.framesToPop=1,r.name=a,s(r,t.prototype),r}return(0,i.ZT)(t,e),t}(Error);function c(e,t){if(!e)throw new u(t)}var l=["debug","log","warn","error","silent"],f=l.indexOf("log");function d(e){return function(){if(l.indexOf(e)>=f)return(console[e]||console.log).apply(console,arguments)}}function h(e){try{return e()}catch(t){}}(r=c||(c={})).debug=d("debug"),r.log=d("log"),r.warn=d("warn"),r.error=d("error");let p=h(function(){return globalThis})||h(function(){return window})||h(function(){return self})||h(function(){return global})||h(function(){return h.constructor("return this")()});var b="__",m=[b,b].join("DEV");function g(){try{return Boolean(__DEV__)}catch(e){return Object.defineProperty(p,m,{value:"production"!==h(function(){return"production"}),enumerable:!1,configurable:!0,writable:!0}),p[m]}}let v=g();function y(e){try{return e()}catch(t){}}var w=y(function(){return globalThis})||y(function(){return window})||y(function(){return self})||y(function(){return global})||y(function(){return y.constructor("return this")()}),_=!1;function E(){!w||y(function(){return"production"})||y(function(){return process})||(Object.defineProperty(w,"process",{value:{env:{NODE_ENV:"production"}},configurable:!0,enumerable:!1,writable:!0}),_=!0)}function S(){_&&(delete w.process,_=!1)}E();var k=n(10143);function x(){return k.H,S()}function T(){__DEV__?c("boolean"==typeof v,v):c("boolean"==typeof v,39)}x(),T()},4942(e,t,n){"use strict";function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}n.d(t,{Z:()=>r})},87462(e,t,n){"use strict";function r(){return(r=Object.assign?Object.assign.bind():function(e){for(var t=1;tr})},51721(e,t,n){"use strict";function r(e,t){return(r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e})(e,t)}function i(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)}n.d(t,{Z:()=>i})},63366(e,t,n){"use strict";function r(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}n.d(t,{Z:()=>r})},25821(e,t,n){"use strict";n.d(t,{Z:()=>s});var r=n(45695);function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var a=10,o=2;function s(e){return u(e,[])}function u(e,t){switch(i(e)){case"string":return JSON.stringify(e);case"function":return e.name?"[function ".concat(e.name,"]"):"[function]";case"object":if(null===e)return"null";return c(e,t);default:return String(e)}}function c(e,t){if(-1!==t.indexOf(e))return"[Circular]";var n=[].concat(t,[e]),r=d(e);if(void 0!==r){var i=r.call(e);if(i!==e)return"string"==typeof i?i:u(i,n)}else if(Array.isArray(e))return f(e,n);return l(e,n)}function l(e,t){var n=Object.keys(e);return 0===n.length?"{}":t.length>o?"["+h(e)+"]":"{ "+n.map(function(n){var r=u(e[n],t);return n+": "+r}).join(", ")+" }"}function f(e,t){if(0===e.length)return"[]";if(t.length>o)return"[Array]";for(var n=Math.min(a,e.length),r=e.length-n,i=[],s=0;s1&&i.push("... ".concat(r," more items")),"["+i.join(", ")+"]"}function d(e){var t=e[String(r.Z)];return"function"==typeof t?t:"function"==typeof e.inspect?e.inspect:void 0}function h(e){var t=Object.prototype.toString.call(e).replace(/^\[object /,"").replace(/]$/,"");if("Object"===t&&"function"==typeof e.constructor){var n=e.constructor.name;if("string"==typeof n&&""!==n)return n}return t}},45695(e,t,n){"use strict";n.d(t,{Z:()=>i});var r="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):void 0;let i=r},25217(e,t,n){"use strict";function r(e,t){if(!Boolean(e))throw Error(null!=t?t:"Unexpected invariant triggered.")}n.d(t,{Ye:()=>o,WU:()=>s,UG:()=>u});var i=n(45695);function a(e){var t=e.prototype.toJSON;"function"==typeof t||r(0),e.prototype.inspect=t,i.Z&&(e.prototype[i.Z]=t)}var o=function(){function e(e,t,n){this.start=e.start,this.end=t.end,this.startToken=e,this.endToken=t,this.source=n}return e.prototype.toJSON=function(){return{start:this.start,end:this.end}},e}();a(o);var s=function(){function e(e,t,n,r,i,a,o){this.kind=e,this.start=t,this.end=n,this.line=r,this.column=i,this.value=o,this.prev=a,this.next=null}return e.prototype.toJSON=function(){return{kind:this.kind,value:this.value,line:this.line,column:this.column}},e}();function u(e){return null!=e&&"string"==typeof e.kind}a(s)},87392(e,t,n){"use strict";function r(e){var t=e.split(/\r\n|[\n\r]/g),n=a(e);if(0!==n)for(var r=1;ro&&i(t[s-1]);)--s;return t.slice(o,s).join("\n")}function i(e){for(var t=0;t1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=-1===e.indexOf("\n"),i=" "===e[0]||" "===e[0],a='"'===e[e.length-1],o="\\"===e[e.length-1],s=!r||a||o||n,u="";return s&&!(r&&i)&&(u+="\n"+t),u+=t?e.replace(/\n/g,"\n"+t):e,s&&(u+="\n"),'"""'+u.replace(/"""/g,'\\"""')+'"""'}n.d(t,{LZ:()=>o,W7:()=>r})},97359(e,t,n){"use strict";n.d(t,{h:()=>r});var r=Object.freeze({NAME:"Name",DOCUMENT:"Document",OPERATION_DEFINITION:"OperationDefinition",VARIABLE_DEFINITION:"VariableDefinition",SELECTION_SET:"SelectionSet",FIELD:"Field",ARGUMENT:"Argument",FRAGMENT_SPREAD:"FragmentSpread",INLINE_FRAGMENT:"InlineFragment",FRAGMENT_DEFINITION:"FragmentDefinition",VARIABLE:"Variable",INT:"IntValue",FLOAT:"FloatValue",STRING:"StringValue",BOOLEAN:"BooleanValue",NULL:"NullValue",ENUM:"EnumValue",LIST:"ListValue",OBJECT:"ObjectValue",OBJECT_FIELD:"ObjectField",DIRECTIVE:"Directive",NAMED_TYPE:"NamedType",LIST_TYPE:"ListType",NON_NULL_TYPE:"NonNullType",SCHEMA_DEFINITION:"SchemaDefinition",OPERATION_TYPE_DEFINITION:"OperationTypeDefinition",SCALAR_TYPE_DEFINITION:"ScalarTypeDefinition",OBJECT_TYPE_DEFINITION:"ObjectTypeDefinition",FIELD_DEFINITION:"FieldDefinition",INPUT_VALUE_DEFINITION:"InputValueDefinition",INTERFACE_TYPE_DEFINITION:"InterfaceTypeDefinition",UNION_TYPE_DEFINITION:"UnionTypeDefinition",ENUM_TYPE_DEFINITION:"EnumTypeDefinition",ENUM_VALUE_DEFINITION:"EnumValueDefinition",INPUT_OBJECT_TYPE_DEFINITION:"InputObjectTypeDefinition",DIRECTIVE_DEFINITION:"DirectiveDefinition",SCHEMA_EXTENSION:"SchemaExtension",SCALAR_TYPE_EXTENSION:"ScalarTypeExtension",OBJECT_TYPE_EXTENSION:"ObjectTypeExtension",INTERFACE_TYPE_EXTENSION:"InterfaceTypeExtension",UNION_TYPE_EXTENSION:"UnionTypeExtension",ENUM_TYPE_EXTENSION:"EnumTypeExtension",INPUT_OBJECT_TYPE_EXTENSION:"InputObjectTypeExtension"})},10143(e,t,n){"use strict";n.d(t,{H:()=>c,T:()=>l});var r=n(99763),i=n(25821);function a(e,t){if(!Boolean(e))throw Error(t)}let o=function(e,t){return e instanceof t};function s(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:"GraphQL request",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{line:1,column:1};"string"==typeof e||a(0,"Body must be a string. Received: ".concat((0,i.Z)(e),".")),this.body=e,this.name=t,this.locationOffset=n,this.locationOffset.line>0||a(0,"line in locationOffset is 1-indexed and must be positive."),this.locationOffset.column>0||a(0,"column in locationOffset is 1-indexed and must be positive.")}return u(e,[{key:r.YF,get:function(){return"Source"}}]),e}();function l(e){return o(e,c)}},99763(e,t,n){"use strict";n.d(t,{YF:()=>r});var r="function"==typeof Symbol&&null!=Symbol.toStringTag?Symbol.toStringTag:"@@toStringTag"},37452(e){"use strict";e.exports=JSON.parse('{"AElig":"\xc6","AMP":"&","Aacute":"\xc1","Acirc":"\xc2","Agrave":"\xc0","Aring":"\xc5","Atilde":"\xc3","Auml":"\xc4","COPY":"\xa9","Ccedil":"\xc7","ETH":"\xd0","Eacute":"\xc9","Ecirc":"\xca","Egrave":"\xc8","Euml":"\xcb","GT":">","Iacute":"\xcd","Icirc":"\xce","Igrave":"\xcc","Iuml":"\xcf","LT":"<","Ntilde":"\xd1","Oacute":"\xd3","Ocirc":"\xd4","Ograve":"\xd2","Oslash":"\xd8","Otilde":"\xd5","Ouml":"\xd6","QUOT":"\\"","REG":"\xae","THORN":"\xde","Uacute":"\xda","Ucirc":"\xdb","Ugrave":"\xd9","Uuml":"\xdc","Yacute":"\xdd","aacute":"\xe1","acirc":"\xe2","acute":"\xb4","aelig":"\xe6","agrave":"\xe0","amp":"&","aring":"\xe5","atilde":"\xe3","auml":"\xe4","brvbar":"\xa6","ccedil":"\xe7","cedil":"\xb8","cent":"\xa2","copy":"\xa9","curren":"\xa4","deg":"\xb0","divide":"\xf7","eacute":"\xe9","ecirc":"\xea","egrave":"\xe8","eth":"\xf0","euml":"\xeb","frac12":"\xbd","frac14":"\xbc","frac34":"\xbe","gt":">","iacute":"\xed","icirc":"\xee","iexcl":"\xa1","igrave":"\xec","iquest":"\xbf","iuml":"\xef","laquo":"\xab","lt":"<","macr":"\xaf","micro":"\xb5","middot":"\xb7","nbsp":"\xa0","not":"\xac","ntilde":"\xf1","oacute":"\xf3","ocirc":"\xf4","ograve":"\xf2","ordf":"\xaa","ordm":"\xba","oslash":"\xf8","otilde":"\xf5","ouml":"\xf6","para":"\xb6","plusmn":"\xb1","pound":"\xa3","quot":"\\"","raquo":"\xbb","reg":"\xae","sect":"\xa7","shy":"\xad","sup1":"\xb9","sup2":"\xb2","sup3":"\xb3","szlig":"\xdf","thorn":"\xfe","times":"\xd7","uacute":"\xfa","ucirc":"\xfb","ugrave":"\xf9","uml":"\xa8","uuml":"\xfc","yacute":"\xfd","yen":"\xa5","yuml":"\xff"}')},93580(e){"use strict";e.exports=JSON.parse('{"0":"�","128":"€","130":"‚","131":"ƒ","132":"„","133":"…","134":"†","135":"‡","136":"ˆ","137":"‰","138":"Š","139":"‹","140":"Œ","142":"Ž","145":"‘","146":"’","147":"“","148":"”","149":"•","150":"–","151":"—","152":"˜","153":"™","154":"š","155":"›","156":"œ","158":"ž","159":"Ÿ"}')},67946(e){"use strict";e.exports=JSON.parse('{"locale":"en","long":{"year":{"previous":"last year","current":"this year","next":"next year","past":{"one":"{0} year ago","other":"{0} years ago"},"future":{"one":"in {0} year","other":"in {0} years"}},"quarter":{"previous":"last quarter","current":"this quarter","next":"next quarter","past":{"one":"{0} quarter ago","other":"{0} quarters ago"},"future":{"one":"in {0} quarter","other":"in {0} quarters"}},"month":{"previous":"last month","current":"this month","next":"next month","past":{"one":"{0} month ago","other":"{0} months ago"},"future":{"one":"in {0} month","other":"in {0} months"}},"week":{"previous":"last week","current":"this week","next":"next week","past":{"one":"{0} week ago","other":"{0} weeks ago"},"future":{"one":"in {0} week","other":"in {0} weeks"}},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":{"one":"{0} hour ago","other":"{0} hours ago"},"future":{"one":"in {0} hour","other":"in {0} hours"}},"minute":{"current":"this minute","past":{"one":"{0} minute ago","other":"{0} minutes ago"},"future":{"one":"in {0} minute","other":"in {0} minutes"}},"second":{"current":"now","past":{"one":"{0} second ago","other":"{0} seconds ago"},"future":{"one":"in {0} second","other":"in {0} seconds"}}},"short":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"narrow":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"now":{"now":{"current":"now","future":"in a moment","past":"just now"}},"mini":{"year":"{0}yr","month":"{0}mo","week":"{0}wk","day":"{0}d","hour":"{0}h","minute":"{0}m","second":"{0}s","now":"now"},"short-time":{"year":"{0} yr.","month":"{0} mo.","week":"{0} wk.","day":{"one":"{0} day","other":"{0} days"},"hour":"{0} hr.","minute":"{0} min.","second":"{0} sec."},"long-time":{"year":{"one":"{0} year","other":"{0} years"},"month":{"one":"{0} month","other":"{0} months"},"week":{"one":"{0} week","other":"{0} weeks"},"day":{"one":"{0} day","other":"{0} days"},"hour":{"one":"{0} hour","other":"{0} hours"},"minute":{"one":"{0} minute","other":"{0} minutes"},"second":{"one":"{0} second","other":"{0} seconds"}}}')}},__webpack_module_cache__={};function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[e]={id:e,loaded:!1,exports:{}};return __webpack_modules__[e].call(n.exports,n,n.exports,__webpack_require__),n.loaded=!0,n.exports}__webpack_require__.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(t,{a:t}),t},(()=>{var e,t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__;__webpack_require__.t=function(n,r){if(1&r&&(n=this(n)),8&r||"object"==typeof n&&n&&(4&r&&n.__esModule||16&r&&"function"==typeof n.then))return n;var i=Object.create(null);__webpack_require__.r(i);var a={};e=e||[null,t({}),t([]),t(t)];for(var o=2&r&&n;"object"==typeof o&&!~e.indexOf(o);o=t(o))Object.getOwnPropertyNames(o).forEach(e=>a[e]=()=>n[e]);return a.default=()=>n,__webpack_require__.d(i,a),i}})(),__webpack_require__.d=(e,t)=>{for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.hmd=e=>((e=Object.create(e)).children||(e.children=[]),Object.defineProperty(e,"exports",{enumerable:!0,set(){throw Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+e.id)}}),e),__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},__webpack_require__.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),__webpack_require__.p="/assets/",__webpack_require__.nc=void 0;var __webpack_exports__={};(()=>{"use strict";var e,t,n,r,i=__webpack_require__(32316),a=__webpack_require__(8126),o=__webpack_require__(5690),s=__webpack_require__(30381),u=__webpack_require__.n(s),c=__webpack_require__(67294),l=__webpack_require__(73935),f=__webpack_require__.n(l),d=__webpack_require__(57209),h=__webpack_require__(37703),p=__webpack_require__(97779),b=__webpack_require__(28500);function m(e){return function(t){var n=t.dispatch,r=t.getState;return function(t){return function(i){return"function"==typeof i?i(n,r,e):t(i)}}}}var g=m();g.withExtraArgument=m;let v=g;var y=__webpack_require__(76489);function w(e){return function(t){return function(n){return function(r){n(r);var i=e||document&&document.cookie||"",a=t.getState();if("MATCH_ROUTE"===r.type&&"/signin"!==a.notifications.currentUrl){var o=(0,y.Q)(i);if(o.explorer)try{var s=JSON.parse(o.explorer);if("error"===s.status){var u=_(s.url);n({type:"NOTIFY_ERROR_MSG",msg:u})}}catch(c){n({type:"NOTIFY_ERROR_MSG",msg:"Invalid explorer status"})}}}}}}function _(e){var t="Can't connect to explorer: ".concat(e);return e.match(/^wss?:.+/)?t:"".concat(t,". You must use a websocket.")}var E=__webpack_require__(16353);function S(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function ei(e,t){if(e){if("string"==typeof e)return ea(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return ea(e,t)}}function ea(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1,i=!1,a=arguments[1],o=a;return new n(function(n){return t.subscribe({next:function(t){var a=!i;if(i=!0,!a||r)try{o=e(o,t)}catch(s){return n.error(s)}else o=t},error:function(e){n.error(e)},complete:function(){if(!i&&!r)return n.error(TypeError("Cannot reduce an empty sequence"));n.next(o),n.complete()}})})},t.concat=function(){for(var e=this,t=arguments.length,n=Array(t),r=0;r=0&&i.splice(e,1),o()}});i.push(s)},error:function(e){r.error(e)},complete:function(){o()}});function o(){a.closed&&0===i.length&&r.complete()}return function(){i.forEach(function(e){return e.unsubscribe()}),a.unsubscribe()}})},t[ed]=function(){return this},e.from=function(t){var n="function"==typeof this?this:e;if(null==t)throw TypeError(t+" is not an object");var r=ep(t,ed);if(r){var i=r.call(t);if(Object(i)!==i)throw TypeError(i+" is not an object");return em(i)&&i.constructor===n?i:new n(function(e){return i.subscribe(e)})}if(ec("iterator")&&(r=ep(t,ef)))return new n(function(e){ev(function(){if(!e.closed){for(var n,i=er(r.call(t));!(n=i()).done;){var a=n.value;if(e.next(a),e.closed)return}e.complete()}})});if(Array.isArray(t))return new n(function(e){ev(function(){if(!e.closed){for(var n=0;n0))return n.connection.key;var r=n.connection.filter?n.connection.filter:[];r.sort();var i={};return r.forEach(function(e){i[e]=t[e]}),"".concat(n.connection.key,"(").concat(eV(i),")")}var a=e;if(t){var o=eV(t);a+="(".concat(o,")")}return n&&Object.keys(n).forEach(function(e){-1===eW.indexOf(e)&&(n[e]&&Object.keys(n[e]).length?a+="@".concat(e,"(").concat(eV(n[e]),")"):a+="@".concat(e))}),a},{setStringify:function(e){var t=eV;return eV=e,t}}),eV=function(e){return JSON.stringify(e,eq)};function eq(e,t){return(0,eO.s)(t)&&!Array.isArray(t)&&(t=Object.keys(t).sort().reduce(function(e,n){return e[n]=t[n],e},{})),t}function eZ(e,t){if(e.arguments&&e.arguments.length){var n={};return e.arguments.forEach(function(e){var r;return ez(n,e.name,e.value,t)}),n}return null}function eX(e){return e.alias?e.alias.value:e.name.value}function eJ(e,t,n){for(var r,i=0,a=t.selections;it.indexOf(i))throw __DEV__?new Q.ej("illegal argument: ".concat(i)):new Q.ej(27)}return e}function tt(e,t){return t?t(e):eT.of()}function tn(e){return"function"==typeof e?new ta(e):e}function tr(e){return e.request.length<=1}var ti=function(e){function t(t,n){var r=e.call(this,t)||this;return r.link=n,r}return(0,en.ZT)(t,e),t}(Error),ta=function(){function e(e){e&&(this.request=e)}return e.empty=function(){return new e(function(){return eT.of()})},e.from=function(t){return 0===t.length?e.empty():t.map(tn).reduce(function(e,t){return e.concat(t)})},e.split=function(t,n,r){var i=tn(n),a=tn(r||new e(tt));return new e(tr(i)&&tr(a)?function(e){return t(e)?i.request(e)||eT.of():a.request(e)||eT.of()}:function(e,n){return t(e)?i.request(e,n)||eT.of():a.request(e,n)||eT.of()})},e.execute=function(e,t){return e.request(eM(t.context,e7(te(t))))||eT.of()},e.concat=function(t,n){var r=tn(t);if(tr(r))return __DEV__&&Q.kG.warn(new ti("You are calling concat on a terminating link, which will have no effect",r)),r;var i=tn(n);return new e(tr(i)?function(e){return r.request(e,function(e){return i.request(e)||eT.of()})||eT.of()}:function(e,t){return r.request(e,function(e){return i.request(e,t)||eT.of()})||eT.of()})},e.prototype.split=function(t,n,r){return this.concat(e.split(t,n,r||new e(tt)))},e.prototype.concat=function(t){return e.concat(this,t)},e.prototype.request=function(e,t){throw __DEV__?new Q.ej("request is not implemented"):new Q.ej(22)},e.prototype.onError=function(e,t){if(t&&t.error)return t.error(e),!1;throw e},e.prototype.setOnError=function(e){return this.onError=e,this},e}(),to=__webpack_require__(25821),ts=__webpack_require__(25217),tu={Name:[],Document:["definitions"],OperationDefinition:["name","variableDefinitions","directives","selectionSet"],VariableDefinition:["variable","type","defaultValue","directives"],Variable:["name"],SelectionSet:["selections"],Field:["alias","name","arguments","directives","selectionSet"],Argument:["name","value"],FragmentSpread:["name","directives"],InlineFragment:["typeCondition","directives","selectionSet"],FragmentDefinition:["name","variableDefinitions","typeCondition","directives","selectionSet"],IntValue:[],FloatValue:[],StringValue:[],BooleanValue:[],NullValue:[],EnumValue:[],ListValue:["values"],ObjectValue:["fields"],ObjectField:["name","value"],Directive:["name","arguments"],NamedType:["name"],ListType:["type"],NonNullType:["type"],SchemaDefinition:["description","directives","operationTypes"],OperationTypeDefinition:["type"],ScalarTypeDefinition:["description","name","directives"],ObjectTypeDefinition:["description","name","interfaces","directives","fields"],FieldDefinition:["description","name","arguments","type","directives"],InputValueDefinition:["description","name","type","defaultValue","directives"],InterfaceTypeDefinition:["description","name","interfaces","directives","fields"],UnionTypeDefinition:["description","name","directives","types"],EnumTypeDefinition:["description","name","directives","values"],EnumValueDefinition:["description","name","directives"],InputObjectTypeDefinition:["description","name","directives","fields"],DirectiveDefinition:["description","name","arguments","locations"],SchemaExtension:["directives","operationTypes"],ScalarTypeExtension:["name","directives"],ObjectTypeExtension:["name","interfaces","directives","fields"],InterfaceTypeExtension:["name","interfaces","directives","fields"],UnionTypeExtension:["name","directives","types"],EnumTypeExtension:["name","directives","values"],InputObjectTypeExtension:["name","directives","fields"]},tc=Object.freeze({});function tl(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:tu,r=void 0,i=Array.isArray(e),a=[e],o=-1,s=[],u=void 0,c=void 0,l=void 0,f=[],d=[],h=e;do{var p,b=++o===a.length,m=b&&0!==s.length;if(b){if(c=0===d.length?void 0:f[f.length-1],u=l,l=d.pop(),m){if(i)u=u.slice();else{for(var g={},v=0,y=Object.keys(u);v1)for(var r=new tB,i=1;i=0;--a){var o=i[a],s=isNaN(+o)?{}:[];s[o]=t,t=s}n=r.merge(n,t)}),n}var tW=Object.prototype.hasOwnProperty;function tK(e,t){var n,r,i,a,o;return(0,en.mG)(this,void 0,void 0,function(){var s,u,c,l,f,d,h,p,b,m,g,v,y,w,_,E,S,k,x,T,M,O,A;return(0,en.Jh)(this,function(L){switch(L.label){case 0:if(void 0===TextDecoder)throw Error("TextDecoder must be defined in the environment: please import a polyfill.");s=new TextDecoder("utf-8"),u=null===(n=e.headers)||void 0===n?void 0:n.get("content-type"),c="boundary=",l=(null==u?void 0:u.includes(c))?null==u?void 0:u.substring((null==u?void 0:u.indexOf(c))+c.length).replace(/['"]/g,"").replace(/\;(.*)/gm,"").trim():"-",f="\r\n--".concat(l),d="",h=tI(e),p=!0,L.label=1;case 1:if(!p)return[3,3];return[4,h.next()];case 2:for(m=(b=L.sent()).value,g=b.done,v="string"==typeof m?m:s.decode(m),y=d.length-f.length+1,p=!g,d+=v,w=d.indexOf(f,y);w>-1;){if(_=void 0,_=(O=[d.slice(0,w),d.slice(w+f.length),])[0],d=O[1],E=_.indexOf("\r\n\r\n"),(k=(S=tV(_.slice(0,E)))["content-type"])&&-1===k.toLowerCase().indexOf("application/json"))throw Error("Unsupported patch content type: application/json is required.");if(x=_.slice(E))try{T=tq(e,x),Object.keys(T).length>1||"data"in T||"incremental"in T||"errors"in T||"payload"in T?tz(T)?(M={},"payload"in T&&(M=(0,en.pi)({},T.payload)),"errors"in T&&(M=(0,en.pi)((0,en.pi)({},M),{extensions:(0,en.pi)((0,en.pi)({},"extensions"in M?M.extensions:null),((A={})[tN.YG]=T.errors,A))})),null===(r=t.next)||void 0===r||r.call(t,M)):null===(i=t.next)||void 0===i||i.call(t,T):1===Object.keys(T).length&&"hasNext"in T&&!T.hasNext&&(null===(a=t.complete)||void 0===a||a.call(t))}catch(C){tZ(C,t)}w=d.indexOf(f)}return[3,1];case 3:return null===(o=t.complete)||void 0===o||o.call(t),[2]}})})}function tV(e){var t={};return e.split("\n").forEach(function(e){var n=e.indexOf(":");if(n>-1){var r=e.slice(0,n).trim().toLowerCase(),i=e.slice(n+1).trim();t[r]=i}}),t}function tq(e,t){e.status>=300&&tD(e,function(){try{return JSON.parse(t)}catch(e){return t}}(),"Response not successful: Received status code ".concat(e.status));try{return JSON.parse(t)}catch(n){var r=n;throw r.name="ServerParseError",r.response=e,r.statusCode=e.status,r.bodyText=t,r}}function tZ(e,t){var n,r;"AbortError"!==e.name&&(e.result&&e.result.errors&&e.result.data&&(null===(n=t.next)||void 0===n||n.call(t,e.result)),null===(r=t.error)||void 0===r||r.call(t,e))}function tX(e,t,n){tJ(t)(e).then(function(e){var t,r;null===(t=n.next)||void 0===t||t.call(n,e),null===(r=n.complete)||void 0===r||r.call(n)}).catch(function(e){return tZ(e,n)})}function tJ(e){return function(t){return t.text().then(function(e){return tq(t,e)}).then(function(n){return t.status>=300&&tD(t,n,"Response not successful: Received status code ".concat(t.status)),Array.isArray(n)||tW.call(n,"data")||tW.call(n,"errors")||tD(t,n,"Server response was missing for query '".concat(Array.isArray(e)?e.map(function(e){return e.operationName}):e.operationName,"'.")),n})}}var tQ=function(e){if(!e&&"undefined"==typeof fetch)throw __DEV__?new Q.ej("\n\"fetch\" has not been found globally and no fetcher has been configured. To fix this, install a fetch package (like https://www.npmjs.com/package/cross-fetch), instantiate the fetcher, and pass it into your HttpLink constructor. For example:\n\nimport fetch from 'cross-fetch';\nimport { ApolloClient, HttpLink } from '@apollo/client';\nconst client = new ApolloClient({\n link: new HttpLink({ uri: '/graphql', fetch })\n});\n "):new Q.ej(23)},t1=__webpack_require__(87392);function t0(e){return tl(e,{leave:t3})}var t2=80,t3={Name:function(e){return e.value},Variable:function(e){return"$"+e.name},Document:function(e){return t6(e.definitions,"\n\n")+"\n"},OperationDefinition:function(e){var t=e.operation,n=e.name,r=t8("(",t6(e.variableDefinitions,", "),")"),i=t6(e.directives," "),a=e.selectionSet;return n||i||r||"query"!==t?t6([t,t6([n,r]),i,a]," "):a},VariableDefinition:function(e){var t=e.variable,n=e.type,r=e.defaultValue,i=e.directives;return t+": "+n+t8(" = ",r)+t8(" ",t6(i," "))},SelectionSet:function(e){return t5(e.selections)},Field:function(e){var t=e.alias,n=e.name,r=e.arguments,i=e.directives,a=e.selectionSet,o=t8("",t,": ")+n,s=o+t8("(",t6(r,", "),")");return s.length>t2&&(s=o+t8("(\n",t9(t6(r,"\n")),"\n)")),t6([s,t6(i," "),a]," ")},Argument:function(e){var t;return e.name+": "+e.value},FragmentSpread:function(e){var t;return"..."+e.name+t8(" ",t6(e.directives," "))},InlineFragment:function(e){var t=e.typeCondition,n=e.directives,r=e.selectionSet;return t6(["...",t8("on ",t),t6(n," "),r]," ")},FragmentDefinition:function(e){var t=e.name,n=e.typeCondition,r=e.variableDefinitions,i=e.directives,a=e.selectionSet;return"fragment ".concat(t).concat(t8("(",t6(r,", "),")")," ")+"on ".concat(n," ").concat(t8("",t6(i," ")," "))+a},IntValue:function(e){return e.value},FloatValue:function(e){return e.value},StringValue:function(e,t){var n=e.value;return e.block?(0,t1.LZ)(n,"description"===t?"":" "):JSON.stringify(n)},BooleanValue:function(e){return e.value?"true":"false"},NullValue:function(){return"null"},EnumValue:function(e){return e.value},ListValue:function(e){return"["+t6(e.values,", ")+"]"},ObjectValue:function(e){return"{"+t6(e.fields,", ")+"}"},ObjectField:function(e){var t;return e.name+": "+e.value},Directive:function(e){var t;return"@"+e.name+t8("(",t6(e.arguments,", "),")")},NamedType:function(e){return e.name},ListType:function(e){return"["+e.type+"]"},NonNullType:function(e){return e.type+"!"},SchemaDefinition:t4(function(e){var t=e.directives,n=e.operationTypes;return t6(["schema",t6(t," "),t5(n)]," ")}),OperationTypeDefinition:function(e){var t;return e.operation+": "+e.type},ScalarTypeDefinition:t4(function(e){var t;return t6(["scalar",e.name,t6(e.directives," ")]," ")}),ObjectTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["type",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")}),FieldDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.type,i=e.directives;return t+(ne(n)?t8("(\n",t9(t6(n,"\n")),"\n)"):t8("(",t6(n,", "),")"))+": "+r+t8(" ",t6(i," "))}),InputValueDefinition:t4(function(e){var t=e.name,n=e.type,r=e.defaultValue,i=e.directives;return t6([t+": "+n,t8("= ",r),t6(i," ")]," ")}),InterfaceTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["interface",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")}),UnionTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.types;return t6(["union",t,t6(n," "),r&&0!==r.length?"= "+t6(r," | "):""]," ")}),EnumTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.values;return t6(["enum",t,t6(n," "),t5(r)]," ")}),EnumValueDefinition:t4(function(e){var t;return t6([e.name,t6(e.directives," ")]," ")}),InputObjectTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.fields;return t6(["input",t,t6(n," "),t5(r)]," ")}),DirectiveDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.repeatable,i=e.locations;return"directive @"+t+(ne(n)?t8("(\n",t9(t6(n,"\n")),"\n)"):t8("(",t6(n,", "),")"))+(r?" repeatable":"")+" on "+t6(i," | ")}),SchemaExtension:function(e){var t=e.directives,n=e.operationTypes;return t6(["extend schema",t6(t," "),t5(n)]," ")},ScalarTypeExtension:function(e){var t;return t6(["extend scalar",e.name,t6(e.directives," ")]," ")},ObjectTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["extend type",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")},InterfaceTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["extend interface",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")},UnionTypeExtension:function(e){var t=e.name,n=e.directives,r=e.types;return t6(["extend union",t,t6(n," "),r&&0!==r.length?"= "+t6(r," | "):""]," ")},EnumTypeExtension:function(e){var t=e.name,n=e.directives,r=e.values;return t6(["extend enum",t,t6(n," "),t5(r)]," ")},InputObjectTypeExtension:function(e){var t=e.name,n=e.directives,r=e.fields;return t6(["extend input",t,t6(n," "),t5(r)]," ")}};function t4(e){return function(t){return t6([t.description,e(t)],"\n")}}function t6(e){var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return null!==(t=null==e?void 0:e.filter(function(e){return e}).join(n))&&void 0!==t?t:""}function t5(e){return t8("{\n",t9(t6(e,"\n")),"\n}")}function t8(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";return null!=t&&""!==t?e+t+n:""}function t9(e){return t8(" ",e.replace(/\n/g,"\n "))}function t7(e){return -1!==e.indexOf("\n")}function ne(e){return null!=e&&e.some(t7)}var nt,nn,nr,ni={http:{includeQuery:!0,includeExtensions:!1,preserveHeaderCase:!1},headers:{accept:"*/*","content-type":"application/json"},options:{method:"POST"}},na=function(e,t){return t(e)};function no(e,t){for(var n=[],r=2;rObject.create(null),{forEach:nv,slice:ny}=Array.prototype,{hasOwnProperty:nw}=Object.prototype;class n_{constructor(e=!0,t=ng){this.weakness=e,this.makeData=t}lookup(...e){return this.lookupArray(e)}lookupArray(e){let t=this;return nv.call(e,e=>t=t.getChildTrie(e)),nw.call(t,"data")?t.data:t.data=this.makeData(ny.call(e))}peek(...e){return this.peekArray(e)}peekArray(e){let t=this;for(let n=0,r=e.length;t&&n=0;--o)t.definitions[o].kind===nL.h.OPERATION_DEFINITION&&++a;var s=nN(e),u=e.some(function(e){return e.remove}),c=function(e){return u&&e&&e.some(s)},l=new Map,f=!1,d={enter:function(e){if(c(e.directives))return f=!0,null}},h=tl(t,{Field:d,InlineFragment:d,VariableDefinition:{enter:function(){return!1}},Variable:{enter:function(e,t,n,r,a){var o=i(a);o&&o.variables.add(e.name.value)}},FragmentSpread:{enter:function(e,t,n,r,a){if(c(e.directives))return f=!0,null;var o=i(a);o&&o.fragmentSpreads.add(e.name.value)}},FragmentDefinition:{enter:function(e,t,n,r){l.set(JSON.stringify(r),e)},leave:function(e,t,n,i){return e===l.get(JSON.stringify(i))?e:a>0&&e.selectionSet.selections.every(function(e){return e.kind===nL.h.FIELD&&"__typename"===e.name.value})?(r(e.name.value).removed=!0,f=!0,null):void 0}},Directive:{leave:function(e){if(s(e))return f=!0,null}}});if(!f)return t;var p=function(e){return e.transitiveVars||(e.transitiveVars=new Set(e.variables),e.removed||e.fragmentSpreads.forEach(function(t){p(r(t)).transitiveVars.forEach(function(t){e.transitiveVars.add(t)})})),e},b=new Set;h.definitions.forEach(function(e){e.kind===nL.h.OPERATION_DEFINITION?p(n(e.name&&e.name.value)).fragmentSpreads.forEach(function(e){b.add(e)}):e.kind!==nL.h.FRAGMENT_DEFINITION||0!==a||r(e.name.value).removed||b.add(e.name.value)}),b.forEach(function(e){p(r(e)).fragmentSpreads.forEach(function(e){b.add(e)})});var m=function(e){return!!(!b.has(e)||r(e).removed)},g={enter:function(e){if(m(e.name.value))return null}};return nD(tl(h,{FragmentSpread:g,FragmentDefinition:g,OperationDefinition:{leave:function(e){if(e.variableDefinitions){var t=p(n(e.name&&e.name.value)).transitiveVars;if(t.size0},t.prototype.tearDownQuery=function(){this.isTornDown||(this.concast&&this.observer&&(this.concast.removeObserver(this.observer),delete this.concast,delete this.observer),this.stopPolling(),this.subscriptions.forEach(function(e){return e.unsubscribe()}),this.subscriptions.clear(),this.queryManager.stopQuery(this.queryId),this.observers.clear(),this.isTornDown=!0)},t}(eT);function n4(e){var t=e.options,n=t.fetchPolicy,r=t.nextFetchPolicy;return"cache-and-network"===n||"network-only"===n?e.reobserve({fetchPolicy:"cache-first",nextFetchPolicy:function(){return(this.nextFetchPolicy=r,"function"==typeof r)?r.apply(this,arguments):n}}):e.reobserve()}function n6(e){__DEV__&&Q.kG.error("Unhandled error",e.message,e.stack)}function n5(e){__DEV__&&e&&__DEV__&&Q.kG.debug("Missing cache result fields: ".concat(JSON.stringify(e)),e)}function n8(e){return"network-only"===e||"no-cache"===e||"standby"===e}nK(n3);function n9(e){return e.kind===nL.h.FIELD||e.kind===nL.h.FRAGMENT_SPREAD||e.kind===nL.h.INLINE_FRAGMENT}function n7(e){return e.kind===Kind.SCALAR_TYPE_DEFINITION||e.kind===Kind.OBJECT_TYPE_DEFINITION||e.kind===Kind.INTERFACE_TYPE_DEFINITION||e.kind===Kind.UNION_TYPE_DEFINITION||e.kind===Kind.ENUM_TYPE_DEFINITION||e.kind===Kind.INPUT_OBJECT_TYPE_DEFINITION}function re(e){return e.kind===Kind.SCALAR_TYPE_EXTENSION||e.kind===Kind.OBJECT_TYPE_EXTENSION||e.kind===Kind.INTERFACE_TYPE_EXTENSION||e.kind===Kind.UNION_TYPE_EXTENSION||e.kind===Kind.ENUM_TYPE_EXTENSION||e.kind===Kind.INPUT_OBJECT_TYPE_EXTENSION}var rt=function(){return Object.create(null)},rn=Array.prototype,rr=rn.forEach,ri=rn.slice,ra=function(){function e(e,t){void 0===e&&(e=!0),void 0===t&&(t=rt),this.weakness=e,this.makeData=t}return e.prototype.lookup=function(){for(var e=[],t=0;tclass{constructor(){this.id=["slot",rc++,Date.now(),Math.random().toString(36).slice(2),].join(":")}hasValue(){for(let e=rs;e;e=e.parent)if(this.id in e.slots){let t=e.slots[this.id];if(t===ru)break;return e!==rs&&(rs.slots[this.id]=t),!0}return rs&&(rs.slots[this.id]=ru),!1}getValue(){if(this.hasValue())return rs.slots[this.id]}withValue(e,t,n,r){let i={__proto__:null,[this.id]:e},a=rs;rs={parent:a,slots:i};try{return t.apply(r,n)}finally{rs=a}}static bind(e){let t=rs;return function(){let n=rs;try{return rs=t,e.apply(this,arguments)}finally{rs=n}}}static noContext(e,t,n){if(!rs)return e.apply(n,t);{let r=rs;try{return rs=null,e.apply(n,t)}finally{rs=r}}}};function rf(e){try{return e()}catch(t){}}let rd="@wry/context:Slot",rh=rf(()=>globalThis)||rf(()=>global)||Object.create(null),rp=rh,rb=rp[rd]||Array[rd]||function(e){try{Object.defineProperty(rp,rd,{value:e,enumerable:!1,writable:!1,configurable:!0})}finally{return e}}(rl()),{bind:rm,noContext:rg}=rb;function rv(){}var ry=function(){function e(e,t){void 0===e&&(e=1/0),void 0===t&&(t=rv),this.max=e,this.dispose=t,this.map=new Map,this.newest=null,this.oldest=null}return e.prototype.has=function(e){return this.map.has(e)},e.prototype.get=function(e){var t=this.getNode(e);return t&&t.value},e.prototype.getNode=function(e){var t=this.map.get(e);if(t&&t!==this.newest){var n=t.older,r=t.newer;r&&(r.older=n),n&&(n.newer=r),t.older=this.newest,t.older.newer=t,t.newer=null,this.newest=t,t===this.oldest&&(this.oldest=r)}return t},e.prototype.set=function(e,t){var n=this.getNode(e);return n?n.value=t:(n={key:e,value:t,newer:null,older:this.newest},this.newest&&(this.newest.newer=n),this.newest=n,this.oldest=this.oldest||n,this.map.set(e,n),n.value)},e.prototype.clean=function(){for(;this.oldest&&this.map.size>this.max;)this.delete(this.oldest.key)},e.prototype.delete=function(e){var t=this.map.get(e);return!!t&&(t===this.newest&&(this.newest=t.older),t===this.oldest&&(this.oldest=t.newer),t.newer&&(t.newer.older=t.older),t.older&&(t.older.newer=t.newer),this.map.delete(e),this.dispose(t.value,e),!0)},e}(),rw=new rb,r_=Object.prototype.hasOwnProperty,rE=void 0===(n=Array.from)?function(e){var t=[];return e.forEach(function(e){return t.push(e)}),t}:n;function rS(e){var t=e.unsubscribe;"function"==typeof t&&(e.unsubscribe=void 0,t())}var rk=[],rx=100;function rT(e,t){if(!e)throw Error(t||"assertion failure")}function rM(e,t){var n=e.length;return n>0&&n===t.length&&e[n-1]===t[n-1]}function rO(e){switch(e.length){case 0:throw Error("unknown value");case 1:return e[0];case 2:throw e[1]}}function rA(e){return e.slice(0)}var rL=function(){function e(t){this.fn=t,this.parents=new Set,this.childValues=new Map,this.dirtyChildren=null,this.dirty=!0,this.recomputing=!1,this.value=[],this.deps=null,++e.count}return e.prototype.peek=function(){if(1===this.value.length&&!rN(this))return rC(this),this.value[0]},e.prototype.recompute=function(e){return rT(!this.recomputing,"already recomputing"),rC(this),rN(this)?rI(this,e):rO(this.value)},e.prototype.setDirty=function(){this.dirty||(this.dirty=!0,this.value.length=0,rR(this),rS(this))},e.prototype.dispose=function(){var e=this;this.setDirty(),rH(this),rF(this,function(t,n){t.setDirty(),r$(t,e)})},e.prototype.forget=function(){this.dispose()},e.prototype.dependOn=function(e){e.add(this),this.deps||(this.deps=rk.pop()||new Set),this.deps.add(e)},e.prototype.forgetDeps=function(){var e=this;this.deps&&(rE(this.deps).forEach(function(t){return t.delete(e)}),this.deps.clear(),rk.push(this.deps),this.deps=null)},e.count=0,e}();function rC(e){var t=rw.getValue();if(t)return e.parents.add(t),t.childValues.has(e)||t.childValues.set(e,[]),rN(e)?rY(t,e):rB(t,e),t}function rI(e,t){return rH(e),rw.withValue(e,rD,[e,t]),rz(e,t)&&rP(e),rO(e.value)}function rD(e,t){e.recomputing=!0,e.value.length=0;try{e.value[0]=e.fn.apply(null,t)}catch(n){e.value[1]=n}e.recomputing=!1}function rN(e){return e.dirty||!!(e.dirtyChildren&&e.dirtyChildren.size)}function rP(e){e.dirty=!1,!rN(e)&&rj(e)}function rR(e){rF(e,rY)}function rj(e){rF(e,rB)}function rF(e,t){var n=e.parents.size;if(n)for(var r=rE(e.parents),i=0;i0&&e.childValues.forEach(function(t,n){r$(e,n)}),e.forgetDeps(),rT(null===e.dirtyChildren)}function r$(e,t){t.parents.delete(e),e.childValues.delete(t),rU(e,t)}function rz(e,t){if("function"==typeof e.subscribe)try{rS(e),e.unsubscribe=e.subscribe.apply(null,t)}catch(n){return e.setDirty(),!1}return!0}var rG={setDirty:!0,dispose:!0,forget:!0};function rW(e){var t=new Map,n=e&&e.subscribe;function r(e){var r=rw.getValue();if(r){var i=t.get(e);i||t.set(e,i=new Set),r.dependOn(i),"function"==typeof n&&(rS(i),i.unsubscribe=n(e))}}return r.dirty=function(e,n){var r=t.get(e);if(r){var i=n&&r_.call(rG,n)?n:"setDirty";rE(r).forEach(function(e){return e[i]()}),t.delete(e),rS(r)}},r}function rK(){var e=new ra("function"==typeof WeakMap);return function(){return e.lookupArray(arguments)}}var rV=rK(),rq=new Set;function rZ(e,t){void 0===t&&(t=Object.create(null));var n=new ry(t.max||65536,function(e){return e.dispose()}),r=t.keyArgs,i=t.makeCacheKey||rK(),a=function(){var a=i.apply(null,r?r.apply(null,arguments):arguments);if(void 0===a)return e.apply(null,arguments);var o=n.get(a);o||(n.set(a,o=new rL(e)),o.subscribe=t.subscribe,o.forget=function(){return n.delete(a)});var s=o.recompute(Array.prototype.slice.call(arguments));return n.set(a,o),rq.add(n),rw.hasValue()||(rq.forEach(function(e){return e.clean()}),rq.clear()),s};function o(e){var t=n.get(e);t&&t.setDirty()}function s(e){var t=n.get(e);if(t)return t.peek()}function u(e){return n.delete(e)}return Object.defineProperty(a,"size",{get:function(){return n.map.size},configurable:!1,enumerable:!1}),a.dirtyKey=o,a.dirty=function(){o(i.apply(null,arguments))},a.peekKey=s,a.peek=function(){return s(i.apply(null,arguments))},a.forgetKey=u,a.forget=function(){return u(i.apply(null,arguments))},a.makeCacheKey=i,a.getKey=r?function(){return i.apply(null,r.apply(null,arguments))}:i,Object.freeze(a)}var rX=new rb,rJ=new WeakMap;function rQ(e){var t=rJ.get(e);return t||rJ.set(e,t={vars:new Set,dep:rW()}),t}function r1(e){rQ(e).vars.forEach(function(t){return t.forgetCache(e)})}function r0(e){rQ(e).vars.forEach(function(t){return t.attachCache(e)})}function r2(e){var t=new Set,n=new Set,r=function(a){if(arguments.length>0){if(e!==a){e=a,t.forEach(function(e){rQ(e).dep.dirty(r),r3(e)});var o=Array.from(n);n.clear(),o.forEach(function(t){return t(e)})}}else{var s=rX.getValue();s&&(i(s),rQ(s).dep(r))}return e};r.onNextChange=function(e){return n.add(e),function(){n.delete(e)}};var i=r.attachCache=function(e){return t.add(e),rQ(e).vars.add(r),r};return r.forgetCache=function(e){return t.delete(e)},r}function r3(e){e.broadcastWatches&&e.broadcastWatches()}var r4=function(){function e(e){var t=e.cache,n=e.client,r=e.resolvers,i=e.fragmentMatcher;this.selectionsToResolveCache=new WeakMap,this.cache=t,n&&(this.client=n),r&&this.addResolvers(r),i&&this.setFragmentMatcher(i)}return e.prototype.addResolvers=function(e){var t=this;this.resolvers=this.resolvers||{},Array.isArray(e)?e.forEach(function(e){t.resolvers=tj(t.resolvers,e)}):this.resolvers=tj(this.resolvers,e)},e.prototype.setResolvers=function(e){this.resolvers={},this.addResolvers(e)},e.prototype.getResolvers=function(){return this.resolvers||{}},e.prototype.runResolvers=function(e){var t=e.document,n=e.remoteResult,r=e.context,i=e.variables,a=e.onlyRunForcedResolvers,o=void 0!==a&&a;return(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(e){return t?[2,this.resolveDocument(t,n.data,r,i,this.fragmentMatcher,o).then(function(e){return(0,en.pi)((0,en.pi)({},n),{data:e.result})})]:[2,n]})})},e.prototype.setFragmentMatcher=function(e){this.fragmentMatcher=e},e.prototype.getFragmentMatcher=function(){return this.fragmentMatcher},e.prototype.clientQuery=function(e){return tb(["client"],e)&&this.resolvers?e:null},e.prototype.serverQuery=function(e){return n$(e)},e.prototype.prepareContext=function(e){var t=this.cache;return(0,en.pi)((0,en.pi)({},e),{cache:t,getCacheKey:function(e){return t.identify(e)}})},e.prototype.addExportedVariables=function(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(r){return e?[2,this.resolveDocument(e,this.buildRootValueFromCache(e,t)||{},this.prepareContext(n),t).then(function(e){return(0,en.pi)((0,en.pi)({},t),e.exportedVariables)})]:[2,(0,en.pi)({},t)]})})},e.prototype.shouldForceResolvers=function(e){var t=!1;return tl(e,{Directive:{enter:function(e){if("client"===e.name.value&&e.arguments&&(t=e.arguments.some(function(e){return"always"===e.name.value&&"BooleanValue"===e.value.kind&&!0===e.value.value})))return tc}}}),t},e.prototype.buildRootValueFromCache=function(e,t){return this.cache.diff({query:nH(e),variables:t,returnPartialData:!0,optimistic:!1}).result},e.prototype.resolveDocument=function(e,t,n,r,i,a){return void 0===n&&(n={}),void 0===r&&(r={}),void 0===i&&(i=function(){return!0}),void 0===a&&(a=!1),(0,en.mG)(this,void 0,void 0,function(){var o,s,u,c,l,f,d,h,p,b,m;return(0,en.Jh)(this,function(g){return o=e8(e),s=e4(e),u=eL(s),c=this.collectSelectionsToResolve(o,u),f=(l=o.operation)?l.charAt(0).toUpperCase()+l.slice(1):"Query",d=this,h=d.cache,p=d.client,b={fragmentMap:u,context:(0,en.pi)((0,en.pi)({},n),{cache:h,client:p}),variables:r,fragmentMatcher:i,defaultOperationType:f,exportedVariables:{},selectionsToResolve:c,onlyRunForcedResolvers:a},m=!1,[2,this.resolveSelectionSet(o.selectionSet,m,t,b).then(function(e){return{result:e,exportedVariables:b.exportedVariables}})]})})},e.prototype.resolveSelectionSet=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c=this;return(0,en.Jh)(this,function(l){return i=r.fragmentMap,a=r.context,o=r.variables,s=[n],u=function(e){return(0,en.mG)(c,void 0,void 0,function(){var u,c;return(0,en.Jh)(this,function(l){return(t||r.selectionsToResolve.has(e))&&td(e,o)?eQ(e)?[2,this.resolveField(e,t,n,r).then(function(t){var n;void 0!==t&&s.push(((n={})[eX(e)]=t,n))})]:(e1(e)?u=e:(u=i[e.name.value],__DEV__?(0,Q.kG)(u,"No fragment named ".concat(e.name.value)):(0,Q.kG)(u,11)),u&&u.typeCondition&&(c=u.typeCondition.name.value,r.fragmentMatcher(n,c,a)))?[2,this.resolveSelectionSet(u.selectionSet,t,n,r).then(function(e){s.push(e)})]:[2]:[2]})})},[2,Promise.all(e.selections.map(u)).then(function(){return tF(s)})]})})},e.prototype.resolveField=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c,l,f,d,h=this;return(0,en.Jh)(this,function(p){return n?(i=r.variables,a=e.name.value,o=eX(e),s=a!==o,c=Promise.resolve(u=n[o]||n[a]),(!r.onlyRunForcedResolvers||this.shouldForceResolvers(e))&&(l=n.__typename||r.defaultOperationType,(f=this.resolvers&&this.resolvers[l])&&(d=f[s?a:o])&&(c=Promise.resolve(rX.withValue(this.cache,d,[n,eZ(e,i),r.context,{field:e,fragmentMap:r.fragmentMap},])))),[2,c.then(function(n){if(void 0===n&&(n=u),e.directives&&e.directives.forEach(function(e){"export"===e.name.value&&e.arguments&&e.arguments.forEach(function(e){"as"===e.name.value&&"StringValue"===e.value.kind&&(r.exportedVariables[e.value.value]=n)})}),!e.selectionSet||null==n)return n;var i,a,o=null!==(a=null===(i=e.directives)||void 0===i?void 0:i.some(function(e){return"client"===e.name.value}))&&void 0!==a&&a;return Array.isArray(n)?h.resolveSubSelectedArray(e,t||o,n,r):e.selectionSet?h.resolveSelectionSet(e.selectionSet,t||o,n,r):void 0})]):[2,null]})})},e.prototype.resolveSubSelectedArray=function(e,t,n,r){var i=this;return Promise.all(n.map(function(n){return null===n?null:Array.isArray(n)?i.resolveSubSelectedArray(e,t,n,r):e.selectionSet?i.resolveSelectionSet(e.selectionSet,t,n,r):void 0}))},e.prototype.collectSelectionsToResolve=function(e,t){var n=function(e){return!Array.isArray(e)},r=this.selectionsToResolveCache;function i(e){if(!r.has(e)){var a=new Set;r.set(e,a),tl(e,{Directive:function(e,t,r,i,o){"client"===e.name.value&&o.forEach(function(e){n(e)&&n9(e)&&a.add(e)})},FragmentSpread:function(e,r,o,s,u){var c=t[e.name.value];__DEV__?(0,Q.kG)(c,"No fragment named ".concat(e.name.value)):(0,Q.kG)(c,12);var l=i(c);l.size>0&&(u.forEach(function(e){n(e)&&n9(e)&&a.add(e)}),a.add(e),l.forEach(function(e){a.add(e)}))}})}return r.get(e)}return i(e)},e}(),r6=new(t_.mr?WeakMap:Map);function r5(e,t){var n=e[t];"function"==typeof n&&(e[t]=function(){return r6.set(e,(r6.get(e)+1)%1e15),n.apply(this,arguments)})}function r8(e){e.notifyTimeout&&(clearTimeout(e.notifyTimeout),e.notifyTimeout=void 0)}var r9=function(){function e(e,t){void 0===t&&(t=e.generateQueryId()),this.queryId=t,this.listeners=new Set,this.document=null,this.lastRequestId=1,this.subscriptions=new Set,this.stopped=!1,this.dirty=!1,this.observableQuery=null;var n=this.cache=e.cache;r6.has(n)||(r6.set(n,0),r5(n,"evict"),r5(n,"modify"),r5(n,"reset"))}return e.prototype.init=function(e){var t=e.networkStatus||nZ.I.loading;return this.variables&&this.networkStatus!==nZ.I.loading&&!(0,nm.D)(this.variables,e.variables)&&(t=nZ.I.setVariables),(0,nm.D)(e.variables,this.variables)||(this.lastDiff=void 0),Object.assign(this,{document:e.document,variables:e.variables,networkError:null,graphQLErrors:this.graphQLErrors||[],networkStatus:t}),e.observableQuery&&this.setObservableQuery(e.observableQuery),e.lastRequestId&&(this.lastRequestId=e.lastRequestId),this},e.prototype.reset=function(){r8(this),this.dirty=!1},e.prototype.getDiff=function(e){void 0===e&&(e=this.variables);var t=this.getDiffOptions(e);if(this.lastDiff&&(0,nm.D)(t,this.lastDiff.options))return this.lastDiff.diff;this.updateWatch(this.variables=e);var n=this.observableQuery;if(n&&"no-cache"===n.options.fetchPolicy)return{complete:!1};var r=this.cache.diff(t);return this.updateLastDiff(r,t),r},e.prototype.updateLastDiff=function(e,t){this.lastDiff=e?{diff:e,options:t||this.getDiffOptions()}:void 0},e.prototype.getDiffOptions=function(e){var t;return void 0===e&&(e=this.variables),{query:this.document,variables:e,returnPartialData:!0,optimistic:!0,canonizeResults:null===(t=this.observableQuery)||void 0===t?void 0:t.options.canonizeResults}},e.prototype.setDiff=function(e){var t=this,n=this.lastDiff&&this.lastDiff.diff;this.updateLastDiff(e),this.dirty||(0,nm.D)(n&&n.result,e&&e.result)||(this.dirty=!0,this.notifyTimeout||(this.notifyTimeout=setTimeout(function(){return t.notify()},0)))},e.prototype.setObservableQuery=function(e){var t=this;e!==this.observableQuery&&(this.oqListener&&this.listeners.delete(this.oqListener),this.observableQuery=e,e?(e.queryInfo=this,this.listeners.add(this.oqListener=function(){t.getDiff().fromOptimisticTransaction?e.observe():n4(e)})):delete this.oqListener)},e.prototype.notify=function(){var e=this;r8(this),this.shouldNotify()&&this.listeners.forEach(function(t){return t(e)}),this.dirty=!1},e.prototype.shouldNotify=function(){if(!this.dirty||!this.listeners.size)return!1;if((0,nZ.O)(this.networkStatus)&&this.observableQuery){var e=this.observableQuery.options.fetchPolicy;if("cache-only"!==e&&"cache-and-network"!==e)return!1}return!0},e.prototype.stop=function(){if(!this.stopped){this.stopped=!0,this.reset(),this.cancel(),this.cancel=e.prototype.cancel,this.subscriptions.forEach(function(e){return e.unsubscribe()});var t=this.observableQuery;t&&t.stopPolling()}},e.prototype.cancel=function(){},e.prototype.updateWatch=function(e){var t=this;void 0===e&&(e=this.variables);var n=this.observableQuery;if(!n||"no-cache"!==n.options.fetchPolicy){var r=(0,en.pi)((0,en.pi)({},this.getDiffOptions(e)),{watcher:this,callback:function(e){return t.setDiff(e)}});this.lastWatch&&(0,nm.D)(r,this.lastWatch)||(this.cancel(),this.cancel=this.cache.watch(this.lastWatch=r))}},e.prototype.resetLastWrite=function(){this.lastWrite=void 0},e.prototype.shouldWrite=function(e,t){var n=this.lastWrite;return!(n&&n.dmCount===r6.get(this.cache)&&(0,nm.D)(t,n.variables)&&(0,nm.D)(e.data,n.result.data))},e.prototype.markResult=function(e,t,n,r){var i=this,a=new tB,o=(0,tP.O)(e.errors)?e.errors.slice(0):[];if(this.reset(),"incremental"in e&&(0,tP.O)(e.incremental)){var s=tG(this.getDiff().result,e);e.data=s}else if("hasNext"in e&&e.hasNext){var u=this.getDiff();e.data=a.merge(u.result,e.data)}this.graphQLErrors=o,"no-cache"===n.fetchPolicy?this.updateLastDiff({result:e.data,complete:!0},this.getDiffOptions(n.variables)):0!==r&&(r7(e,n.errorPolicy)?this.cache.performTransaction(function(a){if(i.shouldWrite(e,n.variables))a.writeQuery({query:t,data:e.data,variables:n.variables,overwrite:1===r}),i.lastWrite={result:e,variables:n.variables,dmCount:r6.get(i.cache)};else if(i.lastDiff&&i.lastDiff.diff.complete){e.data=i.lastDiff.diff.result;return}var o=i.getDiffOptions(n.variables),s=a.diff(o);i.stopped||i.updateWatch(n.variables),i.updateLastDiff(s,o),s.complete&&(e.data=s.result)}):this.lastWrite=void 0)},e.prototype.markReady=function(){return this.networkError=null,this.networkStatus=nZ.I.ready},e.prototype.markError=function(e){return this.networkStatus=nZ.I.error,this.lastWrite=void 0,this.reset(),e.graphQLErrors&&(this.graphQLErrors=e.graphQLErrors),e.networkError&&(this.networkError=e.networkError),e},e}();function r7(e,t){void 0===t&&(t="none");var n="ignore"===t||"all"===t,r=!nO(e);return!r&&n&&e.data&&(r=!0),r}var ie=Object.prototype.hasOwnProperty,it=function(){function e(e){var t=e.cache,n=e.link,r=e.defaultOptions,i=e.queryDeduplication,a=void 0!==i&&i,o=e.onBroadcast,s=e.ssrMode,u=void 0!==s&&s,c=e.clientAwareness,l=void 0===c?{}:c,f=e.localState,d=e.assumeImmutableResults;this.clientAwareness={},this.queries=new Map,this.fetchCancelFns=new Map,this.transformCache=new(t_.mr?WeakMap:Map),this.queryIdCounter=1,this.requestIdCounter=1,this.mutationIdCounter=1,this.inFlightLinkObservables=new Map,this.cache=t,this.link=n,this.defaultOptions=r||Object.create(null),this.queryDeduplication=a,this.clientAwareness=l,this.localState=f||new r4({cache:t}),this.ssrMode=u,this.assumeImmutableResults=!!d,(this.onBroadcast=o)&&(this.mutationStore=Object.create(null))}return e.prototype.stop=function(){var e=this;this.queries.forEach(function(t,n){e.stopQueryNoBroadcast(n)}),this.cancelPendingFetches(__DEV__?new Q.ej("QueryManager stopped while query was in flight"):new Q.ej(14))},e.prototype.cancelPendingFetches=function(e){this.fetchCancelFns.forEach(function(t){return t(e)}),this.fetchCancelFns.clear()},e.prototype.mutate=function(e){var t,n,r=e.mutation,i=e.variables,a=e.optimisticResponse,o=e.updateQueries,s=e.refetchQueries,u=void 0===s?[]:s,c=e.awaitRefetchQueries,l=void 0!==c&&c,f=e.update,d=e.onQueryUpdated,h=e.fetchPolicy,p=void 0===h?(null===(t=this.defaultOptions.mutate)||void 0===t?void 0:t.fetchPolicy)||"network-only":h,b=e.errorPolicy,m=void 0===b?(null===(n=this.defaultOptions.mutate)||void 0===n?void 0:n.errorPolicy)||"none":b,g=e.keepRootFields,v=e.context;return(0,en.mG)(this,void 0,void 0,function(){var e,t,n,s,c,h;return(0,en.Jh)(this,function(b){switch(b.label){case 0:if(__DEV__?(0,Q.kG)(r,"mutation option is required. You must specify your GraphQL document in the mutation option."):(0,Q.kG)(r,15),__DEV__?(0,Q.kG)("network-only"===p||"no-cache"===p,"Mutations support only 'network-only' or 'no-cache' fetchPolicy strings. The default `network-only` behavior automatically writes mutation results to the cache. Passing `no-cache` skips the cache write."):(0,Q.kG)("network-only"===p||"no-cache"===p,16),e=this.generateMutationId(),n=(t=this.transform(r)).document,s=t.hasClientExports,r=this.cache.transformForLink(n),i=this.getVariables(r,i),!s)return[3,2];return[4,this.localState.addExportedVariables(r,i,v)];case 1:i=b.sent(),b.label=2;case 2:return c=this.mutationStore&&(this.mutationStore[e]={mutation:r,variables:i,loading:!0,error:null}),a&&this.markMutationOptimistic(a,{mutationId:e,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,updateQueries:o,update:f,keepRootFields:g}),this.broadcastQueries(),h=this,[2,new Promise(function(t,n){return nM(h.getObservableFromLink(r,(0,en.pi)((0,en.pi)({},v),{optimisticResponse:a}),i,!1),function(t){if(nO(t)&&"none"===m)throw new tN.cA({graphQLErrors:nA(t)});c&&(c.loading=!1,c.error=null);var n=(0,en.pi)({},t);return"function"==typeof u&&(u=u(n)),"ignore"===m&&nO(n)&&delete n.errors,h.markMutationResult({mutationId:e,result:n,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,update:f,updateQueries:o,awaitRefetchQueries:l,refetchQueries:u,removeOptimistic:a?e:void 0,onQueryUpdated:d,keepRootFields:g})}).subscribe({next:function(e){h.broadcastQueries(),"hasNext"in e&&!1!==e.hasNext||t(e)},error:function(t){c&&(c.loading=!1,c.error=t),a&&h.cache.removeOptimistic(e),h.broadcastQueries(),n(t instanceof tN.cA?t:new tN.cA({networkError:t}))}})})]}})})},e.prototype.markMutationResult=function(e,t){var n=this;void 0===t&&(t=this.cache);var r=e.result,i=[],a="no-cache"===e.fetchPolicy;if(!a&&r7(r,e.errorPolicy)){if(tU(r)||i.push({result:r.data,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}),tU(r)&&(0,tP.O)(r.incremental)){var o=t.diff({id:"ROOT_MUTATION",query:this.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0}),s=void 0;o.result&&(s=tG(o.result,r)),void 0!==s&&(r.data=s,i.push({result:s,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}))}var u=e.updateQueries;u&&this.queries.forEach(function(e,a){var o=e.observableQuery,s=o&&o.queryName;if(s&&ie.call(u,s)){var c,l=u[s],f=n.queries.get(a),d=f.document,h=f.variables,p=t.diff({query:d,variables:h,returnPartialData:!0,optimistic:!1}),b=p.result;if(p.complete&&b){var m=l(b,{mutationResult:r,queryName:d&&e3(d)||void 0,queryVariables:h});m&&i.push({result:m,dataId:"ROOT_QUERY",query:d,variables:h})}}})}if(i.length>0||e.refetchQueries||e.update||e.onQueryUpdated||e.removeOptimistic){var c=[];if(this.refetchQueries({updateCache:function(t){a||i.forEach(function(e){return t.write(e)});var o=e.update,s=!t$(r)||tU(r)&&!r.hasNext;if(o){if(!a){var u=t.diff({id:"ROOT_MUTATION",query:n.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0});u.complete&&("incremental"in(r=(0,en.pi)((0,en.pi)({},r),{data:u.result}))&&delete r.incremental,"hasNext"in r&&delete r.hasNext)}s&&o(t,r,{context:e.context,variables:e.variables})}a||e.keepRootFields||!s||t.modify({id:"ROOT_MUTATION",fields:function(e,t){var n=t.fieldName,r=t.DELETE;return"__typename"===n?e:r}})},include:e.refetchQueries,optimistic:!1,removeOptimistic:e.removeOptimistic,onQueryUpdated:e.onQueryUpdated||null}).forEach(function(e){return c.push(e)}),e.awaitRefetchQueries||e.onQueryUpdated)return Promise.all(c).then(function(){return r})}return Promise.resolve(r)},e.prototype.markMutationOptimistic=function(e,t){var n=this,r="function"==typeof e?e(t.variables):e;return this.cache.recordOptimisticTransaction(function(e){try{n.markMutationResult((0,en.pi)((0,en.pi)({},t),{result:{data:r}}),e)}catch(i){__DEV__&&Q.kG.error(i)}},t.mutationId)},e.prototype.fetchQuery=function(e,t,n){return this.fetchQueryObservable(e,t,n).promise},e.prototype.getQueryStore=function(){var e=Object.create(null);return this.queries.forEach(function(t,n){e[n]={variables:t.variables,networkStatus:t.networkStatus,networkError:t.networkError,graphQLErrors:t.graphQLErrors}}),e},e.prototype.resetErrors=function(e){var t=this.queries.get(e);t&&(t.networkError=void 0,t.graphQLErrors=[])},e.prototype.transform=function(e){var t=this.transformCache;if(!t.has(e)){var n=this.cache.transformDocument(e),r=nY(n),i=this.localState.clientQuery(n),a=r&&this.localState.serverQuery(r),o={document:n,hasClientExports:tm(n),hasForcedResolvers:this.localState.shouldForceResolvers(n),clientQuery:i,serverQuery:a,defaultVars:e9(e2(n)),asQuery:(0,en.pi)((0,en.pi)({},n),{definitions:n.definitions.map(function(e){return"OperationDefinition"===e.kind&&"query"!==e.operation?(0,en.pi)((0,en.pi)({},e),{operation:"query"}):e})})},s=function(e){e&&!t.has(e)&&t.set(e,o)};s(e),s(n),s(i),s(a)}return t.get(e)},e.prototype.getVariables=function(e,t){return(0,en.pi)((0,en.pi)({},this.transform(e).defaultVars),t)},e.prototype.watchQuery=function(e){void 0===(e=(0,en.pi)((0,en.pi)({},e),{variables:this.getVariables(e.query,e.variables)})).notifyOnNetworkStatusChange&&(e.notifyOnNetworkStatusChange=!1);var t=new r9(this),n=new n3({queryManager:this,queryInfo:t,options:e});return this.queries.set(n.queryId,t),t.init({document:n.query,observableQuery:n,variables:n.variables}),n},e.prototype.query=function(e,t){var n=this;return void 0===t&&(t=this.generateQueryId()),__DEV__?(0,Q.kG)(e.query,"query option is required. You must specify your GraphQL document in the query option."):(0,Q.kG)(e.query,17),__DEV__?(0,Q.kG)("Document"===e.query.kind,'You must wrap the query string in a "gql" tag.'):(0,Q.kG)("Document"===e.query.kind,18),__DEV__?(0,Q.kG)(!e.returnPartialData,"returnPartialData option only supported on watchQuery."):(0,Q.kG)(!e.returnPartialData,19),__DEV__?(0,Q.kG)(!e.pollInterval,"pollInterval option only supported on watchQuery."):(0,Q.kG)(!e.pollInterval,20),this.fetchQuery(t,e).finally(function(){return n.stopQuery(t)})},e.prototype.generateQueryId=function(){return String(this.queryIdCounter++)},e.prototype.generateRequestId=function(){return this.requestIdCounter++},e.prototype.generateMutationId=function(){return String(this.mutationIdCounter++)},e.prototype.stopQueryInStore=function(e){this.stopQueryInStoreNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryInStoreNoBroadcast=function(e){var t=this.queries.get(e);t&&t.stop()},e.prototype.clearStore=function(e){return void 0===e&&(e={discardWatches:!0}),this.cancelPendingFetches(__DEV__?new Q.ej("Store reset while query was in flight (not completed in link chain)"):new Q.ej(21)),this.queries.forEach(function(e){e.observableQuery?e.networkStatus=nZ.I.loading:e.stop()}),this.mutationStore&&(this.mutationStore=Object.create(null)),this.cache.reset(e)},e.prototype.getObservableQueries=function(e){var t=this;void 0===e&&(e="active");var n=new Map,r=new Map,i=new Set;return Array.isArray(e)&&e.forEach(function(e){"string"==typeof e?r.set(e,!1):eN(e)?r.set(t.transform(e).document,!1):(0,eO.s)(e)&&e.query&&i.add(e)}),this.queries.forEach(function(t,i){var a=t.observableQuery,o=t.document;if(a){if("all"===e){n.set(i,a);return}var s=a.queryName;if("standby"===a.options.fetchPolicy||"active"===e&&!a.hasObservers())return;("active"===e||s&&r.has(s)||o&&r.has(o))&&(n.set(i,a),s&&r.set(s,!0),o&&r.set(o,!0))}}),i.size&&i.forEach(function(e){var r=nG("legacyOneTimeQuery"),i=t.getQuery(r).init({document:e.query,variables:e.variables}),a=new n3({queryManager:t,queryInfo:i,options:(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"network-only"})});(0,Q.kG)(a.queryId===r),i.setObservableQuery(a),n.set(r,a)}),__DEV__&&r.size&&r.forEach(function(e,t){!e&&__DEV__&&Q.kG.warn("Unknown query ".concat("string"==typeof t?"named ":"").concat(JSON.stringify(t,null,2)," requested in refetchQueries options.include array"))}),n},e.prototype.reFetchObservableQueries=function(e){var t=this;void 0===e&&(e=!1);var n=[];return this.getObservableQueries(e?"all":"active").forEach(function(r,i){var a=r.options.fetchPolicy;r.resetLastResults(),(e||"standby"!==a&&"cache-only"!==a)&&n.push(r.refetch()),t.getQuery(i).setDiff(null)}),this.broadcastQueries(),Promise.all(n)},e.prototype.setObservableQuery=function(e){this.getQuery(e.queryId).setObservableQuery(e)},e.prototype.startGraphQLSubscription=function(e){var t=this,n=e.query,r=e.fetchPolicy,i=e.errorPolicy,a=e.variables,o=e.context,s=void 0===o?{}:o;n=this.transform(n).document,a=this.getVariables(n,a);var u=function(e){return t.getObservableFromLink(n,s,e).map(function(a){"no-cache"!==r&&(r7(a,i)&&t.cache.write({query:n,result:a.data,dataId:"ROOT_SUBSCRIPTION",variables:e}),t.broadcastQueries());var o=nO(a),s=(0,tN.ls)(a);if(o||s){var u={};throw o&&(u.graphQLErrors=a.errors),s&&(u.protocolErrors=a.extensions[tN.YG]),new tN.cA(u)}return a})};if(this.transform(n).hasClientExports){var c=this.localState.addExportedVariables(n,a,s).then(u);return new eT(function(e){var t=null;return c.then(function(n){return t=n.subscribe(e)},e.error),function(){return t&&t.unsubscribe()}})}return u(a)},e.prototype.stopQuery=function(e){this.stopQueryNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryNoBroadcast=function(e){this.stopQueryInStoreNoBroadcast(e),this.removeQuery(e)},e.prototype.removeQuery=function(e){this.fetchCancelFns.delete(e),this.queries.has(e)&&(this.getQuery(e).stop(),this.queries.delete(e))},e.prototype.broadcastQueries=function(){this.onBroadcast&&this.onBroadcast(),this.queries.forEach(function(e){return e.notify()})},e.prototype.getLocalState=function(){return this.localState},e.prototype.getObservableFromLink=function(e,t,n,r){var i,a,o=this;void 0===r&&(r=null!==(i=null==t?void 0:t.queryDeduplication)&&void 0!==i?i:this.queryDeduplication);var s=this.transform(e).serverQuery;if(s){var u=this,c=u.inFlightLinkObservables,l=u.link,f={query:s,variables:n,operationName:e3(s)||void 0,context:this.prepareContext((0,en.pi)((0,en.pi)({},t),{forceFetch:!r}))};if(t=f.context,r){var d=c.get(s)||new Map;c.set(s,d);var h=nx(n);if(!(a=d.get(h))){var p=new nq([np(l,f)]);d.set(h,a=p),p.beforeNext(function(){d.delete(h)&&d.size<1&&c.delete(s)})}}else a=new nq([np(l,f)])}else a=new nq([eT.of({data:{}})]),t=this.prepareContext(t);var b=this.transform(e).clientQuery;return b&&(a=nM(a,function(e){return o.localState.runResolvers({document:b,remoteResult:e,context:t,variables:n})})),a},e.prototype.getResultsFromLink=function(e,t,n){var r=e.lastRequestId=this.generateRequestId(),i=this.cache.transformForLink(this.transform(e.document).document);return nM(this.getObservableFromLink(i,n.context,n.variables),function(a){var o=nA(a),s=o.length>0;if(r>=e.lastRequestId){if(s&&"none"===n.errorPolicy)throw e.markError(new tN.cA({graphQLErrors:o}));e.markResult(a,i,n,t),e.markReady()}var u={data:a.data,loading:!1,networkStatus:nZ.I.ready};return s&&"ignore"!==n.errorPolicy&&(u.errors=o,u.networkStatus=nZ.I.error),u},function(t){var n=(0,tN.MS)(t)?t:new tN.cA({networkError:t});throw r>=e.lastRequestId&&e.markError(n),n})},e.prototype.fetchQueryObservable=function(e,t,n){return this.fetchConcastWithInfo(e,t,n).concast},e.prototype.fetchConcastWithInfo=function(e,t,n){var r,i,a=this;void 0===n&&(n=nZ.I.loading);var o=this.transform(t.query).document,s=this.getVariables(o,t.variables),u=this.getQuery(e),c=this.defaultOptions.watchQuery,l=t.fetchPolicy,f=void 0===l?c&&c.fetchPolicy||"cache-first":l,d=t.errorPolicy,h=void 0===d?c&&c.errorPolicy||"none":d,p=t.returnPartialData,b=void 0!==p&&p,m=t.notifyOnNetworkStatusChange,g=void 0!==m&&m,v=t.context,y=void 0===v?{}:v,w=Object.assign({},t,{query:o,variables:s,fetchPolicy:f,errorPolicy:h,returnPartialData:b,notifyOnNetworkStatusChange:g,context:y}),_=function(e){w.variables=e;var r=a.fetchQueryByPolicy(u,w,n);return"standby"!==w.fetchPolicy&&r.sources.length>0&&u.observableQuery&&u.observableQuery.applyNextFetchPolicy("after-fetch",t),r},E=function(){return a.fetchCancelFns.delete(e)};if(this.fetchCancelFns.set(e,function(e){E(),setTimeout(function(){return r.cancel(e)})}),this.transform(w.query).hasClientExports)r=new nq(this.localState.addExportedVariables(w.query,w.variables,w.context).then(_).then(function(e){return e.sources})),i=!0;else{var S=_(w.variables);i=S.fromLink,r=new nq(S.sources)}return r.promise.then(E,E),{concast:r,fromLink:i}},e.prototype.refetchQueries=function(e){var t=this,n=e.updateCache,r=e.include,i=e.optimistic,a=void 0!==i&&i,o=e.removeOptimistic,s=void 0===o?a?nG("refetchQueries"):void 0:o,u=e.onQueryUpdated,c=new Map;r&&this.getObservableQueries(r).forEach(function(e,n){c.set(n,{oq:e,lastDiff:t.getQuery(n).getDiff()})});var l=new Map;return n&&this.cache.batch({update:n,optimistic:a&&s||!1,removeOptimistic:s,onWatchUpdated:function(e,t,n){var r=e.watcher instanceof r9&&e.watcher.observableQuery;if(r){if(u){c.delete(r.queryId);var i=u(r,t,n);return!0===i&&(i=r.refetch()),!1!==i&&l.set(r,i),i}null!==u&&c.set(r.queryId,{oq:r,lastDiff:n,diff:t})}}}),c.size&&c.forEach(function(e,n){var r,i=e.oq,a=e.lastDiff,o=e.diff;if(u){if(!o){var s=i.queryInfo;s.reset(),o=s.getDiff()}r=u(i,o,a)}u&&!0!==r||(r=i.refetch()),!1!==r&&l.set(i,r),n.indexOf("legacyOneTimeQuery")>=0&&t.stopQueryNoBroadcast(n)}),s&&this.cache.removeOptimistic(s),l},e.prototype.fetchQueryByPolicy=function(e,t,n){var r=this,i=t.query,a=t.variables,o=t.fetchPolicy,s=t.refetchWritePolicy,u=t.errorPolicy,c=t.returnPartialData,l=t.context,f=t.notifyOnNetworkStatusChange,d=e.networkStatus;e.init({document:this.transform(i).document,variables:a,networkStatus:n});var h=function(){return e.getDiff(a)},p=function(t,n){void 0===n&&(n=e.networkStatus||nZ.I.loading);var o=t.result;!__DEV__||c||(0,nm.D)(o,{})||n5(t.missing);var s=function(e){return eT.of((0,en.pi)({data:e,loading:(0,nZ.O)(n),networkStatus:n},t.complete?null:{partial:!0}))};return o&&r.transform(i).hasForcedResolvers?r.localState.runResolvers({document:i,remoteResult:{data:o},context:l,variables:a,onlyRunForcedResolvers:!0}).then(function(e){return s(e.data||void 0)}):"none"===u&&n===nZ.I.refetch&&Array.isArray(t.missing)?s(void 0):s(o)},b="no-cache"===o?0:n===nZ.I.refetch&&"merge"!==s?1:2,m=function(){return r.getResultsFromLink(e,b,{variables:a,context:l,fetchPolicy:o,errorPolicy:u})},g=f&&"number"==typeof d&&d!==n&&(0,nZ.O)(n);switch(o){default:case"cache-first":var v=h();if(v.complete)return{fromLink:!1,sources:[p(v,e.markReady())]};if(c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-and-network":var v=h();if(v.complete||c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-only":return{fromLink:!1,sources:[p(h(),e.markReady())]};case"network-only":if(g)return{fromLink:!0,sources:[p(h()),m()]};return{fromLink:!0,sources:[m()]};case"no-cache":if(g)return{fromLink:!0,sources:[p(e.getDiff()),m(),]};return{fromLink:!0,sources:[m()]};case"standby":return{fromLink:!1,sources:[]}}},e.prototype.getQuery=function(e){return e&&!this.queries.has(e)&&this.queries.set(e,new r9(this,e)),this.queries.get(e)},e.prototype.prepareContext=function(e){void 0===e&&(e={});var t=this.localState.prepareContext(e);return(0,en.pi)((0,en.pi)({},t),{clientAwareness:this.clientAwareness})},e}(),ir=__webpack_require__(14012),ii=!1,ia=function(){function e(e){var t=this;this.resetStoreCallbacks=[],this.clearStoreCallbacks=[];var n=e.uri,r=e.credentials,i=e.headers,a=e.cache,o=e.ssrMode,s=void 0!==o&&o,u=e.ssrForceFetchDelay,c=void 0===u?0:u,l=e.connectToDevTools,f=void 0===l?"object"==typeof window&&!window.__APOLLO_CLIENT__&&__DEV__:l,d=e.queryDeduplication,h=void 0===d||d,p=e.defaultOptions,b=e.assumeImmutableResults,m=void 0!==b&&b,g=e.resolvers,v=e.typeDefs,y=e.fragmentMatcher,w=e.name,_=e.version,E=e.link;if(E||(E=n?new nh({uri:n,credentials:r,headers:i}):ta.empty()),!a)throw __DEV__?new Q.ej("To initialize Apollo Client, you must specify a 'cache' property in the options object. \nFor more information, please visit: https://go.apollo.dev/c/docs"):new Q.ej(9);if(this.link=E,this.cache=a,this.disableNetworkFetches=s||c>0,this.queryDeduplication=h,this.defaultOptions=p||Object.create(null),this.typeDefs=v,c&&setTimeout(function(){return t.disableNetworkFetches=!1},c),this.watchQuery=this.watchQuery.bind(this),this.query=this.query.bind(this),this.mutate=this.mutate.bind(this),this.resetStore=this.resetStore.bind(this),this.reFetchObservableQueries=this.reFetchObservableQueries.bind(this),f&&"object"==typeof window&&(window.__APOLLO_CLIENT__=this),!ii&&f&&__DEV__&&(ii=!0,"undefined"!=typeof window&&window.document&&window.top===window.self&&!window.__APOLLO_DEVTOOLS_GLOBAL_HOOK__)){var S=window.navigator,k=S&&S.userAgent,x=void 0;"string"==typeof k&&(k.indexOf("Chrome/")>-1?x="https://chrome.google.com/webstore/detail/apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm":k.indexOf("Firefox/")>-1&&(x="https://addons.mozilla.org/en-US/firefox/addon/apollo-developer-tools/")),x&&__DEV__&&Q.kG.log("Download the Apollo DevTools for a better development experience: "+x)}this.version=nb,this.localState=new r4({cache:a,client:this,resolvers:g,fragmentMatcher:y}),this.queryManager=new it({cache:this.cache,link:this.link,defaultOptions:this.defaultOptions,queryDeduplication:h,ssrMode:s,clientAwareness:{name:w,version:_},localState:this.localState,assumeImmutableResults:m,onBroadcast:f?function(){t.devToolsHookCb&&t.devToolsHookCb({action:{},state:{queries:t.queryManager.getQueryStore(),mutations:t.queryManager.mutationStore||{}},dataWithOptimisticResults:t.cache.extract(!0)})}:void 0})}return e.prototype.stop=function(){this.queryManager.stop()},e.prototype.watchQuery=function(e){return this.defaultOptions.watchQuery&&(e=(0,ir.J)(this.defaultOptions.watchQuery,e)),this.disableNetworkFetches&&("network-only"===e.fetchPolicy||"cache-and-network"===e.fetchPolicy)&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.watchQuery(e)},e.prototype.query=function(e){return this.defaultOptions.query&&(e=(0,ir.J)(this.defaultOptions.query,e)),__DEV__?(0,Q.kG)("cache-and-network"!==e.fetchPolicy,"The cache-and-network fetchPolicy does not work with client.query, because client.query can only return a single result. Please use client.watchQuery to receive multiple results from the cache and the network, or consider using a different fetchPolicy, such as cache-first or network-only."):(0,Q.kG)("cache-and-network"!==e.fetchPolicy,10),this.disableNetworkFetches&&"network-only"===e.fetchPolicy&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.query(e)},e.prototype.mutate=function(e){return this.defaultOptions.mutate&&(e=(0,ir.J)(this.defaultOptions.mutate,e)),this.queryManager.mutate(e)},e.prototype.subscribe=function(e){return this.queryManager.startGraphQLSubscription(e)},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!1),this.cache.readQuery(e,t)},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!1),this.cache.readFragment(e,t)},e.prototype.writeQuery=function(e){var t=this.cache.writeQuery(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.writeFragment=function(e){var t=this.cache.writeFragment(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.__actionHookForDevTools=function(e){this.devToolsHookCb=e},e.prototype.__requestRaw=function(e){return np(this.link,e)},e.prototype.resetStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!1})}).then(function(){return Promise.all(e.resetStoreCallbacks.map(function(e){return e()}))}).then(function(){return e.reFetchObservableQueries()})},e.prototype.clearStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!0})}).then(function(){return Promise.all(e.clearStoreCallbacks.map(function(e){return e()}))})},e.prototype.onResetStore=function(e){var t=this;return this.resetStoreCallbacks.push(e),function(){t.resetStoreCallbacks=t.resetStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.onClearStore=function(e){var t=this;return this.clearStoreCallbacks.push(e),function(){t.clearStoreCallbacks=t.clearStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.reFetchObservableQueries=function(e){return this.queryManager.reFetchObservableQueries(e)},e.prototype.refetchQueries=function(e){var t=this.queryManager.refetchQueries(e),n=[],r=[];t.forEach(function(e,t){n.push(t),r.push(e)});var i=Promise.all(r);return i.queries=n,i.results=r,i.catch(function(e){__DEV__&&Q.kG.debug("In client.refetchQueries, Promise.all promise rejected with error ".concat(e))}),i},e.prototype.getObservableQueries=function(e){return void 0===e&&(e="active"),this.queryManager.getObservableQueries(e)},e.prototype.extract=function(e){return this.cache.extract(e)},e.prototype.restore=function(e){return this.cache.restore(e)},e.prototype.addResolvers=function(e){this.localState.addResolvers(e)},e.prototype.setResolvers=function(e){this.localState.setResolvers(e)},e.prototype.getResolvers=function(){return this.localState.getResolvers()},e.prototype.setLocalStateFragmentMatcher=function(e){this.localState.setFragmentMatcher(e)},e.prototype.setLink=function(e){this.link=this.queryManager.link=e},e}(),io=function(){function e(){this.getFragmentDoc=rZ(eA)}return e.prototype.batch=function(e){var t,n=this,r="string"==typeof e.optimistic?e.optimistic:!1===e.optimistic?null:void 0;return this.performTransaction(function(){return t=e.update(n)},r),t},e.prototype.recordOptimisticTransaction=function(e,t){this.performTransaction(e,t)},e.prototype.transformDocument=function(e){return e},e.prototype.transformForLink=function(e){return e},e.prototype.identify=function(e){},e.prototype.gc=function(){return[]},e.prototype.modify=function(e){return!1},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{rootId:e.id||"ROOT_QUERY",optimistic:t}))},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{query:this.getFragmentDoc(e.fragment,e.fragmentName),rootId:e.id,optimistic:t}))},e.prototype.writeQuery=function(e){var t=e.id,n=e.data,r=(0,en._T)(e,["id","data"]);return this.write(Object.assign(r,{dataId:t||"ROOT_QUERY",result:n}))},e.prototype.writeFragment=function(e){var t=e.id,n=e.data,r=e.fragment,i=e.fragmentName,a=(0,en._T)(e,["id","data","fragment","fragmentName"]);return this.write(Object.assign(a,{query:this.getFragmentDoc(r,i),dataId:t,result:n}))},e.prototype.updateQuery=function(e,t){return this.batch({update:function(n){var r=n.readQuery(e),i=t(r);return null==i?r:(n.writeQuery((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e.prototype.updateFragment=function(e,t){return this.batch({update:function(n){var r=n.readFragment(e),i=t(r);return null==i?r:(n.writeFragment((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e}(),is=function(e){function t(n,r,i,a){var o,s=e.call(this,n)||this;if(s.message=n,s.path=r,s.query=i,s.variables=a,Array.isArray(s.path)){s.missing=s.message;for(var u=s.path.length-1;u>=0;--u)s.missing=((o={})[s.path[u]]=s.missing,o)}else s.missing=s.path;return s.__proto__=t.prototype,s}return(0,en.ZT)(t,e),t}(Error),iu=__webpack_require__(10542),ic=Object.prototype.hasOwnProperty;function il(e){return null==e}function id(e,t){var n=e.__typename,r=e.id,i=e._id;if("string"==typeof n&&(t&&(t.keyObject=il(r)?il(i)?void 0:{_id:i}:{id:r}),il(r)&&!il(i)&&(r=i),!il(r)))return"".concat(n,":").concat("number"==typeof r||"string"==typeof r?r:JSON.stringify(r))}var ih={dataIdFromObject:id,addTypename:!0,resultCaching:!0,canonizeResults:!1};function ip(e){return(0,n1.o)(ih,e)}function ib(e){var t=e.canonizeResults;return void 0===t?ih.canonizeResults:t}function im(e,t){return eD(t)?e.get(t.__ref,"__typename"):t&&t.__typename}var ig=/^[_a-z][_0-9a-z]*/i;function iv(e){var t=e.match(ig);return t?t[0]:e}function iy(e,t,n){return!!(0,eO.s)(t)&&((0,tP.k)(t)?t.every(function(t){return iy(e,t,n)}):e.selections.every(function(e){if(eQ(e)&&td(e,n)){var r=eX(e);return ic.call(t,r)&&(!e.selectionSet||iy(e.selectionSet,t[r],n))}return!0}))}function iw(e){return(0,eO.s)(e)&&!eD(e)&&!(0,tP.k)(e)}function i_(){return new tB}function iE(e,t){var n=eL(e4(e));return{fragmentMap:n,lookupFragment:function(e){var r=n[e];return!r&&t&&(r=t.lookup(e)),r||null}}}var iS=Object.create(null),ik=function(){return iS},ix=Object.create(null),iT=function(){function e(e,t){var n=this;this.policies=e,this.group=t,this.data=Object.create(null),this.rootIds=Object.create(null),this.refs=Object.create(null),this.getFieldValue=function(e,t){return(0,iu.J)(eD(e)?n.get(e.__ref,t):e&&e[t])},this.canRead=function(e){return eD(e)?n.has(e.__ref):"object"==typeof e},this.toReference=function(e,t){if("string"==typeof e)return eI(e);if(eD(e))return e;var r=n.policies.identify(e)[0];if(r){var i=eI(r);return t&&n.merge(r,e),i}}}return e.prototype.toObject=function(){return(0,en.pi)({},this.data)},e.prototype.has=function(e){return void 0!==this.lookup(e,!0)},e.prototype.get=function(e,t){if(this.group.depend(e,t),ic.call(this.data,e)){var n=this.data[e];if(n&&ic.call(n,t))return n[t]}return"__typename"===t&&ic.call(this.policies.rootTypenamesById,e)?this.policies.rootTypenamesById[e]:this instanceof iL?this.parent.get(e,t):void 0},e.prototype.lookup=function(e,t){return(t&&this.group.depend(e,"__exists"),ic.call(this.data,e))?this.data[e]:this instanceof iL?this.parent.lookup(e,t):this.policies.rootTypenamesById[e]?Object.create(null):void 0},e.prototype.merge=function(e,t){var n,r=this;eD(e)&&(e=e.__ref),eD(t)&&(t=t.__ref);var i="string"==typeof e?this.lookup(n=e):e,a="string"==typeof t?this.lookup(n=t):t;if(a){__DEV__?(0,Q.kG)("string"==typeof n,"store.merge expects a string ID"):(0,Q.kG)("string"==typeof n,1);var o=new tB(iI).merge(i,a);if(this.data[n]=o,o!==i&&(delete this.refs[n],this.group.caching)){var s=Object.create(null);i||(s.__exists=1),Object.keys(a).forEach(function(e){if(!i||i[e]!==o[e]){s[e]=1;var t=iv(e);t===e||r.policies.hasKeyArgs(o.__typename,t)||(s[t]=1),void 0!==o[e]||r instanceof iL||delete o[e]}}),s.__typename&&!(i&&i.__typename)&&this.policies.rootTypenamesById[n]===o.__typename&&delete s.__typename,Object.keys(s).forEach(function(e){return r.group.dirty(n,e)})}}},e.prototype.modify=function(e,t){var n=this,r=this.lookup(e);if(r){var i=Object.create(null),a=!1,o=!0,s={DELETE:iS,INVALIDATE:ix,isReference:eD,toReference:this.toReference,canRead:this.canRead,readField:function(t,r){return n.policies.readField("string"==typeof t?{fieldName:t,from:r||eI(e)}:t,{store:n})}};if(Object.keys(r).forEach(function(u){var c=iv(u),l=r[u];if(void 0!==l){var f="function"==typeof t?t:t[u]||t[c];if(f){var d=f===ik?iS:f((0,iu.J)(l),(0,en.pi)((0,en.pi)({},s),{fieldName:c,storeFieldName:u,storage:n.getStorage(e,u)}));d===ix?n.group.dirty(e,u):(d===iS&&(d=void 0),d!==l&&(i[u]=d,a=!0,l=d))}void 0!==l&&(o=!1)}}),a)return this.merge(e,i),o&&(this instanceof iL?this.data[e]=void 0:delete this.data[e],this.group.dirty(e,"__exists")),!0}return!1},e.prototype.delete=function(e,t,n){var r,i=this.lookup(e);if(i){var a=this.getFieldValue(i,"__typename"),o=t&&n?this.policies.getStoreFieldName({typename:a,fieldName:t,args:n}):t;return this.modify(e,o?((r={})[o]=ik,r):ik)}return!1},e.prototype.evict=function(e,t){var n=!1;return e.id&&(ic.call(this.data,e.id)&&(n=this.delete(e.id,e.fieldName,e.args)),this instanceof iL&&this!==t&&(n=this.parent.evict(e,t)||n),(e.fieldName||n)&&this.group.dirty(e.id,e.fieldName||"__exists")),n},e.prototype.clear=function(){this.replace(null)},e.prototype.extract=function(){var e=this,t=this.toObject(),n=[];return this.getRootIdSet().forEach(function(t){ic.call(e.policies.rootTypenamesById,t)||n.push(t)}),n.length&&(t.__META={extraRootIds:n.sort()}),t},e.prototype.replace=function(e){var t=this;if(Object.keys(this.data).forEach(function(n){e&&ic.call(e,n)||t.delete(n)}),e){var n=e.__META,r=(0,en._T)(e,["__META"]);Object.keys(r).forEach(function(e){t.merge(e,r[e])}),n&&n.extraRootIds.forEach(this.retain,this)}},e.prototype.retain=function(e){return this.rootIds[e]=(this.rootIds[e]||0)+1},e.prototype.release=function(e){if(this.rootIds[e]>0){var t=--this.rootIds[e];return t||delete this.rootIds[e],t}return 0},e.prototype.getRootIdSet=function(e){return void 0===e&&(e=new Set),Object.keys(this.rootIds).forEach(e.add,e),this instanceof iL?this.parent.getRootIdSet(e):Object.keys(this.policies.rootTypenamesById).forEach(e.add,e),e},e.prototype.gc=function(){var e=this,t=this.getRootIdSet(),n=this.toObject();t.forEach(function(r){ic.call(n,r)&&(Object.keys(e.findChildRefIds(r)).forEach(t.add,t),delete n[r])});var r=Object.keys(n);if(r.length){for(var i=this;i instanceof iL;)i=i.parent;r.forEach(function(e){return i.delete(e)})}return r},e.prototype.findChildRefIds=function(e){if(!ic.call(this.refs,e)){var t=this.refs[e]=Object.create(null),n=this.data[e];if(!n)return t;var r=new Set([n]);r.forEach(function(e){eD(e)&&(t[e.__ref]=!0),(0,eO.s)(e)&&Object.keys(e).forEach(function(t){var n=e[t];(0,eO.s)(n)&&r.add(n)})})}return this.refs[e]},e.prototype.makeCacheKey=function(){return this.group.keyMaker.lookupArray(arguments)},e}(),iM=function(){function e(e,t){void 0===t&&(t=null),this.caching=e,this.parent=t,this.d=null,this.resetCaching()}return e.prototype.resetCaching=function(){this.d=this.caching?rW():null,this.keyMaker=new n_(t_.mr)},e.prototype.depend=function(e,t){if(this.d){this.d(iO(e,t));var n=iv(t);n!==t&&this.d(iO(e,n)),this.parent&&this.parent.depend(e,t)}},e.prototype.dirty=function(e,t){this.d&&this.d.dirty(iO(e,t),"__exists"===t?"forget":"setDirty")},e}();function iO(e,t){return t+"#"+e}function iA(e,t){iD(e)&&e.group.depend(t,"__exists")}!function(e){var t=function(e){function t(t){var n=t.policies,r=t.resultCaching,i=void 0===r||r,a=t.seed,o=e.call(this,n,new iM(i))||this;return o.stump=new iC(o),o.storageTrie=new n_(t_.mr),a&&o.replace(a),o}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,t){return this.stump.addLayer(e,t)},t.prototype.removeLayer=function(){return this},t.prototype.getStorage=function(){return this.storageTrie.lookupArray(arguments)},t}(e);e.Root=t}(iT||(iT={}));var iL=function(e){function t(t,n,r,i){var a=e.call(this,n.policies,i)||this;return a.id=t,a.parent=n,a.replay=r,a.group=i,r(a),a}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,n){return new t(e,this,n,this.group)},t.prototype.removeLayer=function(e){var t=this,n=this.parent.removeLayer(e);return e===this.id?(this.group.caching&&Object.keys(this.data).forEach(function(e){var r=t.data[e],i=n.lookup(e);i?r?r!==i&&Object.keys(r).forEach(function(n){(0,nm.D)(r[n],i[n])||t.group.dirty(e,n)}):(t.group.dirty(e,"__exists"),Object.keys(i).forEach(function(n){t.group.dirty(e,n)})):t.delete(e)}),n):n===this.parent?this:n.addLayer(this.id,this.replay)},t.prototype.toObject=function(){return(0,en.pi)((0,en.pi)({},this.parent.toObject()),this.data)},t.prototype.findChildRefIds=function(t){var n=this.parent.findChildRefIds(t);return ic.call(this.data,t)?(0,en.pi)((0,en.pi)({},n),e.prototype.findChildRefIds.call(this,t)):n},t.prototype.getStorage=function(){for(var e=this.parent;e.parent;)e=e.parent;return e.getStorage.apply(e,arguments)},t}(iT),iC=function(e){function t(t){return e.call(this,"EntityStore.Stump",t,function(){},new iM(t.group.caching,t.group))||this}return(0,en.ZT)(t,e),t.prototype.removeLayer=function(){return this},t.prototype.merge=function(){return this.parent.merge.apply(this.parent,arguments)},t}(iL);function iI(e,t,n){var r=e[n],i=t[n];return(0,nm.D)(r,i)?r:i}function iD(e){return!!(e instanceof iT&&e.group.caching)}function iN(e){return[e.selectionSet,e.objectOrReference,e.context,e.context.canonizeResults,]}var iP=function(){function e(e){var t=this;this.knownResults=new(t_.mr?WeakMap:Map),this.config=(0,n1.o)(e,{addTypename:!1!==e.addTypename,canonizeResults:ib(e)}),this.canon=e.canon||new nk,this.executeSelectionSet=rZ(function(e){var n,r=e.context.canonizeResults,i=iN(e);i[3]=!r;var a=(n=t.executeSelectionSet).peek.apply(n,i);return a?r?(0,en.pi)((0,en.pi)({},a),{result:t.canon.admit(a.result)}):a:(iA(e.context.store,e.enclosingRef.__ref),t.execSelectionSetImpl(e))},{max:this.config.resultCacheMaxSize,keyArgs:iN,makeCacheKey:function(e,t,n,r){if(iD(n.store))return n.store.makeCacheKey(e,eD(t)?t.__ref:t,n.varString,r)}}),this.executeSubSelectedArray=rZ(function(e){return iA(e.context.store,e.enclosingRef.__ref),t.execSubSelectedArrayImpl(e)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var t=e.field,n=e.array,r=e.context;if(iD(r.store))return r.store.makeCacheKey(t,n,r.varString)}})}return e.prototype.resetCanon=function(){this.canon=new nk},e.prototype.diffQueryAgainstStore=function(e){var t,n=e.store,r=e.query,i=e.rootId,a=void 0===i?"ROOT_QUERY":i,o=e.variables,s=e.returnPartialData,u=void 0===s||s,c=e.canonizeResults,l=void 0===c?this.config.canonizeResults:c,f=this.config.cache.policies;o=(0,en.pi)((0,en.pi)({},e9(e6(r))),o);var d=eI(a),h=this.executeSelectionSet({selectionSet:e8(r).selectionSet,objectOrReference:d,enclosingRef:d,context:(0,en.pi)({store:n,query:r,policies:f,variables:o,varString:nx(o),canonizeResults:l},iE(r,this.config.fragments))});if(h.missing&&(t=[new is(iR(h.missing),h.missing,r,o)],!u))throw t[0];return{result:h.result,complete:!t,missing:t}},e.prototype.isFresh=function(e,t,n,r){if(iD(r.store)&&this.knownResults.get(e)===n){var i=this.executeSelectionSet.peek(n,t,r,this.canon.isKnown(e));if(i&&e===i.result)return!0}return!1},e.prototype.execSelectionSetImpl=function(e){var t,n=this,r=e.selectionSet,i=e.objectOrReference,a=e.enclosingRef,o=e.context;if(eD(i)&&!o.policies.rootTypenamesById[i.__ref]&&!o.store.has(i.__ref))return{result:this.canon.empty,missing:"Dangling reference to missing ".concat(i.__ref," object")};var s=o.variables,u=o.policies,c=o.store.getFieldValue(i,"__typename"),l=[],f=new tB;function d(e,n){var r;return e.missing&&(t=f.merge(t,((r={})[n]=e.missing,r))),e.result}this.config.addTypename&&"string"==typeof c&&!u.rootIdsByTypename[c]&&l.push({__typename:c});var h=new Set(r.selections);h.forEach(function(e){var r,p;if(td(e,s)){if(eQ(e)){var b=u.readField({fieldName:e.name.value,field:e,variables:o.variables,from:i},o),m=eX(e);void 0===b?nj.added(e)||(t=f.merge(t,((r={})[m]="Can't find field '".concat(e.name.value,"' on ").concat(eD(i)?i.__ref+" object":"object "+JSON.stringify(i,null,2)),r))):(0,tP.k)(b)?b=d(n.executeSubSelectedArray({field:e,array:b,enclosingRef:a,context:o}),m):e.selectionSet?null!=b&&(b=d(n.executeSelectionSet({selectionSet:e.selectionSet,objectOrReference:b,enclosingRef:eD(b)?b:a,context:o}),m)):o.canonizeResults&&(b=n.canon.pass(b)),void 0!==b&&l.push(((p={})[m]=b,p))}else{var g=eC(e,o.lookupFragment);if(!g&&e.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(e.name.value)):new Q.ej(5);g&&u.fragmentMatches(g,c)&&g.selectionSet.selections.forEach(h.add,h)}}});var p={result:tF(l),missing:t},b=o.canonizeResults?this.canon.admit(p):(0,iu.J)(p);return b.result&&this.knownResults.set(b.result,r),b},e.prototype.execSubSelectedArrayImpl=function(e){var t,n=this,r=e.field,i=e.array,a=e.enclosingRef,o=e.context,s=new tB;function u(e,n){var r;return e.missing&&(t=s.merge(t,((r={})[n]=e.missing,r))),e.result}return r.selectionSet&&(i=i.filter(o.store.canRead)),i=i.map(function(e,t){return null===e?null:(0,tP.k)(e)?u(n.executeSubSelectedArray({field:r,array:e,enclosingRef:a,context:o}),t):r.selectionSet?u(n.executeSelectionSet({selectionSet:r.selectionSet,objectOrReference:e,enclosingRef:eD(e)?e:a,context:o}),t):(__DEV__&&ij(o.store,r,e),e)}),{result:o.canonizeResults?this.canon.admit(i):i,missing:t}},e}();function iR(e){try{JSON.stringify(e,function(e,t){if("string"==typeof t)throw t;return t})}catch(t){return t}}function ij(e,t,n){if(!t.selectionSet){var r=new Set([n]);r.forEach(function(n){(0,eO.s)(n)&&(__DEV__?(0,Q.kG)(!eD(n),"Missing selection set for object of type ".concat(im(e,n)," returned for query field ").concat(t.name.value)):(0,Q.kG)(!eD(n),6),Object.values(n).forEach(r.add,r))})}}function iF(e){var t=nG("stringifyForDisplay");return JSON.stringify(e,function(e,n){return void 0===n?t:n}).split(JSON.stringify(t)).join("")}var iY=Object.create(null);function iB(e){var t=JSON.stringify(e);return iY[t]||(iY[t]=Object.create(null))}function iU(e){var t=iB(e);return t.keyFieldsFn||(t.keyFieldsFn=function(t,n){var r=function(e,t){return n.readField(t,e)},i=n.keyObject=i$(e,function(e){var i=iW(n.storeObject,e,r);return void 0===i&&t!==n.storeObject&&ic.call(t,e[0])&&(i=iW(t,e,iG)),__DEV__?(0,Q.kG)(void 0!==i,"Missing field '".concat(e.join("."),"' while extracting keyFields from ").concat(JSON.stringify(t))):(0,Q.kG)(void 0!==i,2),i});return"".concat(n.typename,":").concat(JSON.stringify(i))})}function iH(e){var t=iB(e);return t.keyArgsFn||(t.keyArgsFn=function(t,n){var r=n.field,i=n.variables,a=n.fieldName,o=JSON.stringify(i$(e,function(e){var n=e[0],a=n.charAt(0);if("@"===a){if(r&&(0,tP.O)(r.directives)){var o=n.slice(1),s=r.directives.find(function(e){return e.name.value===o}),u=s&&eZ(s,i);return u&&iW(u,e.slice(1))}return}if("$"===a){var c=n.slice(1);if(i&&ic.call(i,c)){var l=e.slice(0);return l[0]=c,iW(i,l)}return}if(t)return iW(t,e)}));return(t||"{}"!==o)&&(a+=":"+o),a})}function i$(e,t){var n=new tB;return iz(e).reduce(function(e,r){var i,a=t(r);if(void 0!==a){for(var o=r.length-1;o>=0;--o)a=((i={})[r[o]]=a,i);e=n.merge(e,a)}return e},Object.create(null))}function iz(e){var t=iB(e);if(!t.paths){var n=t.paths=[],r=[];e.forEach(function(t,i){(0,tP.k)(t)?(iz(t).forEach(function(e){return n.push(r.concat(e))}),r.length=0):(r.push(t),(0,tP.k)(e[i+1])||(n.push(r.slice(0)),r.length=0))})}return t.paths}function iG(e,t){return e[t]}function iW(e,t,n){return n=n||iG,iK(t.reduce(function e(t,r){return(0,tP.k)(t)?t.map(function(t){return e(t,r)}):t&&n(t,r)},e))}function iK(e){return(0,eO.s)(e)?(0,tP.k)(e)?e.map(iK):i$(Object.keys(e).sort(),function(t){return iW(e,t)}):e}function iV(e){return void 0!==e.args?e.args:e.field?eZ(e.field,e.variables):null}eK.setStringify(nx);var iq=function(){},iZ=function(e,t){return t.fieldName},iX=function(e,t,n){return(0,n.mergeObjects)(e,t)},iJ=function(e,t){return t},iQ=function(){function e(e){this.config=e,this.typePolicies=Object.create(null),this.toBeAdded=Object.create(null),this.supertypeMap=new Map,this.fuzzySubtypes=new Map,this.rootIdsByTypename=Object.create(null),this.rootTypenamesById=Object.create(null),this.usingPossibleTypes=!1,this.config=(0,en.pi)({dataIdFromObject:id},e),this.cache=this.config.cache,this.setRootTypename("Query"),this.setRootTypename("Mutation"),this.setRootTypename("Subscription"),e.possibleTypes&&this.addPossibleTypes(e.possibleTypes),e.typePolicies&&this.addTypePolicies(e.typePolicies)}return e.prototype.identify=function(e,t){var n,r,i=this,a=t&&(t.typename||(null===(n=t.storeObject)||void 0===n?void 0:n.__typename))||e.__typename;if(a===this.rootTypenamesById.ROOT_QUERY)return["ROOT_QUERY"];for(var o=t&&t.storeObject||e,s=(0,en.pi)((0,en.pi)({},t),{typename:a,storeObject:o,readField:t&&t.readField||function(){var e=i0(arguments,o);return i.readField(e,{store:i.cache.data,variables:e.variables})}}),u=a&&this.getTypePolicy(a),c=u&&u.keyFn||this.config.dataIdFromObject;c;){var l=c((0,en.pi)((0,en.pi)({},e),o),s);if((0,tP.k)(l))c=iU(l);else{r=l;break}}return r=r?String(r):void 0,s.keyObject?[r,s.keyObject]:[r]},e.prototype.addTypePolicies=function(e){var t=this;Object.keys(e).forEach(function(n){var r=e[n],i=r.queryType,a=r.mutationType,o=r.subscriptionType,s=(0,en._T)(r,["queryType","mutationType","subscriptionType"]);i&&t.setRootTypename("Query",n),a&&t.setRootTypename("Mutation",n),o&&t.setRootTypename("Subscription",n),ic.call(t.toBeAdded,n)?t.toBeAdded[n].push(s):t.toBeAdded[n]=[s]})},e.prototype.updateTypePolicy=function(e,t){var n=this,r=this.getTypePolicy(e),i=t.keyFields,a=t.fields;function o(e,t){e.merge="function"==typeof t?t:!0===t?iX:!1===t?iJ:e.merge}o(r,t.merge),r.keyFn=!1===i?iq:(0,tP.k)(i)?iU(i):"function"==typeof i?i:r.keyFn,a&&Object.keys(a).forEach(function(t){var r=n.getFieldPolicy(e,t,!0),i=a[t];if("function"==typeof i)r.read=i;else{var s=i.keyArgs,u=i.read,c=i.merge;r.keyFn=!1===s?iZ:(0,tP.k)(s)?iH(s):"function"==typeof s?s:r.keyFn,"function"==typeof u&&(r.read=u),o(r,c)}r.read&&r.merge&&(r.keyFn=r.keyFn||iZ)})},e.prototype.setRootTypename=function(e,t){void 0===t&&(t=e);var n="ROOT_"+e.toUpperCase(),r=this.rootTypenamesById[n];t!==r&&(__DEV__?(0,Q.kG)(!r||r===e,"Cannot change root ".concat(e," __typename more than once")):(0,Q.kG)(!r||r===e,3),r&&delete this.rootIdsByTypename[r],this.rootIdsByTypename[t]=n,this.rootTypenamesById[n]=t)},e.prototype.addPossibleTypes=function(e){var t=this;this.usingPossibleTypes=!0,Object.keys(e).forEach(function(n){t.getSupertypeSet(n,!0),e[n].forEach(function(e){t.getSupertypeSet(e,!0).add(n);var r=e.match(ig);r&&r[0]===e||t.fuzzySubtypes.set(e,RegExp(e))})})},e.prototype.getTypePolicy=function(e){var t=this;if(!ic.call(this.typePolicies,e)){var n=this.typePolicies[e]=Object.create(null);n.fields=Object.create(null);var r=this.supertypeMap.get(e);r&&r.size&&r.forEach(function(e){var r=t.getTypePolicy(e),i=r.fields;Object.assign(n,(0,en._T)(r,["fields"])),Object.assign(n.fields,i)})}var i=this.toBeAdded[e];return i&&i.length&&i.splice(0).forEach(function(n){t.updateTypePolicy(e,n)}),this.typePolicies[e]},e.prototype.getFieldPolicy=function(e,t,n){if(e){var r=this.getTypePolicy(e).fields;return r[t]||n&&(r[t]=Object.create(null))}},e.prototype.getSupertypeSet=function(e,t){var n=this.supertypeMap.get(e);return!n&&t&&this.supertypeMap.set(e,n=new Set),n},e.prototype.fragmentMatches=function(e,t,n,r){var i=this;if(!e.typeCondition)return!0;if(!t)return!1;var a=e.typeCondition.name.value;if(t===a)return!0;if(this.usingPossibleTypes&&this.supertypeMap.has(a))for(var o=this.getSupertypeSet(t,!0),s=[o],u=function(e){var t=i.getSupertypeSet(e,!1);t&&t.size&&0>s.indexOf(t)&&s.push(t)},c=!!(n&&this.fuzzySubtypes.size),l=!1,f=0;f1?a:t}:(r=(0,en.pi)({},i),ic.call(r,"from")||(r.from=t)),__DEV__&&void 0===r.from&&__DEV__&&Q.kG.warn("Undefined 'from' passed to readField with arguments ".concat(iF(Array.from(e)))),void 0===r.variables&&(r.variables=n),r}function i2(e){return function(t,n){if((0,tP.k)(t)||(0,tP.k)(n))throw __DEV__?new Q.ej("Cannot automatically merge arrays"):new Q.ej(4);if((0,eO.s)(t)&&(0,eO.s)(n)){var r=e.getFieldValue(t,"__typename"),i=e.getFieldValue(n,"__typename");if(r&&i&&r!==i)return n;if(eD(t)&&iw(n))return e.merge(t.__ref,n),t;if(iw(t)&&eD(n))return e.merge(t,n.__ref),n;if(iw(t)&&iw(n))return(0,en.pi)((0,en.pi)({},t),n)}return n}}function i3(e,t,n){var r="".concat(t).concat(n),i=e.flavors.get(r);return i||e.flavors.set(r,i=e.clientOnly===t&&e.deferred===n?e:(0,en.pi)((0,en.pi)({},e),{clientOnly:t,deferred:n})),i}var i4=function(){function e(e,t,n){this.cache=e,this.reader=t,this.fragments=n}return e.prototype.writeToStore=function(e,t){var n=this,r=t.query,i=t.result,a=t.dataId,o=t.variables,s=t.overwrite,u=e2(r),c=i_();o=(0,en.pi)((0,en.pi)({},e9(u)),o);var l=(0,en.pi)((0,en.pi)({store:e,written:Object.create(null),merge:function(e,t){return c.merge(e,t)},variables:o,varString:nx(o)},iE(r,this.fragments)),{overwrite:!!s,incomingById:new Map,clientOnly:!1,deferred:!1,flavors:new Map}),f=this.processSelectionSet({result:i||Object.create(null),dataId:a,selectionSet:u.selectionSet,mergeTree:{map:new Map},context:l});if(!eD(f))throw __DEV__?new Q.ej("Could not identify object ".concat(JSON.stringify(i))):new Q.ej(7);return l.incomingById.forEach(function(t,r){var i=t.storeObject,a=t.mergeTree,o=t.fieldNodeSet,s=eI(r);if(a&&a.map.size){var u=n.applyMerges(a,s,i,l);if(eD(u))return;i=u}if(__DEV__&&!l.overwrite){var c=Object.create(null);o.forEach(function(e){e.selectionSet&&(c[e.name.value]=!0)});var f=function(e){return!0===c[iv(e)]},d=function(e){var t=a&&a.map.get(e);return Boolean(t&&t.info&&t.info.merge)};Object.keys(i).forEach(function(e){f(e)&&!d(e)&&at(s,i,e,l.store)})}e.merge(r,i)}),e.retain(f.__ref),f},e.prototype.processSelectionSet=function(e){var t=this,n=e.dataId,r=e.result,i=e.selectionSet,a=e.context,o=e.mergeTree,s=this.cache.policies,u=Object.create(null),c=n&&s.rootTypenamesById[n]||eJ(r,i,a.fragmentMap)||n&&a.store.get(n,"__typename");"string"==typeof c&&(u.__typename=c);var l=function(){var e=i0(arguments,u,a.variables);if(eD(e.from)){var t=a.incomingById.get(e.from.__ref);if(t){var n=s.readField((0,en.pi)((0,en.pi)({},e),{from:t.storeObject}),a);if(void 0!==n)return n}}return s.readField(e,a)},f=new Set;this.flattenFields(i,r,a,c).forEach(function(e,n){var i,a=r[eX(n)];if(f.add(n),void 0!==a){var d=s.getStoreFieldName({typename:c,fieldName:n.name.value,field:n,variables:e.variables}),h=i5(o,d),p=t.processFieldValue(a,n,n.selectionSet?i3(e,!1,!1):e,h),b=void 0;n.selectionSet&&(eD(p)||iw(p))&&(b=l("__typename",p));var m=s.getMergeFunction(c,n.name.value,b);m?h.info={field:n,typename:c,merge:m}:i7(o,d),u=e.merge(u,((i={})[d]=p,i))}else __DEV__&&!e.clientOnly&&!e.deferred&&!nj.added(n)&&!s.getReadFunction(c,n.name.value)&&__DEV__&&Q.kG.error("Missing field '".concat(eX(n),"' while writing result ").concat(JSON.stringify(r,null,2)).substring(0,1e3))});try{var d=s.identify(r,{typename:c,selectionSet:i,fragmentMap:a.fragmentMap,storeObject:u,readField:l}),h=d[0],p=d[1];n=n||h,p&&(u=a.merge(u,p))}catch(b){if(!n)throw b}if("string"==typeof n){var m=eI(n),g=a.written[n]||(a.written[n]=[]);if(g.indexOf(i)>=0||(g.push(i),this.reader&&this.reader.isFresh(r,m,i,a)))return m;var v=a.incomingById.get(n);return v?(v.storeObject=a.merge(v.storeObject,u),v.mergeTree=i8(v.mergeTree,o),f.forEach(function(e){return v.fieldNodeSet.add(e)})):a.incomingById.set(n,{storeObject:u,mergeTree:i9(o)?void 0:o,fieldNodeSet:f}),m}return u},e.prototype.processFieldValue=function(e,t,n,r){var i=this;return t.selectionSet&&null!==e?(0,tP.k)(e)?e.map(function(e,a){var o=i.processFieldValue(e,t,n,i5(r,a));return i7(r,a),o}):this.processSelectionSet({result:e,selectionSet:t.selectionSet,context:n,mergeTree:r}):__DEV__?nJ(e):e},e.prototype.flattenFields=function(e,t,n,r){void 0===r&&(r=eJ(t,e,n.fragmentMap));var i=new Map,a=this.cache.policies,o=new n_(!1);return function e(s,u){var c=o.lookup(s,u.clientOnly,u.deferred);c.visited||(c.visited=!0,s.selections.forEach(function(o){if(td(o,n.variables)){var s=u.clientOnly,c=u.deferred;if(!(s&&c)&&(0,tP.O)(o.directives)&&o.directives.forEach(function(e){var t=e.name.value;if("client"===t&&(s=!0),"defer"===t){var r=eZ(e,n.variables);r&&!1===r.if||(c=!0)}}),eQ(o)){var l=i.get(o);l&&(s=s&&l.clientOnly,c=c&&l.deferred),i.set(o,i3(n,s,c))}else{var f=eC(o,n.lookupFragment);if(!f&&o.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(o.name.value)):new Q.ej(8);f&&a.fragmentMatches(f,r,t,n.variables)&&e(f.selectionSet,i3(n,s,c))}}}))}(e,n),i},e.prototype.applyMerges=function(e,t,n,r,i){var a=this;if(e.map.size&&!eD(n)){var o,s,u=!(0,tP.k)(n)&&(eD(t)||iw(t))?t:void 0,c=n;u&&!i&&(i=[eD(u)?u.__ref:u]);var l=function(e,t){return(0,tP.k)(e)?"number"==typeof t?e[t]:void 0:r.store.getFieldValue(e,String(t))};e.map.forEach(function(e,t){var n=l(u,t),o=l(c,t);if(void 0!==o){i&&i.push(t);var f=a.applyMerges(e,n,o,r,i);f!==o&&(s=s||new Map).set(t,f),i&&(0,Q.kG)(i.pop()===t)}}),s&&(n=(0,tP.k)(c)?c.slice(0):(0,en.pi)({},c),s.forEach(function(e,t){n[t]=e}))}return e.info?this.cache.policies.runMergeFunction(t,n,e.info,r,i&&(o=r.store).getStorage.apply(o,i)):n},e}(),i6=[];function i5(e,t){var n=e.map;return n.has(t)||n.set(t,i6.pop()||{map:new Map}),n.get(t)}function i8(e,t){if(e===t||!t||i9(t))return e;if(!e||i9(e))return t;var n=e.info&&t.info?(0,en.pi)((0,en.pi)({},e.info),t.info):e.info||t.info,r=e.map.size&&t.map.size,i=r?new Map:e.map.size?e.map:t.map,a={info:n,map:i};if(r){var o=new Set(t.map.keys());e.map.forEach(function(e,n){a.map.set(n,i8(e,t.map.get(n))),o.delete(n)}),o.forEach(function(n){a.map.set(n,i8(t.map.get(n),e.map.get(n)))})}return a}function i9(e){return!e||!(e.info||e.map.size)}function i7(e,t){var n=e.map,r=n.get(t);r&&i9(r)&&(i6.push(r),n.delete(t))}var ae=new Set;function at(e,t,n,r){var i=function(e){var t=r.getFieldValue(e,n);return"object"==typeof t&&t},a=i(e);if(a){var o=i(t);if(!(!o||eD(a)||(0,nm.D)(a,o)||Object.keys(a).every(function(e){return void 0!==r.getFieldValue(o,e)}))){var s=r.getFieldValue(e,"__typename")||r.getFieldValue(t,"__typename"),u=iv(n),c="".concat(s,".").concat(u);if(!ae.has(c)){ae.add(c);var l=[];(0,tP.k)(a)||(0,tP.k)(o)||[a,o].forEach(function(e){var t=r.getFieldValue(e,"__typename");"string"!=typeof t||l.includes(t)||l.push(t)}),__DEV__&&Q.kG.warn("Cache data may be lost when replacing the ".concat(u," field of a ").concat(s," object.\n\nThis could cause additional (usually avoidable) network requests to fetch data that were otherwise cached.\n\nTo address this problem (which is not a bug in Apollo Client), ").concat(l.length?"either ensure all objects of type "+l.join(" and ")+" have an ID or a custom merge function, or ":"","define a custom merge function for the ").concat(c," field, so InMemoryCache can safely merge these objects:\n\n existing: ").concat(JSON.stringify(a).slice(0,1e3),"\n incoming: ").concat(JSON.stringify(o).slice(0,1e3),"\n\nFor more information about these options, please refer to the documentation:\n\n * Ensuring entity objects have IDs: https://go.apollo.dev/c/generating-unique-identifiers\n * Defining custom merge functions: https://go.apollo.dev/c/merging-non-normalized-objects\n"))}}}}var an=function(e){function t(t){void 0===t&&(t={});var n=e.call(this)||this;return n.watches=new Set,n.typenameDocumentCache=new Map,n.makeVar=r2,n.txCount=0,n.config=ip(t),n.addTypename=!!n.config.addTypename,n.policies=new iQ({cache:n,dataIdFromObject:n.config.dataIdFromObject,possibleTypes:n.config.possibleTypes,typePolicies:n.config.typePolicies}),n.init(),n}return(0,en.ZT)(t,e),t.prototype.init=function(){var e=this.data=new iT.Root({policies:this.policies,resultCaching:this.config.resultCaching});this.optimisticData=e.stump,this.resetResultCache()},t.prototype.resetResultCache=function(e){var t=this,n=this.storeReader,r=this.config.fragments;this.storeWriter=new i4(this,this.storeReader=new iP({cache:this,addTypename:this.addTypename,resultCacheMaxSize:this.config.resultCacheMaxSize,canonizeResults:ib(this.config),canon:e?void 0:n&&n.canon,fragments:r}),r),this.maybeBroadcastWatch=rZ(function(e,n){return t.broadcastWatch(e,n)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var n=e.optimistic?t.optimisticData:t.data;if(iD(n)){var r=e.optimistic,i=e.id,a=e.variables;return n.makeCacheKey(e.query,e.callback,nx({optimistic:r,id:i,variables:a}))}}}),new Set([this.data.group,this.optimisticData.group,]).forEach(function(e){return e.resetCaching()})},t.prototype.restore=function(e){return this.init(),e&&this.data.replace(e),this},t.prototype.extract=function(e){return void 0===e&&(e=!1),(e?this.optimisticData:this.data).extract()},t.prototype.read=function(e){var t=e.returnPartialData,n=void 0!==t&&t;try{return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,config:this.config,returnPartialData:n})).result||null}catch(r){if(r instanceof is)return null;throw r}},t.prototype.write=function(e){try{return++this.txCount,this.storeWriter.writeToStore(this.data,e)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.modify=function(e){if(ic.call(e,"id")&&!e.id)return!1;var t=e.optimistic?this.optimisticData:this.data;try{return++this.txCount,t.modify(e.id||"ROOT_QUERY",e.fields)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.diff=function(e){return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,rootId:e.id||"ROOT_QUERY",config:this.config}))},t.prototype.watch=function(e){var t=this;return this.watches.size||r0(this),this.watches.add(e),e.immediate&&this.maybeBroadcastWatch(e),function(){t.watches.delete(e)&&!t.watches.size&&r1(t),t.maybeBroadcastWatch.forget(e)}},t.prototype.gc=function(e){nx.reset();var t=this.optimisticData.gc();return e&&!this.txCount&&(e.resetResultCache?this.resetResultCache(e.resetResultIdentities):e.resetResultIdentities&&this.storeReader.resetCanon()),t},t.prototype.retain=function(e,t){return(t?this.optimisticData:this.data).retain(e)},t.prototype.release=function(e,t){return(t?this.optimisticData:this.data).release(e)},t.prototype.identify=function(e){if(eD(e))return e.__ref;try{return this.policies.identify(e)[0]}catch(t){__DEV__&&Q.kG.warn(t)}},t.prototype.evict=function(e){if(!e.id){if(ic.call(e,"id"))return!1;e=(0,en.pi)((0,en.pi)({},e),{id:"ROOT_QUERY"})}try{return++this.txCount,this.optimisticData.evict(e,this.data)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.reset=function(e){var t=this;return this.init(),nx.reset(),e&&e.discardWatches?(this.watches.forEach(function(e){return t.maybeBroadcastWatch.forget(e)}),this.watches.clear(),r1(this)):this.broadcastWatches(),Promise.resolve()},t.prototype.removeOptimistic=function(e){var t=this.optimisticData.removeLayer(e);t!==this.optimisticData&&(this.optimisticData=t,this.broadcastWatches())},t.prototype.batch=function(e){var t,n=this,r=e.update,i=e.optimistic,a=void 0===i||i,o=e.removeOptimistic,s=e.onWatchUpdated,u=function(e){var i=n,a=i.data,o=i.optimisticData;++n.txCount,e&&(n.data=n.optimisticData=e);try{return t=r(n)}finally{--n.txCount,n.data=a,n.optimisticData=o}},c=new Set;return s&&!this.txCount&&this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e){return c.add(e),!1}})),"string"==typeof a?this.optimisticData=this.optimisticData.addLayer(a,u):!1===a?u(this.data):u(),"string"==typeof o&&(this.optimisticData=this.optimisticData.removeLayer(o)),s&&c.size?(this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e,t){var n=s.call(this,e,t);return!1!==n&&c.delete(e),n}})),c.size&&c.forEach(function(e){return n.maybeBroadcastWatch.dirty(e)})):this.broadcastWatches(e),t},t.prototype.performTransaction=function(e,t){return this.batch({update:e,optimistic:t||null!==t})},t.prototype.transformDocument=function(e){if(this.addTypename){var t=this.typenameDocumentCache.get(e);return t||(t=nj(e),this.typenameDocumentCache.set(e,t),this.typenameDocumentCache.set(t,t)),t}return e},t.prototype.transformForLink=function(e){var t=this.config.fragments;return t?t.transform(e):e},t.prototype.broadcastWatches=function(e){var t=this;this.txCount||this.watches.forEach(function(n){return t.maybeBroadcastWatch(n,e)})},t.prototype.broadcastWatch=function(e,t){var n=e.lastDiff,r=this.diff(e);(!t||(e.optimistic&&"string"==typeof t.optimistic&&(r.fromOptimisticTransaction=!0),!t.onWatchUpdated||!1!==t.onWatchUpdated.call(this,e,r,n)))&&(n&&(0,nm.D)(n.result,r.result)||e.callback(e.lastDiff=r,n))},t}(io),ar={possibleTypes:{ApproveJobProposalSpecPayload:["ApproveJobProposalSpecSuccess","JobAlreadyExistsError","NotFoundError"],BridgePayload:["Bridge","NotFoundError"],CancelJobProposalSpecPayload:["CancelJobProposalSpecSuccess","NotFoundError"],ChainPayload:["Chain","NotFoundError"],CreateAPITokenPayload:["CreateAPITokenSuccess","InputErrors"],CreateBridgePayload:["CreateBridgeSuccess"],CreateCSAKeyPayload:["CSAKeyExistsError","CreateCSAKeySuccess"],CreateFeedsManagerChainConfigPayload:["CreateFeedsManagerChainConfigSuccess","InputErrors","NotFoundError"],CreateFeedsManagerPayload:["CreateFeedsManagerSuccess","DuplicateFeedsManagerError","InputErrors","NotFoundError","SingleFeedsManagerError"],CreateJobPayload:["CreateJobSuccess","InputErrors"],CreateOCR2KeyBundlePayload:["CreateOCR2KeyBundleSuccess"],CreateOCRKeyBundlePayload:["CreateOCRKeyBundleSuccess"],CreateP2PKeyPayload:["CreateP2PKeySuccess"],DeleteAPITokenPayload:["DeleteAPITokenSuccess","InputErrors"],DeleteBridgePayload:["DeleteBridgeConflictError","DeleteBridgeInvalidNameError","DeleteBridgeSuccess","NotFoundError"],DeleteCSAKeyPayload:["DeleteCSAKeySuccess","NotFoundError"],DeleteFeedsManagerChainConfigPayload:["DeleteFeedsManagerChainConfigSuccess","NotFoundError"],DeleteJobPayload:["DeleteJobSuccess","NotFoundError"],DeleteOCR2KeyBundlePayload:["DeleteOCR2KeyBundleSuccess","NotFoundError"],DeleteOCRKeyBundlePayload:["DeleteOCRKeyBundleSuccess","NotFoundError"],DeleteP2PKeyPayload:["DeleteP2PKeySuccess","NotFoundError"],DeleteVRFKeyPayload:["DeleteVRFKeySuccess","NotFoundError"],DisableFeedsManagerPayload:["DisableFeedsManagerSuccess","NotFoundError"],DismissJobErrorPayload:["DismissJobErrorSuccess","NotFoundError"],EnableFeedsManagerPayload:["EnableFeedsManagerSuccess","NotFoundError"],Error:["CSAKeyExistsError","DeleteBridgeConflictError","DeleteBridgeInvalidNameError","DuplicateFeedsManagerError","InputError","JobAlreadyExistsError","NotFoundError","RunJobCannotRunError","SingleFeedsManagerError"],EthTransactionPayload:["EthTransaction","NotFoundError"],FeaturesPayload:["Features"],FeedsManagerPayload:["FeedsManager","NotFoundError"],GetSQLLoggingPayload:["SQLLogging"],GlobalLogLevelPayload:["GlobalLogLevel"],JobPayload:["Job","NotFoundError"],JobProposalPayload:["JobProposal","NotFoundError"],JobRunPayload:["JobRun","NotFoundError"],JobSpec:["BlockHeaderFeederSpec","BlockhashStoreSpec","BootstrapSpec","CronSpec","DirectRequestSpec","FluxMonitorSpec","GatewaySpec","KeeperSpec","OCR2Spec","OCRSpec","StandardCapabilitiesSpec","StreamSpec","VRFSpec","WebhookSpec","WorkflowSpec"],NodePayload:["Node","NotFoundError"],PaginatedPayload:["BridgesPayload","ChainsPayload","EthTransactionAttemptsPayload","EthTransactionsPayload","JobRunsPayload","JobsPayload","NodesPayload"],RejectJobProposalSpecPayload:["NotFoundError","RejectJobProposalSpecSuccess"],RunJobPayload:["NotFoundError","RunJobCannotRunError","RunJobSuccess"],SetGlobalLogLevelPayload:["InputErrors","SetGlobalLogLevelSuccess"],SetSQLLoggingPayload:["SetSQLLoggingSuccess"],SetServicesLogLevelsPayload:["InputErrors","SetServicesLogLevelsSuccess"],UpdateBridgePayload:["NotFoundError","UpdateBridgeSuccess"],UpdateFeedsManagerChainConfigPayload:["InputErrors","NotFoundError","UpdateFeedsManagerChainConfigSuccess"],UpdateFeedsManagerPayload:["InputErrors","NotFoundError","UpdateFeedsManagerSuccess"],UpdateJobProposalSpecDefinitionPayload:["NotFoundError","UpdateJobProposalSpecDefinitionSuccess"],UpdatePasswordPayload:["InputErrors","UpdatePasswordSuccess"],VRFKeyPayload:["NotFoundError","VRFKeySuccess"]}};let ai=ar;var aa=(r=void 0,location.origin),ao=new nh({uri:"".concat(aa,"/query"),credentials:"include"}),as=new ia({cache:new an({possibleTypes:ai.possibleTypes,dataIdFromObject:function(e){if("Chain"===e.__typename){if(!e.network)throw Error("Due to Chain ID not being unique across chain, ensure network is fetched too");return"Chain:".concat(e.network,":").concat(e.id)}return id(e)}}),link:ao});if(a.Z.locale(o),u().defaultFormat="YYYY-MM-DD h:mm:ss A","undefined"!=typeof document){var au,ac,al=f().hydrate;ac=X,al(c.createElement(et,{client:as},c.createElement(d.zj,null,c.createElement(i.MuiThemeProvider,{theme:J.r},c.createElement(ac,null)))),document.getElementById("root"))}})()})(); \ No newline at end of file diff --git a/core/web/assets/main.ec7b7e88c8c965c1e482.js.gz b/core/web/assets/main.008c37495ba29761321d.js.gz similarity index 92% rename from core/web/assets/main.ec7b7e88c8c965c1e482.js.gz rename to core/web/assets/main.008c37495ba29761321d.js.gz index 446f5f6ece1086536d9f91b9e5ce2fe96aeba416..c5cb981d0055351233b5b95ad14604dc0c02467b 100644 GIT binary patch delta 97083 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 Date: Tue, 10 Dec 2024 05:16:35 -0500 Subject: [PATCH 19/29] CCIP-4329 modify setChainRateLimiterConfig file for setting multiple rate limits (#15386) * modify setChainRateLimiterConfig file for setting multiple rate limits * Update gethwrappers * [Bot] Update changeset file with jira issues * snapshot fix * fix wrappers after merge * fix test that was broken in merge * fix liquidityManager snapshot which is affected by token pool changes * fix broken integration tests from removing critical setup function * add array length check for setChainRateLimitConfigs * formatting and snapshot fix * Update gethwrappers * simplify test setups * Update gethwrappers * update wrappers and snapshots which were broken in merge * Update gethwrappers * update wrappers and snapshot * changeset * snapshot update * Delete contracts/.changeset/orange-buckets-live.md * attempt fix changeset * attempt changeset fix with update pnpm package * re-add function that was removed early in PR to prevent any required tooling changes * update liquidityManager snapshot because of changes to token pools --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- contracts/.changeset/small-countries-flow.md | 5 + contracts/gas-snapshots/ccip.gas-snapshot | 127 ++++++++--------- .../liquiditymanager.gas-snapshot | 8 +- contracts/src/v0.8/ccip/pools/TokenPool.sol | 20 +++ ...TokenPool.setChainRateLimiterConfigs.t.sol | 128 ++++++++++++++++++ .../burn_from_mint_token_pool.go | 18 ++- .../burn_mint_token_pool.go | 18 ++- .../burn_with_from_mint_token_pool.go | 18 ++- .../lock_release_token_pool.go | 18 ++- .../ccip/generated/token_pool/token_pool.go | 16 ++- .../usdc_token_pool/usdc_token_pool.go | 18 ++- ...rapper-dependency-versions-do-not-edit.txt | 12 +- .../ccip-tests/contracts/contract_models.go | 7 +- 13 files changed, 329 insertions(+), 84 deletions(-) create mode 100644 contracts/.changeset/small-countries-flow.md create mode 100644 contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.setChainRateLimiterConfigs.t.sol diff --git a/contracts/.changeset/small-countries-flow.md b/contracts/.changeset/small-countries-flow.md new file mode 100644 index 00000000000..953102874bc --- /dev/null +++ b/contracts/.changeset/small-countries-flow.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +Modify TokenPool.sol function setChainRateLimiterConfig to now accept an array of configs and set sequentially. Requested by front-end. PR issue CCIP-4329 #bugfix diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 955000e016f..4ed7d38afd6 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -68,7 +68,7 @@ CCIPHome_setCandidate:test_setCandidate_success() (gas: 1365439) CCIPHome_supportsInterface:test_supportsInterface_success() (gas: 9885) DefensiveExampleTest:test_HappyPath_Success() (gas: 200540) DefensiveExampleTest:test_Recovery() (gas: 425013) -E2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1512127) +E2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1512391) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_fallbackToWethTransfer() (gas: 96980) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_happyPath() (gas: 49812) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_wrongToken() (gas: 17479) @@ -226,29 +226,29 @@ FeeQuoter_validateDestFamilyAddress:test_InvalidEVMAddressPrecompiles_Revert() ( FeeQuoter_validateDestFamilyAddress:test_InvalidEVMAddress_Revert() (gas: 10906) FeeQuoter_validateDestFamilyAddress:test_ValidEVMAddress_Success() (gas: 6841) FeeQuoter_validateDestFamilyAddress:test_ValidNonEVMAddress_Success() (gas: 6567) -HybridLockReleaseUSDCTokenPool_TransferLiquidity:test_cannotTransferLiquidityDuringPendingMigration_Revert() (gas: 176837) -HybridLockReleaseUSDCTokenPool_TransferLiquidity:test_transferLiquidity_Success() (gas: 166986) -HybridLockReleaseUSDCTokenPool_lockOrBurn:test_PrimaryMechanism_Success() (gas: 135860) -HybridLockReleaseUSDCTokenPool_lockOrBurn:test_WhileMigrationPause_Revert() (gas: 109696) -HybridLockReleaseUSDCTokenPool_lockOrBurn:test_onLockReleaseMechanism_Success() (gas: 146915) -HybridLockReleaseUSDCTokenPool_lockOrBurn:test_onLockReleaseMechanism_thenSwitchToPrimary_Success() (gas: 209124) +HybridLockReleaseUSDCTokenPool_TransferLiquidity:test_cannotTransferLiquidityDuringPendingMigration_Revert() (gas: 176859) +HybridLockReleaseUSDCTokenPool_TransferLiquidity:test_transferLiquidity_Success() (gas: 167004) +HybridLockReleaseUSDCTokenPool_lockOrBurn:test_PrimaryMechanism_Success() (gas: 135878) +HybridLockReleaseUSDCTokenPool_lockOrBurn:test_WhileMigrationPause_Revert() (gas: 109718) +HybridLockReleaseUSDCTokenPool_lockOrBurn:test_onLockReleaseMechanism_Success() (gas: 146937) +HybridLockReleaseUSDCTokenPool_lockOrBurn:test_onLockReleaseMechanism_thenSwitchToPrimary_Success() (gas: 209160) HybridLockReleaseUSDCTokenPool_releaseOrMint:test_OnLockReleaseMechanism_Success() (gas: 213127) HybridLockReleaseUSDCTokenPool_releaseOrMint:test_WhileMigrationPause_Revert() (gas: 109646) HybridLockReleaseUSDCTokenPool_releaseOrMint:test_incomingMessageWithPrimaryMechanism() (gas: 265910) -LockReleaseTokenPool_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3099863) +LockReleaseTokenPool_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3209936) LockReleaseTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 29734) LockReleaseTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Success() (gas: 80625) LockReleaseTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 59227) -LockReleaseTokenPool_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3096192) +LockReleaseTokenPool_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3206264) LockReleaseTokenPool_provideLiquidity:test_Unauthorized_Revert() (gas: 11511) LockReleaseTokenPool_releaseOrMint:test_ChainNotAllowed_Revert() (gas: 74100) LockReleaseTokenPool_releaseOrMint:test_PoolMintNotHealthy_Revert() (gas: 54745) LockReleaseTokenPool_releaseOrMint:test_ReleaseOrMint_Success() (gas: 223256) -LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Revert() (gas: 10936) -LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Success() (gas: 18115) +LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Revert() (gas: 11003) +LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Success() (gas: 18182) LockReleaseTokenPool_supportsInterface:test_SupportsInterface_Success() (gas: 10250) -LockReleaseTokenPool_transferLiquidity:test_transferLiquidity_Success() (gas: 83283) -LockReleaseTokenPool_transferLiquidity:test_transferLiquidity_transferTooMuch_Revert() (gas: 56056) +LockReleaseTokenPool_transferLiquidity:test_transferLiquidity_Success() (gas: 83328) +LockReleaseTokenPool_transferLiquidity:test_transferLiquidity_transferTooMuch_Revert() (gas: 56101) LockReleaseTokenPool_withdrawalLiquidity:test_InsufficientLiquidity_Revert() (gas: 60188) LockReleaseTokenPool_withdrawalLiquidity:test_Unauthorized_Revert() (gas: 11464) MerkleMultiProofTest:test_CVE_2023_34459() (gas: 5456) @@ -386,7 +386,7 @@ OffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 276839) OffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 168529) OffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 188173) OffRamp_batchExecute:test_SingleReport_Success() (gas: 156527) -OffRamp_batchExecute:test_Unhealthy_Success() (gas: 545255) +OffRamp_batchExecute:test_Unhealthy_Success() (gas: 545431) OffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10643) OffRamp_commit:test_CommitOnRampMismatch_Revert() (gas: 92450) OffRamp_commit:test_FailedRMNVerification_Reverts() (gas: 63117) @@ -429,12 +429,12 @@ OffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6933352) OffRamp_execute:test_ZeroReports_Revert() (gas: 17248) OffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens() (gas: 56213) OffRamp_executeSingleMessage:test_executeSingleMessage_NonContract() (gas: 20508) -OffRamp_executeSingleMessage:test_executeSingleMessage_NonContractWithTokens() (gas: 238042) +OffRamp_executeSingleMessage:test_executeSingleMessage_NonContractWithTokens() (gas: 238130) OffRamp_executeSingleMessage:test_executeSingleMessage_WithMessageInterceptor() (gas: 91994) -OffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens() (gas: 268135) +OffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens() (gas: 268223) OffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 28659) OffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 15530) -OffRamp_executeSingleReport:test_InvalidSourcePoolAddress() (gas: 474650) +OffRamp_executeSingleReport:test_InvalidSourcePoolAddress() (gas: 474738) OffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 48296) OffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 34101) OffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 28824) @@ -447,15 +447,15 @@ OffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: OffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 212456) OffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 243699) OffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 141510) -OffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 402534) +OffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 402622) OffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 58242) OffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 73812) -OffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 574160) -OffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 522711) +OffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 574336) +OffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 522887) OffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 26795) -OffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 540787) -OffRamp_executeSingleReport:test_Unhealthy_Success() (gas: 540734) -OffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 451824) +OffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 540963) +OffRamp_executeSingleReport:test_Unhealthy_Success() (gas: 540910) +OffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 452000) OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 135231) OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 164892) OffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3905742) @@ -482,20 +482,20 @@ OffRamp_releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: OffRamp_releaseOrMintSingleToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 36790) OffRamp_releaseOrMintSingleToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 91430) OffRamp_releaseOrMintSingleToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 83518) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens() (gas: 168784) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens() (gas: 168872) OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_RevertWhenInvalidDataLengthReturnData() (gas: 62822) OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_RevertWhenPoolDoesNotSupportDest() (gas: 78426) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_WithGasOverride() (gas: 170654) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals() (gas: 181893) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_WithGasOverride() (gas: 170742) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals() (gas: 181981) OffRamp_setDynamicConfig:test_FeeQuoterZeroAddress_Revert() (gas: 11465) OffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 13975) OffRamp_setDynamicConfig:test_SetDynamicConfigWithInterceptor_Success() (gas: 47491) OffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 25464) -OffRamp_trialExecute:test_trialExecute() (gas: 271771) -OffRamp_trialExecute:test_trialExecute_RateLimitError() (gas: 127457) -OffRamp_trialExecute:test_trialExecute_TokenHandlingErrorIsCaught() (gas: 138767) -OffRamp_trialExecute:test_trialExecute_TokenPoolIsNotAContract() (gas: 289412) -OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 251706) +OffRamp_trialExecute:test_trialExecute() (gas: 271859) +OffRamp_trialExecute:test_trialExecute_RateLimitError() (gas: 127545) +OffRamp_trialExecute:test_trialExecute_TokenHandlingErrorIsCaught() (gas: 138855) +OffRamp_trialExecute:test_trialExecute_TokenPoolIsNotAContract() (gas: 289500) +OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 251641) OnRamp_applyAllowlistUpdates:test_applyAllowlistUpdates_InvalidAllowListRequestDisabledAllowListWithAdds() (gas: 17227) OnRamp_applyAllowlistUpdates:test_applyAllowlistUpdates_Revert() (gas: 67101) OnRamp_applyAllowlistUpdates:test_applyAllowlistUpdates_Success() (gas: 325983) @@ -525,7 +525,7 @@ OnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: OnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 213144) OnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 147070) OnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 161303) -OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3963792) +OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 4073863) OnRamp_forwardFromRouter:test_UnAllowedOriginalSender_Revert() (gas: 24015) OnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 75854) OnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 38588) @@ -671,14 +671,14 @@ TokenAdminRegistry_setPool:test_setPool_ZeroAddressRemovesPool_Success() (gas: 3 TokenAdminRegistry_transferAdminRole:test_transferAdminRole_OnlyAdministrator_Revert() (gas: 18202) TokenAdminRegistry_transferAdminRole:test_transferAdminRole_Success() (gas: 49592) TokenPoolFactory_constructor:test_constructor_Revert() (gas: 1121653) -TokenPoolFactory_createTokenPool:test_createTokenPoolLockRelease_ExistingToken_predict_Success() (gas: 12386310) -TokenPoolFactory_createTokenPool:test_createTokenPool_BurnFromMintTokenPool_Success() (gas: 6364709) -TokenPoolFactory_createTokenPool:test_createTokenPool_ExistingRemoteToken_AndPredictPool_Success() (gas: 13167390) -TokenPoolFactory_createTokenPool:test_createTokenPool_RemoteTokenHasDifferentDecimals_Success() (gas: 13174692) -TokenPoolFactory_createTokenPool:test_createTokenPool_WithNoExistingRemoteContracts_predict_Success() (gas: 13504109) -TokenPoolFactory_createTokenPool:test_createTokenPool_WithNoExistingTokenOnRemoteChain_Success() (gas: 6150583) -TokenPoolFactory_createTokenPool:test_createTokenPool_WithRemoteTokenAndRemotePool_Success() (gas: 6361166) -TokenPoolWithAllowList_applyAllowListUpdates:test_AllowListNotEnabled_Revert() (gas: 2717776) +TokenPoolFactory_createTokenPool:test_createTokenPoolLockRelease_ExistingToken_predict_Success() (gas: 12612969) +TokenPoolFactory_createTokenPool:test_createTokenPool_BurnFromMintTokenPool_Success() (gas: 6513874) +TokenPoolFactory_createTokenPool:test_createTokenPool_ExistingRemoteToken_AndPredictPool_Success() (gas: 13434268) +TokenPoolFactory_createTokenPool:test_createTokenPool_RemoteTokenHasDifferentDecimals_Success() (gas: 13441570) +TokenPoolFactory_createTokenPool:test_createTokenPool_WithNoExistingRemoteContracts_predict_Success() (gas: 13771048) +TokenPoolFactory_createTokenPool:test_createTokenPool_WithNoExistingTokenOnRemoteChain_Success() (gas: 6301066) +TokenPoolFactory_createTokenPool:test_createTokenPool_WithRemoteTokenAndRemotePool_Success() (gas: 6510314) +TokenPoolWithAllowList_applyAllowListUpdates:test_AllowListNotEnabled_Revert() (gas: 2827849) TokenPoolWithAllowList_applyAllowListUpdates:test_OnlyOwner_Revert() (gas: 12119) TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowListSkipsZero_Success() (gas: 23567) TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowList_Success() (gas: 178398) @@ -699,7 +699,7 @@ TokenPool_applyChainUpdates:test_applyChainUpdates_UpdatesRemotePoolHashes() (ga TokenPool_applyChainUpdates:test_applyChainUpdates_ZeroAddressNotAllowed_Revert() (gas: 226472) TokenPool_calculateLocalAmount:test_calculateLocalAmount() (gas: 93680) TokenPool_constructor:test_constructor() (gas: 21930) -TokenPool_constructor:test_constructor_DecimalCallFails() (gas: 2714089) +TokenPool_constructor:test_constructor_DecimalCallFails() (gas: 2824157) TokenPool_getRemotePool:test_getRemotePools() (gas: 330500) TokenPool_onlyOffRamp:test_CallerIsNotARampOnRouter_Revert() (gas: 21504) TokenPool_onlyOffRamp:test_ChainNotAllowed_Revert() (gas: 240435) @@ -714,44 +714,47 @@ TokenPool_removeRemotePool:test_NonExistentChain_Revert() (gas: 14344) TokenPool_removeRemotePool:test_removeRemotePool_Success() (gas: 188387) TokenPool_setChainRateLimiterConfig:test_NonExistentChain_Revert() (gas: 17214) TokenPool_setChainRateLimiterConfig:test_OnlyOwnerOrRateLimitAdmin_Revert() (gas: 15307) +TokenPool_setChainRateLimiterConfigs:test_MismatchedArrayLengths_Revert() (gas: 23960) +TokenPool_setChainRateLimiterConfigs:test_NonExistentChain_Revert() (gas: 19424) +TokenPool_setChainRateLimiterConfigs:test_OnlyOwnerOrRateLimitAdmin_Revert() (gas: 16511) TokenPool_setRateLimitAdmin:test_SetRateLimitAdmin_Revert() (gas: 11002) TokenPool_setRateLimitAdmin:test_SetRateLimitAdmin_Success() (gas: 37606) -USDCBridgeMigrator_BurnLockedUSDC:test_PrimaryMechanism_Success() (gas: 135869) -USDCBridgeMigrator_BurnLockedUSDC:test_WhileMigrationPause_Revert() (gas: 109729) +USDCBridgeMigrator_BurnLockedUSDC:test_PrimaryMechanism_Success() (gas: 135887) +USDCBridgeMigrator_BurnLockedUSDC:test_WhileMigrationPause_Revert() (gas: 109751) USDCBridgeMigrator_BurnLockedUSDC:test_invalidPermissions_Revert() (gas: 39493) -USDCBridgeMigrator_BurnLockedUSDC:test_lockOrBurn_then_BurnInCCTPMigration_Success() (gas: 309798) -USDCBridgeMigrator_BurnLockedUSDC:test_onLockReleaseMechanism_Success() (gas: 146939) -USDCBridgeMigrator_BurnLockedUSDC:test_onLockReleaseMechanism_thenSwitchToPrimary_Success() (gas: 209089) +USDCBridgeMigrator_BurnLockedUSDC:test_lockOrBurn_then_BurnInCCTPMigration_Success() (gas: 309833) +USDCBridgeMigrator_BurnLockedUSDC:test_onLockReleaseMechanism_Success() (gas: 146961) +USDCBridgeMigrator_BurnLockedUSDC:test_onLockReleaseMechanism_thenSwitchToPrimary_Success() (gas: 209124) USDCBridgeMigrator_cancelMigrationProposal:test_cancelExistingCCTPMigrationProposal_Success() (gas: 56155) USDCBridgeMigrator_cancelMigrationProposal:test_cannotCancelANonExistentMigrationProposal_Revert() (gas: 12669) USDCBridgeMigrator_excludeTokensFromBurn:test_excludeTokensWhenNoMigrationProposalPending_Revert() (gas: 13579) USDCBridgeMigrator_proposeMigration:test_ChainNotUsingLockRelease_Revert() (gas: 15765) -USDCBridgeMigrator_provideLiquidity:test_PrimaryMechanism_Success() (gas: 135986) -USDCBridgeMigrator_provideLiquidity:test_WhileMigrationPause_Revert() (gas: 109871) +USDCBridgeMigrator_provideLiquidity:test_PrimaryMechanism_Success() (gas: 136004) +USDCBridgeMigrator_provideLiquidity:test_WhileMigrationPause_Revert() (gas: 109893) USDCBridgeMigrator_provideLiquidity:test_cannotModifyLiquidityWithoutPermissions_Revert() (gas: 13390) USDCBridgeMigrator_provideLiquidity:test_cannotProvideLiquidityWhenMigrationProposalPending_Revert() (gas: 67428) -USDCBridgeMigrator_provideLiquidity:test_cannotProvideLiquidity_AfterMigration_Revert() (gas: 313898) +USDCBridgeMigrator_provideLiquidity:test_cannotProvideLiquidity_AfterMigration_Revert() (gas: 313933) USDCBridgeMigrator_provideLiquidity:test_invalidPermissions_Revert() (gas: 39493) -USDCBridgeMigrator_provideLiquidity:test_lockOrBurn_then_BurnInCCTPMigration_Success() (gas: 310057) -USDCBridgeMigrator_provideLiquidity:test_onLockReleaseMechanism_Success() (gas: 147080) -USDCBridgeMigrator_provideLiquidity:test_onLockReleaseMechanism_thenSwitchToPrimary_Success() (gas: 209395) +USDCBridgeMigrator_provideLiquidity:test_lockOrBurn_then_BurnInCCTPMigration_Success() (gas: 310092) +USDCBridgeMigrator_provideLiquidity:test_onLockReleaseMechanism_Success() (gas: 147102) +USDCBridgeMigrator_provideLiquidity:test_onLockReleaseMechanism_thenSwitchToPrimary_Success() (gas: 209430) USDCBridgeMigrator_releaseOrMint:test_OnLockReleaseMechanism_Success() (gas: 213160) USDCBridgeMigrator_releaseOrMint:test_WhileMigrationPause_Revert() (gas: 109679) USDCBridgeMigrator_releaseOrMint:test_incomingMessageWithPrimaryMechanism() (gas: 265963) USDCBridgeMigrator_releaseOrMint:test_unstickManualTxAfterMigration_destChain_Success() (gas: 150538) USDCBridgeMigrator_releaseOrMint:test_unstickManualTxAfterMigration_homeChain_Success() (gas: 511783) -USDCBridgeMigrator_updateChainSelectorMechanism:test_PrimaryMechanism_Success() (gas: 136004) -USDCBridgeMigrator_updateChainSelectorMechanism:test_WhileMigrationPause_Revert() (gas: 109849) -USDCBridgeMigrator_updateChainSelectorMechanism:test_cannotRevertChainMechanism_afterMigration_Revert() (gas: 313496) +USDCBridgeMigrator_updateChainSelectorMechanism:test_PrimaryMechanism_Success() (gas: 136021) +USDCBridgeMigrator_updateChainSelectorMechanism:test_WhileMigrationPause_Revert() (gas: 109871) +USDCBridgeMigrator_updateChainSelectorMechanism:test_cannotRevertChainMechanism_afterMigration_Revert() (gas: 313532) USDCBridgeMigrator_updateChainSelectorMechanism:test_invalidPermissions_Revert() (gas: 39471) -USDCBridgeMigrator_updateChainSelectorMechanism:test_lockOrBurn_then_BurnInCCTPMigration_Success() (gas: 310057) -USDCBridgeMigrator_updateChainSelectorMechanism:test_onLockReleaseMechanism_Success() (gas: 147035) -USDCBridgeMigrator_updateChainSelectorMechanism:test_onLockReleaseMechanism_thenSwitchToPrimary_Success() (gas: 209448) +USDCBridgeMigrator_updateChainSelectorMechanism:test_lockOrBurn_then_BurnInCCTPMigration_Success() (gas: 310092) +USDCBridgeMigrator_updateChainSelectorMechanism:test_onLockReleaseMechanism_Success() (gas: 147057) +USDCBridgeMigrator_updateChainSelectorMechanism:test_onLockReleaseMechanism_thenSwitchToPrimary_Success() (gas: 209483) USDCTokenPool__validateMessage:test_ValidateInvalidMessage_Revert() (gas: 26049) -USDCTokenPool_lockOrBurn:test_CallerIsNotARampOnRouter_Revert() (gas: 35297) -USDCTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 29875) -USDCTokenPool_lockOrBurn:test_LockOrBurn_Success() (gas: 133408) -USDCTokenPool_lockOrBurn:test_UnknownDomain_Revert() (gas: 433408) +USDCTokenPool_lockOrBurn:test_CallerIsNotARampOnRouter_Revert() (gas: 35319) +USDCTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 29897) +USDCTokenPool_lockOrBurn:test_LockOrBurn_Success() (gas: 133426) +USDCTokenPool_lockOrBurn:test_UnknownDomain_Revert() (gas: 433430) USDCTokenPool_releaseOrMint:test_ReleaseOrMintRealTx_Success() (gas: 265695) USDCTokenPool_releaseOrMint:test_TokenMaxCapacityExceeded_Revert() (gas: 47231) USDCTokenPool_releaseOrMint:test_UnlockingUSDCFailed_Revert() (gas: 95262) diff --git a/contracts/gas-snapshots/liquiditymanager.gas-snapshot b/contracts/gas-snapshots/liquiditymanager.gas-snapshot index 2e2d0962186..bc545b69d38 100644 --- a/contracts/gas-snapshots/liquiditymanager.gas-snapshot +++ b/contracts/gas-snapshots/liquiditymanager.gas-snapshot @@ -3,9 +3,9 @@ LiquidityManager_addLiquidity:test_addLiquiditySuccess() (gas: 279198) LiquidityManager_rebalanceLiquidity:test_InsufficientLiquidityReverts() (gas: 206764) LiquidityManager_rebalanceLiquidity:test_InvalidRemoteChainReverts() (gas: 192374) LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess() (gas: 9141798) -LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess_AlreadyFinalized() (gas: 9306766) -LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_MultiStageFinalization() (gas: 9301906) -LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_NativeRewrap() (gas: 9231739) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess_AlreadyFinalized() (gas: 9435757) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_MultiStageFinalization() (gas: 9430897) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_NativeRewrap() (gas: 9360730) LiquidityManager_rebalanceLiquidity:test_rebalanceLiquiditySuccess() (gas: 382928) LiquidityManager_receive:test_receive_success() (gas: 21182) LiquidityManager_removeLiquidity:test_InsufficientLiquidityReverts() (gas: 184959) @@ -19,7 +19,7 @@ LiquidityManager_setFinanceRole:test_OnlyOwnerReverts() (gas: 10987) LiquidityManager_setFinanceRole:test_setFinanceRoleSuccess() (gas: 21836) LiquidityManager_setLocalLiquidityContainer:test_OnlyOwnerReverts() (gas: 11030) LiquidityManager_setLocalLiquidityContainer:test_ReverstWhen_CalledWithTheZeroAddress() (gas: 10621) -LiquidityManager_setLocalLiquidityContainer:test_setLocalLiquidityContainerSuccess() (gas: 3847203) +LiquidityManager_setLocalLiquidityContainer:test_setLocalLiquidityContainerSuccess() (gas: 3976150) LiquidityManager_setMinimumLiquidity:test_OnlyOwnerReverts() (gas: 10925) LiquidityManager_setMinimumLiquidity:test_setMinimumLiquiditySuccess() (gas: 36389) LiquidityManager_withdrawERC20:test_withdrawERC20Reverts() (gas: 180396) diff --git a/contracts/src/v0.8/ccip/pools/TokenPool.sol b/contracts/src/v0.8/ccip/pools/TokenPool.sol index 69bab031f57..9d8e77a7928 100644 --- a/contracts/src/v0.8/ccip/pools/TokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/TokenPool.sol @@ -52,6 +52,7 @@ abstract contract TokenPool is IPoolV1, Ownable2StepMsgSender { error PoolAlreadyAdded(uint64 remoteChainSelector, bytes remotePoolAddress); error InvalidRemotePoolForChain(uint64 remoteChainSelector, bytes remotePoolAddress); error InvalidRemoteChainDecimals(bytes sourcePoolData); + error MismatchedArrayLengths(); error OverflowDetected(uint8 remoteDecimals, uint8 localDecimals, uint256 remoteAmount); error InvalidDecimalArgs(uint8 expected, uint8 actual); @@ -536,6 +537,25 @@ abstract contract TokenPool is IPoolV1, Ownable2StepMsgSender { return s_remoteChainConfigs[remoteChainSelector].inboundRateLimiterConfig._currentTokenBucketState(); } + /// @notice Sets multiple chain rate limiter configs. + /// @param remoteChainSelectors The remote chain selector for which the rate limits apply. + /// @param outboundConfigs The new outbound rate limiter config, meaning the onRamp rate limits for the given chain. + /// @param inboundConfigs The new inbound rate limiter config, meaning the offRamp rate limits for the given chain. + function setChainRateLimiterConfigs( + uint64[] calldata remoteChainSelectors, + RateLimiter.Config[] calldata outboundConfigs, + RateLimiter.Config[] calldata inboundConfigs + ) external { + if (msg.sender != s_rateLimitAdmin && msg.sender != owner()) revert Unauthorized(msg.sender); + if (remoteChainSelectors.length != outboundConfigs.length || remoteChainSelectors.length != inboundConfigs.length) { + revert MismatchedArrayLengths(); + } + + for (uint256 i = 0; i < remoteChainSelectors.length; ++i) { + _setRateLimitConfig(remoteChainSelectors[i], outboundConfigs[i], inboundConfigs[i]); + } + } + /// @notice Sets the chain rate limiter config. /// @param remoteChainSelector The remote chain selector for which the rate limits apply. /// @param outboundConfig The new outbound rate limiter config, meaning the onRamp rate limits for the given chain. diff --git a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.setChainRateLimiterConfigs.t.sol b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.setChainRateLimiterConfigs.t.sol new file mode 100644 index 00000000000..716e06734ee --- /dev/null +++ b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.setChainRateLimiterConfigs.t.sol @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {RateLimiter} from "../../../libraries/RateLimiter.sol"; +import {TokenPool} from "../../../pools/TokenPool.sol"; +import {TokenPoolSetup} from "./TokenPoolSetup.t.sol"; + +contract TokenPool_setChainRateLimiterConfigs is TokenPoolSetup { + uint64 internal s_remoteChainSelector; + + function setUp() public virtual override { + TokenPoolSetup.setUp(); + + bytes[] memory remotePoolAddresses = new bytes[](1); + remotePoolAddresses[0] = abi.encode(address(2)); + + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); + s_remoteChainSelector = 123124; + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: s_remoteChainSelector, + remotePoolAddresses: remotePoolAddresses, + remoteTokenAddress: abi.encode(address(3)), + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() + }); + s_tokenPool.applyChainUpdates(new uint64[](0), chainUpdates); + } + + function testFuzz_SetChainRateLimiterConfigs_Success(uint128 capacity, uint128 rate, uint32 newTime) public { + // Cap the lower bound to 4 so 4/2 is still >= 2 + vm.assume(capacity >= 4); + // Cap the lower bound to 2 so 2/2 is still >= 1 + rate = uint128(bound(rate, 2, capacity - 2)); + // Bucket updates only work on increasing time + newTime = uint32(bound(newTime, block.timestamp + 1, type(uint32).max)); + vm.warp(newTime); + + uint256 oldOutboundTokens = s_tokenPool.getCurrentOutboundRateLimiterState(DEST_CHAIN_SELECTOR).tokens; + uint256 oldInboundTokens = s_tokenPool.getCurrentInboundRateLimiterState(DEST_CHAIN_SELECTOR).tokens; + + RateLimiter.Config memory newOutboundConfig = RateLimiter.Config({isEnabled: true, capacity: capacity, rate: rate}); + RateLimiter.Config memory newInboundConfig = + RateLimiter.Config({isEnabled: true, capacity: capacity / 2, rate: rate / 2}); + + uint64[] memory chainSelectors = new uint64[](1); + chainSelectors[0] = DEST_CHAIN_SELECTOR; + + RateLimiter.Config[] memory newOutboundConfigs = new RateLimiter.Config[](1); + newOutboundConfigs[0] = newOutboundConfig; + + RateLimiter.Config[] memory newInboundConfigs = new RateLimiter.Config[](1); + newInboundConfigs[0] = newInboundConfig; + + vm.expectEmit(); + emit RateLimiter.ConfigChanged(newOutboundConfig); + vm.expectEmit(); + emit RateLimiter.ConfigChanged(newInboundConfig); + vm.expectEmit(); + emit TokenPool.ChainConfigured(DEST_CHAIN_SELECTOR, newOutboundConfig, newInboundConfig); + + s_tokenPool.setChainRateLimiterConfigs(chainSelectors, newOutboundConfigs, newInboundConfigs); + + uint256 expectedTokens = RateLimiter._min(newOutboundConfig.capacity, oldOutboundTokens); + + RateLimiter.TokenBucket memory bucket = s_tokenPool.getCurrentOutboundRateLimiterState(DEST_CHAIN_SELECTOR); + assertEq(bucket.capacity, newOutboundConfig.capacity); + assertEq(bucket.rate, newOutboundConfig.rate); + assertEq(bucket.tokens, expectedTokens); + assertEq(bucket.lastUpdated, newTime); + + expectedTokens = RateLimiter._min(newInboundConfig.capacity, oldInboundTokens); + + bucket = s_tokenPool.getCurrentInboundRateLimiterState(DEST_CHAIN_SELECTOR); + assertEq(bucket.capacity, newInboundConfig.capacity); + assertEq(bucket.rate, newInboundConfig.rate); + assertEq(bucket.tokens, expectedTokens); + assertEq(bucket.lastUpdated, newTime); + } + + // Reverts + + function test_OnlyOwnerOrRateLimitAdmin_Revert() public { + uint64[] memory chainSelectors = new uint64[](1); + chainSelectors[0] = DEST_CHAIN_SELECTOR; + + RateLimiter.Config[] memory newOutboundConfigs = new RateLimiter.Config[](1); + newOutboundConfigs[0] = _getOutboundRateLimiterConfig(); + + RateLimiter.Config[] memory newInboundConfigs = new RateLimiter.Config[](1); + newInboundConfigs[0] = _getInboundRateLimiterConfig(); + + vm.startPrank(STRANGER); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.Unauthorized.selector, STRANGER)); + s_tokenPool.setChainRateLimiterConfigs(chainSelectors, newOutboundConfigs, newInboundConfigs); + } + + function test_NonExistentChain_Revert() public { + uint64 wrongChainSelector = 9084102894; + + uint64[] memory chainSelectors = new uint64[](1); + chainSelectors[0] = wrongChainSelector; + + RateLimiter.Config[] memory newOutboundConfigs = new RateLimiter.Config[](1); + RateLimiter.Config[] memory newInboundConfigs = new RateLimiter.Config[](1); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.NonExistentChain.selector, wrongChainSelector)); + s_tokenPool.setChainRateLimiterConfigs(chainSelectors, newOutboundConfigs, newInboundConfigs); + } + + function test_MismatchedArrayLengths_Revert() public { + uint64[] memory chainSelectors = new uint64[](1); + + RateLimiter.Config[] memory newOutboundConfigs = new RateLimiter.Config[](1); + RateLimiter.Config[] memory newInboundConfigs = new RateLimiter.Config[](2); + + // test mismatched array lengths between rate limiters + vm.expectRevert(abi.encodeWithSelector(TokenPool.MismatchedArrayLengths.selector)); + s_tokenPool.setChainRateLimiterConfigs(chainSelectors, newOutboundConfigs, newInboundConfigs); + + newInboundConfigs = new RateLimiter.Config[](1); + chainSelectors = new uint64[](2); + + // test mismatched array lengths between chain selectors and rate limiters + vm.expectRevert(abi.encodeWithSelector(TokenPool.MismatchedArrayLengths.selector)); + s_tokenPool.setChainRateLimiterConfigs(chainSelectors, newOutboundConfigs, newInboundConfigs); + } +} diff --git a/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go index def5c4bc258..884dc9e52e5 100644 --- a/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go @@ -81,8 +81,8 @@ type TokenPoolChainUpdate struct { } var BurnFromMintTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"localTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"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\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"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\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"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\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"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\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"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\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"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\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"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\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"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\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"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\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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: "0x6101006040523480156200001257600080fd5b5060405162004c6338038062004c63833981016040819052620000359162000918565b8484848484336000816200005c57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008f576200008f8162000206565b50506001600160a01b0385161580620000af57506001600160a01b038116155b80620000c257506001600160a01b038216155b15620000e1576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808616608081905290831660c0526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa92505050801562000151575060408051601f3d908101601f191682019092526200014e9181019062000a3a565b60015b1562000192578060ff168560ff161462000190576040516332ad3e0760e11b815260ff8087166004830152821660248201526044015b60405180910390fd5b505b60ff841660a052600480546001600160a01b0319166001600160a01b038316179055825115801560e052620001dc57604080516000815260208101909152620001dc908462000280565b50620001fb935050506001600160a01b038716905030600019620003dd565b505050505062000b84565b336001600160a01b038216036200023057604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e051620002a1576040516335f4a7b360e01b815260040160405180910390fd5b60005b82518110156200032c576000838281518110620002c557620002c562000a58565b60209081029190910101519050620002df600282620004c3565b1562000322576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620002a4565b5060005b8151811015620003d857600082828151811062000351576200035162000a58565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200037d5750620003cf565b6200038a600282620004e3565b15620003cd576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000330565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa1580156200042f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000455919062000a6e565b62000461919062000a9e565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b17909152919250620004bd91869190620004fa16565b50505050565b6000620004da836001600160a01b038416620005cb565b90505b92915050565b6000620004da836001600160a01b038416620006cf565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000549906001600160a01b03851690849062000721565b805190915015620003d857808060200190518101906200056a919062000ab4565b620003d85760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000187565b60008181526001830160205260408120548015620006c4576000620005f260018362000adf565b8554909150600090620006089060019062000adf565b9050808214620006745760008660000182815481106200062c576200062c62000a58565b906000526020600020015490508087600001848154811062000652576200065262000a58565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000688576200068862000af5565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620004dd565b6000915050620004dd565b60008181526001830160205260408120546200071857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620004dd565b506000620004dd565b60606200073284846000856200073a565b949350505050565b6060824710156200079d5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000187565b600080866001600160a01b03168587604051620007bb919062000b31565b60006040518083038185875af1925050503d8060008114620007fa576040519150601f19603f3d011682016040523d82523d6000602084013e620007ff565b606091505b50909250905062000813878383876200081e565b979650505050505050565b60608315620008925782516000036200088a576001600160a01b0385163b6200088a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000187565b508162000732565b620007328383815115620008a95781518083602001fd5b8060405162461bcd60e51b815260040162000187919062000b4f565b6001600160a01b0381168114620008db57600080fd5b50565b805160ff81168114620008f057600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b8051620008f081620008c5565b600080600080600060a086880312156200093157600080fd5b85516200093e81620008c5565b945060206200094f878201620008de565b60408801519095506001600160401b03808211156200096d57600080fd5b818901915089601f8301126200098257600080fd5b815181811115620009975762000997620008f5565b8060051b604051601f19603f83011681018181108582111715620009bf57620009bf620008f5565b60405291825284820192508381018501918c831115620009de57600080fd5b938501935b8285101562000a0757620009f7856200090b565b84529385019392850192620009e3565b80985050505050505062000a1e606087016200090b565b915062000a2e608087016200090b565b90509295509295909350565b60006020828403121562000a4d57600080fd5b620004da82620008de565b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000a8157600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115620004dd57620004dd62000a88565b60006020828403121562000ac757600080fd5b8151801515811462000ad857600080fd5b9392505050565b81810381811115620004dd57620004dd62000a88565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000b2857818101518382015260200162000b0e565b50506000910152565b6000825162000b4581846020870162000b0b565b9190910192915050565b602081526000825180602084015262000b7081604085016020870162000b0b565b601f01601f19169190910160400192915050565b60805160a05160c05160e05161402e62000c356000396000818161054f01528181611d8201526127d30152600081816105290152818161189f015261206e0152600081816102e001528181610ba901528181611a4801528181611b0201528181611b3601528181611b6901528181611bce01528181611c270152611cc90152600081816102470152818161029c01528181610708015281816121f10152818161276901526129be015261402e6000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639a4575b911610104578063c0d78655116100a2578063dc0bd97111610071578063dc0bd97114610527578063e0351e131461054d578063e8a1da1714610573578063f2fde38b1461058657600080fd5b8063c0d78655146104d9578063c4bffe2b146104ec578063c75eea9c14610501578063cf7401f31461051457600080fd5b8063acfecf91116100de578063acfecf9114610426578063af58d59f14610439578063b0f479a1146104a8578063b7946580146104c657600080fd5b80639a4575b9146103d1578063a42a7b8b146103f1578063a7cd63b71461041157600080fd5b806354c8a4f31161017157806379ba50971161014b57806379ba5097146103855780637d54534e1461038d5780638926f54f146103a05780638da5cb5b146103b357600080fd5b806354c8a4f31461033f57806362ddd3c4146103545780636d3d1a581461036757600080fd5b8063240028e8116101ad578063240028e81461028c57806324f65ee7146102d9578063390775371461030a5780634c5ef0ed1461032c57600080fd5b806301ffc9a7146101d4578063181f5a77146101fc57806321df0da714610245575b600080fd5b6101e76101e236600461317e565b610599565b60405190151581526020015b60405180910390f35b6102386040518060400160405280601b81526020017f4275726e46726f6d4d696e74546f6b656e506f6f6c20312e352e31000000000081525081565b6040516101f39190613224565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b6101e761029a366004613259565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101f3565b61031d610318366004613276565b61067e565b604051905181526020016101f3565b6101e761033a3660046132cf565b61084d565b61035261034d36600461339e565b610897565b005b6103526103623660046132cf565b610912565b60095473ffffffffffffffffffffffffffffffffffffffff16610267565b6103526109af565b61035261039b366004613259565b610a7d565b6101e76103ae36600461340a565b610afe565b60015473ffffffffffffffffffffffffffffffffffffffff16610267565b6103e46103df366004613425565b610b15565b6040516101f39190613460565b6104046103ff36600461340a565b610bee565b6040516101f391906134b7565b610419610d59565b6040516101f39190613539565b6103526104343660046132cf565b610d6a565b61044c61044736600461340a565b610e82565b6040516101f3919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610267565b6102386104d436600461340a565b610f57565b6103526104e7366004613259565b611007565b6104f46110e2565b6040516101f39190613593565b61044c61050f36600461340a565b61119a565b61035261052236600461371b565b61126c565b7f0000000000000000000000000000000000000000000000000000000000000000610267565b7f00000000000000000000000000000000000000000000000000000000000000006101e7565b61035261058136600461339e565b6112f0565b610352610594366004613259565b611802565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061062c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061067857507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b60408051602081019091526000815261069682611816565b60006106ef60608401356106ea6106b060c0870187613760565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a3a92505050565b611afe565b905073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f1961073d6060860160408701613259565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260248101849052604401600060405180830381600087803b1580156107aa57600080fd5b505af11580156107be573d6000803e3d6000fd5b506107d3925050506060840160408501613259565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08360405161083191815260200190565b60405180910390a3604080516020810190915290815292915050565b600061088f83836040516108629291906137c5565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190611d12565b949350505050565b61089f611d2d565b61090c84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611d8092505050565b50505050565b61091a611d2d565b61092383610afe565b61096a576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6109aa8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611f3692505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a00576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610a85611d2d565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b6000610678600567ffffffffffffffff8416611d12565b6040805180820190915260608082526020820152610b3282612030565b610b3f82606001356121bc565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610b998460200160208101906104d4919061340a565b8152602001610be66040805160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260609101604051602081830303815290604052905090565b905292915050565b67ffffffffffffffff8116600090815260076020526040812060609190610c179060050161225e565b90506000815167ffffffffffffffff811115610c3557610c356135d5565b604051908082528060200260200182016040528015610c6857816020015b6060815260200190600190039081610c535790505b50905060005b8251811015610d515760086000848381518110610c8d57610c8d6137d5565b602002602001015181526020019081526020016000208054610cae90613804565b80601f0160208091040260200160405190810160405280929190818152602001828054610cda90613804565b8015610d275780601f10610cfc57610100808354040283529160200191610d27565b820191906000526020600020905b815481529060010190602001808311610d0a57829003601f168201915b5050505050828281518110610d3e57610d3e6137d5565b6020908102919091010152600101610c6e565b509392505050565b6060610d65600261225e565b905090565b610d72611d2d565b610d7b83610afe565b610dbd576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610961565b610dfd8282604051610dd09291906137c5565b604080519182900390912067ffffffffffffffff861660009081526007602052919091206005019061226b565b610e39578282826040517f74f23c7c000000000000000000000000000000000000000000000000000000008152600401610961939291906138a0565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d768383604051610e759291906138c4565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261067890612277565b67ffffffffffffffff81166000908152600760205260409020600401805460609190610f8290613804565b80601f0160208091040260200160405190810160405280929190818152602001828054610fae90613804565b8015610ffb5780601f10610fd057610100808354040283529160200191610ffb565b820191906000526020600020905b815481529060010190602001808311610fde57829003601f168201915b50505050509050919050565b61100f611d2d565b73ffffffffffffffffffffffffffffffffffffffff811661105c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006110f0600561225e565b90506000815167ffffffffffffffff81111561110e5761110e6135d5565b604051908082528060200260200182016040528015611137578160200160208202803683370190505b50905060005b825181101561119357828181518110611158576111586137d5565b6020026020010151828281518110611172576111726137d5565b67ffffffffffffffff9092166020928302919091019091015260010161113d565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261067890612277565b60095473ffffffffffffffffffffffffffffffffffffffff1633148015906112ac575060015473ffffffffffffffffffffffffffffffffffffffff163314155b156112e5576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610961565b6109aa838383612329565b6112f8611d2d565b60005b838110156114e5576000858583818110611317576113176137d5565b905060200201602081019061132c919061340a565b9050611343600567ffffffffffffffff831661226b565b611385576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610961565b67ffffffffffffffff811660009081526007602052604081206113aa9060050161225e565b905060005b81518110156114165761140d8282815181106113cd576113cd6137d5565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060050161226b90919063ffffffff16565b506001016113af565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff0000000000000000000000000000000000000000009081168255600182018390556002820180549091169055600381018290559061147f6004830182613111565b6005820160008181611491828261314b565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916945060200192506114d3915050565b60405180910390a150506001016112fb565b5060005b818110156117fb576000838383818110611505576115056137d5565b905060200281019061151791906138d8565b611520906139a4565b905061153181606001516000612413565b61154081608001516000612413565b80604001515160000361157f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516115979060059067ffffffffffffffff16612550565b6115dc5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610961565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a90910299909316171790941695909517909255909202909117600382015590820151600482019061175f9082613b1b565b5060005b8260200151518110156117a35761179b83600001518460200151838151811061178e5761178e6137d5565b6020026020010151611f36565b600101611763565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c282600001518360400151846060015185608001516040516117e99493929190613c35565b60405180910390a150506001016114e9565b5050505050565b61180a611d2d565b6118138161255c565b50565b61182961029a60a0830160808401613259565b6118885761183d60a0820160808301613259565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610961565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6118d4604084016020850161340a565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015611945573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119699190613cce565b156119a0576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119b86119b3604083016020840161340a565b612620565b6119d86119cb604083016020840161340a565b61033a60a0840184613760565b611a1d576119e960a0820182613760565b6040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016109619291906138c4565b611813611a30604083016020840161340a565b8260600135612746565b60008151600003611a6c57507f0000000000000000000000000000000000000000000000000000000000000000919050565b8151602014611aa957816040517f953576f70000000000000000000000000000000000000000000000000000000081526004016109619190613224565b600082806020019051810190611abf9190613ceb565b905060ff81111561067857826040517f953576f70000000000000000000000000000000000000000000000000000000081526004016109619190613224565b60007f000000000000000000000000000000000000000000000000000000000000000060ff168260ff1603611b34575081610678565b7f000000000000000000000000000000000000000000000000000000000000000060ff168260ff161115611c1f576000611b8e7f000000000000000000000000000000000000000000000000000000000000000084613d33565b9050604d8160ff161115611c02576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f000000000000000000000000000000000000000000000000000000000000000016602482015260448101859052606401610961565b611c0d81600a613e6c565b611c179085613e7b565b915050610678565b6000611c4b837f0000000000000000000000000000000000000000000000000000000000000000613d33565b9050604d8160ff161180611c925750611c6581600a613e6c565b611c8f907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff613e7b565b84115b15611cfd576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f000000000000000000000000000000000000000000000000000000000000000016602482015260448101859052606401610961565b611d0881600a613e6c565b61088f9085613eb6565b600081815260018301602052604081205415155b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611d7e576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f0000000000000000000000000000000000000000000000000000000000000000611dd7576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611e6d576000838281518110611df757611df76137d5565b60200260200101519050611e1581600261278d90919063ffffffff16565b15611e645760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611dda565b5060005b81518110156109aa576000828281518110611e8e57611e8e6137d5565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ed25750611f2e565b611edd6002826127af565b15611f2c5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611e71565b8051600003611f71576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff8416600090815260079092526040909120611fa39060050182612550565b611fdd5782826040517f393b8ad2000000000000000000000000000000000000000000000000000000008152600401610961929190613ecd565b6000818152600860205260409020611ff58382613b1b565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea83604051610e759190613224565b61204361029a60a0830160808401613259565b6120575761183d60a0820160808301613259565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6120a3604084016020850161340a565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015612114573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121389190613cce565b1561216f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6121876121826060830160408401613259565b6127d1565b61219f61219a604083016020840161340a565b612850565b6118136121b2604083016020840161340a565b826060013561299e565b6040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906379cc679090604401600060405180830381600087803b15801561224a57600080fd5b505af11580156117fb573d6000803e3d6000fd5b60606000611d26836129e2565b6000611d268383612a3d565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261230582606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426122e99190613ef0565b85608001516fffffffffffffffffffffffffffffffff16612b30565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61233283610afe565b612374576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610961565b61237f826000612413565b67ffffffffffffffff831660009081526007602052604090206123a29083612b58565b6123ad816000612413565b67ffffffffffffffff831660009081526007602052604090206123d39060020182612b58565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161240693929190613f03565b60405180910390a1505050565b8151156124de5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612469575060408201516fffffffffffffffffffffffffffffffff16155b156124a257816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016109619190613f86565b80156124da576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff16151580612517575060208201516fffffffffffffffffffffffffffffffff1615155b156124da57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016109619190613f86565b6000611d268383612cfa565b3373ffffffffffffffffffffffffffffffffffffffff8216036125ab576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61262981610afe565b61266b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610961565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa1580156126ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061270e9190613cce565b611813576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610961565b67ffffffffffffffff821660009081526007602052604090206124da90600201827f0000000000000000000000000000000000000000000000000000000000000000612d49565b6000611d268373ffffffffffffffffffffffffffffffffffffffff8416612a3d565b6000611d268373ffffffffffffffffffffffffffffffffffffffff8416612cfa565b7f000000000000000000000000000000000000000000000000000000000000000015611813576128026002826130cc565b611813576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610961565b61285981610afe565b61289b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610961565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612914573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129389190613fc2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611813576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610961565b67ffffffffffffffff821660009081526007602052604090206124da90827f0000000000000000000000000000000000000000000000000000000000000000612d49565b606081600001805480602002602001604051908101604052809291908181526020018280548015610ffb57602002820191906000526020600020905b815481526020019060010190808311612a1e5750505050509050919050565b60008181526001830160205260408120548015612b26576000612a61600183613ef0565b8554909150600090612a7590600190613ef0565b9050808214612ada576000866000018281548110612a9557612a956137d5565b9060005260206000200154905080876000018481548110612ab857612ab86137d5565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612aeb57612aeb613fdf565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610678565b6000915050610678565b6000612b4f85612b408486613eb6565b612b4a908761400e565b6130fb565b95945050505050565b8154600090612b8190700100000000000000000000000000000000900463ffffffff1642613ef0565b90508015612c235760018301548354612bc9916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612b30565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612c49916fffffffffffffffffffffffffffffffff90811691166130fb565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612406908490613f86565b6000818152600183016020526040812054612d4157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610678565b506000610678565b825474010000000000000000000000000000000000000000900460ff161580612d70575081155b15612d7a57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612dc090700100000000000000000000000000000000900463ffffffff1642613ef0565b90508015612e805781831115612e02576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612e3c9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612b30565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612f375773ffffffffffffffffffffffffffffffffffffffff8416612edf576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610961565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610961565b8483101561304a5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612f7b9082613ef0565b612f85878a613ef0565b612f8f919061400e565b612f999190613e7b565b905073ffffffffffffffffffffffffffffffffffffffff8616612ff2576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610961565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610961565b6130548584613ef0565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611d26565b600081831061310a5781611d26565b5090919050565b50805461311d90613804565b6000825580601f1061312d575050565b601f0160209004906000526020600020908101906118139190613165565b508054600082559060005260206000209081019061181391905b5b8082111561317a5760008155600101613166565b5090565b60006020828403121561319057600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611d2657600080fd5b6000815180845260005b818110156131e6576020818501810151868301820152016131ca565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611d2660208301846131c0565b73ffffffffffffffffffffffffffffffffffffffff8116811461181357600080fd5b60006020828403121561326b57600080fd5b8135611d2681613237565b60006020828403121561328857600080fd5b813567ffffffffffffffff81111561329f57600080fd5b82016101008185031215611d2657600080fd5b803567ffffffffffffffff811681146132ca57600080fd5b919050565b6000806000604084860312156132e457600080fd5b6132ed846132b2565b9250602084013567ffffffffffffffff8082111561330a57600080fd5b818601915086601f83011261331e57600080fd5b81358181111561332d57600080fd5b87602082850101111561333f57600080fd5b6020830194508093505050509250925092565b60008083601f84011261336457600080fd5b50813567ffffffffffffffff81111561337c57600080fd5b6020830191508360208260051b850101111561339757600080fd5b9250929050565b600080600080604085870312156133b457600080fd5b843567ffffffffffffffff808211156133cc57600080fd5b6133d888838901613352565b909650945060208701359150808211156133f157600080fd5b506133fe87828801613352565b95989497509550505050565b60006020828403121561341c57600080fd5b611d26826132b2565b60006020828403121561343757600080fd5b813567ffffffffffffffff81111561344e57600080fd5b820160a08185031215611d2657600080fd5b60208152600082516040602084015261347c60608401826131c0565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612b4f82826131c0565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b8281101561352c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261351a8583516131c0565b945092850192908501906001016134e0565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561358757835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613555565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561358757835167ffffffffffffffff16835292840192918401916001016135af565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715613627576136276135d5565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613674576136746135d5565b604052919050565b801515811461181357600080fd5b80356fffffffffffffffffffffffffffffffff811681146132ca57600080fd5b6000606082840312156136bc57600080fd5b6040516060810181811067ffffffffffffffff821117156136df576136df6135d5565b60405290508082356136f08161367c565b81526136fe6020840161368a565b602082015261370f6040840161368a565b60408201525092915050565b600080600060e0848603121561373057600080fd5b613739846132b2565b925061374885602086016136aa565b915061375785608086016136aa565b90509250925092565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261379557600080fd5b83018035915067ffffffffffffffff8211156137b057600080fd5b60200191503681900382131561339757600080fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c9082168061381857607f821691505b602082108103613851577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b67ffffffffffffffff84168152604060208201526000612b4f604083018486613857565b60208152600061088f602083018486613857565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee183360301811261390c57600080fd5b9190910192915050565b600082601f83011261392757600080fd5b813567ffffffffffffffff811115613941576139416135d5565b61397260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161362d565b81815284602083860101111561398757600080fd5b816020850160208301376000918101602001919091529392505050565b600061012082360312156139b757600080fd5b6139bf613604565b6139c8836132b2565b815260208084013567ffffffffffffffff808211156139e657600080fd5b9085019036601f8301126139f957600080fd5b813581811115613a0b57613a0b6135d5565b8060051b613a1a85820161362d565b9182528381018501918581019036841115613a3457600080fd5b86860192505b83831015613a7057823585811115613a525760008081fd5b613a603689838a0101613916565b8352509186019190860190613a3a565b8087890152505050506040860135925080831115613a8d57600080fd5b5050613a9b36828601613916565b604083015250613aae36606085016136aa565b6060820152613ac03660c085016136aa565b608082015292915050565b601f8211156109aa576000816000526020600020601f850160051c81016020861015613af45750805b601f850160051c820191505b81811015613b1357828155600101613b00565b505050505050565b815167ffffffffffffffff811115613b3557613b356135d5565b613b4981613b438454613804565b84613acb565b602080601f831160018114613b9c5760008415613b665750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613b13565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613be957888601518255948401946001909101908401613bca565b5085821015613c2557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613c59818401876131c0565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613c979050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612b4f565b600060208284031215613ce057600080fd5b8151611d268161367c565b600060208284031215613cfd57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff828116828216039081111561067857610678613d04565b600181815b80851115613da557817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613d8b57613d8b613d04565b80851615613d9857918102915b93841c9390800290613d51565b509250929050565b600082613dbc57506001610678565b81613dc957506000610678565b8160018114613ddf5760028114613de957613e05565b6001915050610678565b60ff841115613dfa57613dfa613d04565b50506001821b610678565b5060208310610133831016604e8410600b8410161715613e28575081810a610678565b613e328383613d4c565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613e6457613e64613d04565b029392505050565b6000611d2660ff841683613dad565b600082613eb1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761067857610678613d04565b67ffffffffffffffff8316815260406020820152600061088f60408301846131c0565b8181038181111561067857610678613d04565b67ffffffffffffffff8416815260e08101613f4f60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c083015261088f565b6060810161067882848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060208284031215613fd457600080fd5b8151611d2681613237565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8082018082111561067857610678613d0456fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"localTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"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\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"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\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"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\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MismatchedArrayLengths\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"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\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"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\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"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\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"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\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"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\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"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\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectors\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config[]\",\"name\":\"outboundConfigs\",\"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\":\"inboundConfigs\",\"type\":\"tuple[]\"}],\"name\":\"setChainRateLimiterConfigs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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: "0x6101006040523480156200001257600080fd5b5060405162004ed638038062004ed6833981016040819052620000359162000918565b8484848484336000816200005c57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008f576200008f8162000206565b50506001600160a01b0385161580620000af57506001600160a01b038116155b80620000c257506001600160a01b038216155b15620000e1576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808616608081905290831660c0526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa92505050801562000151575060408051601f3d908101601f191682019092526200014e9181019062000a3a565b60015b1562000192578060ff168560ff161462000190576040516332ad3e0760e11b815260ff8087166004830152821660248201526044015b60405180910390fd5b505b60ff841660a052600480546001600160a01b0319166001600160a01b038316179055825115801560e052620001dc57604080516000815260208101909152620001dc908462000280565b50620001fb935050506001600160a01b038716905030600019620003dd565b505050505062000b84565b336001600160a01b038216036200023057604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e051620002a1576040516335f4a7b360e01b815260040160405180910390fd5b60005b82518110156200032c576000838281518110620002c557620002c562000a58565b60209081029190910101519050620002df600282620004c3565b1562000322576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620002a4565b5060005b8151811015620003d857600082828151811062000351576200035162000a58565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200037d5750620003cf565b6200038a600282620004e3565b15620003cd576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000330565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa1580156200042f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000455919062000a6e565b62000461919062000a9e565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b17909152919250620004bd91869190620004fa16565b50505050565b6000620004da836001600160a01b038416620005cb565b90505b92915050565b6000620004da836001600160a01b038416620006cf565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000549906001600160a01b03851690849062000721565b805190915015620003d857808060200190518101906200056a919062000ab4565b620003d85760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000187565b60008181526001830160205260408120548015620006c4576000620005f260018362000adf565b8554909150600090620006089060019062000adf565b9050808214620006745760008660000182815481106200062c576200062c62000a58565b906000526020600020015490508087600001848154811062000652576200065262000a58565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000688576200068862000af5565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620004dd565b6000915050620004dd565b60008181526001830160205260408120546200071857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620004dd565b506000620004dd565b60606200073284846000856200073a565b949350505050565b6060824710156200079d5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000187565b600080866001600160a01b03168587604051620007bb919062000b31565b60006040518083038185875af1925050503d8060008114620007fa576040519150601f19603f3d011682016040523d82523d6000602084013e620007ff565b606091505b50909250905062000813878383876200081e565b979650505050505050565b60608315620008925782516000036200088a576001600160a01b0385163b6200088a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000187565b508162000732565b620007328383815115620008a95781518083602001fd5b8060405162461bcd60e51b815260040162000187919062000b4f565b6001600160a01b0381168114620008db57600080fd5b50565b805160ff81168114620008f057600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b8051620008f081620008c5565b600080600080600060a086880312156200093157600080fd5b85516200093e81620008c5565b945060206200094f878201620008de565b60408801519095506001600160401b03808211156200096d57600080fd5b818901915089601f8301126200098257600080fd5b815181811115620009975762000997620008f5565b8060051b604051601f19603f83011681018181108582111715620009bf57620009bf620008f5565b60405291825284820192508381018501918c831115620009de57600080fd5b938501935b8285101562000a0757620009f7856200090b565b84529385019392850192620009e3565b80985050505050505062000a1e606087016200090b565b915062000a2e608087016200090b565b90509295509295909350565b60006020828403121562000a4d57600080fd5b620004da82620008de565b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000a8157600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115620004dd57620004dd62000a88565b60006020828403121562000ac757600080fd5b8151801515811462000ad857600080fd5b9392505050565b81810381811115620004dd57620004dd62000a88565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000b2857818101518382015260200162000b0e565b50506000910152565b6000825162000b4581846020870162000b0b565b9190910192915050565b602081526000825180602084015262000b7081604085016020870162000b0b565b601f01601f19169190910160400192915050565b60805160a05160c05160e0516142a162000c356000396000818161056d01528181611efa0152612aed01526000818161054701528181611a1701526122d00152600081816102eb01528181610d2101528181611bc001528181611c7a01528181611cae01528181611ce101528181611d4601528181611d9f0152611e41015260008181610252015281816102a70152818161072601528181612453015281816128e10152612cd801526142a16000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c80639a4575b911610104578063c0d78655116100a2578063dc0bd97111610071578063dc0bd97114610545578063e0351e131461056b578063e8a1da1714610591578063f2fde38b146105a457600080fd5b8063c0d78655146104f7578063c4bffe2b1461050a578063c75eea9c1461051f578063cf7401f31461053257600080fd5b8063acfecf91116100de578063acfecf9114610444578063af58d59f14610457578063b0f479a1146104c6578063b7946580146104e457600080fd5b80639a4575b9146103ef578063a42a7b8b1461040f578063a7cd63b71461042f57600080fd5b806354c8a4f31161017c5780637d54534e1161014b5780637d54534e146103985780638926f54f146103ab5780638da5cb5b146103be578063962d4020146103dc57600080fd5b806354c8a4f31461034a57806362ddd3c41461035f5780636d3d1a581461037257806379ba50971461039057600080fd5b8063240028e8116101b8578063240028e81461029757806324f65ee7146102e457806339077537146103155780634c5ef0ed1461033757600080fd5b806301ffc9a7146101df578063181f5a771461020757806321df0da714610250575b600080fd5b6101f26101ed3660046132f6565b6105b7565b60405190151581526020015b60405180910390f35b6102436040518060400160405280601b81526020017f4275726e46726f6d4d696e74546f6b656e506f6f6c20312e352e31000000000081525081565b6040516101fe919061339c565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101fe565b6101f26102a53660046133d1565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101fe565b6103286103233660046133ee565b61069c565b604051905181526020016101fe565b6101f2610345366004613447565b61086b565b61035d610358366004613516565b6108b5565b005b61035d61036d366004613447565b610930565b60095473ffffffffffffffffffffffffffffffffffffffff16610272565b61035d6109cd565b61035d6103a63660046133d1565b610a9b565b6101f26103b9366004613582565b610b1c565b60015473ffffffffffffffffffffffffffffffffffffffff16610272565b61035d6103ea3660046135e2565b610b33565b6104026103fd36600461367c565b610c8d565b6040516101fe91906136b7565b61042261041d366004613582565b610d66565b6040516101fe919061370e565b610437610ed1565b6040516101fe9190613790565b61035d610452366004613447565b610ee2565b61046a610465366004613582565b610ffa565b6040516101fe919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610272565b6102436104f2366004613582565b6110cf565b61035d6105053660046133d1565b61117f565b61051261125a565b6040516101fe91906137ea565b61046a61052d366004613582565b611312565b61035d610540366004613972565b6113e4565b7f0000000000000000000000000000000000000000000000000000000000000000610272565b7f00000000000000000000000000000000000000000000000000000000000000006101f2565b61035d61059f366004613516565b611468565b61035d6105b23660046133d1565b61197a565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061064a57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061069657507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b6040805160208101909152600081526106b48261198e565b600061070d60608401356107086106ce60c08701876139b7565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bb292505050565b611c76565b905073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f1961075b60608601604087016133d1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260248101849052604401600060405180830381600087803b1580156107c857600080fd5b505af11580156107dc573d6000803e3d6000fd5b506107f19250505060608401604085016133d1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08360405161084f91815260200190565b60405180910390a3604080516020810190915290815292915050565b60006108ad8383604051610880929190613a1c565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190611e8a565b949350505050565b6108bd611ea5565b61092a84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611ef892505050565b50505050565b610938611ea5565b61094183610b1c565b610988576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6109c88383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506120ae92505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a1e576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610aa3611ea5565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b6000610696600567ffffffffffffffff8416611e8a565b60095473ffffffffffffffffffffffffffffffffffffffff163314801590610b73575060015473ffffffffffffffffffffffffffffffffffffffff163314155b15610bac576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161097f565b8483141580610bbb5750848114155b15610bf2576040517f568efce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b85811015610c8457610c7c878783818110610c1257610c12613a2c565b9050602002016020810190610c279190613582565b868684818110610c3957610c39613a2c565b905060600201803603810190610c4f9190613a5b565b858585818110610c6157610c61613a2c565b905060600201803603810190610c779190613a5b565b6121a8565b600101610bf5565b50505050505050565b6040805180820190915260608082526020820152610caa82612292565b610cb7826060013561241e565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610d118460200160208101906104f29190613582565b8152602001610d5e6040805160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260609101604051602081830303815290604052905090565b905292915050565b67ffffffffffffffff8116600090815260076020526040812060609190610d8f906005016124c0565b90506000815167ffffffffffffffff811115610dad57610dad61382c565b604051908082528060200260200182016040528015610de057816020015b6060815260200190600190039081610dcb5790505b50905060005b8251811015610ec95760086000848381518110610e0557610e05613a2c565b602002602001015181526020019081526020016000208054610e2690613a77565b80601f0160208091040260200160405190810160405280929190818152602001828054610e5290613a77565b8015610e9f5780601f10610e7457610100808354040283529160200191610e9f565b820191906000526020600020905b815481529060010190602001808311610e8257829003601f168201915b5050505050828281518110610eb657610eb6613a2c565b6020908102919091010152600101610de6565b509392505050565b6060610edd60026124c0565b905090565b610eea611ea5565b610ef383610b1c565b610f35576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161097f565b610f758282604051610f48929190613a1c565b604080519182900390912067ffffffffffffffff86166000908152600760205291909120600501906124cd565b610fb1578282826040517f74f23c7c00000000000000000000000000000000000000000000000000000000815260040161097f93929190613b13565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d768383604051610fed929190613b37565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526003909101548084166060830152919091049091166080820152610696906124d9565b67ffffffffffffffff811660009081526007602052604090206004018054606091906110fa90613a77565b80601f016020809104026020016040519081016040528092919081815260200182805461112690613a77565b80156111735780601f1061114857610100808354040283529160200191611173565b820191906000526020600020905b81548152906001019060200180831161115657829003601f168201915b50505050509050919050565b611187611ea5565b73ffffffffffffffffffffffffffffffffffffffff81166111d4576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b6060600061126860056124c0565b90506000815167ffffffffffffffff8111156112865761128661382c565b6040519080825280602002602001820160405280156112af578160200160208202803683370190505b50905060005b825181101561130b578281815181106112d0576112d0613a2c565b60200260200101518282815181106112ea576112ea613a2c565b67ffffffffffffffff909216602092830291909101909101526001016112b5565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526001909101548084166060830152919091049091166080820152610696906124d9565b60095473ffffffffffffffffffffffffffffffffffffffff163314801590611424575060015473ffffffffffffffffffffffffffffffffffffffff163314155b1561145d576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161097f565b6109c88383836121a8565b611470611ea5565b60005b8381101561165d57600085858381811061148f5761148f613a2c565b90506020020160208101906114a49190613582565b90506114bb600567ffffffffffffffff83166124cd565b6114fd576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161097f565b67ffffffffffffffff81166000908152600760205260408120611522906005016124c0565b905060005b815181101561158e5761158582828151811061154557611545613a2c565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206005016124cd90919063ffffffff16565b50600101611527565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906115f76004830182613289565b600582016000818161160982826132c3565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169450602001925061164b915050565b60405180910390a15050600101611473565b5060005b8181101561197357600083838381811061167d5761167d613a2c565b905060200281019061168f9190613b4b565b61169890613c17565b90506116a98160600151600061258b565b6116b88160800151600061258b565b8060400151516000036116f7576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805161170f9060059067ffffffffffffffff166126c8565b6117545780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161097f565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a9091029990931617179094169590951790925590920290911760038201559082015160048201906118d79082613d8e565b5060005b82602001515181101561191b5761191383600001518460200151838151811061190657611906613a2c565b60200260200101516120ae565b6001016118db565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c282600001518360400151846060015185608001516040516119619493929190613ea8565b60405180910390a15050600101611661565b5050505050565b611982611ea5565b61198b816126d4565b50565b6119a16102a560a08301608084016133d1565b611a00576119b560a08201608083016133d1565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161097f565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb611a4c6040840160208501613582565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015611abd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae19190613f41565b15611b18576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b30611b2b6040830160208401613582565b612798565b611b50611b436040830160208401613582565b61034560a08401846139b7565b611b9557611b6160a08201826139b7565b6040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161097f929190613b37565b61198b611ba86040830160208401613582565b82606001356128be565b60008151600003611be457507f0000000000000000000000000000000000000000000000000000000000000000919050565b8151602014611c2157816040517f953576f700000000000000000000000000000000000000000000000000000000815260040161097f919061339c565b600082806020019051810190611c379190613f5e565b905060ff81111561069657826040517f953576f700000000000000000000000000000000000000000000000000000000815260040161097f919061339c565b60007f000000000000000000000000000000000000000000000000000000000000000060ff168260ff1603611cac575081610696565b7f000000000000000000000000000000000000000000000000000000000000000060ff168260ff161115611d97576000611d067f000000000000000000000000000000000000000000000000000000000000000084613fa6565b9050604d8160ff161115611d7a576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044810185905260640161097f565b611d8581600a6140df565b611d8f90856140ee565b915050610696565b6000611dc3837f0000000000000000000000000000000000000000000000000000000000000000613fa6565b9050604d8160ff161180611e0a5750611ddd81600a6140df565b611e07907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6140ee565b84115b15611e75576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044810185905260640161097f565b611e8081600a6140df565b6108ad9085614129565b600081815260018301602052604081205415155b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611ef6576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f0000000000000000000000000000000000000000000000000000000000000000611f4f576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611fe5576000838281518110611f6f57611f6f613a2c565b60200260200101519050611f8d81600261290590919063ffffffff16565b15611fdc5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611f52565b5060005b81518110156109c857600082828151811061200657612006613a2c565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361204a57506120a6565b612055600282612927565b156120a45760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611fe9565b80516000036120e9576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff841660009081526007909252604090912061211b90600501826126c8565b6121555782826040517f393b8ad200000000000000000000000000000000000000000000000000000000815260040161097f929190614140565b600081815260086020526040902061216d8382613d8e565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea83604051610fed919061339c565b6121b183610b1c565b6121f3576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161097f565b6121fe82600061258b565b67ffffffffffffffff831660009081526007602052604090206122219083612949565b61222c81600061258b565b67ffffffffffffffff831660009081526007602052604090206122529060020182612949565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161228593929190614163565b60405180910390a1505050565b6122a56102a560a08301608084016133d1565b6122b9576119b560a08201608083016133d1565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6123056040840160208501613582565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015612376573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239a9190613f41565b156123d1576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123e96123e460608301604084016133d1565b612aeb565b6124016123fc6040830160208401613582565b612b6a565b61198b6124146040830160208401613582565b8260600135612cb8565b6040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906379cc679090604401600060405180830381600087803b1580156124ac57600080fd5b505af1158015611973573d6000803e3d6000fd5b60606000611e9e83612cfc565b6000611e9e8383612d57565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261256782606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261254b91906141e6565b85608001516fffffffffffffffffffffffffffffffff16612e4a565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b8151156126565781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806125e1575060408201516fffffffffffffffffffffffffffffffff16155b1561261a57816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161097f91906141f9565b8015612652576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff1615158061268f575060208201516fffffffffffffffffffffffffffffffff1615155b1561265257816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161097f91906141f9565b6000611e9e8383612e72565b3373ffffffffffffffffffffffffffffffffffffffff821603612723576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6127a181610b1c565b6127e3576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161097f565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612862573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128869190613f41565b61198b576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161097f565b67ffffffffffffffff8216600090815260076020526040902061265290600201827f0000000000000000000000000000000000000000000000000000000000000000612ec1565b6000611e9e8373ffffffffffffffffffffffffffffffffffffffff8416612d57565b6000611e9e8373ffffffffffffffffffffffffffffffffffffffff8416612e72565b815460009061297290700100000000000000000000000000000000900463ffffffff16426141e6565b90508015612a1457600183015483546129ba916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612e4a565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612a3a916fffffffffffffffffffffffffffffffff9081169116613244565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906122859084906141f9565b7f00000000000000000000000000000000000000000000000000000000000000001561198b57612b1c60028261325a565b61198b576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161097f565b612b7381610b1c565b612bb5576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161097f565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612c2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c529190614235565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461198b576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161097f565b67ffffffffffffffff8216600090815260076020526040902061265290827f0000000000000000000000000000000000000000000000000000000000000000612ec1565b60608160000180548060200260200160405190810160405280929190818152602001828054801561117357602002820191906000526020600020905b815481526020019060010190808311612d385750505050509050919050565b60008181526001830160205260408120548015612e40576000612d7b6001836141e6565b8554909150600090612d8f906001906141e6565b9050808214612df4576000866000018281548110612daf57612daf613a2c565b9060005260206000200154905080876000018481548110612dd257612dd2613a2c565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612e0557612e05614252565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610696565b6000915050610696565b6000612e6985612e5a8486614129565b612e649087614281565b613244565b95945050505050565b6000818152600183016020526040812054612eb957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610696565b506000610696565b825474010000000000000000000000000000000000000000900460ff161580612ee8575081155b15612ef257505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612f3890700100000000000000000000000000000000900463ffffffff16426141e6565b90508015612ff85781831115612f7a576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612fb49083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612e4a565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156130af5773ffffffffffffffffffffffffffffffffffffffff8416613057576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161097f565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161097f565b848310156131c25760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906130f390826141e6565b6130fd878a6141e6565b6131079190614281565b61311191906140ee565b905073ffffffffffffffffffffffffffffffffffffffff861661316a576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161097f565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161097f565b6131cc85846141e6565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b60008183106132535781611e9e565b5090919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611e9e565b50805461329590613a77565b6000825580601f106132a5575050565b601f01602090049060005260206000209081019061198b91906132dd565b508054600082559060005260206000209081019061198b91905b5b808211156132f257600081556001016132de565b5090565b60006020828403121561330857600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611e9e57600080fd5b6000815180845260005b8181101561335e57602081850181015186830182015201613342565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611e9e6020830184613338565b73ffffffffffffffffffffffffffffffffffffffff8116811461198b57600080fd5b6000602082840312156133e357600080fd5b8135611e9e816133af565b60006020828403121561340057600080fd5b813567ffffffffffffffff81111561341757600080fd5b82016101008185031215611e9e57600080fd5b803567ffffffffffffffff8116811461344257600080fd5b919050565b60008060006040848603121561345c57600080fd5b6134658461342a565b9250602084013567ffffffffffffffff8082111561348257600080fd5b818601915086601f83011261349657600080fd5b8135818111156134a557600080fd5b8760208285010111156134b757600080fd5b6020830194508093505050509250925092565b60008083601f8401126134dc57600080fd5b50813567ffffffffffffffff8111156134f457600080fd5b6020830191508360208260051b850101111561350f57600080fd5b9250929050565b6000806000806040858703121561352c57600080fd5b843567ffffffffffffffff8082111561354457600080fd5b613550888389016134ca565b9096509450602087013591508082111561356957600080fd5b50613576878288016134ca565b95989497509550505050565b60006020828403121561359457600080fd5b611e9e8261342a565b60008083601f8401126135af57600080fd5b50813567ffffffffffffffff8111156135c757600080fd5b60208301915083602060608302850101111561350f57600080fd5b600080600080600080606087890312156135fb57600080fd5b863567ffffffffffffffff8082111561361357600080fd5b61361f8a838b016134ca565b9098509650602089013591508082111561363857600080fd5b6136448a838b0161359d565b9096509450604089013591508082111561365d57600080fd5b5061366a89828a0161359d565b979a9699509497509295939492505050565b60006020828403121561368e57600080fd5b813567ffffffffffffffff8111156136a557600080fd5b820160a08185031215611e9e57600080fd5b6020815260008251604060208401526136d36060840182613338565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e698282613338565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015613783577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452613771858351613338565b94509285019290850190600101613737565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b818110156137de57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016137ac565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156137de57835167ffffffffffffffff1683529284019291840191600101613806565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff8111828210171561387e5761387e61382c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156138cb576138cb61382c565b604052919050565b801515811461198b57600080fd5b80356fffffffffffffffffffffffffffffffff8116811461344257600080fd5b60006060828403121561391357600080fd5b6040516060810181811067ffffffffffffffff821117156139365761393661382c565b6040529050808235613947816138d3565b8152613955602084016138e1565b6020820152613966604084016138e1565b60408201525092915050565b600080600060e0848603121561398757600080fd5b6139908461342a565b925061399f8560208601613901565b91506139ae8560808601613901565b90509250925092565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126139ec57600080fd5b83018035915067ffffffffffffffff821115613a0757600080fd5b60200191503681900382131561350f57600080fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060608284031215613a6d57600080fd5b611e9e8383613901565b600181811c90821680613a8b57607f821691505b602082108103613ac4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b67ffffffffffffffff84168152604060208201526000612e69604083018486613aca565b6020815260006108ad602083018486613aca565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee1833603018112613b7f57600080fd5b9190910192915050565b600082601f830112613b9a57600080fd5b813567ffffffffffffffff811115613bb457613bb461382c565b613be560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613884565b818152846020838601011115613bfa57600080fd5b816020850160208301376000918101602001919091529392505050565b60006101208236031215613c2a57600080fd5b613c3261385b565b613c3b8361342a565b815260208084013567ffffffffffffffff80821115613c5957600080fd5b9085019036601f830112613c6c57600080fd5b813581811115613c7e57613c7e61382c565b8060051b613c8d858201613884565b9182528381018501918581019036841115613ca757600080fd5b86860192505b83831015613ce357823585811115613cc55760008081fd5b613cd33689838a0101613b89565b8352509186019190860190613cad565b8087890152505050506040860135925080831115613d0057600080fd5b5050613d0e36828601613b89565b604083015250613d213660608501613901565b6060820152613d333660c08501613901565b608082015292915050565b601f8211156109c8576000816000526020600020601f850160051c81016020861015613d675750805b601f850160051c820191505b81811015613d8657828155600101613d73565b505050505050565b815167ffffffffffffffff811115613da857613da861382c565b613dbc81613db68454613a77565b84613d3e565b602080601f831160018114613e0f5760008415613dd95750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613d86565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613e5c57888601518255948401946001909101908401613e3d565b5085821015613e9857878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613ecc81840187613338565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613f0a9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e69565b600060208284031215613f5357600080fd5b8151611e9e816138d3565b600060208284031215613f7057600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff828116828216039081111561069657610696613f77565b600181815b8085111561401857817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613ffe57613ffe613f77565b8085161561400b57918102915b93841c9390800290613fc4565b509250929050565b60008261402f57506001610696565b8161403c57506000610696565b8160018114614052576002811461405c57614078565b6001915050610696565b60ff84111561406d5761406d613f77565b50506001821b610696565b5060208310610133831016604e8410600b841016171561409b575081810a610696565b6140a58383613fbf565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156140d7576140d7613f77565b029392505050565b6000611e9e60ff841683614020565b600082614124577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761069657610696613f77565b67ffffffffffffffff831681526040602082015260006108ad6040830184613338565b67ffffffffffffffff8416815260e081016141af60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526108ad565b8181038181111561069657610696613f77565b6060810161069682848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561424757600080fd5b8151611e9e816133af565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8082018082111561069657610696613f7756fea164736f6c6343000818000a", } var BurnFromMintTokenPoolABI = BurnFromMintTokenPoolMetaData.ABI @@ -713,6 +713,18 @@ func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) SetChainRa return _BurnFromMintTokenPool.Contract.SetChainRateLimiterConfig(&_BurnFromMintTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) } +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _BurnFromMintTokenPool.contract.Transact(opts, "setChainRateLimiterConfigs", remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.SetChainRateLimiterConfigs(&_BurnFromMintTokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.SetChainRateLimiterConfigs(&_BurnFromMintTokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) { return _BurnFromMintTokenPool.contract.Transact(opts, "setRateLimitAdmin", rateLimitAdmin) } @@ -3033,6 +3045,8 @@ type BurnFromMintTokenPoolInterface interface { SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) + SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go index ecfad493c2c..d789ab8e3bf 100644 --- a/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go @@ -81,8 +81,8 @@ type TokenPoolChainUpdate struct { } var BurnMintTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"localTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"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\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"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\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"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\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"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\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"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\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"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\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"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\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"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\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"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\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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: "0x6101006040523480156200001257600080fd5b5060405162004809380380620048098339810160408190526200003591620005a2565b8484848484336000816200005c57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008f576200008f81620001eb565b50506001600160a01b0385161580620000af57506001600160a01b038116155b80620000c257506001600160a01b038216155b15620000e1576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808616608081905290831660c0526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa92505050801562000151575060408051601f3d908101601f191682019092526200014e91810190620006c4565b60015b1562000191578060ff168560ff16146200018f576040516332ad3e0760e11b815260ff80871660048301528216602482015260440160405180910390fd5b505b60ff841660a052600480546001600160a01b0319166001600160a01b038316179055825115801560e052620001db57604080516000815260208101909152620001db908462000265565b5050505050505050505062000730565b336001600160a01b038216036200021557604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e05162000286576040516335f4a7b360e01b815260040160405180910390fd5b60005b825181101562000311576000838281518110620002aa57620002aa620006e2565b60209081029190910101519050620002c4600282620003c2565b1562000307576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000289565b5060005b8151811015620003bd576000828281518110620003365762000336620006e2565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003625750620003b4565b6200036f600282620003e2565b15620003b2576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000315565b505050565b6000620003d9836001600160a01b038416620003f9565b90505b92915050565b6000620003d9836001600160a01b038416620004fd565b60008181526001830160205260408120548015620004f257600062000420600183620006f8565b85549091506000906200043690600190620006f8565b9050808214620004a25760008660000182815481106200045a576200045a620006e2565b9060005260206000200154905080876000018481548110620004805762000480620006e2565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004b657620004b66200071a565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003dc565b6000915050620003dc565b60008181526001830160205260408120546200054657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003dc565b506000620003dc565b6001600160a01b03811681146200056557600080fd5b50565b805160ff811681146200057a57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b80516200057a816200054f565b600080600080600060a08688031215620005bb57600080fd5b8551620005c8816200054f565b94506020620005d987820162000568565b60408801519095506001600160401b0380821115620005f757600080fd5b818901915089601f8301126200060c57600080fd5b8151818111156200062157620006216200057f565b8060051b604051601f19603f830116810181811085821117156200064957620006496200057f565b60405291825284820192508381018501918c8311156200066857600080fd5b938501935b828510156200069157620006818562000595565b845293850193928501926200066d565b809850505050505050620006a86060870162000595565b9150620006b86080870162000595565b90509295509295909350565b600060208284031215620006d757600080fd5b620003d98262000568565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003dc57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e051614028620007e16000396000818161054f01528181611d8201526127cd0152600081816105290152818161189f015261206e0152600081816102e001528181610ba901528181611a4801528181611b0201528181611b3601528181611b6901528181611bce01528181611c270152611cc90152600081816102470152818161029c01528181610708015281816121eb0152818161276301526129b801526140286000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639a4575b911610104578063c0d78655116100a2578063dc0bd97111610071578063dc0bd97114610527578063e0351e131461054d578063e8a1da1714610573578063f2fde38b1461058657600080fd5b8063c0d78655146104d9578063c4bffe2b146104ec578063c75eea9c14610501578063cf7401f31461051457600080fd5b8063acfecf91116100de578063acfecf9114610426578063af58d59f14610439578063b0f479a1146104a8578063b7946580146104c657600080fd5b80639a4575b9146103d1578063a42a7b8b146103f1578063a7cd63b71461041157600080fd5b806354c8a4f31161017157806379ba50971161014b57806379ba5097146103855780637d54534e1461038d5780638926f54f146103a05780638da5cb5b146103b357600080fd5b806354c8a4f31461033f57806362ddd3c4146103545780636d3d1a581461036757600080fd5b8063240028e8116101ad578063240028e81461028c57806324f65ee7146102d9578063390775371461030a5780634c5ef0ed1461032c57600080fd5b806301ffc9a7146101d4578063181f5a77146101fc57806321df0da714610245575b600080fd5b6101e76101e2366004613178565b610599565b60405190151581526020015b60405180910390f35b6102386040518060400160405280601781526020017f4275726e4d696e74546f6b656e506f6f6c20312e352e3100000000000000000081525081565b6040516101f3919061321e565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b6101e761029a366004613253565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101f3565b61031d610318366004613270565b61067e565b604051905181526020016101f3565b6101e761033a3660046132c9565b61084d565b61035261034d366004613398565b610897565b005b6103526103623660046132c9565b610912565b60095473ffffffffffffffffffffffffffffffffffffffff16610267565b6103526109af565b61035261039b366004613253565b610a7d565b6101e76103ae366004613404565b610afe565b60015473ffffffffffffffffffffffffffffffffffffffff16610267565b6103e46103df36600461341f565b610b15565b6040516101f3919061345a565b6104046103ff366004613404565b610bee565b6040516101f391906134b1565b610419610d59565b6040516101f39190613533565b6103526104343660046132c9565b610d6a565b61044c610447366004613404565b610e82565b6040516101f3919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610267565b6102386104d4366004613404565b610f57565b6103526104e7366004613253565b611007565b6104f46110e2565b6040516101f3919061358d565b61044c61050f366004613404565b61119a565b610352610522366004613715565b61126c565b7f0000000000000000000000000000000000000000000000000000000000000000610267565b7f00000000000000000000000000000000000000000000000000000000000000006101e7565b610352610581366004613398565b6112f0565b610352610594366004613253565b611802565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061062c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061067857507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b60408051602081019091526000815261069682611816565b60006106ef60608401356106ea6106b060c087018761375a565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a3a92505050565b611afe565b905073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f1961073d6060860160408701613253565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260248101849052604401600060405180830381600087803b1580156107aa57600080fd5b505af11580156107be573d6000803e3d6000fd5b506107d3925050506060840160408501613253565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08360405161083191815260200190565b60405180910390a3604080516020810190915290815292915050565b600061088f83836040516108629291906137bf565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190611d12565b949350505050565b61089f611d2d565b61090c84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611d8092505050565b50505050565b61091a611d2d565b61092383610afe565b61096a576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6109aa8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611f3692505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a00576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610a85611d2d565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b6000610678600567ffffffffffffffff8416611d12565b6040805180820190915260608082526020820152610b3282612030565b610b3f82606001356121bc565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610b998460200160208101906104d49190613404565b8152602001610be66040805160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260609101604051602081830303815290604052905090565b905292915050565b67ffffffffffffffff8116600090815260076020526040812060609190610c1790600501612258565b90506000815167ffffffffffffffff811115610c3557610c356135cf565b604051908082528060200260200182016040528015610c6857816020015b6060815260200190600190039081610c535790505b50905060005b8251811015610d515760086000848381518110610c8d57610c8d6137cf565b602002602001015181526020019081526020016000208054610cae906137fe565b80601f0160208091040260200160405190810160405280929190818152602001828054610cda906137fe565b8015610d275780601f10610cfc57610100808354040283529160200191610d27565b820191906000526020600020905b815481529060010190602001808311610d0a57829003601f168201915b5050505050828281518110610d3e57610d3e6137cf565b6020908102919091010152600101610c6e565b509392505050565b6060610d656002612258565b905090565b610d72611d2d565b610d7b83610afe565b610dbd576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610961565b610dfd8282604051610dd09291906137bf565b604080519182900390912067ffffffffffffffff8616600090815260076020529190912060050190612265565b610e39578282826040517f74f23c7c0000000000000000000000000000000000000000000000000000000081526004016109619392919061389a565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d768383604051610e759291906138be565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261067890612271565b67ffffffffffffffff81166000908152600760205260409020600401805460609190610f82906137fe565b80601f0160208091040260200160405190810160405280929190818152602001828054610fae906137fe565b8015610ffb5780601f10610fd057610100808354040283529160200191610ffb565b820191906000526020600020905b815481529060010190602001808311610fde57829003601f168201915b50505050509050919050565b61100f611d2d565b73ffffffffffffffffffffffffffffffffffffffff811661105c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006110f06005612258565b90506000815167ffffffffffffffff81111561110e5761110e6135cf565b604051908082528060200260200182016040528015611137578160200160208202803683370190505b50905060005b825181101561119357828181518110611158576111586137cf565b6020026020010151828281518110611172576111726137cf565b67ffffffffffffffff9092166020928302919091019091015260010161113d565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261067890612271565b60095473ffffffffffffffffffffffffffffffffffffffff1633148015906112ac575060015473ffffffffffffffffffffffffffffffffffffffff163314155b156112e5576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610961565b6109aa838383612323565b6112f8611d2d565b60005b838110156114e5576000858583818110611317576113176137cf565b905060200201602081019061132c9190613404565b9050611343600567ffffffffffffffff8316612265565b611385576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610961565b67ffffffffffffffff811660009081526007602052604081206113aa90600501612258565b905060005b81518110156114165761140d8282815181106113cd576113cd6137cf565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060050161226590919063ffffffff16565b506001016113af565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff0000000000000000000000000000000000000000009081168255600182018390556002820180549091169055600381018290559061147f600483018261310b565b60058201600081816114918282613145565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916945060200192506114d3915050565b60405180910390a150506001016112fb565b5060005b818110156117fb576000838383818110611505576115056137cf565b905060200281019061151791906138d2565b6115209061399e565b90506115318160600151600061240d565b6115408160800151600061240d565b80604001515160000361157f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516115979060059067ffffffffffffffff1661254a565b6115dc5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610961565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a90910299909316171790941695909517909255909202909117600382015590820151600482019061175f9082613b15565b5060005b8260200151518110156117a35761179b83600001518460200151838151811061178e5761178e6137cf565b6020026020010151611f36565b600101611763565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c282600001518360400151846060015185608001516040516117e99493929190613c2f565b60405180910390a150506001016114e9565b5050505050565b61180a611d2d565b61181381612556565b50565b61182961029a60a0830160808401613253565b6118885761183d60a0820160808301613253565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610961565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6118d46040840160208501613404565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015611945573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119699190613cc8565b156119a0576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119b86119b36040830160208401613404565b61261a565b6119d86119cb6040830160208401613404565b61033a60a084018461375a565b611a1d576119e960a082018261375a565b6040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016109619291906138be565b611813611a306040830160208401613404565b8260600135612740565b60008151600003611a6c57507f0000000000000000000000000000000000000000000000000000000000000000919050565b8151602014611aa957816040517f953576f7000000000000000000000000000000000000000000000000000000008152600401610961919061321e565b600082806020019051810190611abf9190613ce5565b905060ff81111561067857826040517f953576f7000000000000000000000000000000000000000000000000000000008152600401610961919061321e565b60007f000000000000000000000000000000000000000000000000000000000000000060ff168260ff1603611b34575081610678565b7f000000000000000000000000000000000000000000000000000000000000000060ff168260ff161115611c1f576000611b8e7f000000000000000000000000000000000000000000000000000000000000000084613d2d565b9050604d8160ff161115611c02576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f000000000000000000000000000000000000000000000000000000000000000016602482015260448101859052606401610961565b611c0d81600a613e66565b611c179085613e75565b915050610678565b6000611c4b837f0000000000000000000000000000000000000000000000000000000000000000613d2d565b9050604d8160ff161180611c925750611c6581600a613e66565b611c8f907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff613e75565b84115b15611cfd576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f000000000000000000000000000000000000000000000000000000000000000016602482015260448101859052606401610961565b611d0881600a613e66565b61088f9085613eb0565b600081815260018301602052604081205415155b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611d7e576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f0000000000000000000000000000000000000000000000000000000000000000611dd7576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611e6d576000838281518110611df757611df76137cf565b60200260200101519050611e1581600261278790919063ffffffff16565b15611e645760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611dda565b5060005b81518110156109aa576000828281518110611e8e57611e8e6137cf565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ed25750611f2e565b611edd6002826127a9565b15611f2c5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611e71565b8051600003611f71576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff8416600090815260079092526040909120611fa3906005018261254a565b611fdd5782826040517f393b8ad2000000000000000000000000000000000000000000000000000000008152600401610961929190613ec7565b6000818152600860205260409020611ff58382613b15565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea83604051610e75919061321e565b61204361029a60a0830160808401613253565b6120575761183d60a0820160808301613253565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6120a36040840160208501613404565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015612114573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121389190613cc8565b1561216f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6121876121826060830160408401613253565b6127cb565b61219f61219a6040830160208401613404565b61284a565b6118136121b26040830160208401613404565b8260600135612998565b6040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b15801561224457600080fd5b505af11580156117fb573d6000803e3d6000fd5b60606000611d26836129dc565b6000611d268383612a37565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526122ff82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426122e39190613eea565b85608001516fffffffffffffffffffffffffffffffff16612b2a565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61232c83610afe565b61236e576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610961565b61237982600061240d565b67ffffffffffffffff8316600090815260076020526040902061239c9083612b52565b6123a781600061240d565b67ffffffffffffffff831660009081526007602052604090206123cd9060020182612b52565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161240093929190613efd565b60405180910390a1505050565b8151156124d85781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612463575060408201516fffffffffffffffffffffffffffffffff16155b1561249c57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016109619190613f80565b80156124d4576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff16151580612511575060208201516fffffffffffffffffffffffffffffffff1615155b156124d457816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016109619190613f80565b6000611d268383612cf4565b3373ffffffffffffffffffffffffffffffffffffffff8216036125a5576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61262381610afe565b612665576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610961565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa1580156126e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127089190613cc8565b611813576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610961565b67ffffffffffffffff821660009081526007602052604090206124d490600201827f0000000000000000000000000000000000000000000000000000000000000000612d43565b6000611d268373ffffffffffffffffffffffffffffffffffffffff8416612a37565b6000611d268373ffffffffffffffffffffffffffffffffffffffff8416612cf4565b7f000000000000000000000000000000000000000000000000000000000000000015611813576127fc6002826130c6565b611813576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610961565b61285381610afe565b612895576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610961565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561290e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129329190613fbc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611813576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610961565b67ffffffffffffffff821660009081526007602052604090206124d490827f0000000000000000000000000000000000000000000000000000000000000000612d43565b606081600001805480602002602001604051908101604052809291908181526020018280548015610ffb57602002820191906000526020600020905b815481526020019060010190808311612a185750505050509050919050565b60008181526001830160205260408120548015612b20576000612a5b600183613eea565b8554909150600090612a6f90600190613eea565b9050808214612ad4576000866000018281548110612a8f57612a8f6137cf565b9060005260206000200154905080876000018481548110612ab257612ab26137cf565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612ae557612ae5613fd9565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610678565b6000915050610678565b6000612b4985612b3a8486613eb0565b612b449087614008565b6130f5565b95945050505050565b8154600090612b7b90700100000000000000000000000000000000900463ffffffff1642613eea565b90508015612c1d5760018301548354612bc3916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612b2a565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612c43916fffffffffffffffffffffffffffffffff90811691166130f5565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612400908490613f80565b6000818152600183016020526040812054612d3b57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610678565b506000610678565b825474010000000000000000000000000000000000000000900460ff161580612d6a575081155b15612d7457505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612dba90700100000000000000000000000000000000900463ffffffff1642613eea565b90508015612e7a5781831115612dfc576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612e369083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612b2a565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612f315773ffffffffffffffffffffffffffffffffffffffff8416612ed9576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610961565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610961565b848310156130445760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612f759082613eea565b612f7f878a613eea565b612f899190614008565b612f939190613e75565b905073ffffffffffffffffffffffffffffffffffffffff8616612fec576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610961565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610961565b61304e8584613eea565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611d26565b60008183106131045781611d26565b5090919050565b508054613117906137fe565b6000825580601f10613127575050565b601f016020900490600052602060002090810190611813919061315f565b508054600082559060005260206000209081019061181391905b5b808211156131745760008155600101613160565b5090565b60006020828403121561318a57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611d2657600080fd5b6000815180845260005b818110156131e0576020818501810151868301820152016131c4565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611d2660208301846131ba565b73ffffffffffffffffffffffffffffffffffffffff8116811461181357600080fd5b60006020828403121561326557600080fd5b8135611d2681613231565b60006020828403121561328257600080fd5b813567ffffffffffffffff81111561329957600080fd5b82016101008185031215611d2657600080fd5b803567ffffffffffffffff811681146132c457600080fd5b919050565b6000806000604084860312156132de57600080fd5b6132e7846132ac565b9250602084013567ffffffffffffffff8082111561330457600080fd5b818601915086601f83011261331857600080fd5b81358181111561332757600080fd5b87602082850101111561333957600080fd5b6020830194508093505050509250925092565b60008083601f84011261335e57600080fd5b50813567ffffffffffffffff81111561337657600080fd5b6020830191508360208260051b850101111561339157600080fd5b9250929050565b600080600080604085870312156133ae57600080fd5b843567ffffffffffffffff808211156133c657600080fd5b6133d28883890161334c565b909650945060208701359150808211156133eb57600080fd5b506133f88782880161334c565b95989497509550505050565b60006020828403121561341657600080fd5b611d26826132ac565b60006020828403121561343157600080fd5b813567ffffffffffffffff81111561344857600080fd5b820160a08185031215611d2657600080fd5b60208152600082516040602084015261347660608401826131ba565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612b4982826131ba565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015613526577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526135148583516131ba565b945092850192908501906001016134da565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561358157835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161354f565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561358157835167ffffffffffffffff16835292840192918401916001016135a9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715613621576136216135cf565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561366e5761366e6135cf565b604052919050565b801515811461181357600080fd5b80356fffffffffffffffffffffffffffffffff811681146132c457600080fd5b6000606082840312156136b657600080fd5b6040516060810181811067ffffffffffffffff821117156136d9576136d96135cf565b60405290508082356136ea81613676565b81526136f860208401613684565b602082015261370960408401613684565b60408201525092915050565b600080600060e0848603121561372a57600080fd5b613733846132ac565b925061374285602086016136a4565b915061375185608086016136a4565b90509250925092565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261378f57600080fd5b83018035915067ffffffffffffffff8211156137aa57600080fd5b60200191503681900382131561339157600080fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c9082168061381257607f821691505b60208210810361384b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b67ffffffffffffffff84168152604060208201526000612b49604083018486613851565b60208152600061088f602083018486613851565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee183360301811261390657600080fd5b9190910192915050565b600082601f83011261392157600080fd5b813567ffffffffffffffff81111561393b5761393b6135cf565b61396c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613627565b81815284602083860101111561398157600080fd5b816020850160208301376000918101602001919091529392505050565b600061012082360312156139b157600080fd5b6139b96135fe565b6139c2836132ac565b815260208084013567ffffffffffffffff808211156139e057600080fd5b9085019036601f8301126139f357600080fd5b813581811115613a0557613a056135cf565b8060051b613a14858201613627565b9182528381018501918581019036841115613a2e57600080fd5b86860192505b83831015613a6a57823585811115613a4c5760008081fd5b613a5a3689838a0101613910565b8352509186019190860190613a34565b8087890152505050506040860135925080831115613a8757600080fd5b5050613a9536828601613910565b604083015250613aa836606085016136a4565b6060820152613aba3660c085016136a4565b608082015292915050565b601f8211156109aa576000816000526020600020601f850160051c81016020861015613aee5750805b601f850160051c820191505b81811015613b0d57828155600101613afa565b505050505050565b815167ffffffffffffffff811115613b2f57613b2f6135cf565b613b4381613b3d84546137fe565b84613ac5565b602080601f831160018114613b965760008415613b605750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613b0d565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613be357888601518255948401946001909101908401613bc4565b5085821015613c1f57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613c53818401876131ba565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613c919050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612b49565b600060208284031215613cda57600080fd5b8151611d2681613676565b600060208284031215613cf757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff828116828216039081111561067857610678613cfe565b600181815b80851115613d9f57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613d8557613d85613cfe565b80851615613d9257918102915b93841c9390800290613d4b565b509250929050565b600082613db657506001610678565b81613dc357506000610678565b8160018114613dd95760028114613de357613dff565b6001915050610678565b60ff841115613df457613df4613cfe565b50506001821b610678565b5060208310610133831016604e8410600b8410161715613e22575081810a610678565b613e2c8383613d46565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613e5e57613e5e613cfe565b029392505050565b6000611d2660ff841683613da7565b600082613eab577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761067857610678613cfe565b67ffffffffffffffff8316815260406020820152600061088f60408301846131ba565b8181038181111561067857610678613cfe565b67ffffffffffffffff8416815260e08101613f4960208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c083015261088f565b6060810161067882848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060208284031215613fce57600080fd5b8151611d2681613231565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8082018082111561067857610678613cfe56fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"localTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"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\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"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\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"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\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MismatchedArrayLengths\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"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\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"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\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"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\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"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\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"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\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"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\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectors\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config[]\",\"name\":\"outboundConfigs\",\"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\":\"inboundConfigs\",\"type\":\"tuple[]\"}],\"name\":\"setChainRateLimiterConfigs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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: "0x6101006040523480156200001257600080fd5b5060405162004a7c38038062004a7c8339810160408190526200003591620005a2565b8484848484336000816200005c57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008f576200008f81620001eb565b50506001600160a01b0385161580620000af57506001600160a01b038116155b80620000c257506001600160a01b038216155b15620000e1576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808616608081905290831660c0526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa92505050801562000151575060408051601f3d908101601f191682019092526200014e91810190620006c4565b60015b1562000191578060ff168560ff16146200018f576040516332ad3e0760e11b815260ff80871660048301528216602482015260440160405180910390fd5b505b60ff841660a052600480546001600160a01b0319166001600160a01b038316179055825115801560e052620001db57604080516000815260208101909152620001db908462000265565b5050505050505050505062000730565b336001600160a01b038216036200021557604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e05162000286576040516335f4a7b360e01b815260040160405180910390fd5b60005b825181101562000311576000838281518110620002aa57620002aa620006e2565b60209081029190910101519050620002c4600282620003c2565b1562000307576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000289565b5060005b8151811015620003bd576000828281518110620003365762000336620006e2565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003625750620003b4565b6200036f600282620003e2565b15620003b2576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000315565b505050565b6000620003d9836001600160a01b038416620003f9565b90505b92915050565b6000620003d9836001600160a01b038416620004fd565b60008181526001830160205260408120548015620004f257600062000420600183620006f8565b85549091506000906200043690600190620006f8565b9050808214620004a25760008660000182815481106200045a576200045a620006e2565b9060005260206000200154905080876000018481548110620004805762000480620006e2565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004b657620004b66200071a565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003dc565b6000915050620003dc565b60008181526001830160205260408120546200054657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003dc565b506000620003dc565b6001600160a01b03811681146200056557600080fd5b50565b805160ff811681146200057a57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b80516200057a816200054f565b600080600080600060a08688031215620005bb57600080fd5b8551620005c8816200054f565b94506020620005d987820162000568565b60408801519095506001600160401b0380821115620005f757600080fd5b818901915089601f8301126200060c57600080fd5b8151818111156200062157620006216200057f565b8060051b604051601f19603f830116810181811085821117156200064957620006496200057f565b60405291825284820192508381018501918c8311156200066857600080fd5b938501935b828510156200069157620006818562000595565b845293850193928501926200066d565b809850505050505050620006a86060870162000595565b9150620006b86080870162000595565b90509295509295909350565b600060208284031215620006d757600080fd5b620003d98262000568565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003dc57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e05161429b620007e16000396000818161056d01528181611efa0152612ae701526000818161054701528181611a1701526122d00152600081816102eb01528181610d2101528181611bc001528181611c7a01528181611cae01528181611ce101528181611d4601528181611d9f0152611e41015260008181610252015281816102a7015281816107260152818161244d015281816128db0152612cd2015261429b6000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c80639a4575b911610104578063c0d78655116100a2578063dc0bd97111610071578063dc0bd97114610545578063e0351e131461056b578063e8a1da1714610591578063f2fde38b146105a457600080fd5b8063c0d78655146104f7578063c4bffe2b1461050a578063c75eea9c1461051f578063cf7401f31461053257600080fd5b8063acfecf91116100de578063acfecf9114610444578063af58d59f14610457578063b0f479a1146104c6578063b7946580146104e457600080fd5b80639a4575b9146103ef578063a42a7b8b1461040f578063a7cd63b71461042f57600080fd5b806354c8a4f31161017c5780637d54534e1161014b5780637d54534e146103985780638926f54f146103ab5780638da5cb5b146103be578063962d4020146103dc57600080fd5b806354c8a4f31461034a57806362ddd3c41461035f5780636d3d1a581461037257806379ba50971461039057600080fd5b8063240028e8116101b8578063240028e81461029757806324f65ee7146102e457806339077537146103155780634c5ef0ed1461033757600080fd5b806301ffc9a7146101df578063181f5a771461020757806321df0da714610250575b600080fd5b6101f26101ed3660046132f0565b6105b7565b60405190151581526020015b60405180910390f35b6102436040518060400160405280601781526020017f4275726e4d696e74546f6b656e506f6f6c20312e352e3100000000000000000081525081565b6040516101fe9190613396565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101fe565b6101f26102a53660046133cb565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101fe565b6103286103233660046133e8565b61069c565b604051905181526020016101fe565b6101f2610345366004613441565b61086b565b61035d610358366004613510565b6108b5565b005b61035d61036d366004613441565b610930565b60095473ffffffffffffffffffffffffffffffffffffffff16610272565b61035d6109cd565b61035d6103a63660046133cb565b610a9b565b6101f26103b936600461357c565b610b1c565b60015473ffffffffffffffffffffffffffffffffffffffff16610272565b61035d6103ea3660046135dc565b610b33565b6104026103fd366004613676565b610c8d565b6040516101fe91906136b1565b61042261041d36600461357c565b610d66565b6040516101fe9190613708565b610437610ed1565b6040516101fe919061378a565b61035d610452366004613441565b610ee2565b61046a61046536600461357c565b610ffa565b6040516101fe919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610272565b6102436104f236600461357c565b6110cf565b61035d6105053660046133cb565b61117f565b61051261125a565b6040516101fe91906137e4565b61046a61052d36600461357c565b611312565b61035d61054036600461396c565b6113e4565b7f0000000000000000000000000000000000000000000000000000000000000000610272565b7f00000000000000000000000000000000000000000000000000000000000000006101f2565b61035d61059f366004613510565b611468565b61035d6105b23660046133cb565b61197a565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061064a57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061069657507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b6040805160208101909152600081526106b48261198e565b600061070d60608401356107086106ce60c08701876139b1565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bb292505050565b611c76565b905073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f1961075b60608601604087016133cb565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260248101849052604401600060405180830381600087803b1580156107c857600080fd5b505af11580156107dc573d6000803e3d6000fd5b506107f19250505060608401604085016133cb565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08360405161084f91815260200190565b60405180910390a3604080516020810190915290815292915050565b60006108ad8383604051610880929190613a16565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190611e8a565b949350505050565b6108bd611ea5565b61092a84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611ef892505050565b50505050565b610938611ea5565b61094183610b1c565b610988576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6109c88383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506120ae92505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a1e576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610aa3611ea5565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b6000610696600567ffffffffffffffff8416611e8a565b60095473ffffffffffffffffffffffffffffffffffffffff163314801590610b73575060015473ffffffffffffffffffffffffffffffffffffffff163314155b15610bac576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161097f565b8483141580610bbb5750848114155b15610bf2576040517f568efce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b85811015610c8457610c7c878783818110610c1257610c12613a26565b9050602002016020810190610c27919061357c565b868684818110610c3957610c39613a26565b905060600201803603810190610c4f9190613a55565b858585818110610c6157610c61613a26565b905060600201803603810190610c779190613a55565b6121a8565b600101610bf5565b50505050505050565b6040805180820190915260608082526020820152610caa82612292565b610cb7826060013561241e565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610d118460200160208101906104f2919061357c565b8152602001610d5e6040805160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260609101604051602081830303815290604052905090565b905292915050565b67ffffffffffffffff8116600090815260076020526040812060609190610d8f906005016124ba565b90506000815167ffffffffffffffff811115610dad57610dad613826565b604051908082528060200260200182016040528015610de057816020015b6060815260200190600190039081610dcb5790505b50905060005b8251811015610ec95760086000848381518110610e0557610e05613a26565b602002602001015181526020019081526020016000208054610e2690613a71565b80601f0160208091040260200160405190810160405280929190818152602001828054610e5290613a71565b8015610e9f5780601f10610e7457610100808354040283529160200191610e9f565b820191906000526020600020905b815481529060010190602001808311610e8257829003601f168201915b5050505050828281518110610eb657610eb6613a26565b6020908102919091010152600101610de6565b509392505050565b6060610edd60026124ba565b905090565b610eea611ea5565b610ef383610b1c565b610f35576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161097f565b610f758282604051610f48929190613a16565b604080519182900390912067ffffffffffffffff86166000908152600760205291909120600501906124c7565b610fb1578282826040517f74f23c7c00000000000000000000000000000000000000000000000000000000815260040161097f93929190613b0d565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d768383604051610fed929190613b31565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526003909101548084166060830152919091049091166080820152610696906124d3565b67ffffffffffffffff811660009081526007602052604090206004018054606091906110fa90613a71565b80601f016020809104026020016040519081016040528092919081815260200182805461112690613a71565b80156111735780601f1061114857610100808354040283529160200191611173565b820191906000526020600020905b81548152906001019060200180831161115657829003601f168201915b50505050509050919050565b611187611ea5565b73ffffffffffffffffffffffffffffffffffffffff81166111d4576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b6060600061126860056124ba565b90506000815167ffffffffffffffff81111561128657611286613826565b6040519080825280602002602001820160405280156112af578160200160208202803683370190505b50905060005b825181101561130b578281815181106112d0576112d0613a26565b60200260200101518282815181106112ea576112ea613a26565b67ffffffffffffffff909216602092830291909101909101526001016112b5565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526001909101548084166060830152919091049091166080820152610696906124d3565b60095473ffffffffffffffffffffffffffffffffffffffff163314801590611424575060015473ffffffffffffffffffffffffffffffffffffffff163314155b1561145d576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161097f565b6109c88383836121a8565b611470611ea5565b60005b8381101561165d57600085858381811061148f5761148f613a26565b90506020020160208101906114a4919061357c565b90506114bb600567ffffffffffffffff83166124c7565b6114fd576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161097f565b67ffffffffffffffff81166000908152600760205260408120611522906005016124ba565b905060005b815181101561158e5761158582828151811061154557611545613a26565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206005016124c790919063ffffffff16565b50600101611527565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906115f76004830182613283565b600582016000818161160982826132bd565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169450602001925061164b915050565b60405180910390a15050600101611473565b5060005b8181101561197357600083838381811061167d5761167d613a26565b905060200281019061168f9190613b45565b61169890613c11565b90506116a981606001516000612585565b6116b881608001516000612585565b8060400151516000036116f7576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805161170f9060059067ffffffffffffffff166126c2565b6117545780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161097f565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a9091029990931617179094169590951790925590920290911760038201559082015160048201906118d79082613d88565b5060005b82602001515181101561191b5761191383600001518460200151838151811061190657611906613a26565b60200260200101516120ae565b6001016118db565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c282600001518360400151846060015185608001516040516119619493929190613ea2565b60405180910390a15050600101611661565b5050505050565b611982611ea5565b61198b816126ce565b50565b6119a16102a560a08301608084016133cb565b611a00576119b560a08201608083016133cb565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161097f565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb611a4c604084016020850161357c565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015611abd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae19190613f3b565b15611b18576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b30611b2b604083016020840161357c565b612792565b611b50611b43604083016020840161357c565b61034560a08401846139b1565b611b9557611b6160a08201826139b1565b6040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161097f929190613b31565b61198b611ba8604083016020840161357c565b82606001356128b8565b60008151600003611be457507f0000000000000000000000000000000000000000000000000000000000000000919050565b8151602014611c2157816040517f953576f700000000000000000000000000000000000000000000000000000000815260040161097f9190613396565b600082806020019051810190611c379190613f58565b905060ff81111561069657826040517f953576f700000000000000000000000000000000000000000000000000000000815260040161097f9190613396565b60007f000000000000000000000000000000000000000000000000000000000000000060ff168260ff1603611cac575081610696565b7f000000000000000000000000000000000000000000000000000000000000000060ff168260ff161115611d97576000611d067f000000000000000000000000000000000000000000000000000000000000000084613fa0565b9050604d8160ff161115611d7a576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044810185905260640161097f565b611d8581600a6140d9565b611d8f90856140e8565b915050610696565b6000611dc3837f0000000000000000000000000000000000000000000000000000000000000000613fa0565b9050604d8160ff161180611e0a5750611ddd81600a6140d9565b611e07907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6140e8565b84115b15611e75576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044810185905260640161097f565b611e8081600a6140d9565b6108ad9085614123565b600081815260018301602052604081205415155b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611ef6576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f0000000000000000000000000000000000000000000000000000000000000000611f4f576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611fe5576000838281518110611f6f57611f6f613a26565b60200260200101519050611f8d8160026128ff90919063ffffffff16565b15611fdc5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611f52565b5060005b81518110156109c857600082828151811061200657612006613a26565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361204a57506120a6565b612055600282612921565b156120a45760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611fe9565b80516000036120e9576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff841660009081526007909252604090912061211b90600501826126c2565b6121555782826040517f393b8ad200000000000000000000000000000000000000000000000000000000815260040161097f92919061413a565b600081815260086020526040902061216d8382613d88565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea83604051610fed9190613396565b6121b183610b1c565b6121f3576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161097f565b6121fe826000612585565b67ffffffffffffffff831660009081526007602052604090206122219083612943565b61222c816000612585565b67ffffffffffffffff831660009081526007602052604090206122529060020182612943565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516122859392919061415d565b60405180910390a1505050565b6122a56102a560a08301608084016133cb565b6122b9576119b560a08201608083016133cb565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb612305604084016020850161357c565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015612376573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239a9190613f3b565b156123d1576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123e96123e460608301604084016133cb565b612ae5565b6124016123fc604083016020840161357c565b612b64565b61198b612414604083016020840161357c565b8260600135612cb2565b6040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b1580156124a657600080fd5b505af1158015611973573d6000803e3d6000fd5b60606000611e9e83612cf6565b6000611e9e8383612d51565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261256182606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261254591906141e0565b85608001516fffffffffffffffffffffffffffffffff16612e44565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b8151156126505781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806125db575060408201516fffffffffffffffffffffffffffffffff16155b1561261457816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161097f91906141f3565b801561264c576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff16151580612689575060208201516fffffffffffffffffffffffffffffffff1615155b1561264c57816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161097f91906141f3565b6000611e9e8383612e6c565b3373ffffffffffffffffffffffffffffffffffffffff82160361271d576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61279b81610b1c565b6127dd576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161097f565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561285c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128809190613f3b565b61198b576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161097f565b67ffffffffffffffff8216600090815260076020526040902061264c90600201827f0000000000000000000000000000000000000000000000000000000000000000612ebb565b6000611e9e8373ffffffffffffffffffffffffffffffffffffffff8416612d51565b6000611e9e8373ffffffffffffffffffffffffffffffffffffffff8416612e6c565b815460009061296c90700100000000000000000000000000000000900463ffffffff16426141e0565b90508015612a0e57600183015483546129b4916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612e44565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612a34916fffffffffffffffffffffffffffffffff908116911661323e565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906122859084906141f3565b7f00000000000000000000000000000000000000000000000000000000000000001561198b57612b16600282613254565b61198b576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161097f565b612b6d81610b1c565b612baf576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161097f565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612c28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c4c919061422f565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461198b576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161097f565b67ffffffffffffffff8216600090815260076020526040902061264c90827f0000000000000000000000000000000000000000000000000000000000000000612ebb565b60608160000180548060200260200160405190810160405280929190818152602001828054801561117357602002820191906000526020600020905b815481526020019060010190808311612d325750505050509050919050565b60008181526001830160205260408120548015612e3a576000612d756001836141e0565b8554909150600090612d89906001906141e0565b9050808214612dee576000866000018281548110612da957612da9613a26565b9060005260206000200154905080876000018481548110612dcc57612dcc613a26565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612dff57612dff61424c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610696565b6000915050610696565b6000612e6385612e548486614123565b612e5e908761427b565b61323e565b95945050505050565b6000818152600183016020526040812054612eb357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610696565b506000610696565b825474010000000000000000000000000000000000000000900460ff161580612ee2575081155b15612eec57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612f3290700100000000000000000000000000000000900463ffffffff16426141e0565b90508015612ff25781831115612f74576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612fae9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612e44565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156130a95773ffffffffffffffffffffffffffffffffffffffff8416613051576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161097f565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161097f565b848310156131bc5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906130ed90826141e0565b6130f7878a6141e0565b613101919061427b565b61310b91906140e8565b905073ffffffffffffffffffffffffffffffffffffffff8616613164576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161097f565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161097f565b6131c685846141e0565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b600081831061324d5781611e9e565b5090919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611e9e565b50805461328f90613a71565b6000825580601f1061329f575050565b601f01602090049060005260206000209081019061198b91906132d7565b508054600082559060005260206000209081019061198b91905b5b808211156132ec57600081556001016132d8565b5090565b60006020828403121561330257600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611e9e57600080fd5b6000815180845260005b818110156133585760208185018101518683018201520161333c565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611e9e6020830184613332565b73ffffffffffffffffffffffffffffffffffffffff8116811461198b57600080fd5b6000602082840312156133dd57600080fd5b8135611e9e816133a9565b6000602082840312156133fa57600080fd5b813567ffffffffffffffff81111561341157600080fd5b82016101008185031215611e9e57600080fd5b803567ffffffffffffffff8116811461343c57600080fd5b919050565b60008060006040848603121561345657600080fd5b61345f84613424565b9250602084013567ffffffffffffffff8082111561347c57600080fd5b818601915086601f83011261349057600080fd5b81358181111561349f57600080fd5b8760208285010111156134b157600080fd5b6020830194508093505050509250925092565b60008083601f8401126134d657600080fd5b50813567ffffffffffffffff8111156134ee57600080fd5b6020830191508360208260051b850101111561350957600080fd5b9250929050565b6000806000806040858703121561352657600080fd5b843567ffffffffffffffff8082111561353e57600080fd5b61354a888389016134c4565b9096509450602087013591508082111561356357600080fd5b50613570878288016134c4565b95989497509550505050565b60006020828403121561358e57600080fd5b611e9e82613424565b60008083601f8401126135a957600080fd5b50813567ffffffffffffffff8111156135c157600080fd5b60208301915083602060608302850101111561350957600080fd5b600080600080600080606087890312156135f557600080fd5b863567ffffffffffffffff8082111561360d57600080fd5b6136198a838b016134c4565b9098509650602089013591508082111561363257600080fd5b61363e8a838b01613597565b9096509450604089013591508082111561365757600080fd5b5061366489828a01613597565b979a9699509497509295939492505050565b60006020828403121561368857600080fd5b813567ffffffffffffffff81111561369f57600080fd5b820160a08185031215611e9e57600080fd5b6020815260008251604060208401526136cd6060840182613332565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e638282613332565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b8281101561377d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261376b858351613332565b94509285019290850190600101613731565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b818110156137d857835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016137a6565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156137d857835167ffffffffffffffff1683529284019291840191600101613800565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff8111828210171561387857613878613826565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156138c5576138c5613826565b604052919050565b801515811461198b57600080fd5b80356fffffffffffffffffffffffffffffffff8116811461343c57600080fd5b60006060828403121561390d57600080fd5b6040516060810181811067ffffffffffffffff8211171561393057613930613826565b6040529050808235613941816138cd565b815261394f602084016138db565b6020820152613960604084016138db565b60408201525092915050565b600080600060e0848603121561398157600080fd5b61398a84613424565b925061399985602086016138fb565b91506139a885608086016138fb565b90509250925092565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126139e657600080fd5b83018035915067ffffffffffffffff821115613a0157600080fd5b60200191503681900382131561350957600080fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060608284031215613a6757600080fd5b611e9e83836138fb565b600181811c90821680613a8557607f821691505b602082108103613abe577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b67ffffffffffffffff84168152604060208201526000612e63604083018486613ac4565b6020815260006108ad602083018486613ac4565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee1833603018112613b7957600080fd5b9190910192915050565b600082601f830112613b9457600080fd5b813567ffffffffffffffff811115613bae57613bae613826565b613bdf60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161387e565b818152846020838601011115613bf457600080fd5b816020850160208301376000918101602001919091529392505050565b60006101208236031215613c2457600080fd5b613c2c613855565b613c3583613424565b815260208084013567ffffffffffffffff80821115613c5357600080fd5b9085019036601f830112613c6657600080fd5b813581811115613c7857613c78613826565b8060051b613c8785820161387e565b9182528381018501918581019036841115613ca157600080fd5b86860192505b83831015613cdd57823585811115613cbf5760008081fd5b613ccd3689838a0101613b83565b8352509186019190860190613ca7565b8087890152505050506040860135925080831115613cfa57600080fd5b5050613d0836828601613b83565b604083015250613d1b36606085016138fb565b6060820152613d2d3660c085016138fb565b608082015292915050565b601f8211156109c8576000816000526020600020601f850160051c81016020861015613d615750805b601f850160051c820191505b81811015613d8057828155600101613d6d565b505050505050565b815167ffffffffffffffff811115613da257613da2613826565b613db681613db08454613a71565b84613d38565b602080601f831160018114613e095760008415613dd35750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613d80565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613e5657888601518255948401946001909101908401613e37565b5085821015613e9257878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613ec681840187613332565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613f049050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e63565b600060208284031215613f4d57600080fd5b8151611e9e816138cd565b600060208284031215613f6a57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff828116828216039081111561069657610696613f71565b600181815b8085111561401257817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613ff857613ff8613f71565b8085161561400557918102915b93841c9390800290613fbe565b509250929050565b60008261402957506001610696565b8161403657506000610696565b816001811461404c576002811461405657614072565b6001915050610696565b60ff84111561406757614067613f71565b50506001821b610696565b5060208310610133831016604e8410600b8410161715614095575081810a610696565b61409f8383613fb9565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156140d1576140d1613f71565b029392505050565b6000611e9e60ff84168361401a565b60008261411e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761069657610696613f71565b67ffffffffffffffff831681526040602082015260006108ad6040830184613332565b67ffffffffffffffff8416815260e081016141a960208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526108ad565b8181038181111561069657610696613f71565b6060810161069682848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561424157600080fd5b8151611e9e816133a9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8082018082111561069657610696613f7156fea164736f6c6343000818000a", } var BurnMintTokenPoolABI = BurnMintTokenPoolMetaData.ABI @@ -713,6 +713,18 @@ func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) SetChainRateLimite return _BurnMintTokenPool.Contract.SetChainRateLimiterConfig(&_BurnMintTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) } +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "setChainRateLimiterConfigs", remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.SetChainRateLimiterConfigs(&_BurnMintTokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.SetChainRateLimiterConfigs(&_BurnMintTokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) { return _BurnMintTokenPool.contract.Transact(opts, "setRateLimitAdmin", rateLimitAdmin) } @@ -3033,6 +3045,8 @@ type BurnMintTokenPoolInterface interface { SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) + SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go index 7315989c076..46f233948ce 100644 --- a/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go @@ -81,8 +81,8 @@ type TokenPoolChainUpdate struct { } var BurnWithFromMintTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"localTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"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\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"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\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"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\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"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\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"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\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"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\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"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\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"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\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"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\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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\":\"pure\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b5060405162004c5c38038062004c5c833981016040819052620000359162000918565b8484848484336000816200005c57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008f576200008f8162000206565b50506001600160a01b0385161580620000af57506001600160a01b038116155b80620000c257506001600160a01b038216155b15620000e1576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808616608081905290831660c0526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa92505050801562000151575060408051601f3d908101601f191682019092526200014e9181019062000a3a565b60015b1562000192578060ff168560ff161462000190576040516332ad3e0760e11b815260ff8087166004830152821660248201526044015b60405180910390fd5b505b60ff841660a052600480546001600160a01b0319166001600160a01b038316179055825115801560e052620001dc57604080516000815260208101909152620001dc908462000280565b50620001fb935050506001600160a01b038716905030600019620003dd565b505050505062000b84565b336001600160a01b038216036200023057604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e051620002a1576040516335f4a7b360e01b815260040160405180910390fd5b60005b82518110156200032c576000838281518110620002c557620002c562000a58565b60209081029190910101519050620002df600282620004c3565b1562000322576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620002a4565b5060005b8151811015620003d857600082828151811062000351576200035162000a58565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200037d5750620003cf565b6200038a600282620004e3565b15620003cd576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000330565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa1580156200042f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000455919062000a6e565b62000461919062000a9e565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b17909152919250620004bd91869190620004fa16565b50505050565b6000620004da836001600160a01b038416620005cb565b90505b92915050565b6000620004da836001600160a01b038416620006cf565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000549906001600160a01b03851690849062000721565b805190915015620003d857808060200190518101906200056a919062000ab4565b620003d85760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000187565b60008181526001830160205260408120548015620006c4576000620005f260018362000adf565b8554909150600090620006089060019062000adf565b9050808214620006745760008660000182815481106200062c576200062c62000a58565b906000526020600020015490508087600001848154811062000652576200065262000a58565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000688576200068862000af5565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620004dd565b6000915050620004dd565b60008181526001830160205260408120546200071857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620004dd565b506000620004dd565b60606200073284846000856200073a565b949350505050565b6060824710156200079d5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000187565b600080866001600160a01b03168587604051620007bb919062000b31565b60006040518083038185875af1925050503d8060008114620007fa576040519150601f19603f3d011682016040523d82523d6000602084013e620007ff565b606091505b50909250905062000813878383876200081e565b979650505050505050565b60608315620008925782516000036200088a576001600160a01b0385163b6200088a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000187565b508162000732565b620007328383815115620008a95781518083602001fd5b8060405162461bcd60e51b815260040162000187919062000b4f565b6001600160a01b0381168114620008db57600080fd5b50565b805160ff81168114620008f057600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b8051620008f081620008c5565b600080600080600060a086880312156200093157600080fd5b85516200093e81620008c5565b945060206200094f878201620008de565b60408801519095506001600160401b03808211156200096d57600080fd5b818901915089601f8301126200098257600080fd5b815181811115620009975762000997620008f5565b8060051b604051601f19603f83011681018181108582111715620009bf57620009bf620008f5565b60405291825284820192508381018501918c831115620009de57600080fd5b938501935b8285101562000a0757620009f7856200090b565b84529385019392850192620009e3565b80985050505050505062000a1e606087016200090b565b915062000a2e608087016200090b565b90509295509295909350565b60006020828403121562000a4d57600080fd5b620004da82620008de565b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000a8157600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115620004dd57620004dd62000a88565b60006020828403121562000ac757600080fd5b8151801515811462000ad857600080fd5b9392505050565b81810381811115620004dd57620004dd62000a88565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000b2857818101518382015260200162000b0e565b50506000910152565b6000825162000b4581846020870162000b0b565b9190910192915050565b602081526000825180602084015262000b7081604085016020870162000b0b565b601f01601f19169190910160400192915050565b60805160a05160c05160e05161402762000c356000396000818161054801528181611d7b01526127cc0152600081816105220152818161189801526120670152600081816102d901528181610ba201528181611a4101528181611afb01528181611b2f01528181611b6201528181611bc701528181611c200152611cc20152600081816102400152818161029501528181610701015281816121ea0152818161276201526129b701526140276000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639a4575b911610104578063c0d78655116100a2578063dc0bd97111610071578063dc0bd97114610520578063e0351e1314610546578063e8a1da171461056c578063f2fde38b1461057f57600080fd5b8063c0d78655146104d2578063c4bffe2b146104e5578063c75eea9c146104fa578063cf7401f31461050d57600080fd5b8063acfecf91116100de578063acfecf911461041f578063af58d59f14610432578063b0f479a1146104a1578063b7946580146104bf57600080fd5b80639a4575b9146103ca578063a42a7b8b146103ea578063a7cd63b71461040a57600080fd5b806354c8a4f31161017157806379ba50971161014b57806379ba50971461037e5780637d54534e146103865780638926f54f146103995780638da5cb5b146103ac57600080fd5b806354c8a4f31461033857806362ddd3c41461034d5780636d3d1a581461036057600080fd5b8063240028e8116101ad578063240028e81461028557806324f65ee7146102d257806339077537146103035780634c5ef0ed1461032557600080fd5b806301ffc9a7146101d4578063181f5a77146101fc57806321df0da71461023e575b600080fd5b6101e76101e2366004613177565b610592565b60405190151581526020015b60405180910390f35b60408051808201909152601f81527f4275726e5769746846726f6d4d696e74546f6b656e506f6f6c20312e352e310060208201525b6040516101f3919061321d565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b6101e7610293366004613252565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101f3565b61031661031136600461326f565b610677565b604051905181526020016101f3565b6101e76103333660046132c8565b610846565b61034b610346366004613397565b610890565b005b61034b61035b3660046132c8565b61090b565b60095473ffffffffffffffffffffffffffffffffffffffff16610260565b61034b6109a8565b61034b610394366004613252565b610a76565b6101e76103a7366004613403565b610af7565b60015473ffffffffffffffffffffffffffffffffffffffff16610260565b6103dd6103d836600461341e565b610b0e565b6040516101f39190613459565b6103fd6103f8366004613403565b610be7565b6040516101f391906134b0565b610412610d52565b6040516101f39190613532565b61034b61042d3660046132c8565b610d63565b610445610440366004613403565b610e7b565b6040516101f3919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610260565b6102316104cd366004613403565b610f50565b61034b6104e0366004613252565b611000565b6104ed6110db565b6040516101f3919061358c565b610445610508366004613403565b611193565b61034b61051b366004613714565b611265565b7f0000000000000000000000000000000000000000000000000000000000000000610260565b7f00000000000000000000000000000000000000000000000000000000000000006101e7565b61034b61057a366004613397565b6112e9565b61034b61058d366004613252565b6117fb565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061062557507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061067157507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b60408051602081019091526000815261068f8261180f565b60006106e860608401356106e36106a960c0870187613759565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a3392505050565b611af7565b905073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f196107366060860160408701613252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260248101849052604401600060405180830381600087803b1580156107a357600080fd5b505af11580156107b7573d6000803e3d6000fd5b506107cc925050506060840160408501613252565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08360405161082a91815260200190565b60405180910390a3604080516020810190915290815292915050565b6000610888838360405161085b9291906137be565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190611d0b565b949350505050565b610898611d26565b61090584848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611d7992505050565b50505050565b610913611d26565b61091c83610af7565b610963576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6109a38383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611f2f92505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146109f9576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610a7e611d26565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b6000610671600567ffffffffffffffff8416611d0b565b6040805180820190915260608082526020820152610b2b82612029565b610b3882606001356121b5565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610b928460200160208101906104cd9190613403565b8152602001610bdf6040805160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260609101604051602081830303815290604052905090565b905292915050565b67ffffffffffffffff8116600090815260076020526040812060609190610c1090600501612257565b90506000815167ffffffffffffffff811115610c2e57610c2e6135ce565b604051908082528060200260200182016040528015610c6157816020015b6060815260200190600190039081610c4c5790505b50905060005b8251811015610d4a5760086000848381518110610c8657610c866137ce565b602002602001015181526020019081526020016000208054610ca7906137fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610cd3906137fd565b8015610d205780601f10610cf557610100808354040283529160200191610d20565b820191906000526020600020905b815481529060010190602001808311610d0357829003601f168201915b5050505050828281518110610d3757610d376137ce565b6020908102919091010152600101610c67565b509392505050565b6060610d5e6002612257565b905090565b610d6b611d26565b610d7483610af7565b610db6576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161095a565b610df68282604051610dc99291906137be565b604080519182900390912067ffffffffffffffff8616600090815260076020529190912060050190612264565b610e32578282826040517f74f23c7c00000000000000000000000000000000000000000000000000000000815260040161095a93929190613899565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d768383604051610e6e9291906138bd565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261067190612270565b67ffffffffffffffff81166000908152600760205260409020600401805460609190610f7b906137fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610fa7906137fd565b8015610ff45780601f10610fc957610100808354040283529160200191610ff4565b820191906000526020600020905b815481529060010190602001808311610fd757829003601f168201915b50505050509050919050565b611008611d26565b73ffffffffffffffffffffffffffffffffffffffff8116611055576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006110e96005612257565b90506000815167ffffffffffffffff811115611107576111076135ce565b604051908082528060200260200182016040528015611130578160200160208202803683370190505b50905060005b825181101561118c57828181518110611151576111516137ce565b602002602001015182828151811061116b5761116b6137ce565b67ffffffffffffffff90921660209283029190910190910152600101611136565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261067190612270565b60095473ffffffffffffffffffffffffffffffffffffffff1633148015906112a5575060015473ffffffffffffffffffffffffffffffffffffffff163314155b156112de576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161095a565b6109a3838383612322565b6112f1611d26565b60005b838110156114de576000858583818110611310576113106137ce565b90506020020160208101906113259190613403565b905061133c600567ffffffffffffffff8316612264565b61137e576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161095a565b67ffffffffffffffff811660009081526007602052604081206113a390600501612257565b905060005b815181101561140f576114068282815181106113c6576113c66137ce565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060050161226490919063ffffffff16565b506001016113a8565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff00000000000000000000000000000000000000000090811682556001820183905560028201805490911690556003810182905590611478600483018261310a565b600582016000818161148a8282613144565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916945060200192506114cc915050565b60405180910390a150506001016112f4565b5060005b818110156117f45760008383838181106114fe576114fe6137ce565b905060200281019061151091906138d1565b6115199061399d565b905061152a8160600151600061240c565b6115398160800151600061240c565b806040015151600003611578576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516115909060059067ffffffffffffffff16612549565b6115d55780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161095a565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a9091029990931617179094169590951790925590920290911760038201559082015160048201906117589082613b14565b5060005b82602001515181101561179c57611794836000015184602001518381518110611787576117876137ce565b6020026020010151611f2f565b60010161175c565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c282600001518360400151846060015185608001516040516117e29493929190613c2e565b60405180910390a150506001016114e2565b5050505050565b611803611d26565b61180c81612555565b50565b61182261029360a0830160808401613252565b6118815761183660a0820160808301613252565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161095a565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6118cd6040840160208501613403565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa15801561193e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119629190613cc7565b15611999576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119b16119ac6040830160208401613403565b612619565b6119d16119c46040830160208401613403565b61033360a0840184613759565b611a16576119e260a0820182613759565b6040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161095a9291906138bd565b61180c611a296040830160208401613403565b826060013561273f565b60008151600003611a6557507f0000000000000000000000000000000000000000000000000000000000000000919050565b8151602014611aa257816040517f953576f700000000000000000000000000000000000000000000000000000000815260040161095a919061321d565b600082806020019051810190611ab89190613ce4565b905060ff81111561067157826040517f953576f700000000000000000000000000000000000000000000000000000000815260040161095a919061321d565b60007f000000000000000000000000000000000000000000000000000000000000000060ff168260ff1603611b2d575081610671565b7f000000000000000000000000000000000000000000000000000000000000000060ff168260ff161115611c18576000611b877f000000000000000000000000000000000000000000000000000000000000000084613d2c565b9050604d8160ff161115611bfb576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044810185905260640161095a565b611c0681600a613e65565b611c109085613e74565b915050610671565b6000611c44837f0000000000000000000000000000000000000000000000000000000000000000613d2c565b9050604d8160ff161180611c8b5750611c5e81600a613e65565b611c88907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff613e74565b84115b15611cf6576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044810185905260640161095a565b611d0181600a613e65565b6108889085613eaf565b600081815260018301602052604081205415155b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611d77576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f0000000000000000000000000000000000000000000000000000000000000000611dd0576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611e66576000838281518110611df057611df06137ce565b60200260200101519050611e0e81600261278690919063ffffffff16565b15611e5d5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611dd3565b5060005b81518110156109a3576000828281518110611e8757611e876137ce565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ecb5750611f27565b611ed66002826127a8565b15611f255760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611e6a565b8051600003611f6a576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff8416600090815260079092526040909120611f9c9060050182612549565b611fd65782826040517f393b8ad200000000000000000000000000000000000000000000000000000000815260040161095a929190613ec6565b6000818152600860205260409020611fee8382613b14565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea83604051610e6e919061321d565b61203c61029360a0830160808401613252565b6120505761183660a0820160808301613252565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb61209c6040840160208501613403565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa15801561210d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121319190613cc7565b15612168576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61218061217b6060830160408401613252565b6127ca565b6121986121936040830160208401613403565b612849565b61180c6121ab6040830160208401613403565b8260600135612997565b6040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639dc29fac90604401600060405180830381600087803b15801561224357600080fd5b505af11580156117f4573d6000803e3d6000fd5b60606000611d1f836129db565b6000611d1f8383612a36565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526122fe82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426122e29190613ee9565b85608001516fffffffffffffffffffffffffffffffff16612b29565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61232b83610af7565b61236d576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161095a565b61237882600061240c565b67ffffffffffffffff8316600090815260076020526040902061239b9083612b51565b6123a681600061240c565b67ffffffffffffffff831660009081526007602052604090206123cc9060020182612b51565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516123ff93929190613efc565b60405180910390a1505050565b8151156124d75781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612462575060408201516fffffffffffffffffffffffffffffffff16155b1561249b57816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161095a9190613f7f565b80156124d3576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff16151580612510575060208201516fffffffffffffffffffffffffffffffff1615155b156124d357816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161095a9190613f7f565b6000611d1f8383612cf3565b3373ffffffffffffffffffffffffffffffffffffffff8216036125a4576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61262281610af7565b612664576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161095a565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa1580156126e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127079190613cc7565b61180c576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161095a565b67ffffffffffffffff821660009081526007602052604090206124d390600201827f0000000000000000000000000000000000000000000000000000000000000000612d42565b6000611d1f8373ffffffffffffffffffffffffffffffffffffffff8416612a36565b6000611d1f8373ffffffffffffffffffffffffffffffffffffffff8416612cf3565b7f00000000000000000000000000000000000000000000000000000000000000001561180c576127fb6002826130c5565b61180c576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161095a565b61285281610af7565b612894576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161095a565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561290d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129319190613fbb565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461180c576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161095a565b67ffffffffffffffff821660009081526007602052604090206124d390827f0000000000000000000000000000000000000000000000000000000000000000612d42565b606081600001805480602002602001604051908101604052809291908181526020018280548015610ff457602002820191906000526020600020905b815481526020019060010190808311612a175750505050509050919050565b60008181526001830160205260408120548015612b1f576000612a5a600183613ee9565b8554909150600090612a6e90600190613ee9565b9050808214612ad3576000866000018281548110612a8e57612a8e6137ce565b9060005260206000200154905080876000018481548110612ab157612ab16137ce565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612ae457612ae4613fd8565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610671565b6000915050610671565b6000612b4885612b398486613eaf565b612b439087614007565b6130f4565b95945050505050565b8154600090612b7a90700100000000000000000000000000000000900463ffffffff1642613ee9565b90508015612c1c5760018301548354612bc2916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612b29565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612c42916fffffffffffffffffffffffffffffffff90811691166130f4565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906123ff908490613f7f565b6000818152600183016020526040812054612d3a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610671565b506000610671565b825474010000000000000000000000000000000000000000900460ff161580612d69575081155b15612d7357505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612db990700100000000000000000000000000000000900463ffffffff1642613ee9565b90508015612e795781831115612dfb576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612e359083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612b29565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612f305773ffffffffffffffffffffffffffffffffffffffff8416612ed8576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161095a565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161095a565b848310156130435760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612f749082613ee9565b612f7e878a613ee9565b612f889190614007565b612f929190613e74565b905073ffffffffffffffffffffffffffffffffffffffff8616612feb576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161095a565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161095a565b61304d8584613ee9565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611d1f565b60008183106131035781611d1f565b5090919050565b508054613116906137fd565b6000825580601f10613126575050565b601f01602090049060005260206000209081019061180c919061315e565b508054600082559060005260206000209081019061180c91905b5b80821115613173576000815560010161315f565b5090565b60006020828403121561318957600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611d1f57600080fd5b6000815180845260005b818110156131df576020818501810151868301820152016131c3565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611d1f60208301846131b9565b73ffffffffffffffffffffffffffffffffffffffff8116811461180c57600080fd5b60006020828403121561326457600080fd5b8135611d1f81613230565b60006020828403121561328157600080fd5b813567ffffffffffffffff81111561329857600080fd5b82016101008185031215611d1f57600080fd5b803567ffffffffffffffff811681146132c357600080fd5b919050565b6000806000604084860312156132dd57600080fd5b6132e6846132ab565b9250602084013567ffffffffffffffff8082111561330357600080fd5b818601915086601f83011261331757600080fd5b81358181111561332657600080fd5b87602082850101111561333857600080fd5b6020830194508093505050509250925092565b60008083601f84011261335d57600080fd5b50813567ffffffffffffffff81111561337557600080fd5b6020830191508360208260051b850101111561339057600080fd5b9250929050565b600080600080604085870312156133ad57600080fd5b843567ffffffffffffffff808211156133c557600080fd5b6133d18883890161334b565b909650945060208701359150808211156133ea57600080fd5b506133f78782880161334b565b95989497509550505050565b60006020828403121561341557600080fd5b611d1f826132ab565b60006020828403121561343057600080fd5b813567ffffffffffffffff81111561344757600080fd5b820160a08185031215611d1f57600080fd5b60208152600082516040602084015261347560608401826131b9565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612b4882826131b9565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015613525577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526135138583516131b9565b945092850192908501906001016134d9565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561358057835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161354e565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561358057835167ffffffffffffffff16835292840192918401916001016135a8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715613620576136206135ce565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561366d5761366d6135ce565b604052919050565b801515811461180c57600080fd5b80356fffffffffffffffffffffffffffffffff811681146132c357600080fd5b6000606082840312156136b557600080fd5b6040516060810181811067ffffffffffffffff821117156136d8576136d86135ce565b60405290508082356136e981613675565b81526136f760208401613683565b602082015261370860408401613683565b60408201525092915050565b600080600060e0848603121561372957600080fd5b613732846132ab565b925061374185602086016136a3565b915061375085608086016136a3565b90509250925092565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261378e57600080fd5b83018035915067ffffffffffffffff8211156137a957600080fd5b60200191503681900382131561339057600080fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c9082168061381157607f821691505b60208210810361384a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b67ffffffffffffffff84168152604060208201526000612b48604083018486613850565b602081526000610888602083018486613850565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee183360301811261390557600080fd5b9190910192915050565b600082601f83011261392057600080fd5b813567ffffffffffffffff81111561393a5761393a6135ce565b61396b60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613626565b81815284602083860101111561398057600080fd5b816020850160208301376000918101602001919091529392505050565b600061012082360312156139b057600080fd5b6139b86135fd565b6139c1836132ab565b815260208084013567ffffffffffffffff808211156139df57600080fd5b9085019036601f8301126139f257600080fd5b813581811115613a0457613a046135ce565b8060051b613a13858201613626565b9182528381018501918581019036841115613a2d57600080fd5b86860192505b83831015613a6957823585811115613a4b5760008081fd5b613a593689838a010161390f565b8352509186019190860190613a33565b8087890152505050506040860135925080831115613a8657600080fd5b5050613a943682860161390f565b604083015250613aa736606085016136a3565b6060820152613ab93660c085016136a3565b608082015292915050565b601f8211156109a3576000816000526020600020601f850160051c81016020861015613aed5750805b601f850160051c820191505b81811015613b0c57828155600101613af9565b505050505050565b815167ffffffffffffffff811115613b2e57613b2e6135ce565b613b4281613b3c84546137fd565b84613ac4565b602080601f831160018114613b955760008415613b5f5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613b0c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613be257888601518255948401946001909101908401613bc3565b5085821015613c1e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613c52818401876131b9565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613c909050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612b48565b600060208284031215613cd957600080fd5b8151611d1f81613675565b600060208284031215613cf657600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff828116828216039081111561067157610671613cfd565b600181815b80851115613d9e57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613d8457613d84613cfd565b80851615613d9157918102915b93841c9390800290613d4a565b509250929050565b600082613db557506001610671565b81613dc257506000610671565b8160018114613dd85760028114613de257613dfe565b6001915050610671565b60ff841115613df357613df3613cfd565b50506001821b610671565b5060208310610133831016604e8410600b8410161715613e21575081810a610671565b613e2b8383613d45565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613e5d57613e5d613cfd565b029392505050565b6000611d1f60ff841683613da6565b600082613eaa577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761067157610671613cfd565b67ffffffffffffffff8316815260406020820152600061088860408301846131b9565b8181038181111561067157610671613cfd565b67ffffffffffffffff8416815260e08101613f4860208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152610888565b6060810161067182848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060208284031215613fcd57600080fd5b8151611d1f81613230565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8082018082111561067157610671613cfd56fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"localTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"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\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"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\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"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\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MismatchedArrayLengths\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"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\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"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\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"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\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"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\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"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\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"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\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectors\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config[]\",\"name\":\"outboundConfigs\",\"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\":\"inboundConfigs\",\"type\":\"tuple[]\"}],\"name\":\"setChainRateLimiterConfigs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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\":\"pure\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b5060405162004ecf38038062004ecf833981016040819052620000359162000918565b8484848484336000816200005c57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008f576200008f8162000206565b50506001600160a01b0385161580620000af57506001600160a01b038116155b80620000c257506001600160a01b038216155b15620000e1576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808616608081905290831660c0526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa92505050801562000151575060408051601f3d908101601f191682019092526200014e9181019062000a3a565b60015b1562000192578060ff168560ff161462000190576040516332ad3e0760e11b815260ff8087166004830152821660248201526044015b60405180910390fd5b505b60ff841660a052600480546001600160a01b0319166001600160a01b038316179055825115801560e052620001dc57604080516000815260208101909152620001dc908462000280565b50620001fb935050506001600160a01b038716905030600019620003dd565b505050505062000b84565b336001600160a01b038216036200023057604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e051620002a1576040516335f4a7b360e01b815260040160405180910390fd5b60005b82518110156200032c576000838281518110620002c557620002c562000a58565b60209081029190910101519050620002df600282620004c3565b1562000322576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620002a4565b5060005b8151811015620003d857600082828151811062000351576200035162000a58565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200037d5750620003cf565b6200038a600282620004e3565b15620003cd576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000330565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa1580156200042f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000455919062000a6e565b62000461919062000a9e565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b17909152919250620004bd91869190620004fa16565b50505050565b6000620004da836001600160a01b038416620005cb565b90505b92915050565b6000620004da836001600160a01b038416620006cf565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000549906001600160a01b03851690849062000721565b805190915015620003d857808060200190518101906200056a919062000ab4565b620003d85760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000187565b60008181526001830160205260408120548015620006c4576000620005f260018362000adf565b8554909150600090620006089060019062000adf565b9050808214620006745760008660000182815481106200062c576200062c62000a58565b906000526020600020015490508087600001848154811062000652576200065262000a58565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000688576200068862000af5565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620004dd565b6000915050620004dd565b60008181526001830160205260408120546200071857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620004dd565b506000620004dd565b60606200073284846000856200073a565b949350505050565b6060824710156200079d5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000187565b600080866001600160a01b03168587604051620007bb919062000b31565b60006040518083038185875af1925050503d8060008114620007fa576040519150601f19603f3d011682016040523d82523d6000602084013e620007ff565b606091505b50909250905062000813878383876200081e565b979650505050505050565b60608315620008925782516000036200088a576001600160a01b0385163b6200088a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000187565b508162000732565b620007328383815115620008a95781518083602001fd5b8060405162461bcd60e51b815260040162000187919062000b4f565b6001600160a01b0381168114620008db57600080fd5b50565b805160ff81168114620008f057600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b8051620008f081620008c5565b600080600080600060a086880312156200093157600080fd5b85516200093e81620008c5565b945060206200094f878201620008de565b60408801519095506001600160401b03808211156200096d57600080fd5b818901915089601f8301126200098257600080fd5b815181811115620009975762000997620008f5565b8060051b604051601f19603f83011681018181108582111715620009bf57620009bf620008f5565b60405291825284820192508381018501918c831115620009de57600080fd5b938501935b8285101562000a0757620009f7856200090b565b84529385019392850192620009e3565b80985050505050505062000a1e606087016200090b565b915062000a2e608087016200090b565b90509295509295909350565b60006020828403121562000a4d57600080fd5b620004da82620008de565b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000a8157600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115620004dd57620004dd62000a88565b60006020828403121562000ac757600080fd5b8151801515811462000ad857600080fd5b9392505050565b81810381811115620004dd57620004dd62000a88565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000b2857818101518382015260200162000b0e565b50506000910152565b6000825162000b4581846020870162000b0b565b9190910192915050565b602081526000825180602084015262000b7081604085016020870162000b0b565b601f01601f19169190910160400192915050565b60805160a05160c05160e05161429a62000c356000396000818161056601528181611ef30152612ae601526000818161054001528181611a1001526122c90152600081816102e401528181610d1a01528181611bb901528181611c7301528181611ca701528181611cda01528181611d3f01528181611d980152611e3a01526000818161024b015281816102a00152818161071f0152818161244c015281816128da0152612cd1015261429a6000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c80639a4575b911610104578063c0d78655116100a2578063dc0bd97111610071578063dc0bd9711461053e578063e0351e1314610564578063e8a1da171461058a578063f2fde38b1461059d57600080fd5b8063c0d78655146104f0578063c4bffe2b14610503578063c75eea9c14610518578063cf7401f31461052b57600080fd5b8063acfecf91116100de578063acfecf911461043d578063af58d59f14610450578063b0f479a1146104bf578063b7946580146104dd57600080fd5b80639a4575b9146103e8578063a42a7b8b14610408578063a7cd63b71461042857600080fd5b806354c8a4f31161017c5780637d54534e1161014b5780637d54534e146103915780638926f54f146103a45780638da5cb5b146103b7578063962d4020146103d557600080fd5b806354c8a4f31461034357806362ddd3c4146103585780636d3d1a581461036b57806379ba50971461038957600080fd5b8063240028e8116101b8578063240028e81461029057806324f65ee7146102dd578063390775371461030e5780634c5ef0ed1461033057600080fd5b806301ffc9a7146101df578063181f5a771461020757806321df0da714610249575b600080fd5b6101f26101ed3660046132ef565b6105b0565b60405190151581526020015b60405180910390f35b60408051808201909152601f81527f4275726e5769746846726f6d4d696e74546f6b656e506f6f6c20312e352e310060208201525b6040516101fe9190613395565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101fe565b6101f261029e3660046133ca565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101fe565b61032161031c3660046133e7565b610695565b604051905181526020016101fe565b6101f261033e366004613440565b610864565b61035661035136600461350f565b6108ae565b005b610356610366366004613440565b610929565b60095473ffffffffffffffffffffffffffffffffffffffff1661026b565b6103566109c6565b61035661039f3660046133ca565b610a94565b6101f26103b236600461357b565b610b15565b60015473ffffffffffffffffffffffffffffffffffffffff1661026b565b6103566103e33660046135db565b610b2c565b6103fb6103f6366004613675565b610c86565b6040516101fe91906136b0565b61041b61041636600461357b565b610d5f565b6040516101fe9190613707565b610430610eca565b6040516101fe9190613789565b61035661044b366004613440565b610edb565b61046361045e36600461357b565b610ff3565b6040516101fe919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff1661026b565b61023c6104eb36600461357b565b6110c8565b6103566104fe3660046133ca565b611178565b61050b611253565b6040516101fe91906137e3565b61046361052636600461357b565b61130b565b61035661053936600461396b565b6113dd565b7f000000000000000000000000000000000000000000000000000000000000000061026b565b7f00000000000000000000000000000000000000000000000000000000000000006101f2565b61035661059836600461350f565b611461565b6103566105ab3660046133ca565b611973565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061064357507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061068f57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b6040805160208101909152600081526106ad82611987565b600061070660608401356107016106c760c08701876139b0565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bab92505050565b611c6f565b905073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f1961075460608601604087016133ca565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260248101849052604401600060405180830381600087803b1580156107c157600080fd5b505af11580156107d5573d6000803e3d6000fd5b506107ea9250505060608401604085016133ca565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08360405161084891815260200190565b60405180910390a3604080516020810190915290815292915050565b60006108a68383604051610879929190613a15565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190611e83565b949350505050565b6108b6611e9e565b61092384848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611ef192505050565b50505050565b610931611e9e565b61093a83610b15565b610981576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6109c18383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506120a792505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a17576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610a9c611e9e565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b600061068f600567ffffffffffffffff8416611e83565b60095473ffffffffffffffffffffffffffffffffffffffff163314801590610b6c575060015473ffffffffffffffffffffffffffffffffffffffff163314155b15610ba5576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610978565b8483141580610bb45750848114155b15610beb576040517f568efce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b85811015610c7d57610c75878783818110610c0b57610c0b613a25565b9050602002016020810190610c20919061357b565b868684818110610c3257610c32613a25565b905060600201803603810190610c489190613a54565b858585818110610c5a57610c5a613a25565b905060600201803603810190610c709190613a54565b6121a1565b600101610bee565b50505050505050565b6040805180820190915260608082526020820152610ca38261228b565b610cb08260600135612417565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610d0a8460200160208101906104eb919061357b565b8152602001610d576040805160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260609101604051602081830303815290604052905090565b905292915050565b67ffffffffffffffff8116600090815260076020526040812060609190610d88906005016124b9565b90506000815167ffffffffffffffff811115610da657610da6613825565b604051908082528060200260200182016040528015610dd957816020015b6060815260200190600190039081610dc45790505b50905060005b8251811015610ec25760086000848381518110610dfe57610dfe613a25565b602002602001015181526020019081526020016000208054610e1f90613a70565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4b90613a70565b8015610e985780601f10610e6d57610100808354040283529160200191610e98565b820191906000526020600020905b815481529060010190602001808311610e7b57829003601f168201915b5050505050828281518110610eaf57610eaf613a25565b6020908102919091010152600101610ddf565b509392505050565b6060610ed660026124b9565b905090565b610ee3611e9e565b610eec83610b15565b610f2e576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610978565b610f6e8282604051610f41929190613a15565b604080519182900390912067ffffffffffffffff86166000908152600760205291909120600501906124c6565b610faa578282826040517f74f23c7c00000000000000000000000000000000000000000000000000000000815260040161097893929190613b0c565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d768383604051610fe6929190613b30565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261068f906124d2565b67ffffffffffffffff811660009081526007602052604090206004018054606091906110f390613a70565b80601f016020809104026020016040519081016040528092919081815260200182805461111f90613a70565b801561116c5780601f106111415761010080835404028352916020019161116c565b820191906000526020600020905b81548152906001019060200180831161114f57829003601f168201915b50505050509050919050565b611180611e9e565b73ffffffffffffffffffffffffffffffffffffffff81166111cd576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b6060600061126160056124b9565b90506000815167ffffffffffffffff81111561127f5761127f613825565b6040519080825280602002602001820160405280156112a8578160200160208202803683370190505b50905060005b8251811015611304578281815181106112c9576112c9613a25565b60200260200101518282815181106112e3576112e3613a25565b67ffffffffffffffff909216602092830291909101909101526001016112ae565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261068f906124d2565b60095473ffffffffffffffffffffffffffffffffffffffff16331480159061141d575060015473ffffffffffffffffffffffffffffffffffffffff163314155b15611456576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610978565b6109c18383836121a1565b611469611e9e565b60005b8381101561165657600085858381811061148857611488613a25565b905060200201602081019061149d919061357b565b90506114b4600567ffffffffffffffff83166124c6565b6114f6576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610978565b67ffffffffffffffff8116600090815260076020526040812061151b906005016124b9565b905060005b81518110156115875761157e82828151811061153e5761153e613a25565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206005016124c690919063ffffffff16565b50600101611520565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906115f06004830182613282565b600582016000818161160282826132bc565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d85991694506020019250611644915050565b60405180910390a1505060010161146c565b5060005b8181101561196c57600083838381811061167657611676613a25565b90506020028101906116889190613b44565b61169190613c10565b90506116a281606001516000612584565b6116b181608001516000612584565b8060400151516000036116f0576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516117089060059067ffffffffffffffff166126c1565b61174d5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610978565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a9091029990931617179094169590951790925590920290911760038201559082015160048201906118d09082613d87565b5060005b8260200151518110156119145761190c8360000151846020015183815181106118ff576118ff613a25565b60200260200101516120a7565b6001016118d4565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2826000015183604001518460600151856080015160405161195a9493929190613ea1565b60405180910390a1505060010161165a565b5050505050565b61197b611e9e565b611984816126cd565b50565b61199a61029e60a08301608084016133ca565b6119f9576119ae60a08201608083016133ca565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610978565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb611a45604084016020850161357b565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015611ab6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ada9190613f3a565b15611b11576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b29611b24604083016020840161357b565b612791565b611b49611b3c604083016020840161357b565b61033e60a08401846139b0565b611b8e57611b5a60a08201826139b0565b6040517f24eb47e5000000000000000000000000000000000000000000000000000000008152600401610978929190613b30565b611984611ba1604083016020840161357b565b82606001356128b7565b60008151600003611bdd57507f0000000000000000000000000000000000000000000000000000000000000000919050565b8151602014611c1a57816040517f953576f70000000000000000000000000000000000000000000000000000000081526004016109789190613395565b600082806020019051810190611c309190613f57565b905060ff81111561068f57826040517f953576f70000000000000000000000000000000000000000000000000000000081526004016109789190613395565b60007f000000000000000000000000000000000000000000000000000000000000000060ff168260ff1603611ca557508161068f565b7f000000000000000000000000000000000000000000000000000000000000000060ff168260ff161115611d90576000611cff7f000000000000000000000000000000000000000000000000000000000000000084613f9f565b9050604d8160ff161115611d73576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f000000000000000000000000000000000000000000000000000000000000000016602482015260448101859052606401610978565b611d7e81600a6140d8565b611d8890856140e7565b91505061068f565b6000611dbc837f0000000000000000000000000000000000000000000000000000000000000000613f9f565b9050604d8160ff161180611e035750611dd681600a6140d8565b611e00907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6140e7565b84115b15611e6e576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f000000000000000000000000000000000000000000000000000000000000000016602482015260448101859052606401610978565b611e7981600a6140d8565b6108a69085614122565b600081815260018301602052604081205415155b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611eef576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f0000000000000000000000000000000000000000000000000000000000000000611f48576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611fde576000838281518110611f6857611f68613a25565b60200260200101519050611f868160026128fe90919063ffffffff16565b15611fd55760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611f4b565b5060005b81518110156109c1576000828281518110611fff57611fff613a25565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612043575061209f565b61204e600282612920565b1561209d5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611fe2565b80516000036120e2576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff841660009081526007909252604090912061211490600501826126c1565b61214e5782826040517f393b8ad2000000000000000000000000000000000000000000000000000000008152600401610978929190614139565b60008181526008602052604090206121668382613d87565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea83604051610fe69190613395565b6121aa83610b15565b6121ec576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610978565b6121f7826000612584565b67ffffffffffffffff8316600090815260076020526040902061221a9083612942565b612225816000612584565b67ffffffffffffffff8316600090815260076020526040902061224b9060020182612942565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161227e9392919061415c565b60405180910390a1505050565b61229e61029e60a08301608084016133ca565b6122b2576119ae60a08201608083016133ca565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6122fe604084016020850161357b565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa15801561236f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123939190613f3a565b156123ca576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123e26123dd60608301604084016133ca565b612ae4565b6123fa6123f5604083016020840161357b565b612b63565b61198461240d604083016020840161357b565b8260600135612cb1565b6040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639dc29fac90604401600060405180830381600087803b1580156124a557600080fd5b505af115801561196c573d6000803e3d6000fd5b60606000611e9783612cf5565b6000611e978383612d50565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261256082606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261254491906141df565b85608001516fffffffffffffffffffffffffffffffff16612e43565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b81511561264f5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806125da575060408201516fffffffffffffffffffffffffffffffff16155b1561261357816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161097891906141f2565b801561264b576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff16151580612688575060208201516fffffffffffffffffffffffffffffffff1615155b1561264b57816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161097891906141f2565b6000611e978383612e6b565b3373ffffffffffffffffffffffffffffffffffffffff82160361271c576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61279a81610b15565b6127dc576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610978565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561285b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061287f9190613f3a565b611984576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610978565b67ffffffffffffffff8216600090815260076020526040902061264b90600201827f0000000000000000000000000000000000000000000000000000000000000000612eba565b6000611e978373ffffffffffffffffffffffffffffffffffffffff8416612d50565b6000611e978373ffffffffffffffffffffffffffffffffffffffff8416612e6b565b815460009061296b90700100000000000000000000000000000000900463ffffffff16426141df565b90508015612a0d57600183015483546129b3916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612e43565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612a33916fffffffffffffffffffffffffffffffff908116911661323d565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061227e9084906141f2565b7f00000000000000000000000000000000000000000000000000000000000000001561198457612b15600282613253565b611984576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610978565b612b6c81610b15565b612bae576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610978565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612c27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c4b919061422e565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611984576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610978565b67ffffffffffffffff8216600090815260076020526040902061264b90827f0000000000000000000000000000000000000000000000000000000000000000612eba565b60608160000180548060200260200160405190810160405280929190818152602001828054801561116c57602002820191906000526020600020905b815481526020019060010190808311612d315750505050509050919050565b60008181526001830160205260408120548015612e39576000612d746001836141df565b8554909150600090612d88906001906141df565b9050808214612ded576000866000018281548110612da857612da8613a25565b9060005260206000200154905080876000018481548110612dcb57612dcb613a25565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612dfe57612dfe61424b565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061068f565b600091505061068f565b6000612e6285612e538486614122565b612e5d908761427a565b61323d565b95945050505050565b6000818152600183016020526040812054612eb25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561068f565b50600061068f565b825474010000000000000000000000000000000000000000900460ff161580612ee1575081155b15612eeb57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612f3190700100000000000000000000000000000000900463ffffffff16426141df565b90508015612ff15781831115612f73576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612fad9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612e43565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156130a85773ffffffffffffffffffffffffffffffffffffffff8416613050576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610978565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610978565b848310156131bb5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906130ec90826141df565b6130f6878a6141df565b613100919061427a565b61310a91906140e7565b905073ffffffffffffffffffffffffffffffffffffffff8616613163576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610978565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610978565b6131c585846141df565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b600081831061324c5781611e97565b5090919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611e97565b50805461328e90613a70565b6000825580601f1061329e575050565b601f01602090049060005260206000209081019061198491906132d6565b508054600082559060005260206000209081019061198491905b5b808211156132eb57600081556001016132d7565b5090565b60006020828403121561330157600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611e9757600080fd5b6000815180845260005b818110156133575760208185018101518683018201520161333b565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611e976020830184613331565b73ffffffffffffffffffffffffffffffffffffffff8116811461198457600080fd5b6000602082840312156133dc57600080fd5b8135611e97816133a8565b6000602082840312156133f957600080fd5b813567ffffffffffffffff81111561341057600080fd5b82016101008185031215611e9757600080fd5b803567ffffffffffffffff8116811461343b57600080fd5b919050565b60008060006040848603121561345557600080fd5b61345e84613423565b9250602084013567ffffffffffffffff8082111561347b57600080fd5b818601915086601f83011261348f57600080fd5b81358181111561349e57600080fd5b8760208285010111156134b057600080fd5b6020830194508093505050509250925092565b60008083601f8401126134d557600080fd5b50813567ffffffffffffffff8111156134ed57600080fd5b6020830191508360208260051b850101111561350857600080fd5b9250929050565b6000806000806040858703121561352557600080fd5b843567ffffffffffffffff8082111561353d57600080fd5b613549888389016134c3565b9096509450602087013591508082111561356257600080fd5b5061356f878288016134c3565b95989497509550505050565b60006020828403121561358d57600080fd5b611e9782613423565b60008083601f8401126135a857600080fd5b50813567ffffffffffffffff8111156135c057600080fd5b60208301915083602060608302850101111561350857600080fd5b600080600080600080606087890312156135f457600080fd5b863567ffffffffffffffff8082111561360c57600080fd5b6136188a838b016134c3565b9098509650602089013591508082111561363157600080fd5b61363d8a838b01613596565b9096509450604089013591508082111561365657600080fd5b5061366389828a01613596565b979a9699509497509295939492505050565b60006020828403121561368757600080fd5b813567ffffffffffffffff81111561369e57600080fd5b820160a08185031215611e9757600080fd5b6020815260008251604060208401526136cc6060840182613331565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e628282613331565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b8281101561377c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261376a858351613331565b94509285019290850190600101613730565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b818110156137d757835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016137a5565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156137d757835167ffffffffffffffff16835292840192918401916001016137ff565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff8111828210171561387757613877613825565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156138c4576138c4613825565b604052919050565b801515811461198457600080fd5b80356fffffffffffffffffffffffffffffffff8116811461343b57600080fd5b60006060828403121561390c57600080fd5b6040516060810181811067ffffffffffffffff8211171561392f5761392f613825565b6040529050808235613940816138cc565b815261394e602084016138da565b602082015261395f604084016138da565b60408201525092915050565b600080600060e0848603121561398057600080fd5b61398984613423565b925061399885602086016138fa565b91506139a785608086016138fa565b90509250925092565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126139e557600080fd5b83018035915067ffffffffffffffff821115613a0057600080fd5b60200191503681900382131561350857600080fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060608284031215613a6657600080fd5b611e9783836138fa565b600181811c90821680613a8457607f821691505b602082108103613abd577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b67ffffffffffffffff84168152604060208201526000612e62604083018486613ac3565b6020815260006108a6602083018486613ac3565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee1833603018112613b7857600080fd5b9190910192915050565b600082601f830112613b9357600080fd5b813567ffffffffffffffff811115613bad57613bad613825565b613bde60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161387d565b818152846020838601011115613bf357600080fd5b816020850160208301376000918101602001919091529392505050565b60006101208236031215613c2357600080fd5b613c2b613854565b613c3483613423565b815260208084013567ffffffffffffffff80821115613c5257600080fd5b9085019036601f830112613c6557600080fd5b813581811115613c7757613c77613825565b8060051b613c8685820161387d565b9182528381018501918581019036841115613ca057600080fd5b86860192505b83831015613cdc57823585811115613cbe5760008081fd5b613ccc3689838a0101613b82565b8352509186019190860190613ca6565b8087890152505050506040860135925080831115613cf957600080fd5b5050613d0736828601613b82565b604083015250613d1a36606085016138fa565b6060820152613d2c3660c085016138fa565b608082015292915050565b601f8211156109c1576000816000526020600020601f850160051c81016020861015613d605750805b601f850160051c820191505b81811015613d7f57828155600101613d6c565b505050505050565b815167ffffffffffffffff811115613da157613da1613825565b613db581613daf8454613a70565b84613d37565b602080601f831160018114613e085760008415613dd25750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613d7f565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613e5557888601518255948401946001909101908401613e36565b5085821015613e9157878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613ec581840187613331565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613f039050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e62565b600060208284031215613f4c57600080fd5b8151611e97816138cc565b600060208284031215613f6957600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff828116828216039081111561068f5761068f613f70565b600181815b8085111561401157817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613ff757613ff7613f70565b8085161561400457918102915b93841c9390800290613fbd565b509250929050565b6000826140285750600161068f565b816140355750600061068f565b816001811461404b576002811461405557614071565b600191505061068f565b60ff84111561406657614066613f70565b50506001821b61068f565b5060208310610133831016604e8410600b8410161715614094575081810a61068f565b61409e8383613fb8565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156140d0576140d0613f70565b029392505050565b6000611e9760ff841683614019565b60008261411d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761068f5761068f613f70565b67ffffffffffffffff831681526040602082015260006108a66040830184613331565b67ffffffffffffffff8416815260e081016141a860208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526108a6565b8181038181111561068f5761068f613f70565b6060810161068f82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561424057600080fd5b8151611e97816133a8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8082018082111561068f5761068f613f7056fea164736f6c6343000818000a", } var BurnWithFromMintTokenPoolABI = BurnWithFromMintTokenPoolMetaData.ABI @@ -713,6 +713,18 @@ func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) Se return _BurnWithFromMintTokenPool.Contract.SetChainRateLimiterConfig(&_BurnWithFromMintTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) } +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.contract.Transact(opts, "setChainRateLimiterConfigs", remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.SetChainRateLimiterConfigs(&_BurnWithFromMintTokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.SetChainRateLimiterConfigs(&_BurnWithFromMintTokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) { return _BurnWithFromMintTokenPool.contract.Transact(opts, "setRateLimitAdmin", rateLimitAdmin) } @@ -3033,6 +3045,8 @@ type BurnWithFromMintTokenPoolInterface interface { SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) + SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go b/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go index 32edf6ef6c3..fa5a6a4cdac 100644 --- a/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go +++ b/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go @@ -81,8 +81,8 @@ type TokenPoolChainUpdate struct { } var LockReleaseTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"localTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"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\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"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\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"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\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"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\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"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\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"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\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"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\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"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\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"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\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferLiquidity\",\"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\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101206040523480156200001257600080fd5b506040516200511f3803806200511f8339810160408190526200003591620005bb565b8585858584336000816200005c57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008f576200008f81620001f3565b50506001600160a01b0385161580620000af57506001600160a01b038116155b80620000c257506001600160a01b038216155b15620000e1576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808616608081905290831660c0526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa92505050801562000151575060408051601f3d908101601f191682019092526200014e91810190620006ee565b60015b1562000191578060ff168560ff16146200018f576040516332ad3e0760e11b815260ff80871660048301528216602482015260440160405180910390fd5b505b60ff841660a052600480546001600160a01b0319166001600160a01b038316179055825115801560e052620001db57604080516000815260208101909152620001db90846200026d565b5050505091151561010052506200075a945050505050565b336001600160a01b038216036200021d57604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e0516200028e576040516335f4a7b360e01b815260040160405180910390fd5b60005b825181101562000319576000838281518110620002b257620002b26200070c565b60209081029190910101519050620002cc600282620003ca565b156200030f576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000291565b5060005b8151811015620003c55760008282815181106200033e576200033e6200070c565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200036a5750620003bc565b62000377600282620003ea565b15620003ba576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6001016200031d565b505050565b6000620003e1836001600160a01b03841662000401565b90505b92915050565b6000620003e1836001600160a01b03841662000505565b60008181526001830160205260408120548015620004fa5760006200042860018362000722565b85549091506000906200043e9060019062000722565b9050808214620004aa5760008660000182815481106200046257620004626200070c565b90600052602060002001549050808760000184815481106200048857620004886200070c565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004be57620004be62000744565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003e4565b6000915050620003e4565b60008181526001830160205260408120546200054e57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003e4565b506000620003e4565b6001600160a01b03811681146200056d57600080fd5b50565b805160ff811681146200058257600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b8051620005828162000557565b805180151581146200058257600080fd5b60008060008060008060c08789031215620005d557600080fd5b8651620005e28162000557565b95506020620005f388820162000570565b60408901519096506001600160401b03808211156200061157600080fd5b818a0191508a601f8301126200062657600080fd5b8151818111156200063b576200063b62000587565b8060051b604051601f19603f8301168101818110858211171562000663576200066362000587565b60405291825284820192508381018501918d8311156200068257600080fd5b938501935b82851015620006ab576200069b856200059d565b8452938501939285019262000687565b809950505050505050620006c2606088016200059d565b9250620006d260808801620005aa565b9150620006e260a088016200059d565b90509295509295509295565b6000602082840312156200070157600080fd5b620003e18262000570565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003e457634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e051610100516148f46200082b600039600081816105a40152611ac601526000818161063e015281816123180152612e3101526000818161061801528181611e35015261260401526000818161036701528181610e6b01528181611fde01528181612098015281816120cc015281816120ff01528181612164015281816121bd015261225f0152600081816102ce015281816103230152818161077f015281816108510152818161094501528181611b8801528181612dc7015261301c01526148f46000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c80638da5cb5b11610145578063c0d78655116100bd578063dc0bd9711161008c578063e8a1da1711610071578063e8a1da1714610662578063eb521a4c14610675578063f2fde38b1461068857600080fd5b8063dc0bd97114610616578063e0351e131461063c57600080fd5b8063c0d78655146105c8578063c4bffe2b146105db578063c75eea9c146105f0578063cf7401f31461060357600080fd5b8063acfecf9111610114578063b0f479a1116100f9578063b0f479a114610571578063b79465801461058f578063bb98546b146105a257600080fd5b8063acfecf91146104ef578063af58d59f1461050257600080fd5b80638da5cb5b1461047c5780639a4575b91461049a578063a42a7b8b146104ba578063a7cd63b7146104da57600080fd5b80634c5ef0ed116101d85780636cfd1553116101a757806379ba50971161018c57806379ba50971461044e5780637d54534e146104565780638926f54f1461046957600080fd5b80636cfd15531461041d5780636d3d1a581461043057600080fd5b80634c5ef0ed146103d157806354c8a4f3146103e457806362ddd3c4146103f7578063663200871461040a57600080fd5b8063240028e811610214578063240028e81461031357806324f65ee7146103605780633907753714610391578063432a6ba3146103b357600080fd5b806301ffc9a7146102465780630a861f2a1461026e578063181f5a771461028357806321df0da7146102cc575b600080fd5b6102596102543660046139e3565b61069b565b60405190151581526020015b60405180910390f35b61028161027c366004613a25565b6106f7565b005b6102bf6040518060400160405280601a81526020017f4c6f636b52656c65617365546f6b656e506f6f6c20312e352e3100000000000081525081565b6040516102659190613aac565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610265565b610259610321366004613ae1565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610265565b6103a461039f366004613afe565b6108a8565b60405190518152602001610265565b600a5473ffffffffffffffffffffffffffffffffffffffff166102ee565b6102596103df366004613b57565b6109f6565b6102816103f2366004613c26565b610a40565b610281610405366004613b57565b610abb565b610281610418366004613c92565b610b53565b61028161042b366004613ae1565b610c2f565b60095473ffffffffffffffffffffffffffffffffffffffff166102ee565b610281610c7e565b610281610464366004613ae1565b610d4c565b610259610477366004613cbe565b610dcd565b60015473ffffffffffffffffffffffffffffffffffffffff166102ee565b6104ad6104a8366004613cd9565b610de4565b6040516102659190613d14565b6104cd6104c8366004613cbe565b610eb0565b6040516102659190613d6b565b6104e261101b565b6040516102659190613ded565b6102816104fd366004613b57565b61102c565b610515610510366004613cbe565b611144565b604051610265919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102ee565b6102bf61059d366004613cbe565b611219565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102816105d6366004613ae1565b6112c9565b6105e36113a4565b6040516102659190613e47565b6105156105fe366004613cbe565b61145c565b610281610611366004613fcf565b61152e565b7f00000000000000000000000000000000000000000000000000000000000000006102ee565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b610281610670366004613c26565b6115b2565b610281610683366004613a25565b611ac4565b610281610696366004613ae1565b611be0565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d405660000000000000000000000000000000000000000000000000000000014806106f157506106f182611bf4565b92915050565b600a5473ffffffffffffffffffffffffffffffffffffffff16331461074f576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156107db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ff9190614014565b1015610837576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61087873ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611cd8565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040805160208101909152600081526108c082611dac565b600061091960608401356109146108da60c087018761402d565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611fd092505050565b612094565b905061096c61092e6060850160408601613ae1565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169083611cd8565b61097c6060840160408501613ae1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52836040516109da91815260200190565b60405180910390a3604080516020810190915290815292915050565b6000610a388383604051610a0b929190614092565b604080519182900390912067ffffffffffffffff87166000908152600760205291909120600501906122a8565b949350505050565b610a486122c3565b610ab58484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061231692505050565b50505050565b610ac36122c3565b610acc83610dcd565b610b0e576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610746565b610b4e8383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506124cc92505050565b505050565b610b5b6122c3565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610bc357600080fd5b505af1158015610bd7573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167f6fa7abcf1345d1d478e5ea0da6b5f26a90eadb0546ef15ed3833944fbfd1db6282604051610c2391815260200190565b60405180910390a25050565b610c376122c3565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ccf576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610d546122c3565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b60006106f1600567ffffffffffffffff84166122a8565b6040805180820190915260608082526020820152610e01826125c6565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a26040518060400160405280610e5b84602001602081019061059d9190613cbe565b8152602001610ea86040805160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260609101604051602081830303815290604052905090565b905292915050565b67ffffffffffffffff8116600090815260076020526040812060609190610ed990600501612752565b90506000815167ffffffffffffffff811115610ef757610ef7613e89565b604051908082528060200260200182016040528015610f2a57816020015b6060815260200190600190039081610f155790505b50905060005b82518110156110135760086000848381518110610f4f57610f4f6140a2565b602002602001015181526020019081526020016000208054610f70906140d1565b80601f0160208091040260200160405190810160405280929190818152602001828054610f9c906140d1565b8015610fe95780601f10610fbe57610100808354040283529160200191610fe9565b820191906000526020600020905b815481529060010190602001808311610fcc57829003601f168201915b5050505050828281518110611000576110006140a2565b6020908102919091010152600101610f30565b509392505050565b60606110276002612752565b905090565b6110346122c3565b61103d83610dcd565b61107f576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610746565b6110bf8282604051611092929190614092565b604080519182900390912067ffffffffffffffff861660009081526007602052919091206005019061275f565b6110fb578282826040517f74f23c7c0000000000000000000000000000000000000000000000000000000081526004016107469392919061416d565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d768383604051611137929190614191565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526106f19061276b565b67ffffffffffffffff81166000908152600760205260409020600401805460609190611244906140d1565b80601f0160208091040260200160405190810160405280929190818152602001828054611270906140d1565b80156112bd5780601f10611292576101008083540402835291602001916112bd565b820191906000526020600020905b8154815290600101906020018083116112a057829003601f168201915b50505050509050919050565b6112d16122c3565b73ffffffffffffffffffffffffffffffffffffffff811661131e576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006113b26005612752565b90506000815167ffffffffffffffff8111156113d0576113d0613e89565b6040519080825280602002602001820160405280156113f9578160200160208202803683370190505b50905060005b82518110156114555782818151811061141a5761141a6140a2565b6020026020010151828281518110611434576114346140a2565b67ffffffffffffffff909216602092830291909101909101526001016113ff565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526106f19061276b565b60095473ffffffffffffffffffffffffffffffffffffffff16331480159061156e575060015473ffffffffffffffffffffffffffffffffffffffff163314155b156115a7576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610746565b610b4e83838361281d565b6115ba6122c3565b60005b838110156117a75760008585838181106115d9576115d96140a2565b90506020020160208101906115ee9190613cbe565b9050611605600567ffffffffffffffff831661275f565b611647576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610746565b67ffffffffffffffff8116600090815260076020526040812061166c90600501612752565b905060005b81518110156116d8576116cf82828151811061168f5761168f6140a2565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060050161275f90919063ffffffff16565b50600101611671565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906117416004830182613976565b600582016000818161175382826139b0565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d85991694506020019250611795915050565b60405180910390a150506001016115bd565b5060005b81811015611abd5760008383838181106117c7576117c76140a2565b90506020028101906117d991906141a5565b6117e290614271565b90506117f381606001516000612907565b61180281608001516000612907565b806040015151600003611841576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516118599060059067ffffffffffffffff16612a44565b61189e5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610746565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a909102999093161717909416959095179092559092029091176003820155908201516004820190611a2190826143e8565b5060005b826020015151811015611a6557611a5d836000015184602001518381518110611a5057611a506140a2565b60200260200101516124cc565b600101611a25565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c28260000151836040015184606001518560800151604051611aab9493929190614502565b60405180910390a150506001016117ab565b5050505050565b7f0000000000000000000000000000000000000000000000000000000000000000611b1b576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a5473ffffffffffffffffffffffffffffffffffffffff163314611b6e576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610746565b611bb073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084612a50565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611be86122c3565b611bf181612aae565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf000000000000000000000000000000000000000000000000000000001480611c8757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806106f157507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610b4e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612b72565b611dbf61032160a0830160808401613ae1565b611e1e57611dd360a0820160808301613ae1565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610746565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb611e6a6040840160208501613cbe565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015611edb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eff919061459b565b15611f36576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f4e611f496040830160208401613cbe565b612c7e565b611f6e611f616040830160208401613cbe565b6103df60a084018461402d565b611fb357611f7f60a082018261402d565b6040517f24eb47e5000000000000000000000000000000000000000000000000000000008152600401610746929190614191565b611bf1611fc66040830160208401613cbe565b8260600135612da4565b6000815160000361200257507f0000000000000000000000000000000000000000000000000000000000000000919050565b815160201461203f57816040517f953576f70000000000000000000000000000000000000000000000000000000081526004016107469190613aac565b6000828060200190518101906120559190614014565b905060ff8111156106f157826040517f953576f70000000000000000000000000000000000000000000000000000000081526004016107469190613aac565b60007f000000000000000000000000000000000000000000000000000000000000000060ff168260ff16036120ca5750816106f1565b7f000000000000000000000000000000000000000000000000000000000000000060ff168260ff1611156121b55760006121247f0000000000000000000000000000000000000000000000000000000000000000846145e7565b9050604d8160ff161115612198576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f000000000000000000000000000000000000000000000000000000000000000016602482015260448101859052606401610746565b6121a381600a614720565b6121ad908561472f565b9150506106f1565b60006121e1837f00000000000000000000000000000000000000000000000000000000000000006145e7565b9050604d8160ff16118061222857506121fb81600a614720565b612225907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61472f565b84115b15612293576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f000000000000000000000000000000000000000000000000000000000000000016602482015260448101859052606401610746565b61229e81600a614720565b610a38908561476a565b600081815260018301602052604081205415155b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314612314576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f000000000000000000000000000000000000000000000000000000000000000061236d576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561240357600083828151811061238d5761238d6140a2565b602002602001015190506123ab816002612deb90919063ffffffff16565b156123fa5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101612370565b5060005b8151811015610b4e576000828281518110612424576124246140a2565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361246857506124c4565b612473600282612e0d565b156124c25760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101612407565b8051600003612507576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff84166000908152600790925260409091206125399060050182612a44565b6125735782826040517f393b8ad2000000000000000000000000000000000000000000000000000000008152600401610746929190614781565b600081815260086020526040902061258b83826143e8565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea836040516111379190613aac565b6125d961032160a0830160808401613ae1565b6125ed57611dd360a0820160808301613ae1565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6126396040840160208501613cbe565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa1580156126aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ce919061459b565b15612705576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61271d6127186060830160408401613ae1565b612e2f565b6127356127306040830160208401613cbe565b612eae565b611bf16127486040830160208401613cbe565b8260600135612ffc565b606060006122bc83613040565b60006122bc838361309b565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526127f982606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426127dd91906147a4565b85608001516fffffffffffffffffffffffffffffffff1661318e565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61282683610dcd565b612868576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610746565b612873826000612907565b67ffffffffffffffff8316600090815260076020526040902061289690836131b6565b6128a1816000612907565b67ffffffffffffffff831660009081526007602052604090206128c790600201826131b6565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516128fa939291906147b7565b60405180910390a1505050565b8151156129d25781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff1610158061295d575060408201516fffffffffffffffffffffffffffffffff16155b1561299657816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610746919061483a565b80156129ce576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff16151580612a0b575060208201516fffffffffffffffffffffffffffffffff1615155b156129ce57816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610746919061483a565b60006122bc8383613358565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610ab59085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611d2a565b3373ffffffffffffffffffffffffffffffffffffffff821603612afd576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612bd4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166133a79092919063ffffffff16565b805190915015610b4e5780806020019051810190612bf2919061459b565b610b4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610746565b612c8781610dcd565b612cc9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610746565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612d48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d6c919061459b565b611bf1576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610746565b67ffffffffffffffff821660009081526007602052604090206129ce90600201827f00000000000000000000000000000000000000000000000000000000000000006133b6565b60006122bc8373ffffffffffffffffffffffffffffffffffffffff841661309b565b60006122bc8373ffffffffffffffffffffffffffffffffffffffff8416613358565b7f000000000000000000000000000000000000000000000000000000000000000015611bf157612e60600282613739565b611bf1576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610746565b612eb781610dcd565b612ef9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610746565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612f72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f969190614876565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611bf1576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610746565b67ffffffffffffffff821660009081526007602052604090206129ce90827f00000000000000000000000000000000000000000000000000000000000000006133b6565b6060816000018054806020026020016040519081016040528092919081815260200182805480156112bd57602002820191906000526020600020905b81548152602001906001019080831161307c5750505050509050919050565b600081815260018301602052604081205480156131845760006130bf6001836147a4565b85549091506000906130d3906001906147a4565b90508082146131385760008660000182815481106130f3576130f36140a2565b9060005260206000200154905080876000018481548110613116576131166140a2565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061314957613149614893565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106f1565b60009150506106f1565b60006131ad8561319e848661476a565b6131a890876148c2565b613768565b95945050505050565b81546000906131df90700100000000000000000000000000000000900463ffffffff16426147a4565b905080156132815760018301548354613227916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661318e565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546132a7916fffffffffffffffffffffffffffffffff9081169116613768565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906128fa90849061483a565b600081815260018301602052604081205461339f575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106f1565b5060006106f1565b6060610a38848460008561377e565b825474010000000000000000000000000000000000000000900460ff1615806133dd575081155b156133e757505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061342d90700100000000000000000000000000000000900463ffffffff16426147a4565b905080156134ed578183111561346f576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546134a99083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661318e565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156135a45773ffffffffffffffffffffffffffffffffffffffff841661354c576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610746565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610746565b848310156136b75760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906135e890826147a4565b6135f2878a6147a4565b6135fc91906148c2565b613606919061472f565b905073ffffffffffffffffffffffffffffffffffffffff861661365f576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610746565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610746565b6136c185846147a4565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415156122bc565b600081831061377757816122bc565b5090919050565b606082471015613810576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610746565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161383991906148d5565b60006040518083038185875af1925050503d8060008114613876576040519150601f19603f3d011682016040523d82523d6000602084013e61387b565b606091505b509150915061388c87838387613897565b979650505050505050565b6060831561392d5782516000036139265773ffffffffffffffffffffffffffffffffffffffff85163b613926576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610746565b5081610a38565b610a3883838151156139425781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107469190613aac565b508054613982906140d1565b6000825580601f10613992575050565b601f016020900490600052602060002090810190611bf191906139ca565b5080546000825590600052602060002090810190611bf191905b5b808211156139df57600081556001016139cb565b5090565b6000602082840312156139f557600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146122bc57600080fd5b600060208284031215613a3757600080fd5b5035919050565b60005b83811015613a59578181015183820152602001613a41565b50506000910152565b60008151808452613a7a816020860160208601613a3e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006122bc6020830184613a62565b73ffffffffffffffffffffffffffffffffffffffff81168114611bf157600080fd5b600060208284031215613af357600080fd5b81356122bc81613abf565b600060208284031215613b1057600080fd5b813567ffffffffffffffff811115613b2757600080fd5b820161010081850312156122bc57600080fd5b803567ffffffffffffffff81168114613b5257600080fd5b919050565b600080600060408486031215613b6c57600080fd5b613b7584613b3a565b9250602084013567ffffffffffffffff80821115613b9257600080fd5b818601915086601f830112613ba657600080fd5b813581811115613bb557600080fd5b876020828501011115613bc757600080fd5b6020830194508093505050509250925092565b60008083601f840112613bec57600080fd5b50813567ffffffffffffffff811115613c0457600080fd5b6020830191508360208260051b8501011115613c1f57600080fd5b9250929050565b60008060008060408587031215613c3c57600080fd5b843567ffffffffffffffff80821115613c5457600080fd5b613c6088838901613bda565b90965094506020870135915080821115613c7957600080fd5b50613c8687828801613bda565b95989497509550505050565b60008060408385031215613ca557600080fd5b8235613cb081613abf565b946020939093013593505050565b600060208284031215613cd057600080fd5b6122bc82613b3a565b600060208284031215613ceb57600080fd5b813567ffffffffffffffff811115613d0257600080fd5b820160a081850312156122bc57600080fd5b602081526000825160406020840152613d306060840182613a62565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526131ad8282613a62565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015613de0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452613dce858351613a62565b94509285019290850190600101613d94565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613e3b57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613e09565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613e3b57835167ffffffffffffffff1683529284019291840191600101613e63565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715613edb57613edb613e89565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613f2857613f28613e89565b604052919050565b8015158114611bf157600080fd5b80356fffffffffffffffffffffffffffffffff81168114613b5257600080fd5b600060608284031215613f7057600080fd5b6040516060810181811067ffffffffffffffff82111715613f9357613f93613e89565b6040529050808235613fa481613f30565b8152613fb260208401613f3e565b6020820152613fc360408401613f3e565b60408201525092915050565b600080600060e08486031215613fe457600080fd5b613fed84613b3a565b9250613ffc8560208601613f5e565b915061400b8560808601613f5e565b90509250925092565b60006020828403121561402657600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261406257600080fd5b83018035915067ffffffffffffffff82111561407d57600080fd5b602001915036819003821315613c1f57600080fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c908216806140e557607f821691505b60208210810361411e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b67ffffffffffffffff841681526040602082015260006131ad604083018486614124565b602081526000610a38602083018486614124565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee18336030181126141d957600080fd5b9190910192915050565b600082601f8301126141f457600080fd5b813567ffffffffffffffff81111561420e5761420e613e89565b61423f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613ee1565b81815284602083860101111561425457600080fd5b816020850160208301376000918101602001919091529392505050565b6000610120823603121561428457600080fd5b61428c613eb8565b61429583613b3a565b815260208084013567ffffffffffffffff808211156142b357600080fd5b9085019036601f8301126142c657600080fd5b8135818111156142d8576142d8613e89565b8060051b6142e7858201613ee1565b918252838101850191858101903684111561430157600080fd5b86860192505b8383101561433d5782358581111561431f5760008081fd5b61432d3689838a01016141e3565b8352509186019190860190614307565b808789015250505050604086013592508083111561435a57600080fd5b5050614368368286016141e3565b60408301525061437b3660608501613f5e565b606082015261438d3660c08501613f5e565b608082015292915050565b601f821115610b4e576000816000526020600020601f850160051c810160208610156143c15750805b601f850160051c820191505b818110156143e0578281556001016143cd565b505050505050565b815167ffffffffffffffff81111561440257614402613e89565b6144168161441084546140d1565b84614398565b602080601f83116001811461446957600084156144335750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556143e0565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156144b657888601518255948401946001909101908401614497565b50858210156144f257878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261452681840187613a62565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506145649050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526131ad565b6000602082840312156145ad57600080fd5b81516122bc81613f30565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff82811682821603908111156106f1576106f16145b8565b600181815b8085111561465957817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561463f5761463f6145b8565b8085161561464c57918102915b93841c9390800290614605565b509250929050565b600082614670575060016106f1565b8161467d575060006106f1565b8160018114614693576002811461469d576146b9565b60019150506106f1565b60ff8411156146ae576146ae6145b8565b50506001821b6106f1565b5060208310610133831016604e8410600b84101617156146dc575081810a6106f1565b6146e68383614600565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614718576147186145b8565b029392505050565b60006122bc60ff841683614661565b600082614765577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176106f1576106f16145b8565b67ffffffffffffffff83168152604060208201526000610a386040830184613a62565b818103818111156106f1576106f16145b8565b67ffffffffffffffff8416815260e0810161480360208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152610a38565b606081016106f182848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561488857600080fd5b81516122bc81613abf565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b808201808211156106f1576106f16145b8565b600082516141d9818460208701613a3e56fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"localTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"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\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"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\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"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\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MismatchedArrayLengths\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"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\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"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\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"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\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"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\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"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\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"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\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectors\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config[]\",\"name\":\"outboundConfigs\",\"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\":\"inboundConfigs\",\"type\":\"tuple[]\"}],\"name\":\"setChainRateLimiterConfigs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferLiquidity\",\"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\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101206040523480156200001257600080fd5b50604051620053a2380380620053a28339810160408190526200003591620005bb565b8585858584336000816200005c57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008f576200008f81620001f3565b50506001600160a01b0385161580620000af57506001600160a01b038116155b80620000c257506001600160a01b038216155b15620000e1576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808616608081905290831660c0526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa92505050801562000151575060408051601f3d908101601f191682019092526200014e91810190620006ee565b60015b1562000191578060ff168560ff16146200018f576040516332ad3e0760e11b815260ff80871660048301528216602482015260440160405180910390fd5b505b60ff841660a052600480546001600160a01b0319166001600160a01b038316179055825115801560e052620001db57604080516000815260208101909152620001db90846200026d565b5050505091151561010052506200075a945050505050565b336001600160a01b038216036200021d57604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e0516200028e576040516335f4a7b360e01b815260040160405180910390fd5b60005b825181101562000319576000838281518110620002b257620002b26200070c565b60209081029190910101519050620002cc600282620003ca565b156200030f576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000291565b5060005b8151811015620003c55760008282815181106200033e576200033e6200070c565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200036a5750620003bc565b62000377600282620003ea565b15620003ba576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6001016200031d565b505050565b6000620003e1836001600160a01b03841662000401565b90505b92915050565b6000620003e1836001600160a01b03841662000505565b60008181526001830160205260408120548015620004fa5760006200042860018362000722565b85549091506000906200043e9060019062000722565b9050808214620004aa5760008660000182815481106200046257620004626200070c565b90600052602060002001549050808760000184815481106200048857620004886200070c565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004be57620004be62000744565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003e4565b6000915050620003e4565b60008181526001830160205260408120546200054e57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003e4565b506000620003e4565b6001600160a01b03811681146200056d57600080fd5b50565b805160ff811681146200058257600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b8051620005828162000557565b805180151581146200058257600080fd5b60008060008060008060c08789031215620005d557600080fd5b8651620005e28162000557565b95506020620005f388820162000570565b60408901519096506001600160401b03808211156200061157600080fd5b818a0191508a601f8301126200062657600080fd5b8151818111156200063b576200063b62000587565b8060051b604051601f19603f8301168101818110858211171562000663576200066362000587565b60405291825284820192508381018501918d8311156200068257600080fd5b938501935b82851015620006ab576200069b856200059d565b8452938501939285019262000687565b809950505050505050620006c2606088016200059d565b9250620006d260808801620005aa565b9150620006e260a088016200059d565b90509295509295509295565b6000602082840312156200070157600080fd5b620003e18262000570565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003e457634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e05161010051614b776200082b600039600081816105d20152611c4e01526000818161066c015281816124a0015261315b01526000818161064601528181611fbd015261287601526000818161038201528181610ff301528181612166015281816122200152818161225401528181612287015281816122ec0152818161234501526123e70152600081816102e90152818161033e015281816107ad0152818161087f0152818161097301528181611d1001528181612f4f01526133460152614b776000f3fe608060405234801561001057600080fd5b506004361061025c5760003560e01c8063962d402011610145578063c0d78655116100bd578063dc0bd9711161008c578063e8a1da1711610071578063e8a1da1714610690578063eb521a4c146106a3578063f2fde38b146106b657600080fd5b8063dc0bd97114610644578063e0351e131461066a57600080fd5b8063c0d78655146105f6578063c4bffe2b14610609578063c75eea9c1461061e578063cf7401f31461063157600080fd5b8063acfecf9111610114578063b0f479a1116100f9578063b0f479a11461059f578063b7946580146105bd578063bb98546b146105d057600080fd5b8063acfecf911461051d578063af58d59f1461053057600080fd5b8063962d4020146104b55780639a4575b9146104c8578063a42a7b8b146104e8578063a7cd63b71461050857600080fd5b806354c8a4f3116101d85780636d3d1a58116101a75780637d54534e1161018c5780637d54534e146104715780638926f54f146104845780638da5cb5b1461049757600080fd5b80636d3d1a581461044b57806379ba50971461046957600080fd5b806354c8a4f3146103ff57806362ddd3c41461041257806366320087146104255780636cfd15531461043857600080fd5b8063240028e81161022f578063390775371161021457806339077537146103ac578063432a6ba3146103ce5780634c5ef0ed146103ec57600080fd5b8063240028e81461032e57806324f65ee71461037b57600080fd5b806301ffc9a7146102615780630a861f2a14610289578063181f5a771461029e57806321df0da7146102e7575b600080fd5b61027461026f366004613b6b565b6106c9565b60405190151581526020015b60405180910390f35b61029c610297366004613bad565b610725565b005b6102da6040518060400160405280601a81526020017f4c6f636b52656c65617365546f6b656e506f6f6c20312e352e3100000000000081525081565b6040516102809190613c34565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610280565b61027461033c366004613c69565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610280565b6103bf6103ba366004613c86565b6108d6565b60405190518152602001610280565b600a5473ffffffffffffffffffffffffffffffffffffffff16610309565b6102746103fa366004613cdf565b610a24565b61029c61040d366004613dae565b610a6e565b61029c610420366004613cdf565b610ae9565b61029c610433366004613e1a565b610b81565b61029c610446366004613c69565b610c5d565b60095473ffffffffffffffffffffffffffffffffffffffff16610309565b61029c610cac565b61029c61047f366004613c69565b610d7a565b610274610492366004613e46565b610dfb565b60015473ffffffffffffffffffffffffffffffffffffffff16610309565b61029c6104c3366004613ea6565b610e12565b6104db6104d6366004613f40565b610f6c565b6040516102809190613f7b565b6104fb6104f6366004613e46565b611038565b6040516102809190613fd2565b6105106111a3565b6040516102809190614054565b61029c61052b366004613cdf565b6111b4565b61054361053e366004613e46565b6112cc565b604051610280919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610309565b6102da6105cb366004613e46565b6113a1565b7f0000000000000000000000000000000000000000000000000000000000000000610274565b61029c610604366004613c69565b611451565b61061161152c565b60405161028091906140ae565b61054361062c366004613e46565b6115e4565b61029c61063f366004614236565b6116b6565b7f0000000000000000000000000000000000000000000000000000000000000000610309565b7f0000000000000000000000000000000000000000000000000000000000000000610274565b61029c61069e366004613dae565b61173a565b61029c6106b1366004613bad565b611c4c565b61029c6106c4366004613c69565b611d68565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d4056600000000000000000000000000000000000000000000000000000000148061071f575061071f82611d7c565b92915050565b600a5473ffffffffffffffffffffffffffffffffffffffff16331461077d576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610809573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061082d919061427b565b1015610865576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108a673ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611e60565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040805160208101909152600081526108ee82611f34565b6000610947606084013561094261090860c0870187614294565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061215892505050565b61221c565b905061099a61095c6060850160408601613c69565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169083611e60565b6109aa6060840160408501613c69565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f5283604051610a0891815260200190565b60405180910390a3604080516020810190915290815292915050565b6000610a668383604051610a399291906142f9565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190612430565b949350505050565b610a7661244b565b610ae38484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061249e92505050565b50505050565b610af161244b565b610afa83610dfb565b610b3c576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610774565b610b7c8383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061265492505050565b505050565b610b8961244b565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610bf157600080fd5b505af1158015610c05573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167f6fa7abcf1345d1d478e5ea0da6b5f26a90eadb0546ef15ed3833944fbfd1db6282604051610c5191815260200190565b60405180910390a25050565b610c6561244b565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314610cfd576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610d8261244b565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b600061071f600567ffffffffffffffff8416612430565b60095473ffffffffffffffffffffffffffffffffffffffff163314801590610e52575060015473ffffffffffffffffffffffffffffffffffffffff163314155b15610e8b576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610774565b8483141580610e9a5750848114155b15610ed1576040517f568efce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b85811015610f6357610f5b878783818110610ef157610ef1614309565b9050602002016020810190610f069190613e46565b868684818110610f1857610f18614309565b905060600201803603810190610f2e9190614338565b858585818110610f4057610f40614309565b905060600201803603810190610f569190614338565b61274e565b600101610ed4565b50505050505050565b6040805180820190915260608082526020820152610f8982612838565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a26040518060400160405280610fe38460200160208101906105cb9190613e46565b81526020016110306040805160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260609101604051602081830303815290604052905090565b905292915050565b67ffffffffffffffff8116600090815260076020526040812060609190611061906005016129c4565b90506000815167ffffffffffffffff81111561107f5761107f6140f0565b6040519080825280602002602001820160405280156110b257816020015b606081526020019060019003908161109d5790505b50905060005b825181101561119b57600860008483815181106110d7576110d7614309565b6020026020010151815260200190815260200160002080546110f890614354565b80601f016020809104026020016040519081016040528092919081815260200182805461112490614354565b80156111715780601f1061114657610100808354040283529160200191611171565b820191906000526020600020905b81548152906001019060200180831161115457829003601f168201915b505050505082828151811061118857611188614309565b60209081029190910101526001016110b8565b509392505050565b60606111af60026129c4565b905090565b6111bc61244b565b6111c583610dfb565b611207576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610774565b611247828260405161121a9291906142f9565b604080519182900390912067ffffffffffffffff86166000908152600760205291909120600501906129d1565b611283578282826040517f74f23c7c000000000000000000000000000000000000000000000000000000008152600401610774939291906143f0565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d7683836040516112bf929190614414565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261071f906129dd565b67ffffffffffffffff811660009081526007602052604090206004018054606091906113cc90614354565b80601f01602080910402602001604051908101604052809291908181526020018280546113f890614354565b80156114455780601f1061141a57610100808354040283529160200191611445565b820191906000526020600020905b81548152906001019060200180831161142857829003601f168201915b50505050509050919050565b61145961244b565b73ffffffffffffffffffffffffffffffffffffffff81166114a6576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b6060600061153a60056129c4565b90506000815167ffffffffffffffff811115611558576115586140f0565b604051908082528060200260200182016040528015611581578160200160208202803683370190505b50905060005b82518110156115dd578281815181106115a2576115a2614309565b60200260200101518282815181106115bc576115bc614309565b67ffffffffffffffff90921660209283029190910190910152600101611587565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261071f906129dd565b60095473ffffffffffffffffffffffffffffffffffffffff1633148015906116f6575060015473ffffffffffffffffffffffffffffffffffffffff163314155b1561172f576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610774565b610b7c83838361274e565b61174261244b565b60005b8381101561192f57600085858381811061176157611761614309565b90506020020160208101906117769190613e46565b905061178d600567ffffffffffffffff83166129d1565b6117cf576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610774565b67ffffffffffffffff811660009081526007602052604081206117f4906005016129c4565b905060005b81518110156118605761185782828151811061181757611817614309565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206005016129d190919063ffffffff16565b506001016117f9565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906118c96004830182613afe565b60058201600081816118db8282613b38565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169450602001925061191d915050565b60405180910390a15050600101611745565b5060005b81811015611c4557600083838381811061194f5761194f614309565b90506020028101906119619190614428565b61196a906144f4565b905061197b81606001516000612a8f565b61198a81608001516000612a8f565b8060400151516000036119c9576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516119e19060059067ffffffffffffffff16612bcc565b611a265780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610774565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a909102999093161717909416959095179092559092029091176003820155908201516004820190611ba9908261466b565b5060005b826020015151811015611bed57611be5836000015184602001518381518110611bd857611bd8614309565b6020026020010151612654565b600101611bad565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c28260000151836040015184606001518560800151604051611c339493929190614785565b60405180910390a15050600101611933565b5050505050565b7f0000000000000000000000000000000000000000000000000000000000000000611ca3576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a5473ffffffffffffffffffffffffffffffffffffffff163314611cf6576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610774565b611d3873ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084612bd8565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611d7061244b565b611d7981612c36565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf000000000000000000000000000000000000000000000000000000001480611e0f57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061071f57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610b7c9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612cfa565b611f4761033c60a0830160808401613c69565b611fa657611f5b60a0820160808301613c69565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610774565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb611ff26040840160208501613e46565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015612063573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612087919061481e565b156120be576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120d66120d16040830160208401613e46565b612e06565b6120f66120e96040830160208401613e46565b6103fa60a0840184614294565b61213b5761210760a0820182614294565b6040517f24eb47e5000000000000000000000000000000000000000000000000000000008152600401610774929190614414565b611d7961214e6040830160208401613e46565b8260600135612f2c565b6000815160000361218a57507f0000000000000000000000000000000000000000000000000000000000000000919050565b81516020146121c757816040517f953576f70000000000000000000000000000000000000000000000000000000081526004016107749190613c34565b6000828060200190518101906121dd919061427b565b905060ff81111561071f57826040517f953576f70000000000000000000000000000000000000000000000000000000081526004016107749190613c34565b60007f000000000000000000000000000000000000000000000000000000000000000060ff168260ff160361225257508161071f565b7f000000000000000000000000000000000000000000000000000000000000000060ff168260ff16111561233d5760006122ac7f00000000000000000000000000000000000000000000000000000000000000008461486a565b9050604d8160ff161115612320576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f000000000000000000000000000000000000000000000000000000000000000016602482015260448101859052606401610774565b61232b81600a6149a3565b61233590856149b2565b91505061071f565b6000612369837f000000000000000000000000000000000000000000000000000000000000000061486a565b9050604d8160ff1611806123b0575061238381600a6149a3565b6123ad907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6149b2565b84115b1561241b576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f000000000000000000000000000000000000000000000000000000000000000016602482015260448101859052606401610774565b61242681600a6149a3565b610a6690856149ed565b600081815260018301602052604081205415155b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461249c576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f00000000000000000000000000000000000000000000000000000000000000006124f5576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561258b57600083828151811061251557612515614309565b60200260200101519050612533816002612f7390919063ffffffff16565b156125825760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016124f8565b5060005b8151811015610b7c5760008282815181106125ac576125ac614309565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036125f0575061264c565b6125fb600282612f95565b1561264a5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010161258f565b805160000361268f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff84166000908152600790925260409091206126c19060050182612bcc565b6126fb5782826040517f393b8ad2000000000000000000000000000000000000000000000000000000008152600401610774929190614a04565b6000818152600860205260409020612713838261466b565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea836040516112bf9190613c34565b61275783610dfb565b612799576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610774565b6127a4826000612a8f565b67ffffffffffffffff831660009081526007602052604090206127c79083612fb7565b6127d2816000612a8f565b67ffffffffffffffff831660009081526007602052604090206127f89060020182612fb7565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161282b93929190614a27565b60405180910390a1505050565b61284b61033c60a0830160808401613c69565b61285f57611f5b60a0820160808301613c69565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6128ab6040840160208501613e46565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa15801561291c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612940919061481e565b15612977576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61298f61298a6060830160408401613c69565b613159565b6129a76129a26040830160208401613e46565b6131d8565b611d796129ba6040830160208401613e46565b8260600135613326565b606060006124448361336a565b600061244483836133c5565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152612a6b82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642612a4f9190614aaa565b85608001516fffffffffffffffffffffffffffffffff166134b8565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b815115612b5a5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612ae5575060408201516fffffffffffffffffffffffffffffffff16155b15612b1e57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016107749190614abd565b8015612b56576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff16151580612b93575060208201516fffffffffffffffffffffffffffffffff1615155b15612b5657816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016107749190614abd565b600061244483836134e0565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610ae39085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611eb2565b3373ffffffffffffffffffffffffffffffffffffffff821603612c85576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612d5c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661352f9092919063ffffffff16565b805190915015610b7c5780806020019051810190612d7a919061481e565b610b7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610774565b612e0f81610dfb565b612e51576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610774565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612ed0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ef4919061481e565b611d79576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610774565b67ffffffffffffffff82166000908152600760205260409020612b5690600201827f000000000000000000000000000000000000000000000000000000000000000061353e565b60006124448373ffffffffffffffffffffffffffffffffffffffff84166133c5565b60006124448373ffffffffffffffffffffffffffffffffffffffff84166134e0565b8154600090612fe090700100000000000000000000000000000000900463ffffffff1642614aaa565b905080156130825760018301548354613028916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166134b8565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546130a8916fffffffffffffffffffffffffffffffff90811691166138c1565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061282b908490614abd565b7f000000000000000000000000000000000000000000000000000000000000000015611d795761318a6002826138d7565b611d79576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610774565b6131e181610dfb565b613223576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610774565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561329c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132c09190614af9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611d79576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610774565b67ffffffffffffffff82166000908152600760205260409020612b5690827f000000000000000000000000000000000000000000000000000000000000000061353e565b60608160000180548060200260200160405190810160405280929190818152602001828054801561144557602002820191906000526020600020905b8154815260200190600101908083116133a65750505050509050919050565b600081815260018301602052604081205480156134ae5760006133e9600183614aaa565b85549091506000906133fd90600190614aaa565b905080821461346257600086600001828154811061341d5761341d614309565b906000526020600020015490508087600001848154811061344057613440614309565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061347357613473614b16565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061071f565b600091505061071f565b60006134d7856134c884866149ed565b6134d29087614b45565b6138c1565b95945050505050565b60008181526001830160205260408120546135275750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561071f565b50600061071f565b6060610a668484600085613906565b825474010000000000000000000000000000000000000000900460ff161580613565575081155b1561356f57505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906135b590700100000000000000000000000000000000900463ffffffff1642614aaa565b9050801561367557818311156135f7576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546136319083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166134b8565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b8482101561372c5773ffffffffffffffffffffffffffffffffffffffff84166136d4576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610774565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610774565b8483101561383f5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906137709082614aaa565b61377a878a614aaa565b6137849190614b45565b61378e91906149b2565b905073ffffffffffffffffffffffffffffffffffffffff86166137e7576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610774565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610774565b6138498584614aaa565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b60008183106138d05781612444565b5090919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515612444565b606082471015613998576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610774565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516139c19190614b58565b60006040518083038185875af1925050503d80600081146139fe576040519150601f19603f3d011682016040523d82523d6000602084013e613a03565b606091505b5091509150613a1487838387613a1f565b979650505050505050565b60608315613ab5578251600003613aae5773ffffffffffffffffffffffffffffffffffffffff85163b613aae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610774565b5081610a66565b610a668383815115613aca5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107749190613c34565b508054613b0a90614354565b6000825580601f10613b1a575050565b601f016020900490600052602060002090810190611d799190613b52565b5080546000825590600052602060002090810190611d7991905b5b80821115613b675760008155600101613b53565b5090565b600060208284031215613b7d57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461244457600080fd5b600060208284031215613bbf57600080fd5b5035919050565b60005b83811015613be1578181015183820152602001613bc9565b50506000910152565b60008151808452613c02816020860160208601613bc6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006124446020830184613bea565b73ffffffffffffffffffffffffffffffffffffffff81168114611d7957600080fd5b600060208284031215613c7b57600080fd5b813561244481613c47565b600060208284031215613c9857600080fd5b813567ffffffffffffffff811115613caf57600080fd5b8201610100818503121561244457600080fd5b803567ffffffffffffffff81168114613cda57600080fd5b919050565b600080600060408486031215613cf457600080fd5b613cfd84613cc2565b9250602084013567ffffffffffffffff80821115613d1a57600080fd5b818601915086601f830112613d2e57600080fd5b813581811115613d3d57600080fd5b876020828501011115613d4f57600080fd5b6020830194508093505050509250925092565b60008083601f840112613d7457600080fd5b50813567ffffffffffffffff811115613d8c57600080fd5b6020830191508360208260051b8501011115613da757600080fd5b9250929050565b60008060008060408587031215613dc457600080fd5b843567ffffffffffffffff80821115613ddc57600080fd5b613de888838901613d62565b90965094506020870135915080821115613e0157600080fd5b50613e0e87828801613d62565b95989497509550505050565b60008060408385031215613e2d57600080fd5b8235613e3881613c47565b946020939093013593505050565b600060208284031215613e5857600080fd5b61244482613cc2565b60008083601f840112613e7357600080fd5b50813567ffffffffffffffff811115613e8b57600080fd5b602083019150836020606083028501011115613da757600080fd5b60008060008060008060608789031215613ebf57600080fd5b863567ffffffffffffffff80821115613ed757600080fd5b613ee38a838b01613d62565b90985096506020890135915080821115613efc57600080fd5b613f088a838b01613e61565b90965094506040890135915080821115613f2157600080fd5b50613f2e89828a01613e61565b979a9699509497509295939492505050565b600060208284031215613f5257600080fd5b813567ffffffffffffffff811115613f6957600080fd5b820160a0818503121561244457600080fd5b602081526000825160406020840152613f976060840182613bea565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526134d78282613bea565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015614047577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452614035858351613bea565b94509285019290850190600101613ffb565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b818110156140a257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614070565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156140a257835167ffffffffffffffff16835292840192918401916001016140ca565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715614142576141426140f0565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561418f5761418f6140f0565b604052919050565b8015158114611d7957600080fd5b80356fffffffffffffffffffffffffffffffff81168114613cda57600080fd5b6000606082840312156141d757600080fd5b6040516060810181811067ffffffffffffffff821117156141fa576141fa6140f0565b604052905080823561420b81614197565b8152614219602084016141a5565b602082015261422a604084016141a5565b60408201525092915050565b600080600060e0848603121561424b57600080fd5b61425484613cc2565b925061426385602086016141c5565b915061427285608086016141c5565b90509250925092565b60006020828403121561428d57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126142c957600080fd5b83018035915067ffffffffffffffff8211156142e457600080fd5b602001915036819003821315613da757600080fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006060828403121561434a57600080fd5b61244483836141c5565b600181811c9082168061436857607f821691505b6020821081036143a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b67ffffffffffffffff841681526040602082015260006134d76040830184866143a7565b602081526000610a666020830184866143a7565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee183360301811261445c57600080fd5b9190910192915050565b600082601f83011261447757600080fd5b813567ffffffffffffffff811115614491576144916140f0565b6144c260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614148565b8181528460208386010111156144d757600080fd5b816020850160208301376000918101602001919091529392505050565b6000610120823603121561450757600080fd5b61450f61411f565b61451883613cc2565b815260208084013567ffffffffffffffff8082111561453657600080fd5b9085019036601f83011261454957600080fd5b81358181111561455b5761455b6140f0565b8060051b61456a858201614148565b918252838101850191858101903684111561458457600080fd5b86860192505b838310156145c0578235858111156145a25760008081fd5b6145b03689838a0101614466565b835250918601919086019061458a565b80878901525050505060408601359250808311156145dd57600080fd5b50506145eb36828601614466565b6040830152506145fe36606085016141c5565b60608201526146103660c085016141c5565b608082015292915050565b601f821115610b7c576000816000526020600020601f850160051c810160208610156146445750805b601f850160051c820191505b8181101561466357828155600101614650565b505050505050565b815167ffffffffffffffff811115614685576146856140f0565b614699816146938454614354565b8461461b565b602080601f8311600181146146ec57600084156146b65750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555614663565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156147395788860151825594840194600190910190840161471a565b508582101561477557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526147a981840187613bea565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506147e79050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526134d7565b60006020828403121561483057600080fd5b815161244481614197565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff828116828216039081111561071f5761071f61483b565b600181815b808511156148dc57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156148c2576148c261483b565b808516156148cf57918102915b93841c9390800290614888565b509250929050565b6000826148f35750600161071f565b816149005750600061071f565b816001811461491657600281146149205761493c565b600191505061071f565b60ff8411156149315761493161483b565b50506001821b61071f565b5060208310610133831016604e8410600b841016171561495f575081810a61071f565b6149698383614883565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561499b5761499b61483b565b029392505050565b600061244460ff8416836148e4565b6000826149e8577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761071f5761071f61483b565b67ffffffffffffffff83168152604060208201526000610a666040830184613bea565b67ffffffffffffffff8416815260e08101614a7360208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152610a66565b8181038181111561071f5761071f61483b565b6060810161071f82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060208284031215614b0b57600080fd5b815161244481613c47565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8082018082111561071f5761071f61483b565b6000825161445c818460208701613bc656fea164736f6c6343000818000a", } var LockReleaseTokenPoolABI = LockReleaseTokenPoolMetaData.ABI @@ -769,6 +769,18 @@ func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) SetChainRate return _LockReleaseTokenPool.Contract.SetChainRateLimiterConfig(&_LockReleaseTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) } +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "setChainRateLimiterConfigs", remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetChainRateLimiterConfigs(&_LockReleaseTokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetChainRateLimiterConfigs(&_LockReleaseTokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) { return _LockReleaseTokenPool.contract.Transact(opts, "setRateLimitAdmin", rateLimitAdmin) } @@ -3549,6 +3561,8 @@ type LockReleaseTokenPoolInterface interface { SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) + SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) SetRebalancer(opts *bind.TransactOpts, rebalancer common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generated/token_pool/token_pool.go b/core/gethwrappers/ccip/generated/token_pool/token_pool.go index 5032b336e0a..c7c947d8636 100644 --- a/core/gethwrappers/ccip/generated/token_pool/token_pool.go +++ b/core/gethwrappers/ccip/generated/token_pool/token_pool.go @@ -81,7 +81,7 @@ type TokenPoolChainUpdate struct { } var TokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"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\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"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\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"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\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"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\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"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\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"lockOrBurnOut\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"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\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"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\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"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\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MismatchedArrayLengths\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"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\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"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\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"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\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"lockOrBurnOut\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"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\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectors\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config[]\",\"name\":\"outboundConfigs\",\"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\":\"inboundConfigs\",\"type\":\"tuple[]\"}],\"name\":\"setChainRateLimiterConfigs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", } var TokenPoolABI = TokenPoolMetaData.ABI @@ -672,6 +672,18 @@ func (_TokenPool *TokenPoolTransactorSession) SetChainRateLimiterConfig(remoteCh return _TokenPool.Contract.SetChainRateLimiterConfig(&_TokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) } +func (_TokenPool *TokenPoolTransactor) SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "setChainRateLimiterConfigs", remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_TokenPool *TokenPoolSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _TokenPool.Contract.SetChainRateLimiterConfigs(&_TokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_TokenPool *TokenPoolTransactorSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _TokenPool.Contract.SetChainRateLimiterConfigs(&_TokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + func (_TokenPool *TokenPoolTransactor) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) { return _TokenPool.contract.Transact(opts, "setRateLimitAdmin", rateLimitAdmin) } @@ -2867,6 +2879,8 @@ type TokenPoolInterface interface { SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) + SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go b/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go index ca6c4a1977f..fb9493b24ac 100644 --- a/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go +++ b/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go @@ -94,8 +94,8 @@ type USDCTokenPoolDomainUpdate struct { } var USDCTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"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\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"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\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidDestinationDomain\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate\",\"name\":\"domain\",\"type\":\"tuple\"}],\"name\":\"InvalidDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidMessageVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"}],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[{\"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\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"}],\"name\":\"InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidSourceDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidTokenMessengerVersion\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"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\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"domain\",\"type\":\"uint64\"}],\"name\":\"UnknownDomain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnlockingUSDCFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"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\":false,\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"DomainsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SUPPORTED_USDC_VERSION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"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\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"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\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getDomain\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.Domain\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_localDomainIdentifier\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_messageTransmitter\",\"outputs\":[{\"internalType\":\"contractIMessageTransmitter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_tokenMessenger\",\"outputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"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\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"domains\",\"type\":\"tuple[]\"}],\"name\":\"setDomains\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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: "0x6101606040523480156200001257600080fd5b50604051620054b7380380620054b7833981016040819052620000359162000b93565b836006848484336000816200005d57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200009057620000908162000493565b50506001600160a01b0385161580620000b057506001600160a01b038116155b80620000c357506001600160a01b038216155b15620000e2576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808616608081905290831660c0526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa92505050801562000152575060408051601f3d908101601f191682019092526200014f9181019062000cb9565b60015b1562000193578060ff168560ff161462000191576040516332ad3e0760e11b815260ff8087166004830152821660248201526044015b60405180910390fd5b505b60ff841660a052600480546001600160a01b0319166001600160a01b038316179055825115801560e052620001dd57604080516000815260208101909152620001dd90846200050d565b5050506001600160a01b03871691506200020c9050576040516306b7c75960e31b815260040160405180910390fd5b6000856001600160a01b0316632c1219216040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200024d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000273919062000ce5565b90506000816001600160a01b03166354fd4d506040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002b6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002dc919062000d05565b905063ffffffff8116156200030d576040516334697c6b60e11b815263ffffffff8216600482015260240162000188565b6000876001600160a01b0316639cdbb1816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200034e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000374919062000d05565b905063ffffffff811615620003a5576040516316ba39c560e31b815263ffffffff8216600482015260240162000188565b6001600160a01b038089166101005283166101208190526040805163234d8e3d60e21b81529051638d3638f4916004808201926020929091908290030181865afa158015620003f8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200041e919062000d05565b63ffffffff16610140526101005160805162000449916001600160a01b03909116906000196200066a565b6040516001600160a01b03891681527f2e902d38f15b233cbb63711add0fca4545334d3a169d60c0a616494d7eea95449060200160405180910390a1505050505050505062000e52565b336001600160a01b03821603620004bd57604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e0516200052e576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620005b957600083828151811062000552576200055262000d2d565b602090810291909101015190506200056c60028262000750565b15620005af576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000531565b5060005b815181101562000665576000828281518110620005de57620005de62000d2d565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200060a57506200065c565b6200061760028262000770565b156200065a576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620005bd565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620006bc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620006e2919062000d43565b620006ee919062000d73565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200074a918691906200078716565b50505050565b600062000767836001600160a01b03841662000858565b90505b92915050565b600062000767836001600160a01b0384166200095c565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490820152600090620007d6906001600160a01b038516908490620009ae565b805190915015620006655780806020019051810190620007f7919062000d89565b620006655760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000188565b60008181526001830160205260408120548015620009515760006200087f60018362000dad565b8554909150600090620008959060019062000dad565b905080821462000901576000866000018281548110620008b957620008b962000d2d565b9060005260206000200154905080876000018481548110620008df57620008df62000d2d565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000915576200091562000dc3565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200076a565b60009150506200076a565b6000818152600183016020526040812054620009a5575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200076a565b5060006200076a565b6060620009bf8484600085620009c7565b949350505050565b60608247101562000a2a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000188565b600080866001600160a01b0316858760405162000a48919062000dff565b60006040518083038185875af1925050503d806000811462000a87576040519150601f19603f3d011682016040523d82523d6000602084013e62000a8c565b606091505b50909250905062000aa08783838762000aab565b979650505050505050565b6060831562000b1f57825160000362000b17576001600160a01b0385163b62000b175760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000188565b5081620009bf565b620009bf838381511562000b365781518083602001fd5b8060405162461bcd60e51b815260040162000188919062000e1d565b6001600160a01b038116811462000b6857600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000b8e8162000b52565b919050565b600080600080600060a0868803121562000bac57600080fd5b855162000bb98162000b52565b8095505060208087015162000bce8162000b52565b60408801519095506001600160401b038082111562000bec57600080fd5b818901915089601f83011262000c0157600080fd5b81518181111562000c165762000c1662000b6b565b8060051b604051601f19603f8301168101818110858211171562000c3e5762000c3e62000b6b565b60405291825284820192508381018501918c83111562000c5d57600080fd5b938501935b8285101562000c865762000c768562000b81565b8452938501939285019262000c62565b80985050505050505062000c9d6060870162000b81565b915062000cad6080870162000b81565b90509295509295909350565b60006020828403121562000ccc57600080fd5b815160ff8116811462000cde57600080fd5b9392505050565b60006020828403121562000cf857600080fd5b815162000cde8162000b52565b60006020828403121562000d1857600080fd5b815163ffffffff8116811462000cde57600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000d5657600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156200076a576200076a62000d5d565b60006020828403121562000d9c57600080fd5b8151801515811462000cde57600080fd5b818103818111156200076a576200076a62000d5d565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000df657818101518382015260200162000ddc565b50506000910152565b6000825162000e1381846020870162000dd9565b9190910192915050565b602081526000825180602084015262000e3e81604085016020870162000dd9565b601f01601f19169190910160400192915050565b60805160a05160c05160e0516101005161012051610140516145af62000f08600039600081816104170152818161113c01528181612107015261216501526000818161072b0152610a750152600081816103dd01526110520152600081816106dc0152818161221d0152612bcc01526000818161061801528181611eb40152612509015260006103660152600081816102cd015281816103220152818161101c01528181612b620152612db701526145af6000f3fe608060405234801561001057600080fd5b50600436106102405760003560e01c80639a4575b911610145578063c4bffe2b116100bd578063dfadfa351161008c578063e8a1da1711610071578063e8a1da1714610700578063f2fde38b14610713578063fbf84dd71461072657600080fd5b8063dfadfa351461063c578063e0351e13146106da57600080fd5b8063c4bffe2b146105db578063c75eea9c146105f0578063cf7401f314610603578063dc0bd9711461061657600080fd5b8063acfecf9111610114578063b0f479a1116100f9578063b0f479a114610597578063b7946580146105b5578063c0d78655146105c857600080fd5b8063acfecf9114610515578063af58d59f1461052857600080fd5b80639a4575b9146104b85780639fdf13ff146104d8578063a42a7b8b146104e0578063a7cd63b71461050057600080fd5b806354c8a4f3116101d85780636d3d1a58116101a75780637d54534e1161018c5780637d54534e146104745780638926f54f146104875780638da5cb5b1461049a57600080fd5b80636d3d1a581461044e57806379ba50971461046c57600080fd5b806354c8a4f3146103c55780636155cda0146103d857806362ddd3c4146103ff5780636b716b0d1461041257600080fd5b8063240028e811610214578063240028e81461031257806324f65ee71461035f57806339077537146103905780634c5ef0ed146103b257600080fd5b806241d3c11461024557806301ffc9a71461025a578063181f5a771461028257806321df0da7146102cb575b600080fd5b610258610253366004613577565b61074d565b005b61026d6102683660046135ec565b6108ea565b60405190151581526020015b60405180910390f35b6102be6040518060400160405280601381526020017f55534443546f6b656e506f6f6c20312e352e310000000000000000000000000081525081565b6040516102799190613692565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610279565b61026d6103203660046136c7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610279565b6103a361039e3660046136e4565b6109cf565b60405190518152602001610279565b61026d6103c0366004613736565b610bb4565b6102586103d3366004613807565b610bfe565b6102ed7f000000000000000000000000000000000000000000000000000000000000000081565b61025861040d366004613736565b610c79565b6104397f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610279565b60095473ffffffffffffffffffffffffffffffffffffffff166102ed565b610258610d11565b6102586104823660046136c7565b610ddf565b61026d610495366004613873565b610e60565b60015473ffffffffffffffffffffffffffffffffffffffff166102ed565b6104cb6104c6366004613890565b610e77565b60405161027991906138cb565b610439600081565b6104f36104ee366004613873565b6111b7565b6040516102799190613922565b610508611322565b60405161027991906139a4565b610258610523366004613736565b611333565b61053b610536366004613873565b61144b565b604051610279919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102ed565b6102be6105c3366004613873565b611520565b6102586105d63660046136c7565b6115d0565b6105e36116a4565b60405161027991906139fe565b61053b6105fe366004613873565b61175c565b610258610611366004613b8b565b61182e565b7f00000000000000000000000000000000000000000000000000000000000000006102ed565b6106b061064a366004613873565b60408051606080820183526000808352602080840182905292840181905267ffffffffffffffff949094168452600a82529282902082519384018352805484526001015463ffffffff811691840191909152640100000000900460ff1615159082015290565b604080518251815260208084015163ffffffff169082015291810151151590820152606001610279565b7f000000000000000000000000000000000000000000000000000000000000000061026d565b61025861070e366004613807565b6118b2565b6102586107213660046136c7565b611dc4565b6102ed7f000000000000000000000000000000000000000000000000000000000000000081565b610755611dd8565b60005b818110156108ac57600083838381811061077457610774613bd2565b90506080020180360381019061078a9190613c15565b805190915015806107a75750604081015167ffffffffffffffff16155b1561081657604080517fa087bd2900000000000000000000000000000000000000000000000000000000815282516004820152602083015163ffffffff1660248201529082015167ffffffffffffffff1660448201526060820151151560648201526084015b60405180910390fd5b60408051606080820183528351825260208085015163ffffffff9081168285019081529286015115158486019081529585015167ffffffffffffffff166000908152600a90925293902091518255516001918201805494511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000909516919093161792909217905501610758565b507f1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee5682826040516108de929190613c8f565b60405180910390a15050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061097d57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806109c957507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b6040805160208101909152600081526109e782611e2b565b60006109f660c0840184613d16565b810190610a039190613d7b565b90506000610a1460e0850185613d16565b810190610a219190613e48565b9050610a3181600001518361204f565b805160208201516040517f57ecfd2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016926357ecfd2892610aa892600401613ed9565b6020604051808303816000875af1158015610ac7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aeb9190613efe565b610b21576040517fbf969f2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b3160608501604086016136c7565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08660600135604051610b9391815260200190565b60405180910390a35050604080516020810190915260609092013582525090565b6000610bf68383604051610bc9929190613f1b565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190612200565b949350505050565b610c06611dd8565b610c738484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061221b92505050565b50505050565b610c81611dd8565b610c8a83610e60565b610ccc576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161080d565b610d0c8383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506123d192505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d62576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610de7611dd8565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b60006109c9600567ffffffffffffffff8416612200565b6040805180820190915260608082526020820152610e94826124cb565b6000600a81610ea96040860160208701613873565b67ffffffffffffffff168152602080820192909252604090810160002081516060810183528154815260019091015463ffffffff81169382019390935264010000000090920460ff161515908201819052909150610f5057610f116040840160208501613873565b6040517fd201c48a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161080d565b610f5a8380613d16565b9050602014610fa157610f6d8380613d16565b6040517fa3c8cf0900000000000000000000000000000000000000000000000000000000815260040161080d929190613f74565b6000610fad8480613d16565b810190610fba9190613f88565b602083015183516040517ff856ddb60000000000000000000000000000000000000000000000000000000081526060880135600482015263ffffffff90921660248301526044820183905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116606484015260848301919091529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063f856ddb69060a4016020604051808303816000875af115801561109b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110bf9190613fa1565b6040516060870135815290915033907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a2604051806040016040528061111c8760200160208101906105c39190613873565b815260408051808201825267ffffffffffffffff851680825263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602093840190815284518085019390935251169281019290925290910190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905295945050505050565b67ffffffffffffffff81166000908152600760205260408120606091906111e090600501612657565b90506000815167ffffffffffffffff8111156111fe576111fe613a40565b60405190808252806020026020018201604052801561123157816020015b606081526020019060019003908161121c5790505b50905060005b825181101561131a576008600084838151811061125657611256613bd2565b60200260200101518152602001908152602001600020805461127790613fbe565b80601f01602080910402602001604051908101604052809291908181526020018280546112a390613fbe565b80156112f05780601f106112c5576101008083540402835291602001916112f0565b820191906000526020600020905b8154815290600101906020018083116112d357829003601f168201915b505050505082828151811061130757611307613bd2565b6020908102919091010152600101611237565b509392505050565b606061132e6002612657565b905090565b61133b611dd8565b61134483610e60565b611386576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161080d565b6113c68282604051611399929190613f1b565b604080519182900390912067ffffffffffffffff8616600090815260076020529190912060050190612664565b611402578282826040517f74f23c7c00000000000000000000000000000000000000000000000000000000815260040161080d93929190614011565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d76838360405161143e929190613f74565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526109c990612670565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061154b90613fbe565b80601f016020809104026020016040519081016040528092919081815260200182805461157790613fbe565b80156115c45780601f10611599576101008083540402835291602001916115c4565b820191906000526020600020905b8154815290600101906020018083116115a757829003601f168201915b50505050509050919050565b6115d8611dd8565b73ffffffffffffffffffffffffffffffffffffffff8116611625576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f168491016108de565b606060006116b26005612657565b90506000815167ffffffffffffffff8111156116d0576116d0613a40565b6040519080825280602002602001820160405280156116f9578160200160208202803683370190505b50905060005b82518110156117555782818151811061171a5761171a613bd2565b602002602001015182828151811061173457611734613bd2565b67ffffffffffffffff909216602092830291909101909101526001016116ff565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526109c990612670565b60095473ffffffffffffffffffffffffffffffffffffffff16331480159061186e575060015473ffffffffffffffffffffffffffffffffffffffff163314155b156118a7576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161080d565b610d0c838383612722565b6118ba611dd8565b60005b83811015611aa75760008585838181106118d9576118d9613bd2565b90506020020160208101906118ee9190613873565b9050611905600567ffffffffffffffff8316612664565b611947576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161080d565b67ffffffffffffffff8116600090815260076020526040812061196c90600501612657565b905060005b81518110156119d8576119cf82828151811061198f5761198f613bd2565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060050161266490919063ffffffff16565b50600101611971565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff00000000000000000000000000000000000000000090811682556001820183905560028201805490911690556003810182905590611a41600483018261350a565b6005820160008181611a538282613544565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d85991694506020019250611a95915050565b60405180910390a150506001016118bd565b5060005b81811015611dbd576000838383818110611ac757611ac7613bd2565b9050602002810190611ad99190614035565b611ae290614112565b9050611af38160600151600061280c565b611b028160800151600061280c565b806040015151600003611b41576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051611b599060059067ffffffffffffffff16612949565b611b9e5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161080d565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a909102999093161717909416959095179092559092029091176003820155908201516004820190611d21908261421a565b5060005b826020015151811015611d6557611d5d836000015184602001518381518110611d5057611d50613bd2565b60200260200101516123d1565b600101611d25565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c28260000151836040015184606001518560800151604051611dab9493929190614334565b60405180910390a15050600101611aab565b5050505050565b611dcc611dd8565b611dd581612955565b50565b60015473ffffffffffffffffffffffffffffffffffffffff163314611e29576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b611e3e61032060a08301608084016136c7565b611e9d57611e5260a08201608083016136c7565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161080d565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb611ee96040840160208501613873565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015611f5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f7e9190613efe565b15611fb5576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611fcd611fc86040830160208401613873565b612a19565b611fed611fe06040830160208401613873565b6103c060a0840184613d16565b61203257611ffe60a0820182613d16565b6040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161080d929190613f74565b611dd56120456040830160208401613873565b8260600135612b3f565b600482015163ffffffff81161561209a576040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff8216600482015260240161080d565b6008830151600c8401516014850151602085015163ffffffff8085169116146121055760208501516040517fe366a11700000000000000000000000000000000000000000000000000000000815263ffffffff9182166004820152908416602482015260440161080d565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168263ffffffff161461219a576040517f77e4802600000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301528316602482015260440161080d565b845167ffffffffffffffff8281169116146121f85784516040517ff917ffea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9182166004820152908216602482015260440161080d565b505050505050565b600081815260018301602052604081205415155b9392505050565b7f0000000000000000000000000000000000000000000000000000000000000000612272576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561230857600083828151811061229257612292613bd2565b602002602001015190506122b0816002612b8690919063ffffffff16565b156122ff5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101612275565b5060005b8151811015610d0c57600082828151811061232957612329613bd2565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361236d57506123c9565b612378600282612ba8565b156123c75760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010161230c565b805160000361240c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff841660009081526007909252604090912061243e9060050182612949565b6124785782826040517f393b8ad200000000000000000000000000000000000000000000000000000000815260040161080d9291906143cd565b6000818152600860205260409020612490838261421a565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea8360405161143e9190613692565b6124de61032060a08301608084016136c7565b6124f257611e5260a08201608083016136c7565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb61253e6040840160208501613873565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa1580156125af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d39190613efe565b1561260a576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61262261261d60608301604084016136c7565b612bca565b61263a6126356040830160208401613873565b612c49565b611dd561264d6040830160208401613873565b8260600135612d97565b6060600061221483612ddb565b60006122148383612e36565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526126fe82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426126e2919061441f565b85608001516fffffffffffffffffffffffffffffffff16612f29565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61272b83610e60565b61276d576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161080d565b61277882600061280c565b67ffffffffffffffff8316600090815260076020526040902061279b9083612f51565b6127a681600061280c565b67ffffffffffffffff831660009081526007602052604090206127cc9060020182612f51565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516127ff93929190614432565b60405180910390a1505050565b8151156128d75781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612862575060408201516fffffffffffffffffffffffffffffffff16155b1561289b57816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161080d91906144b5565b80156128d3576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff16151580612910575060208201516fffffffffffffffffffffffffffffffff1615155b156128d357816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161080d91906144b5565b600061221483836130f3565b3373ffffffffffffffffffffffffffffffffffffffff8216036129a4576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b612a2281610e60565b612a64576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161080d565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612ae3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b079190613efe565b611dd5576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161080d565b67ffffffffffffffff821660009081526007602052604090206128d390600201827f0000000000000000000000000000000000000000000000000000000000000000613142565b60006122148373ffffffffffffffffffffffffffffffffffffffff8416612e36565b60006122148373ffffffffffffffffffffffffffffffffffffffff84166130f3565b7f000000000000000000000000000000000000000000000000000000000000000015611dd557612bfb6002826134c5565b611dd5576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161080d565b612c5281610e60565b612c94576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161080d565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612d0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d3191906144f1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611dd5576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161080d565b67ffffffffffffffff821660009081526007602052604090206128d390827f0000000000000000000000000000000000000000000000000000000000000000613142565b6060816000018054806020026020016040519081016040528092919081815260200182805480156115c457602002820191906000526020600020905b815481526020019060010190808311612e175750505050509050919050565b60008181526001830160205260408120548015612f1f576000612e5a60018361441f565b8554909150600090612e6e9060019061441f565b9050808214612ed3576000866000018281548110612e8e57612e8e613bd2565b9060005260206000200154905080876000018481548110612eb157612eb1613bd2565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612ee457612ee461450e565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506109c9565b60009150506109c9565b6000612f4885612f39848661453d565b612f439087614554565b6134f4565b95945050505050565b8154600090612f7a90700100000000000000000000000000000000900463ffffffff164261441f565b9050801561301c5760018301548354612fc2916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612f29565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354613042916fffffffffffffffffffffffffffffffff90811691166134f4565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906127ff9084906144b5565b600081815260018301602052604081205461313a575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556109c9565b5060006109c9565b825474010000000000000000000000000000000000000000900460ff161580613169575081155b1561317357505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906131b990700100000000000000000000000000000000900463ffffffff164261441f565b9050801561327957818311156131fb576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546132359083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612f29565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156133305773ffffffffffffffffffffffffffffffffffffffff84166132d8576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161080d565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161080d565b848310156134435760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290613374908261441f565b61337e878a61441f565b6133889190614554565b6133929190614567565b905073ffffffffffffffffffffffffffffffffffffffff86166133eb576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161080d565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161080d565b61344d858461441f565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515612214565b60008183106135035781612214565b5090919050565b50805461351690613fbe565b6000825580601f10613526575050565b601f016020900490600052602060002090810190611dd5919061355e565b5080546000825590600052602060002090810190611dd591905b5b80821115613573576000815560010161355f565b5090565b6000806020838503121561358a57600080fd5b823567ffffffffffffffff808211156135a257600080fd5b818501915085601f8301126135b657600080fd5b8135818111156135c557600080fd5b8660208260071b85010111156135da57600080fd5b60209290920196919550909350505050565b6000602082840312156135fe57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461221457600080fd5b6000815180845260005b8181101561365457602081850181015186830182015201613638565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000612214602083018461362e565b73ffffffffffffffffffffffffffffffffffffffff81168114611dd557600080fd5b6000602082840312156136d957600080fd5b8135612214816136a5565b6000602082840312156136f657600080fd5b813567ffffffffffffffff81111561370d57600080fd5b8201610100818503121561221457600080fd5b67ffffffffffffffff81168114611dd557600080fd5b60008060006040848603121561374b57600080fd5b833561375681613720565b9250602084013567ffffffffffffffff8082111561377357600080fd5b818601915086601f83011261378757600080fd5b81358181111561379657600080fd5b8760208285010111156137a857600080fd5b6020830194508093505050509250925092565b60008083601f8401126137cd57600080fd5b50813567ffffffffffffffff8111156137e557600080fd5b6020830191508360208260051b850101111561380057600080fd5b9250929050565b6000806000806040858703121561381d57600080fd5b843567ffffffffffffffff8082111561383557600080fd5b613841888389016137bb565b9096509450602087013591508082111561385a57600080fd5b50613867878288016137bb565b95989497509550505050565b60006020828403121561388557600080fd5b813561221481613720565b6000602082840312156138a257600080fd5b813567ffffffffffffffff8111156138b957600080fd5b820160a0818503121561221457600080fd5b6020815260008251604060208401526138e7606084018261362e565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612f48828261362e565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015613997577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261398585835161362e565b9450928501929085019060010161394b565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b818110156139f257835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016139c0565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156139f257835167ffffffffffffffff1683529284019291840191600101613a1a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715613a9257613a92613a40565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613adf57613adf613a40565b604052919050565b8015158114611dd557600080fd5b80356fffffffffffffffffffffffffffffffff81168114613b1557600080fd5b919050565b600060608284031215613b2c57600080fd5b6040516060810181811067ffffffffffffffff82111715613b4f57613b4f613a40565b6040529050808235613b6081613ae7565b8152613b6e60208401613af5565b6020820152613b7f60408401613af5565b60408201525092915050565b600080600060e08486031215613ba057600080fd5b8335613bab81613720565b9250613bba8560208601613b1a565b9150613bc98560808601613b1a565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b803563ffffffff81168114613b1557600080fd5b600060808284031215613c2757600080fd5b6040516080810181811067ffffffffffffffff82111715613c4a57613c4a613a40565b60405282358152613c5d60208401613c01565b60208201526040830135613c7081613720565b60408201526060830135613c8381613ae7565b60608201529392505050565b6020808252818101839052600090604080840186845b87811015613d09578135835263ffffffff613cc1868401613c01565b168584015283820135613cd381613720565b67ffffffffffffffff1683850152606082810135613cf081613ae7565b1515908401526080928301929190910190600101613ca5565b5090979650505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613d4b57600080fd5b83018035915067ffffffffffffffff821115613d6657600080fd5b60200191503681900382131561380057600080fd5b600060408284031215613d8d57600080fd5b613d95613a6f565b8235613da081613720565b8152613dae60208401613c01565b60208201529392505050565b600082601f830112613dcb57600080fd5b813567ffffffffffffffff811115613de557613de5613a40565b613e1660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613a98565b818152846020838601011115613e2b57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215613e5a57600080fd5b813567ffffffffffffffff80821115613e7257600080fd5b9083019060408286031215613e8657600080fd5b613e8e613a6f565b823582811115613e9d57600080fd5b613ea987828601613dba565b825250602083013582811115613ebe57600080fd5b613eca87828601613dba565b60208301525095945050505050565b604081526000613eec604083018561362e565b8281036020840152612f48818561362e565b600060208284031215613f1057600080fd5b815161221481613ae7565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000610bf6602083018486613f2b565b600060208284031215613f9a57600080fd5b5035919050565b600060208284031215613fb357600080fd5b815161221481613720565b600181811c90821680613fd257607f821691505b60208210810361400b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b67ffffffffffffffff84168152604060208201526000612f48604083018486613f2b565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee183360301811261406957600080fd5b9190910192915050565b600082601f83011261408457600080fd5b8135602067ffffffffffffffff808311156140a1576140a1613a40565b8260051b6140b0838201613a98565b93845285810183019383810190888611156140ca57600080fd5b84880192505b85831015614106578235848111156140e85760008081fd5b6140f68a87838c0101613dba565b83525091840191908401906140d0565b98975050505050505050565b6000610120823603121561412557600080fd5b60405160a0810167ffffffffffffffff828210818311171561414957614149613a40565b816040528435915061415a82613720565b9082526020840135908082111561417057600080fd5b61417c36838701614073565b6020840152604085013591508082111561419557600080fd5b506141a236828601613dba565b6040830152506141b53660608501613b1a565b60608201526141c73660c08501613b1a565b608082015292915050565b601f821115610d0c576000816000526020600020601f850160051c810160208610156141fb5750805b601f850160051c820191505b818110156121f857828155600101614207565b815167ffffffffffffffff81111561423457614234613a40565b614248816142428454613fbe565b846141d2565b602080601f83116001811461429b57600084156142655750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556121f8565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156142e8578886015182559484019460019091019084016142c9565b508582101561432457878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526143588184018761362e565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506143969050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612f48565b67ffffffffffffffff83168152604060208201526000610bf6604083018461362e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109c9576109c96143f0565b67ffffffffffffffff8416815260e0810161447e60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152610bf6565b606081016109c982848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561450357600080fd5b8151612214816136a5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b80820281158282048414176109c9576109c96143f0565b808201808211156109c9576109c96143f0565b60008261459d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"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\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"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\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidDestinationDomain\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate\",\"name\":\"domain\",\"type\":\"tuple\"}],\"name\":\"InvalidDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidMessageVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"}],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[{\"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\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"}],\"name\":\"InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidSourceDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidTokenMessengerVersion\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MismatchedArrayLengths\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"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\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"domain\",\"type\":\"uint64\"}],\"name\":\"UnknownDomain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnlockingUSDCFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"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\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"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\":false,\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"DomainsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SUPPORTED_USDC_VERSION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"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\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"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\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"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\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getDomain\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.Domain\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_localDomainIdentifier\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_messageTransmitter\",\"outputs\":[{\"internalType\":\"contractIMessageTransmitter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_tokenMessenger\",\"outputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"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\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectors\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config[]\",\"name\":\"outboundConfigs\",\"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\":\"inboundConfigs\",\"type\":\"tuple[]\"}],\"name\":\"setChainRateLimiterConfigs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"domains\",\"type\":\"tuple[]\"}],\"name\":\"setDomains\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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: "0x6101606040523480156200001257600080fd5b506040516200573a3803806200573a833981016040819052620000359162000b93565b836006848484336000816200005d57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200009057620000908162000493565b50506001600160a01b0385161580620000b057506001600160a01b038116155b80620000c357506001600160a01b038216155b15620000e2576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808616608081905290831660c0526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa92505050801562000152575060408051601f3d908101601f191682019092526200014f9181019062000cb9565b60015b1562000193578060ff168560ff161462000191576040516332ad3e0760e11b815260ff8087166004830152821660248201526044015b60405180910390fd5b505b60ff841660a052600480546001600160a01b0319166001600160a01b038316179055825115801560e052620001dd57604080516000815260208101909152620001dd90846200050d565b5050506001600160a01b03871691506200020c9050576040516306b7c75960e31b815260040160405180910390fd5b6000856001600160a01b0316632c1219216040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200024d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000273919062000ce5565b90506000816001600160a01b03166354fd4d506040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002b6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002dc919062000d05565b905063ffffffff8116156200030d576040516334697c6b60e11b815263ffffffff8216600482015260240162000188565b6000876001600160a01b0316639cdbb1816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200034e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000374919062000d05565b905063ffffffff811615620003a5576040516316ba39c560e31b815263ffffffff8216600482015260240162000188565b6001600160a01b038089166101005283166101208190526040805163234d8e3d60e21b81529051638d3638f4916004808201926020929091908290030181865afa158015620003f8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200041e919062000d05565b63ffffffff16610140526101005160805162000449916001600160a01b03909116906000196200066a565b6040516001600160a01b03891681527f2e902d38f15b233cbb63711add0fca4545334d3a169d60c0a616494d7eea95449060200160405180910390a1505050505050505062000e52565b336001600160a01b03821603620004bd57604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e0516200052e576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620005b957600083828151811062000552576200055262000d2d565b602090810291909101015190506200056c60028262000750565b15620005af576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000531565b5060005b815181101562000665576000828281518110620005de57620005de62000d2d565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200060a57506200065c565b6200061760028262000770565b156200065a576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620005bd565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620006bc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620006e2919062000d43565b620006ee919062000d73565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200074a918691906200078716565b50505050565b600062000767836001600160a01b03841662000858565b90505b92915050565b600062000767836001600160a01b0384166200095c565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490820152600090620007d6906001600160a01b038516908490620009ae565b805190915015620006655780806020019051810190620007f7919062000d89565b620006655760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000188565b60008181526001830160205260408120548015620009515760006200087f60018362000dad565b8554909150600090620008959060019062000dad565b905080821462000901576000866000018281548110620008b957620008b962000d2d565b9060005260206000200154905080876000018481548110620008df57620008df62000d2d565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000915576200091562000dc3565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200076a565b60009150506200076a565b6000818152600183016020526040812054620009a5575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200076a565b5060006200076a565b6060620009bf8484600085620009c7565b949350505050565b60608247101562000a2a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000188565b600080866001600160a01b0316858760405162000a48919062000dff565b60006040518083038185875af1925050503d806000811462000a87576040519150601f19603f3d011682016040523d82523d6000602084013e62000a8c565b606091505b50909250905062000aa08783838762000aab565b979650505050505050565b6060831562000b1f57825160000362000b17576001600160a01b0385163b62000b175760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000188565b5081620009bf565b620009bf838381511562000b365781518083602001fd5b8060405162461bcd60e51b815260040162000188919062000e1d565b6001600160a01b038116811462000b6857600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000b8e8162000b52565b919050565b600080600080600060a0868803121562000bac57600080fd5b855162000bb98162000b52565b8095505060208087015162000bce8162000b52565b60408801519095506001600160401b038082111562000bec57600080fd5b818901915089601f83011262000c0157600080fd5b81518181111562000c165762000c1662000b6b565b8060051b604051601f19603f8301168101818110858211171562000c3e5762000c3e62000b6b565b60405291825284820192508381018501918c83111562000c5d57600080fd5b938501935b8285101562000c865762000c768562000b81565b8452938501939285019262000c62565b80985050505050505062000c9d6060870162000b81565b915062000cad6080870162000b81565b90509295509295909350565b60006020828403121562000ccc57600080fd5b815160ff8116811462000cde57600080fd5b9392505050565b60006020828403121562000cf857600080fd5b815162000cde8162000b52565b60006020828403121562000d1857600080fd5b815163ffffffff8116811462000cde57600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000d5657600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156200076a576200076a62000d5d565b60006020828403121562000d9c57600080fd5b8151801515811462000cde57600080fd5b818103818111156200076a576200076a62000d5d565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000df657818101518382015260200162000ddc565b50506000910152565b6000825162000e1381846020870162000dd9565b9190910192915050565b602081526000825180602084015262000e3e81604085016020870162000dd9565b601f01601f19169190910160400192915050565b60805160a05160c05160e05161010051610120516101405161483262000f0860003960008181610432015281816112c40152818161228f01526122ed0152600081816107590152610aa30152600081816103f801526111da01526000818161070a015281816123a50152612ef60152600081816106460152818161203c015261277b015260006103810152600081816102e80152818161033d015281816111a401528181612cea01526130e101526148326000f3fe608060405234801561001057600080fd5b506004361061025b5760003560e01c80639a4575b911610145578063c4bffe2b116100bd578063dfadfa351161008c578063e8a1da1711610071578063e8a1da171461072e578063f2fde38b14610741578063fbf84dd71461075457600080fd5b8063dfadfa351461066a578063e0351e131461070857600080fd5b8063c4bffe2b14610609578063c75eea9c1461061e578063cf7401f314610631578063dc0bd9711461064457600080fd5b8063acfecf9111610114578063b0f479a1116100f9578063b0f479a1146105c5578063b7946580146105e3578063c0d78655146105f657600080fd5b8063acfecf9114610543578063af58d59f1461055657600080fd5b80639a4575b9146104e65780639fdf13ff14610506578063a42a7b8b1461050e578063a7cd63b71461052e57600080fd5b80636155cda0116101d857806379ba5097116101a75780638926f54f1161018c5780638926f54f146104a25780638da5cb5b146104b5578063962d4020146104d357600080fd5b806379ba5097146104875780637d54534e1461048f57600080fd5b80636155cda0146103f357806362ddd3c41461041a5780636b716b0d1461042d5780636d3d1a581461046957600080fd5b8063240028e81161022f578063390775371161021457806339077537146103ab5780634c5ef0ed146103cd57806354c8a4f3146103e057600080fd5b8063240028e81461032d57806324f65ee71461037a57600080fd5b806241d3c11461026057806301ffc9a714610275578063181f5a771461029d57806321df0da7146102e6575b600080fd5b61027361026e3660046136ff565b61077b565b005b610288610283366004613774565b610918565b60405190151581526020015b60405180910390f35b6102d96040518060400160405280601381526020017f55534443546f6b656e506f6f6c20312e352e310000000000000000000000000081525081565b604051610294919061381a565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610294565b61028861033b36600461384f565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610294565b6103be6103b936600461386c565b6109fd565b60405190518152602001610294565b6102886103db3660046138be565b610be2565b6102736103ee36600461398f565b610c2c565b6103087f000000000000000000000000000000000000000000000000000000000000000081565b6102736104283660046138be565b610ca7565b6104547f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610294565b60095473ffffffffffffffffffffffffffffffffffffffff16610308565b610273610d3f565b61027361049d36600461384f565b610e0d565b6102886104b03660046139fb565b610e8e565b60015473ffffffffffffffffffffffffffffffffffffffff16610308565b6102736104e1366004613a5d565b610ea5565b6104f96104f4366004613af7565b610fff565b6040516102949190613b32565b610454600081565b61052161051c3660046139fb565b61133f565b6040516102949190613b89565b6105366114aa565b6040516102949190613c0b565b6102736105513660046138be565b6114bb565b6105696105643660046139fb565b6115d3565b604051610294919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610308565b6102d96105f13660046139fb565b6116a8565b61027361060436600461384f565b611758565b61061161182c565b6040516102949190613c65565b61056961062c3660046139fb565b6118e4565b61027361063f366004613df2565b6119b6565b7f0000000000000000000000000000000000000000000000000000000000000000610308565b6106de6106783660046139fb565b60408051606080820183526000808352602080840182905292840181905267ffffffffffffffff949094168452600a82529282902082519384018352805484526001015463ffffffff811691840191909152640100000000900460ff1615159082015290565b604080518251815260208084015163ffffffff169082015291810151151590820152606001610294565b7f0000000000000000000000000000000000000000000000000000000000000000610288565b61027361073c36600461398f565b611a3a565b61027361074f36600461384f565b611f4c565b6103087f000000000000000000000000000000000000000000000000000000000000000081565b610783611f60565b60005b818110156108da5760008383838181106107a2576107a2613e39565b9050608002018036038101906107b89190613e7c565b805190915015806107d55750604081015167ffffffffffffffff16155b1561084457604080517fa087bd2900000000000000000000000000000000000000000000000000000000815282516004820152602083015163ffffffff1660248201529082015167ffffffffffffffff1660448201526060820151151560648201526084015b60405180910390fd5b60408051606080820183528351825260208085015163ffffffff9081168285019081529286015115158486019081529585015167ffffffffffffffff166000908152600a90925293902091518255516001918201805494511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000909516919093161792909217905501610786565b507f1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee56828260405161090c929190613ef6565b60405180910390a15050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806109ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806109f757507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b604080516020810190915260008152610a1582611fb3565b6000610a2460c0840184613f7d565b810190610a319190613fe2565b90506000610a4260e0850185613f7d565b810190610a4f91906140af565b9050610a5f8160000151836121d7565b805160208201516040517f57ecfd2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016926357ecfd2892610ad692600401614140565b6020604051808303816000875af1158015610af5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b199190614165565b610b4f576040517fbf969f2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b5f606085016040860161384f565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08660600135604051610bc191815260200190565b60405180910390a35050604080516020810190915260609092013582525090565b6000610c248383604051610bf7929190614182565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190612388565b949350505050565b610c34611f60565b610ca1848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040805160208088028281018201909352878252909350879250869182918501908490808284376000920191909152506123a392505050565b50505050565b610caf611f60565b610cb883610e8e565b610cfa576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161083b565b610d3a8383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061255992505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d90576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e15611f60565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b60006109f7600567ffffffffffffffff8416612388565b60095473ffffffffffffffffffffffffffffffffffffffff163314801590610ee5575060015473ffffffffffffffffffffffffffffffffffffffff163314155b15610f1e576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161083b565b8483141580610f2d5750848114155b15610f64576040517f568efce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b85811015610ff657610fee878783818110610f8457610f84613e39565b9050602002016020810190610f9991906139fb565b868684818110610fab57610fab613e39565b905060600201803603810190610fc19190614192565b858585818110610fd357610fd3613e39565b905060600201803603810190610fe99190614192565b612653565b600101610f67565b50505050505050565b604080518082019091526060808252602082015261101c8261273d565b6000600a8161103160408601602087016139fb565b67ffffffffffffffff168152602080820192909252604090810160002081516060810183528154815260019091015463ffffffff81169382019390935264010000000090920460ff1615159082018190529091506110d85761109960408401602085016139fb565b6040517fd201c48a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161083b565b6110e28380613f7d565b9050602014611129576110f58380613f7d565b6040517fa3c8cf0900000000000000000000000000000000000000000000000000000000815260040161083b9291906141f7565b60006111358480613f7d565b810190611142919061420b565b602083015183516040517ff856ddb60000000000000000000000000000000000000000000000000000000081526060880135600482015263ffffffff90921660248301526044820183905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116606484015260848301919091529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063f856ddb69060a4016020604051808303816000875af1158015611223573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112479190614224565b6040516060870135815290915033907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a260405180604001604052806112a48760200160208101906105f191906139fb565b815260408051808201825267ffffffffffffffff851680825263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602093840190815284518085019390935251169281019290925290910190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905295945050505050565b67ffffffffffffffff8116600090815260076020526040812060609190611368906005016128c9565b90506000815167ffffffffffffffff81111561138657611386613ca7565b6040519080825280602002602001820160405280156113b957816020015b60608152602001906001900390816113a45790505b50905060005b82518110156114a257600860008483815181106113de576113de613e39565b6020026020010151815260200190815260200160002080546113ff90614241565b80601f016020809104026020016040519081016040528092919081815260200182805461142b90614241565b80156114785780601f1061144d57610100808354040283529160200191611478565b820191906000526020600020905b81548152906001019060200180831161145b57829003601f168201915b505050505082828151811061148f5761148f613e39565b60209081029190910101526001016113bf565b509392505050565b60606114b660026128c9565b905090565b6114c3611f60565b6114cc83610e8e565b61150e576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161083b565b61154e8282604051611521929190614182565b604080519182900390912067ffffffffffffffff86166000908152600760205291909120600501906128d6565b61158a578282826040517f74f23c7c00000000000000000000000000000000000000000000000000000000815260040161083b93929190614294565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d7683836040516115c69291906141f7565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526109f7906128e2565b67ffffffffffffffff811660009081526007602052604090206004018054606091906116d390614241565b80601f01602080910402602001604051908101604052809291908181526020018280546116ff90614241565b801561174c5780601f106117215761010080835404028352916020019161174c565b820191906000526020600020905b81548152906001019060200180831161172f57829003601f168201915b50505050509050919050565b611760611f60565b73ffffffffffffffffffffffffffffffffffffffff81166117ad576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910161090c565b6060600061183a60056128c9565b90506000815167ffffffffffffffff81111561185857611858613ca7565b604051908082528060200260200182016040528015611881578160200160208202803683370190505b50905060005b82518110156118dd578281815181106118a2576118a2613e39565b60200260200101518282815181106118bc576118bc613e39565b67ffffffffffffffff90921660209283029190910190910152600101611887565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526109f7906128e2565b60095473ffffffffffffffffffffffffffffffffffffffff1633148015906119f6575060015473ffffffffffffffffffffffffffffffffffffffff163314155b15611a2f576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161083b565b610d3a838383612653565b611a42611f60565b60005b83811015611c2f576000858583818110611a6157611a61613e39565b9050602002016020810190611a7691906139fb565b9050611a8d600567ffffffffffffffff83166128d6565b611acf576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161083b565b67ffffffffffffffff81166000908152600760205260408120611af4906005016128c9565b905060005b8151811015611b6057611b57828281518110611b1757611b17613e39565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206005016128d690919063ffffffff16565b50600101611af9565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff00000000000000000000000000000000000000000090811682556001820183905560028201805490911690556003810182905590611bc96004830182613692565b6005820160008181611bdb82826136cc565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d85991694506020019250611c1d915050565b60405180910390a15050600101611a45565b5060005b81811015611f45576000838383818110611c4f57611c4f613e39565b9050602002810190611c6191906142b8565b611c6a90614395565b9050611c7b81606001516000612994565b611c8a81608001516000612994565b806040015151600003611cc9576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051611ce19060059067ffffffffffffffff16612ad1565b611d265780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161083b565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a909102999093161717909416959095179092559092029091176003820155908201516004820190611ea9908261449d565b5060005b826020015151811015611eed57611ee5836000015184602001518381518110611ed857611ed8613e39565b6020026020010151612559565b600101611ead565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c28260000151836040015184606001518560800151604051611f3394939291906145b7565b60405180910390a15050600101611c33565b5050505050565b611f54611f60565b611f5d81612add565b50565b60015473ffffffffffffffffffffffffffffffffffffffff163314611fb1576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b611fc661033b60a083016080840161384f565b61202557611fda60a082016080830161384f565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161083b565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb61207160408401602085016139fb565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa1580156120e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121069190614165565b1561213d576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61215561215060408301602084016139fb565b612ba1565b61217561216860408301602084016139fb565b6103db60a0840184613f7d565b6121ba5761218660a0820182613f7d565b6040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161083b9291906141f7565b611f5d6121cd60408301602084016139fb565b8260600135612cc7565b600482015163ffffffff811615612222576040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff8216600482015260240161083b565b6008830151600c8401516014850151602085015163ffffffff80851691161461228d5760208501516040517fe366a11700000000000000000000000000000000000000000000000000000000815263ffffffff9182166004820152908416602482015260440161083b565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168263ffffffff1614612322576040517f77e4802600000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301528316602482015260440161083b565b845167ffffffffffffffff8281169116146123805784516040517ff917ffea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9182166004820152908216602482015260440161083b565b505050505050565b600081815260018301602052604081205415155b9392505050565b7f00000000000000000000000000000000000000000000000000000000000000006123fa576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561249057600083828151811061241a5761241a613e39565b60200260200101519050612438816002612d0e90919063ffffffff16565b156124875760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016123fd565b5060005b8151811015610d3a5760008282815181106124b1576124b1613e39565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036124f55750612551565b612500600282612d30565b1561254f5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101612494565b8051600003612594576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff84166000908152600790925260409091206125c69060050182612ad1565b6126005782826040517f393b8ad200000000000000000000000000000000000000000000000000000000815260040161083b929190614650565b6000818152600860205260409020612618838261449d565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea836040516115c6919061381a565b61265c83610e8e565b61269e576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161083b565b6126a9826000612994565b67ffffffffffffffff831660009081526007602052604090206126cc9083612d52565b6126d7816000612994565b67ffffffffffffffff831660009081526007602052604090206126fd9060020182612d52565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161273093929190614673565b60405180910390a1505050565b61275061033b60a083016080840161384f565b61276457611fda60a082016080830161384f565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6127b060408401602085016139fb565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015612821573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128459190614165565b1561287c576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61289461288f606083016040840161384f565b612ef4565b6128ac6128a760408301602084016139fb565b612f73565b611f5d6128bf60408301602084016139fb565b82606001356130c1565b6060600061239c83613105565b600061239c8383613160565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261297082606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426129549190614725565b85608001516fffffffffffffffffffffffffffffffff16613253565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b815115612a5f5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806129ea575060408201516fffffffffffffffffffffffffffffffff16155b15612a2357816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161083b9190614738565b8015612a5b576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff16151580612a98575060208201516fffffffffffffffffffffffffffffffff1615155b15612a5b57816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161083b9190614738565b600061239c838361327b565b3373ffffffffffffffffffffffffffffffffffffffff821603612b2c576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b612baa81610e8e565b612bec576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161083b565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612c6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c8f9190614165565b611f5d576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161083b565b67ffffffffffffffff82166000908152600760205260409020612a5b90600201827f00000000000000000000000000000000000000000000000000000000000000006132ca565b600061239c8373ffffffffffffffffffffffffffffffffffffffff8416613160565b600061239c8373ffffffffffffffffffffffffffffffffffffffff841661327b565b8154600090612d7b90700100000000000000000000000000000000900463ffffffff1642614725565b90508015612e1d5760018301548354612dc3916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416613253565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612e43916fffffffffffffffffffffffffffffffff908116911661364d565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612730908490614738565b7f000000000000000000000000000000000000000000000000000000000000000015611f5d57612f25600282613663565b611f5d576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161083b565b612f7c81610e8e565b612fbe576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161083b565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015613037573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061305b9190614774565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f5d576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161083b565b67ffffffffffffffff82166000908152600760205260409020612a5b90827f00000000000000000000000000000000000000000000000000000000000000006132ca565b60608160000180548060200260200160405190810160405280929190818152602001828054801561174c57602002820191906000526020600020905b8154815260200190600101908083116131415750505050509050919050565b60008181526001830160205260408120548015613249576000613184600183614725565b855490915060009061319890600190614725565b90508082146131fd5760008660000182815481106131b8576131b8613e39565b90600052602060002001549050808760000184815481106131db576131db613e39565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061320e5761320e614791565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506109f7565b60009150506109f7565b60006132728561326384866147c0565b61326d90876147d7565b61364d565b95945050505050565b60008181526001830160205260408120546132c2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556109f7565b5060006109f7565b825474010000000000000000000000000000000000000000900460ff1615806132f1575081155b156132fb57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061334190700100000000000000000000000000000000900463ffffffff1642614725565b905080156134015781831115613383576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546133bd9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16613253565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156134b85773ffffffffffffffffffffffffffffffffffffffff8416613460576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161083b565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161083b565b848310156135cb5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906134fc9082614725565b613506878a614725565b61351091906147d7565b61351a91906147ea565b905073ffffffffffffffffffffffffffffffffffffffff8616613573576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161083b565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161083b565b6135d58584614725565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b600081831061365c578161239c565b5090919050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561239c565b50805461369e90614241565b6000825580601f106136ae575050565b601f016020900490600052602060002090810190611f5d91906136e6565b5080546000825590600052602060002090810190611f5d91905b5b808211156136fb57600081556001016136e7565b5090565b6000806020838503121561371257600080fd5b823567ffffffffffffffff8082111561372a57600080fd5b818501915085601f83011261373e57600080fd5b81358181111561374d57600080fd5b8660208260071b850101111561376257600080fd5b60209290920196919550909350505050565b60006020828403121561378657600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461239c57600080fd5b6000815180845260005b818110156137dc576020818501810151868301820152016137c0565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061239c60208301846137b6565b73ffffffffffffffffffffffffffffffffffffffff81168114611f5d57600080fd5b60006020828403121561386157600080fd5b813561239c8161382d565b60006020828403121561387e57600080fd5b813567ffffffffffffffff81111561389557600080fd5b8201610100818503121561239c57600080fd5b67ffffffffffffffff81168114611f5d57600080fd5b6000806000604084860312156138d357600080fd5b83356138de816138a8565b9250602084013567ffffffffffffffff808211156138fb57600080fd5b818601915086601f83011261390f57600080fd5b81358181111561391e57600080fd5b87602082850101111561393057600080fd5b6020830194508093505050509250925092565b60008083601f84011261395557600080fd5b50813567ffffffffffffffff81111561396d57600080fd5b6020830191508360208260051b850101111561398857600080fd5b9250929050565b600080600080604085870312156139a557600080fd5b843567ffffffffffffffff808211156139bd57600080fd5b6139c988838901613943565b909650945060208701359150808211156139e257600080fd5b506139ef87828801613943565b95989497509550505050565b600060208284031215613a0d57600080fd5b813561239c816138a8565b60008083601f840112613a2a57600080fd5b50813567ffffffffffffffff811115613a4257600080fd5b60208301915083602060608302850101111561398857600080fd5b60008060008060008060608789031215613a7657600080fd5b863567ffffffffffffffff80821115613a8e57600080fd5b613a9a8a838b01613943565b90985096506020890135915080821115613ab357600080fd5b613abf8a838b01613a18565b90965094506040890135915080821115613ad857600080fd5b50613ae589828a01613a18565b979a9699509497509295939492505050565b600060208284031215613b0957600080fd5b813567ffffffffffffffff811115613b2057600080fd5b820160a0818503121561239c57600080fd5b602081526000825160406020840152613b4e60608401826137b6565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301604085015261327282826137b6565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015613bfe577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452613bec8583516137b6565b94509285019290850190600101613bb2565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613c5957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613c27565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613c5957835167ffffffffffffffff1683529284019291840191600101613c81565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715613cf957613cf9613ca7565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613d4657613d46613ca7565b604052919050565b8015158114611f5d57600080fd5b80356fffffffffffffffffffffffffffffffff81168114613d7c57600080fd5b919050565b600060608284031215613d9357600080fd5b6040516060810181811067ffffffffffffffff82111715613db657613db6613ca7565b6040529050808235613dc781613d4e565b8152613dd560208401613d5c565b6020820152613de660408401613d5c565b60408201525092915050565b600080600060e08486031215613e0757600080fd5b8335613e12816138a8565b9250613e218560208601613d81565b9150613e308560808601613d81565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b803563ffffffff81168114613d7c57600080fd5b600060808284031215613e8e57600080fd5b6040516080810181811067ffffffffffffffff82111715613eb157613eb1613ca7565b60405282358152613ec460208401613e68565b60208201526040830135613ed7816138a8565b60408201526060830135613eea81613d4e565b60608201529392505050565b6020808252818101839052600090604080840186845b87811015613f70578135835263ffffffff613f28868401613e68565b168584015283820135613f3a816138a8565b67ffffffffffffffff1683850152606082810135613f5781613d4e565b1515908401526080928301929190910190600101613f0c565b5090979650505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613fb257600080fd5b83018035915067ffffffffffffffff821115613fcd57600080fd5b60200191503681900382131561398857600080fd5b600060408284031215613ff457600080fd5b613ffc613cd6565b8235614007816138a8565b815261401560208401613e68565b60208201529392505050565b600082601f83011261403257600080fd5b813567ffffffffffffffff81111561404c5761404c613ca7565b61407d60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613cff565b81815284602083860101111561409257600080fd5b816020850160208301376000918101602001919091529392505050565b6000602082840312156140c157600080fd5b813567ffffffffffffffff808211156140d957600080fd5b90830190604082860312156140ed57600080fd5b6140f5613cd6565b82358281111561410457600080fd5b61411087828601614021565b82525060208301358281111561412557600080fd5b61413187828601614021565b60208301525095945050505050565b60408152600061415360408301856137b6565b828103602084015261327281856137b6565b60006020828403121561417757600080fd5b815161239c81613d4e565b8183823760009101908152919050565b6000606082840312156141a457600080fd5b61239c8383613d81565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000610c246020830184866141ae565b60006020828403121561421d57600080fd5b5035919050565b60006020828403121561423657600080fd5b815161239c816138a8565b600181811c9082168061425557607f821691505b60208210810361428e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b67ffffffffffffffff841681526040602082015260006132726040830184866141ae565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee18336030181126142ec57600080fd5b9190910192915050565b600082601f83011261430757600080fd5b8135602067ffffffffffffffff8083111561432457614324613ca7565b8260051b614333838201613cff565b938452858101830193838101908886111561434d57600080fd5b84880192505b858310156143895782358481111561436b5760008081fd5b6143798a87838c0101614021565b8352509184019190840190614353565b98975050505050505050565b600061012082360312156143a857600080fd5b60405160a0810167ffffffffffffffff82821081831117156143cc576143cc613ca7565b81604052843591506143dd826138a8565b908252602084013590808211156143f357600080fd5b6143ff368387016142f6565b6020840152604085013591508082111561441857600080fd5b5061442536828601614021565b6040830152506144383660608501613d81565b606082015261444a3660c08501613d81565b608082015292915050565b601f821115610d3a576000816000526020600020601f850160051c8101602086101561447e5750805b601f850160051c820191505b818110156123805782815560010161448a565b815167ffffffffffffffff8111156144b7576144b7613ca7565b6144cb816144c58454614241565b84614455565b602080601f83116001811461451e57600084156144e85750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555612380565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561456b5788860151825594840194600190910190840161454c565b50858210156145a757878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526145db818401876137b6565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506146199050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613272565b67ffffffffffffffff83168152604060208201526000610c2460408301846137b6565b67ffffffffffffffff8416815260e081016146bf60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152610c24565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109f7576109f76146f6565b606081016109f782848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561478657600080fd5b815161239c8161382d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b80820281158282048414176109f7576109f76146f6565b808201808211156109f7576109f76146f6565b600082614820577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", } var USDCTokenPoolABI = USDCTokenPoolMetaData.ABI @@ -836,6 +836,18 @@ func (_USDCTokenPool *USDCTokenPoolTransactorSession) SetChainRateLimiterConfig( return _USDCTokenPool.Contract.SetChainRateLimiterConfig(&_USDCTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) } +func (_USDCTokenPool *USDCTokenPoolTransactor) SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "setChainRateLimiterConfigs", remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_USDCTokenPool *USDCTokenPoolSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _USDCTokenPool.Contract.SetChainRateLimiterConfigs(&_USDCTokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _USDCTokenPool.Contract.SetChainRateLimiterConfigs(&_USDCTokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + func (_USDCTokenPool *USDCTokenPoolTransactor) SetDomains(opts *bind.TransactOpts, domains []USDCTokenPoolDomainUpdate) (*types.Transaction, error) { return _USDCTokenPool.contract.Transact(opts, "setDomains", domains) } @@ -3424,6 +3436,8 @@ type USDCTokenPoolInterface interface { SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) + SetDomains(opts *bind.TransactOpts, domains []USDCTokenPoolDomainUpdate) (*types.Transaction, error) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, 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 dd2799ba810..3d084f43606 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 @@ -1,13 +1,13 @@ GETH_VERSION: 1.14.11 -burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin 642919607d5642aa98713b88f737c918487adba682535cf630b7c7d5fd80dc43 -burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 054d95f302a142f7b64eea27237e0889bee6c9eb8a487579c7279c09646dc42b -burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin c3f723e7f6394297c095a9d9696f1bceec4a2e85b5be2159f7a21d257eb6b480 +burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin 76c31f52fe1df85528c08b2e772e37dcf99ca1ec492d83a221abc1d5ec833694 +burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 1c78cd3118b3c9ca82f8cb77ffc1137619ea4e8e503c460f2dafb659d0dd766b +burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin eab9c19ef27b245e5ef0216ab1080c9dd89c96013b7dc978bf610288d5e82b00 ccip_encoding_utils: ../../../contracts/solc/v0.8.24/ICCIPEncodingUtils/ICCIPEncodingUtils.abi ../../../contracts/solc/v0.8.24/ICCIPEncodingUtils/ICCIPEncodingUtils.bin 9971fc93c34442a0989570d3dab90a125de31e6e60754ad972807ce6ad4dfba0 ccip_home: ../../../contracts/solc/v0.8.24/CCIPHome/CCIPHome.abi ../../../contracts/solc/v0.8.24/CCIPHome/CCIPHome.bin 02cb75b4274a5be7f4006cf2b72cc09e77eb6dba4c1a9c720af86668ff8ea1df ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin b368699ae7dbee7c21d049a641642837f18ce2cc8d4ece69509f205de673108e ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de fee_quoter: ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.abi ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.bin aee49c9246d5903e68b175516b3cdfdec5df23e25d53d604cd382b6bc0bf34f7 -lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin 1067f557abeb5570f1da7f050ea982ffad0f35dc064e668a8a0e6af128df490c +lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin 04b40584830294fb603cc2a250af7d831d05a04650a8c2fc9e3af5a78c471be6 maybe_revert_message_receiver: ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin d73956c26232ebcc4a5444429fa99cbefed960e323be9b5a24925885c2e477d5 message_hasher: ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.abi ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.bin ec2d3a92348d8e7b8f0d359b62a45157b9d2c750c01fbcf991826c4392f6e218 mock_usdc_token_messenger: ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.bin d976651d36b33ac2196b32b9d2f4fa6690c6a18d41b621365659fce1c1d1e737 @@ -26,7 +26,7 @@ rmn_proxy_contract: ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../ rmn_remote: ../../../contracts/solc/v0.8.24/RMNRemote/RMNRemote.abi ../../../contracts/solc/v0.8.24/RMNRemote/RMNRemote.bin 941118dfdc6bb042c339cfe8d8e0c7a0b486afb731a785d58a64994e7a13c459 router: ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin 2e4f0a7826c8abb49d882bb49fc5ff20a186dbd3137624b9097ffed903ae4888 token_admin_registry: ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin 397bc7be08c2848c0f4715f90b16206d6367f78ffb7cd48e2b1dfc0ccc5aea26 -token_pool: ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin da86a1407f31134e7246bde63c80ce8c78ce7d7b44e267f3c1f6030441ff4252 +token_pool: ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin 793d65f336929becdcf8bc3f2208a5b6de93774215fe2e863bef64df419cfdb0 usdc_reader_tester: ../../../contracts/solc/v0.8.24/USDCReaderTester/USDCReaderTester.abi ../../../contracts/solc/v0.8.24/USDCReaderTester/USDCReaderTester.bin 672a07c9218fd6ad7c04dde583088b0f5ffc8d55a46f4be1714008dd3409438b -usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin b688126b13353f7aab7481f3f6b8f79cd2cace96be71eace70237d402823493a +usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin a9fef4db2c901302c0293b139eb77017b18da8543b7623e17f2932efbb8e3011 weth9: ../../../contracts/solc/v0.8.24/WETH9/WETH9.abi ../../../contracts/solc/v0.8.24/WETH9/WETH9.bin 2970d79a0ca6dd6279cde130de45e56c8790ed695eae477fb5ba4c1bb75b720d diff --git a/integration-tests/ccip-tests/contracts/contract_models.go b/integration-tests/ccip-tests/contracts/contract_models.go index 376f70192d2..257670dbaa1 100644 --- a/integration-tests/ccip-tests/contracts/contract_models.go +++ b/integration-tests/ccip-tests/contracts/contract_models.go @@ -503,8 +503,13 @@ func (w TokenPoolWrapper) ApplyChainUpdates(opts *bind.TransactOpts, update []to } func (w TokenPoolWrapper) SetChainRateLimiterConfig(opts *bind.TransactOpts, selector uint64, out token_pool.RateLimiterConfig, in token_pool.RateLimiterConfig) (*types.Transaction, error) { + if w.Latest != nil && w.Latest.PoolInterface != nil { - return w.Latest.PoolInterface.SetChainRateLimiterConfig(opts, selector, out, in) + selectors := []uint64{selector} + out := []token_pool.RateLimiterConfig{out} + in := []token_pool.RateLimiterConfig{in} + + return w.Latest.PoolInterface.SetChainRateLimiterConfigs(opts, selectors, out, in) } if w.V1_4_0 != nil && w.V1_4_0.PoolInterface != nil { return w.V1_4_0.PoolInterface.SetChainRateLimiterConfig(opts, selector, From c1341a5081d098bce04a7564a6525a91f2beeecf Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Tue, 10 Dec 2024 12:55:28 +0100 Subject: [PATCH 20/29] Add getChainConfig (#15570) * add getChainConfig * [Bot] Update changeset file with jira issues --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- contracts/.changeset/young-bats-rhyme.md | 10 +++++ contracts/gas-snapshots/ccip.gas-snapshot | 42 +++++++++---------- .../src/v0.8/ccip/capability/CCIPHome.sol | 9 ++++ .../CCIPHome.applyChainConfigUpdates.t.sol | 6 +++ .../ccip/generated/ccip_home/ccip_home.go | 28 ++++++++++++- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 6 files changed, 73 insertions(+), 24 deletions(-) create mode 100644 contracts/.changeset/young-bats-rhyme.md diff --git a/contracts/.changeset/young-bats-rhyme.md b/contracts/.changeset/young-bats-rhyme.md new file mode 100644 index 00000000000..e68a646b78e --- /dev/null +++ b/contracts/.changeset/young-bats-rhyme.md @@ -0,0 +1,10 @@ +--- +'@chainlink/contracts': patch +--- + +add getChainConfig to ccipHome + + +PR issue: CCIP-4517 + +Solidity Review issue: CCIP-3966 \ No newline at end of file diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 4ed7d38afd6..fd008698d52 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -38,30 +38,30 @@ CCIPHome__validateConfig:test__validateConfig_Success() (gas: 299797) CCIPHome__validateConfig:test__validateConfig_TooManySigners_Reverts() (gas: 773105) CCIPHome__validateConfig:test__validateConfig_ZeroP2PId_Reverts() (gas: 293455) CCIPHome__validateConfig:test__validateConfig_ZeroSignerKey_Reverts() (gas: 293503) -CCIPHome_applyChainConfigUpdates:test__applyChainConfigUpdates_FChainNotPositive_Reverts() (gas: 187738) -CCIPHome_applyChainConfigUpdates:test_applyChainConfigUpdates_addChainConfigs_Success() (gas: 349623) -CCIPHome_applyChainConfigUpdates:test_applyChainConfigUpdates_nodeNotInRegistry_Reverts() (gas: 18065) -CCIPHome_applyChainConfigUpdates:test_applyChainConfigUpdates_removeChainConfigs_Success() (gas: 272742) -CCIPHome_applyChainConfigUpdates:test_applyChainConfigUpdates_selectorNotFound_Reverts() (gas: 14952) -CCIPHome_applyChainConfigUpdates:test_getPaginatedCCIPHomes_Success() (gas: 372561) +CCIPHome_applyChainConfigUpdates:test__applyChainConfigUpdates_FChainNotPositive_Reverts() (gas: 187822) +CCIPHome_applyChainConfigUpdates:test_applyChainConfigUpdates_addChainConfigs_Success() (gas: 350051) +CCIPHome_applyChainConfigUpdates:test_applyChainConfigUpdates_nodeNotInRegistry_Reverts() (gas: 18089) +CCIPHome_applyChainConfigUpdates:test_applyChainConfigUpdates_removeChainConfigs_Success() (gas: 282212) +CCIPHome_applyChainConfigUpdates:test_applyChainConfigUpdates_selectorNotFound_Reverts() (gas: 14976) +CCIPHome_applyChainConfigUpdates:test_getPaginatedCCIPHomes_Success() (gas: 373475) CCIPHome_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_DONIdMismatch_reverts() (gas: 38098) -CCIPHome_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_InnerCallReverts_reverts() (gas: 11827) +CCIPHome_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_InnerCallReverts_reverts() (gas: 11783) CCIPHome_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_InvalidSelector_reverts() (gas: 11015) CCIPHome_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_OnlyCapabilitiesRegistryCanCall_reverts() (gas: 37072) -CCIPHome_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_success() (gas: 1455716) -CCIPHome_constructor:test_constructor_CapabilitiesRegistryAddressZero_reverts() (gas: 63767) -CCIPHome_constructor:test_constructor_success() (gas: 3455841) -CCIPHome_getAllConfigs:test_getAllConfigs_success() (gas: 2773000) -CCIPHome_getCapabilityConfiguration:test_getCapabilityConfiguration_success() (gas: 9138) -CCIPHome_getConfigDigests:test_getConfigDigests_success() (gas: 2547397) -CCIPHome_promoteCandidateAndRevokeActive:test_promoteCandidateAndRevokeActive_CanOnlySelfCall_reverts() (gas: 9087) -CCIPHome_promoteCandidateAndRevokeActive:test_promoteCandidateAndRevokeActive_ConfigDigestMismatch_reverts() (gas: 23005) -CCIPHome_promoteCandidateAndRevokeActive:test_promoteCandidateAndRevokeActive_NoOpStateTransitionNotAllowed_reverts() (gas: 8817) -CCIPHome_promoteCandidateAndRevokeActive:test_promoteCandidateAndRevokeActive_multiplePlugins_success() (gas: 5113570) -CCIPHome_revokeCandidate:test_revokeCandidate_CanOnlySelfCall_reverts() (gas: 9068) -CCIPHome_revokeCandidate:test_revokeCandidate_ConfigDigestMismatch_reverts() (gas: 19105) -CCIPHome_revokeCandidate:test_revokeCandidate_RevokingZeroDigestNotAllowed_reverts() (gas: 8817) -CCIPHome_revokeCandidate:test_revokeCandidate_success() (gas: 30674) +CCIPHome_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_success() (gas: 1455674) +CCIPHome_constructor:test_constructor_CapabilitiesRegistryAddressZero_reverts() (gas: 63865) +CCIPHome_constructor:test_constructor_success() (gas: 3531036) +CCIPHome_getAllConfigs:test_getAllConfigs_success() (gas: 2773023) +CCIPHome_getCapabilityConfiguration:test_getCapabilityConfiguration_success() (gas: 9116) +CCIPHome_getConfigDigests:test_getConfigDigests_success() (gas: 2547513) +CCIPHome_promoteCandidateAndRevokeActive:test_promoteCandidateAndRevokeActive_CanOnlySelfCall_reverts() (gas: 9110) +CCIPHome_promoteCandidateAndRevokeActive:test_promoteCandidateAndRevokeActive_ConfigDigestMismatch_reverts() (gas: 23074) +CCIPHome_promoteCandidateAndRevokeActive:test_promoteCandidateAndRevokeActive_NoOpStateTransitionNotAllowed_reverts() (gas: 8840) +CCIPHome_promoteCandidateAndRevokeActive:test_promoteCandidateAndRevokeActive_multiplePlugins_success() (gas: 5113754) +CCIPHome_revokeCandidate:test_revokeCandidate_CanOnlySelfCall_reverts() (gas: 9024) +CCIPHome_revokeCandidate:test_revokeCandidate_ConfigDigestMismatch_reverts() (gas: 19084) +CCIPHome_revokeCandidate:test_revokeCandidate_RevokingZeroDigestNotAllowed_reverts() (gas: 8773) +CCIPHome_revokeCandidate:test_revokeCandidate_success() (gas: 30676) CCIPHome_setCandidate:test_setCandidate_CanOnlySelfCall_reverts() (gas: 29383) CCIPHome_setCandidate:test_setCandidate_ConfigDigestMismatch_reverts() (gas: 1395154) CCIPHome_setCandidate:test_setCandidate_success() (gas: 1365439) diff --git a/contracts/src/v0.8/ccip/capability/CCIPHome.sol b/contracts/src/v0.8/ccip/capability/CCIPHome.sol index e43e4b0d03f..00ffe20ded4 100644 --- a/contracts/src/v0.8/ccip/capability/CCIPHome.sol +++ b/contracts/src/v0.8/ccip/capability/CCIPHome.sol @@ -533,6 +533,15 @@ contract CCIPHome is Ownable2StepMsgSender, ITypeAndVersion, ICapabilityConfigur return s_remoteChainSelectors.length(); } + /// @notice Returns the chain configuration for a given chain selector. + /// @param chainSelector The chain selector. + /// @return chainConfig The chain configuration. + function getChainConfig( + uint64 chainSelector + ) external view returns (ChainConfig memory) { + return s_chainConfigurations[chainSelector]; + } + /// @notice Returns all the chain configurations. /// @param pageIndex The page index. /// @param pageSize The page size. diff --git a/contracts/src/v0.8/ccip/test/capability/CCIPHome/CCIPHome.applyChainConfigUpdates.t.sol b/contracts/src/v0.8/ccip/test/capability/CCIPHome/CCIPHome.applyChainConfigUpdates.t.sol index 1d2c3a70895..9bf096b9551 100644 --- a/contracts/src/v0.8/ccip/test/capability/CCIPHome/CCIPHome.applyChainConfigUpdates.t.sol +++ b/contracts/src/v0.8/ccip/test/capability/CCIPHome/CCIPHome.applyChainConfigUpdates.t.sol @@ -109,6 +109,7 @@ contract CCIPHome_applyChainConfigUpdates is CCIPHomeTestSetup { function test_applyChainConfigUpdates_removeChainConfigs_Success() public { bytes32[] memory chainReaders = new bytes32[](1); chainReaders[0] = keccak256(abi.encode(1)); + CCIPHome.ChainConfigArgs[] memory adds = new CCIPHome.ChainConfigArgs[](2); adds[0] = CCIPHome.ChainConfigArgs({ chainSelector: 1, @@ -130,6 +131,7 @@ contract CCIPHome_applyChainConfigUpdates is CCIPHomeTestSetup { workflowDONId: uint32(1), capabilitiesDONIds: new uint256[](0) }); + vm.mockCall( CAPABILITIES_REGISTRY, abi.encodeWithSelector(INodeInfoProvider.getNodesByP2PIds.selector, chainReaders), @@ -140,10 +142,14 @@ contract CCIPHome_applyChainConfigUpdates is CCIPHomeTestSetup { emit CCIPHome.ChainConfigSet(1, adds[0].chainConfig); vm.expectEmit(); emit CCIPHome.ChainConfigSet(2, adds[1].chainConfig); + s_ccipHome.applyChainConfigUpdates(new uint64[](0), adds); assertEq(s_ccipHome.getNumChainConfigurations(), 2, "total chain configs must be 2"); + assertEq(s_ccipHome.getChainConfig(adds[0].chainSelector).config, adds[0].chainConfig.config); + assertEq(s_ccipHome.getChainConfig(adds[1].chainSelector).config, adds[1].chainConfig.config); + uint64[] memory removes = new uint64[](1); removes[0] = uint64(1); diff --git a/core/gethwrappers/ccip/generated/ccip_home/ccip_home.go b/core/gethwrappers/ccip/generated/ccip_home/ccip_home.go index b44dc9a5f96..7ea7f633147 100644 --- a/core/gethwrappers/ccip/generated/ccip_home/ccip_home.go +++ b/core/gethwrappers/ccip/generated/ccip_home/ccip_home.go @@ -65,8 +65,8 @@ type CCIPHomeVersionedConfig struct { } var CCIPHomeMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"capabilitiesRegistry\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainSelectorNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ChainSelectorNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expectedConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"gotConfigDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"callDonId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"capabilityRegistryDonId\",\"type\":\"uint32\"}],\"name\":\"DONIdMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FChainMustBePositive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fChain\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"FRoleDON\",\"type\":\"uint256\"}],\"name\":\"FChainTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node\",\"name\":\"node\",\"type\":\"tuple\"}],\"name\":\"InvalidNode\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPluginType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"}],\"name\":\"InvalidSelector\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoOpStateTransitionNotAllowed\",\"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\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCapabilitiesRegistryCanCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RMNHomeAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RevokingZeroDigestNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManySigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ActiveConfigRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"CandidateConfigRevoked\",\"type\":\"event\"},{\"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\":\"structCCIPHome.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigPromoted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"FRoleDON\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rmnHomeAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structCCIPHome.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"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\":\"structCCIPHome.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPHome.ChainConfigArgs[]\",\"name\":\"chainConfigAdds\",\"type\":\"tuple[]\"}],\"name\":\"applyChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"update\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"beforeCapabilityConfigSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getActiveDigest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"pageIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"pageSize\",\"type\":\"uint256\"}],\"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\":\"structCCIPHome.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPHome.ChainConfigArgs[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getAllConfigs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"FRoleDON\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rmnHomeAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPHome.VersionedConfig\",\"name\":\"activeConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"FRoleDON\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rmnHomeAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPHome.VersionedConfig\",\"name\":\"candidateConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getCandidateDigest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"getCapabilityConfiguration\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"configuration\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilityRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"FRoleDON\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rmnHomeAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPHome.VersionedConfig\",\"name\":\"versionedConfig\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"ok\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getConfigDigests\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"activeConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"candidateConfigDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNumChainConfigurations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"digestToPromote\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"digestToRevoke\",\"type\":\"bytes32\"}],\"name\":\"promoteCandidateAndRevokeActive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"revokeCandidate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"FRoleDON\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rmnHomeAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"digestToOverwrite\",\"type\":\"bytes32\"}],\"name\":\"setCandidate\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"newConfigDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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: "0x60a06040526006805463ffffffff191690553480156200001e57600080fd5b5060405162004c7a38038062004c7a83398101604081905262000041916200014c565b336000816200006357604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038481169190911790915581161562000096576200009681620000d2565b50506001600160a01b038116620000c0576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03166080526200017e565b336001600160a01b03821603620000fc57604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200015f57600080fd5b81516001600160a01b03811681146200017757600080fd5b9392505050565b608051614ad2620001a860003960008181610180015281816121eb0152612c450152614ad26000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c806379ba5097116100cd578063b74b235611610081578063f2fde38b11610066578063f2fde38b14610356578063f442c89a14610369578063fba64a7c1461037c57600080fd5b8063b74b235614610323578063bae4e0fa1461034357600080fd5b80638318ed5d116100b25780638318ed5d146102d15780638da5cb5b146102f2578063922ea4061461031057600080fd5b806379ba5097146102c15780637ac0d41e146102c957600080fd5b80633df45a72116101245780635a837f97116101095780635a837f97146102785780635f1edd9c1461028d5780637524051a146102ae57600080fd5b80633df45a721461022f5780634851d5491461025057600080fd5b806301ffc9a714610156578063020330e61461017e578063181f5a77146101c557806333d9704a1461020e575b600080fd5b610169610164366004612fb2565b61038f565b60405190151581526020015b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610175565b6102016040518060400160405280601281526020017f43434950486f6d6520312e362e302d646576000000000000000000000000000081525081565b6040516101759190613044565b61022161021c366004613091565b610428565b6040516101759291906132d8565b61024261023d3660046132fc565b610922565b604051610175929190613335565b61026361025e3660046132fc565b611222565b60408051928352602083019190915201610175565b61028b61028636600461335a565b611318565b005b6102a061029b3660046132fc565b61162b565b604051908152602001610175565b61028b6102bc366004613091565b6116a2565b61028b61188d565b6102a061195b565b6102016102df3660046133a0565b5060408051602081019091526000815290565b60015473ffffffffffffffffffffffffffffffffffffffff166101a0565b6102a061031e3660046132fc565b61196c565b6103366103313660046133bd565b6119bd565b6040516101759190613456565b6102a06103513660046134f4565b611c22565b61028b610364366004613564565b611e20565b61028b6103773660046135df565b611e34565b61028b61038a36600461366c565b6121d3565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f78bea72100000000000000000000000000000000000000000000000000000000148061042257507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b610430612e3b565b6000805b60028110156109145763ffffffff861660009081526005602052604081208591876001811115610466576104666130d2565b6001811115610477576104776130d2565b8152602001908152602001600020826002811061049657610496613729565b60070201600101541480156104aa57508315155b1561090c5763ffffffff86166000908152600560205260408120908660018111156104d7576104d76130d2565b60018111156104e8576104e86130d2565b8152602001908152602001600020816002811061050757610507613729565b6040805160608101825260079290920292909201805463ffffffff1682526001808201546020840152835161010081018552600283018054939592949386938501929190829060ff1687811115610560576105606130d2565b6001811115610571576105716130d2565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a01000000000000000000009091041660608201526001820180546080909201916105c990613758565b80601f01602080910402602001604051908101604052809291908181526020018280546105f590613758565b80156106425780601f1061061757610100808354040283529160200191610642565b820191906000526020600020905b81548152906001019060200180831161062557829003601f168201915b5050505050815260200160028201805461065b90613758565b80601f016020809104026020016040519081016040528092919081815260200182805461068790613758565b80156106d45780601f106106a9576101008083540402835291602001916106d4565b820191906000526020600020905b8154815290600101906020018083116106b757829003601f168201915b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b8282101561086257838290600052602060002090600302016040518060600160405290816000820154815260200160018201805461073f90613758565b80601f016020809104026020016040519081016040528092919081815260200182805461076b90613758565b80156107b85780601f1061078d576101008083540402835291602001916107b8565b820191906000526020600020905b81548152906001019060200180831161079b57829003601f168201915b505050505081526020016002820180546107d190613758565b80601f01602080910402602001604051908101604052809291908181526020018280546107fd90613758565b801561084a5780601f1061081f5761010080835404028352916020019161084a565b820191906000526020600020905b81548152906001019060200180831161082d57829003601f168201915b50505050508152505081526020019060010190610702565b50505050815260200160048201805461087a90613758565b80601f01602080910402602001604051908101604052809291908181526020018280546108a690613758565b80156108f35780601f106108c8576101008083540402835291602001916108f3565b820191906000526020600020905b8154815290600101906020018083116108d657829003601f168201915b505050505081525050815250509150925092505061091a565b600101610434565b50600090505b935093915050565b61092a612e3b565b610932612e3b565b63ffffffff841660009081526005602052604081208185600181111561095a5761095a6130d2565b600181111561096b5761096b6130d2565b81526020019081526020016000206109838686612490565b63ffffffff166002811061099957610999613729565b6040805160608101825260079290920292909201805463ffffffff1682526001808201546020840152835161010081018552600283018054949593949386019391929091839160ff909116908111156109f4576109f46130d2565b6001811115610a0557610a056130d2565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a0100000000000000000000909104166060820152600182018054608090920191610a5d90613758565b80601f0160208091040260200160405190810160405280929190818152602001828054610a8990613758565b8015610ad65780601f10610aab57610100808354040283529160200191610ad6565b820191906000526020600020905b815481529060010190602001808311610ab957829003601f168201915b50505050508152602001600282018054610aef90613758565b80601f0160208091040260200160405190810160405280929190818152602001828054610b1b90613758565b8015610b685780601f10610b3d57610100808354040283529160200191610b68565b820191906000526020600020905b815481529060010190602001808311610b4b57829003601f168201915b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b82821015610cf6578382906000526020600020906003020160405180606001604052908160008201548152602001600182018054610bd390613758565b80601f0160208091040260200160405190810160405280929190818152602001828054610bff90613758565b8015610c4c5780601f10610c2157610100808354040283529160200191610c4c565b820191906000526020600020905b815481529060010190602001808311610c2f57829003601f168201915b50505050508152602001600282018054610c6590613758565b80601f0160208091040260200160405190810160405280929190818152602001828054610c9190613758565b8015610cde5780601f10610cb357610100808354040283529160200191610cde565b820191906000526020600020905b815481529060010190602001808311610cc157829003601f168201915b50505050508152505081526020019060010190610b96565b505050508152602001600482018054610d0e90613758565b80601f0160208091040260200160405190810160405280929190818152602001828054610d3a90613758565b8015610d875780601f10610d5c57610100808354040283529160200191610d87565b820191906000526020600020905b815481529060010190602001808311610d6a57829003601f168201915b50505091909252505050905250602081015190915015610da5578092505b63ffffffff8516600090815260056020526040812081866001811115610dcd57610dcd6130d2565b6001811115610dde57610dde6130d2565b8152602001908152602001600020610df687876124e7565b63ffffffff1660028110610e0c57610e0c613729565b6040805160608101825260079290920292909201805463ffffffff1682526001808201546020840152835161010081018552600283018054949593949386019391929091839160ff90911690811115610e6757610e676130d2565b6001811115610e7857610e786130d2565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a0100000000000000000000909104166060820152600182018054608090920191610ed090613758565b80601f0160208091040260200160405190810160405280929190818152602001828054610efc90613758565b8015610f495780601f10610f1e57610100808354040283529160200191610f49565b820191906000526020600020905b815481529060010190602001808311610f2c57829003601f168201915b50505050508152602001600282018054610f6290613758565b80601f0160208091040260200160405190810160405280929190818152602001828054610f8e90613758565b8015610fdb5780601f10610fb057610100808354040283529160200191610fdb565b820191906000526020600020905b815481529060010190602001808311610fbe57829003601f168201915b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b8282101561116957838290600052602060002090600302016040518060600160405290816000820154815260200160018201805461104690613758565b80601f016020809104026020016040519081016040528092919081815260200182805461107290613758565b80156110bf5780601f10611094576101008083540402835291602001916110bf565b820191906000526020600020905b8154815290600101906020018083116110a257829003601f168201915b505050505081526020016002820180546110d890613758565b80601f016020809104026020016040519081016040528092919081815260200182805461110490613758565b80156111515780601f1061112657610100808354040283529160200191611151565b820191906000526020600020905b81548152906001019060200180831161113457829003601f168201915b50505050508152505081526020019060010190611009565b50505050815260200160048201805461118190613758565b80601f01602080910402602001604051908101604052809291908181526020018280546111ad90613758565b80156111fa5780601f106111cf576101008083540402835291602001916111fa565b820191906000526020600020905b8154815290600101906020018083116111dd57829003601f168201915b50505091909252505050905250602081015190915015611218578092505b50505b9250929050565b63ffffffff8216600090815260056020526040812081908184600181111561124c5761124c6130d2565b600181111561125d5761125d6130d2565b81526020019081526020016000206112758585612490565b63ffffffff166002811061128b5761128b613729565b6007020160010154600560008663ffffffff1663ffffffff16815260200190815260200160002060008560018111156112c6576112c66130d2565b60018111156112d7576112d76130d2565b81526020019081526020016000206112ef86866124e7565b63ffffffff166002811061130557611305613729565b6007020160010154915091509250929050565b611320612542565b8115801561132c575080155b15611363576040517f7b4d1e4f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061136f85856124e7565b63ffffffff86811660009081526005602052604081209290911692508491908660018111156113a0576113a06130d2565b60018111156113b1576113b16130d2565b815260200190815260200160002082600281106113d0576113d0613729565b6007020160010154146114845763ffffffff8516600090815260056020526040812090856001811115611405576114056130d2565b6001811115611416576114166130d2565b8152602001908152602001600020816002811061143557611435613729565b6007020160010154836040517f93df584c00000000000000000000000000000000000000000000000000000000815260040161147b929190918252602082015260400190565b60405180910390fd5b63ffffffff85166000908152600560205260408120818660018111156114ac576114ac6130d2565b60018111156114bd576114bd6130d2565b81526020019081526020016000206114d58787612490565b63ffffffff16600281106114eb576114eb613729565b6007020190508281600101541461153e5760018101546040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101919091526024810184905260440161147b565b6000600180830182905563ffffffff881682526007602052604082209091878381111561156d5761156d6130d2565b600181111561157e5761157e6130d2565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000811663ffffffff918216939093181691909117905582156115f85760405183907f0b31c0055e2d464bef7781994b98c4ff9ef4ae0d05f59feb6a68c42de5e201b890600090a25b60405184907ffc3e98dbbd47c3fa7c1c05b6ec711caeaf70eca4554192b9ada8fc11a37f298e90600090a2505050505050565b63ffffffff8216600090815260056020526040812081836001811115611653576116536130d2565b6001811115611664576116646130d2565b815260200190815260200160002061167c8484612490565b63ffffffff166002811061169257611692613729565b6007020160010154905092915050565b6116aa612542565b806116e1576040517f0849d8cc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006116ed84846124e7565b63ffffffff858116600090815260056020526040812092909116925083919085600181111561171e5761171e6130d2565b600181111561172f5761172f6130d2565b8152602001908152602001600020826002811061174e5761174e613729565b6007020160010154146117f95763ffffffff8416600090815260056020526040812090846001811115611783576117836130d2565b6001811115611794576117946130d2565b815260200190815260200160002081600281106117b3576117b3613729565b6007020160010154826040517f93df584c00000000000000000000000000000000000000000000000000000000815260040161147b929190918252602082015260400190565b60405182907f53f5d9228f0a4173bea6e5931c9b3afe6eeb6692ede1d182952970f152534e3b90600090a263ffffffff841660009081526005602052604081209084600181111561184c5761184c6130d2565b600181111561185d5761185d6130d2565b8152602001908152602001600020816002811061187c5761187c613729565b600702016001016000905550505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146118de576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6000611967600361257d565b905090565b63ffffffff8216600090815260056020526040812081836001811115611994576119946130d2565b60018111156119a5576119a56130d2565b815260200190815260200160002061167c84846124e7565b606060006119cb600361257d565b905060006119d984866137da565b90508315806119e85750818110155b15611a28576040805160008082526020820190925290611a1e565b611a0b612eb7565b815260200190600190039081611a035790505b5092505050610422565b6000611a348583613820565b905082811115611a415750815b6000611a4d8383613833565b67ffffffffffffffff811115611a6557611a656137f1565b604051908082528060200260200182016040528015611a9e57816020015b611a8b612eb7565b815260200190600190039081611a835790505b509050825b82811015611c17576000611ab8600383612587565b60408051808201825267ffffffffffffffff83168082526000908152600260209081529083902083518154608081850283018101909652606082018181529697509395928601949093919284929091849190840182828015611b3957602002820191906000526020600020905b815481526020019060010190808311611b25575b5050509183525050600182015460ff166020820152600282018054604090920191611b6390613758565b80601f0160208091040260200160405190810160405280929190818152602001828054611b8f90613758565b8015611bdc5780601f10611bb157610100808354040283529160200191611bdc565b820191906000526020600020905b815481529060010190602001808311611bbf57829003601f168201915b50505091909252505050905283611bf38785613833565b81518110611c0357611c03613729565b602090810291909101015250600101611aa3565b509695505050505050565b6000611c2c612542565b611c3d611c3884613a61565b61259a565b6000611c49868661196c565b9050828114611c8e576040517f93df584c000000000000000000000000000000000000000000000000000000008152600481018290526024810184905260440161147b565b8015611cc05760405183907f53f5d9228f0a4173bea6e5931c9b3afe6eeb6692ede1d182952970f152534e3b90600090a25b60068054600091908290611cd99063ffffffff16613b5d565b91906101000a81548163ffffffff021916908363ffffffff16021790559050611d23878787604051602001611d0e9190613e39565b60405160208183030381529060405284612a08565b63ffffffff881660009081526005602052604081209194509081886001811115611d4f57611d4f6130d2565b6001811115611d6057611d606130d2565b8152602001908152602001600020611d7889896124e7565b63ffffffff1660028110611d8e57611d8e613729565b600702016001810185905580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff841617815590508560028201611dd8828261431f565b905050837f94f085b7c57ec2a270befd0b7b2ec7452580040edee8bb0fb04609c81f0359c68388604051611e0d9291906144e6565b60405180910390a2505050949350505050565b611e28612ac8565b611e3181612b19565b50565b611e3c612ac8565b60005b8381101561202257611e83858583818110611e5c57611e5c613729565b9050602002016020810190611e71919061450d565b60039067ffffffffffffffff16612bdd565b611eed57848482818110611e9957611e99613729565b9050602002016020810190611eae919061450d565b6040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161147b565b60026000868684818110611f0357611f03613729565b9050602002016020810190611f18919061450d565b67ffffffffffffffff1681526020810191909152604001600090812090611f3f8282612efa565b6001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055611f77600283016000612f18565b5050611fb5858583818110611f8e57611f8e613729565b9050602002016020810190611fa3919061450d565b60039067ffffffffffffffff16612bf5565b507f2a680691fef3b2d105196805935232c661ce703e92d464ef0b94a7bc62d714f0858583818110611fe957611fe9613729565b9050602002016020810190611ffe919061450d565b60405167ffffffffffffffff909116815260200160405180910390a1600101611e3f565b5060005b818110156121cc57600083838381811061204257612042613729565b9050602002810190612054919061452a565b612062906020810190614082565b61206b9061455e565b9050600084848481811061208157612081613729565b9050602002810190612093919061452a565b6120a190602081019061450d565b90506120b08260000151612c01565b816020015160ff166000036120f1576040517fa9b3766e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600260209081526040909120835180518593612121928492910190612f52565b5060208201516001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff9092169190911790556040820151600282019061216e9082614630565b5061218891506003905067ffffffffffffffff8316612cc3565b507f05dd57854af2c291a94ea52e7c43d80bc3be7fa73022f98b735dea86642fa5e081836040516121ba92919061472c565b60405180910390a15050600101612026565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614612242576040517fac7a7efd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612251600482868861474f565b61225a91614779565b90507fffffffff0000000000000000000000000000000000000000000000000000000081167fbae4e0fa00000000000000000000000000000000000000000000000000000000148015906122f057507fffffffff0000000000000000000000000000000000000000000000000000000081167f7524051a0000000000000000000000000000000000000000000000000000000014155b801561233e57507fffffffff0000000000000000000000000000000000000000000000000000000081167f5a837f970000000000000000000000000000000000000000000000000000000014155b15612399576040517f12ba286f0000000000000000000000000000000000000000000000000000000081527fffffffff000000000000000000000000000000000000000000000000000000008216600482015260240161147b565b60006123a960246004878961474f565b8101906123b691906147c1565b90508263ffffffff168114612407576040517f8a6e4ce800000000000000000000000000000000000000000000000000000000815263ffffffff80831660048301528416602482015260440161147b565b6000803073ffffffffffffffffffffffffffffffffffffffff1688886040516124319291906147da565b6000604051808303816000865af19150503d806000811461246e576040519150601f19603f3d011682016040523d82523d6000602084013e612473565b606091505b509150915081612484573d60208201fd5b50505050505050505050565b63ffffffff82166000908152600760205260408120818360018111156124b8576124b86130d2565b60018111156124c9576124c96130d2565b815260208101919091526040016000205463ffffffff169392505050565b63ffffffff821660009081526007602052604081208183600181111561250f5761250f6130d2565b6001811115612520576125206130d2565b815260208101919091526040016000205463ffffffff16600118905092915050565b33301461257b576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6000610422825490565b60006125938383612ccf565b9392505050565b806020015167ffffffffffffffff166000036125e2576040517f698cf8e000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815160018111156125f7576125f76130d2565b141580156126185750600181516001811115612615576126156130d2565b14155b1561264f576040517f3302dbd700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608081015151158061268c575060408051600060208201520160405160208183030381529060405280519060200120816080015180519060200120145b156126c3576040517f358c192700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a08101515115806127005750604080516000602082015201604051602081830303815290604052805190602001208160a0015180519060200120145b15612737576040517fdee9857400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101516127529060039067ffffffffffffffff16612bdd565b61279a5760208101516040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161147b565b60408082015160208084015167ffffffffffffffff1660009081526002909152919091206001015460ff91821691168181111561280d576040517f2db22040000000000000000000000000000000000000000000000000000000008152600481018290526024810183905260440161147b565b60c08301515161010081111561284f576040517f1b925da600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61285a8360036137da565b8111612892576040517f4856694e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808267ffffffffffffffff8111156128ae576128ae6137f1565b6040519080825280602002602001820160405280156128d7578160200160208202803683370190505b50905060005b838110156129975760008760c0015182815181106128fd576128fd613729565b60200260200101519050806040015151600014612922578361291e816147ea565b9450505b602081015151158061293357508051155b1561296c57806040517f9fa4031400000000000000000000000000000000000000000000000000000000815260040161147b9190614822565b806000015183838151811061298357612983613729565b6020908102919091010152506001016128dd565b5060006129a58560036137da565b6129b0906001613820565b9050808310156129f6576040517f548dd21f000000000000000000000000000000000000000000000000000000008152600481018490526024810182905260440161147b565b6129ff82612c01565b50505050505050565b6040516000907dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90612a66907f45564d000000000000000000000000000000000000000000000000000000000090469030908a908a908990602001614835565b60408051601f1981840301815290829052612a8591869060200161488e565b60408051808303601f190181529190528051602090910120167e0a0000000000000000000000000000000000000000000000000000000000001795945050505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461257b576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603612b68576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120541515612593565b60006125938383612cf9565b805115611e31576040517f05a5196600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906305a5196690612c7a9084906004016148bd565b600060405180830381865afa158015612c97573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612cbf919081019061493a565b5050565b60006125938383612dec565b6000826000018281548110612ce657612ce6613729565b9060005260206000200154905092915050565b60008181526001830160205260408120548015612de2576000612d1d600183613833565b8554909150600090612d3190600190613833565b9050808214612d96576000866000018281548110612d5157612d51613729565b9060005260206000200154905080876000018481548110612d7457612d74613729565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612da757612da7614a96565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610422565b6000915050610422565b6000818152600183016020526040812054612e3357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610422565b506000610422565b6040805160608101825260008082526020820152908101612eb26040805161010081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff168152602001606081526020016060815260200160608152602001606081525090565b905290565b6040518060400160405280600067ffffffffffffffff168152602001612eb2604051806060016040528060608152602001600060ff168152602001606081525090565b5080546000825590600052602060002090810190611e319190612f9d565b508054612f2490613758565b6000825580601f10612f34575050565b601f016020900490600052602060002090810190611e319190612f9d565b828054828255906000526020600020908101928215612f8d579160200282015b82811115612f8d578251825591602001919060010190612f72565b50612f99929150612f9d565b5090565b5b80821115612f995760008155600101612f9e565b600060208284031215612fc457600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461259357600080fd5b60005b8381101561300f578181015183820152602001612ff7565b50506000910152565b60008151808452613030816020860160208601612ff4565b601f01601f19169290920160200192915050565b6020815260006125936020830184613018565b63ffffffff81168114611e3157600080fd5b803561307481613057565b919050565b60028110611e3157600080fd5b803561307481613079565b6000806000606084860312156130a657600080fd5b83356130b181613057565b925060208401356130c181613079565b929592945050506040919091013590565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60028110613138577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b80518252600060208201516060602085015261315b6060850182613018565b9050604083015184820360408601526131748282613018565b95945050505050565b60008282518085526020808601955060208260051b8401016020860160005b848110156131ca57601f198684030189526131b883835161313c565b9884019892509083019060010161319c565b5090979650505050505050565b63ffffffff8151168252602081015160208301526000604082015160606040850152613207606085018251613101565b602081015167ffffffffffffffff8116608086015250604081015160ff811660a086015250606081015167ffffffffffffffff811660c08601525060808101516101008060e087015261325e610160870183613018565b915060a08301517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08088850301838901526132998483613018565b935060c0850151925080888503016101208901526132b7848461317d565b935060e0850151945080888503016101408901525050506131748183613018565b6040815260006132eb60408301856131d7565b905082151560208301529392505050565b6000806040838503121561330f57600080fd5b823561331a81613057565b9150602083013561332a81613079565b809150509250929050565b60408152600061334860408301856131d7565b828103602084015261317481856131d7565b6000806000806080858703121561337057600080fd5b843561337b81613057565b9350602085013561338b81613079565b93969395505050506040820135916060013590565b6000602082840312156133b257600080fd5b813561259381613057565b600080604083850312156133d057600080fd5b50508035926020909101359150565b60008151808452602080850194506020840160005b83811015613410578151875295820195908201906001016133f4565b509495945050505050565b600081516060845261343060608501826133df565b905060ff6020840151166020850152604083015184820360408601526131748282613018565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b838110156134e6578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805167ffffffffffffffff1684528701518784018790526134d38785018261341b565b958801959350509086019060010161347f565b509098975050505050505050565b6000806000806080858703121561350a57600080fd5b843561351581613057565b9350602085013561352581613079565b9250604085013567ffffffffffffffff81111561354157600080fd5b8501610100818803121561355457600080fd5b9396929550929360600135925050565b60006020828403121561357657600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461259357600080fd5b60008083601f8401126135ac57600080fd5b50813567ffffffffffffffff8111156135c457600080fd5b6020830191508360208260051b850101111561121b57600080fd5b600080600080604085870312156135f557600080fd5b843567ffffffffffffffff8082111561360d57600080fd5b6136198883890161359a565b9096509450602087013591508082111561363257600080fd5b5061363f8782880161359a565b95989497509550505050565b67ffffffffffffffff81168114611e3157600080fd5b80356130748161364b565b6000806000806000806080878903121561368557600080fd5b863567ffffffffffffffff8082111561369d57600080fd5b6136a98a838b0161359a565b909850965060208901359150808211156136c257600080fd5b818901915089601f8301126136d657600080fd5b8135818111156136e557600080fd5b8a60208285010111156136f757600080fd5b60208301965080955050505061370f60408801613661565b915061371d60608801613069565b90509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c9082168061376c57607f821691505b6020821081036137a5577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610422576104226137ab565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b80820180821115610422576104226137ab565b81810381811115610422576104226137ab565b6040516060810167ffffffffffffffff81118282101715613869576138696137f1565b60405290565b604051610100810167ffffffffffffffff81118282101715613869576138696137f1565b604051601f8201601f1916810167ffffffffffffffff811182821017156138bc576138bc6137f1565b604052919050565b60ff81168114611e3157600080fd5b8035613074816138c4565b600082601f8301126138ef57600080fd5b813567ffffffffffffffff811115613909576139096137f1565b61391c6020601f19601f84011601613893565b81815284602083860101111561393157600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff821115613968576139686137f1565b5060051b60200190565b600082601f83011261398357600080fd5b813560206139986139938361394e565b613893565b82815260059290921b840181019181810190868411156139b757600080fd5b8286015b84811015611c1757803567ffffffffffffffff808211156139dc5760008081fd5b8189019150606080601f19848d030112156139f75760008081fd5b6139ff613846565b87840135815260408085013584811115613a195760008081fd5b613a278e8b838901016138de565b838b015250918401359183831115613a3f5760008081fd5b613a4d8d8a858801016138de565b9082015286525050509183019183016139bb565b60006101008236031215613a7457600080fd5b613a7c61386f565b613a8583613086565b8152613a9360208401613661565b6020820152613aa4604084016138d3565b6040820152613ab560608401613661565b6060820152608083013567ffffffffffffffff80821115613ad557600080fd5b613ae1368387016138de565b608084015260a0850135915080821115613afa57600080fd5b613b06368387016138de565b60a084015260c0850135915080821115613b1f57600080fd5b613b2b36838701613972565b60c084015260e0850135915080821115613b4457600080fd5b50613b51368286016138de565b60e08301525092915050565b600063ffffffff808316818103613b7657613b766137ab565b6001019392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613bb557600080fd5b830160208101925035905067ffffffffffffffff811115613bd557600080fd5b80360382131561121b57600080fd5b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613c4457600080fd5b830160208101925035905067ffffffffffffffff811115613c6457600080fd5b8060051b360382131561121b57600080fd5b60008383855260208086019550808560051b830101846000805b88811015613d3457601f19868503018a5282357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1893603018112613cd2578283fd5b8801803585526060613ce687830183613b80565b8289890152613cf88389018284613be4565b925050506040613d0a81840184613b80565b935087830382890152613d1e838583613be4565b9d89019d97505050938601935050600101613c90565b509198975050505050505050565b6000610100613d5984613d5485613086565b613101565b613d6560208401613661565b67ffffffffffffffff166020850152613d80604084016138d3565b60ff166040850152613d9460608401613661565b67ffffffffffffffff166060850152613db06080840184613b80565b826080870152613dc38387018284613be4565b92505050613dd460a0840184613b80565b85830360a0870152613de7838284613be4565b92505050613df860c0840184613c0f565b85830360c0870152613e0b838284613c76565b92505050613e1c60e0840184613b80565b85830360e0870152613e2f838284613be4565b9695505050505050565b6020815260006125936020830184613d42565b600081356104228161364b565b60008135610422816138c4565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613e9b57600080fd5b83018035915067ffffffffffffffff821115613eb657600080fd5b60200191503681900382131561121b57600080fd5b5b81811015612cbf5760008155600101613ecc565b601f821115613f1957806000526020600020601f840160051c81016020851015613f075750805b6121cc601f850160051c830182613ecb565b505050565b67ffffffffffffffff831115613f3657613f366137f1565b613f4a83613f448354613758565b83613ee0565b6000601f841160018114613f9c5760008515613f665750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556121cc565b600083815260209020601f19861690835b82811015613fcd5786850135825560209485019460019092019101613fad565b5086821015614008577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261404f57600080fd5b83018035915067ffffffffffffffff82111561406a57600080fd5b6020019150600581901b360382131561121b57600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18336030181126140b657600080fd5b9190910192915050565b6140ca8154613758565b8015612cbf57601f8111600181146140e457505060009055565b826000526020600020614102601f840160051c820160018301613ecb565b60008085559055505050565b81358155600180820160206141266020860186613e66565b67ffffffffffffffff81111561413e5761413e6137f1565b6141528161414c8654613758565b86613ee0565b6000601f8211600181146141a4576000831561416e5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600385901b1c1916600184901b178655614219565b600086815260209020601f19841690835b828110156141d257868501358255938701939089019087016141b5565b508482101561420d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88660031b161c19848701351681555b505060018360011b0186555b5050505050505061422d6040830183613e66565b61423b818360028601613f1e565b50505050565b6801000000000000000083111561425a5761425a6137f1565b8054838255808410156142d95760038160030260038104831461427f5761427f6137ab565b85600302600381048714614295576142956137ab565b6000858152602081209283019291909101905b828210156142d4578082556142bf600183016140c0565b6142cb600283016140c0565b908301906142a8565b505050505b5060008181526020812083915b85811015614317576143016142fb8487614082565b8361410e565b60209290920191600391909101906001016142e6565b505050505050565b813561432a81613079565b60028110614361577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082541660ff82168117835550506143d861439e60208401613e4c565b82547fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff1660089190911b68ffffffffffffffff0016178255565b6144226143e760408401613e59565b82547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff1660489190911b69ff00000000000000000016178255565b61447461443160608401613e4c565b82547fffffffffffffffffffffffffffff0000000000000000ffffffffffffffffffff1660509190911b71ffffffffffffffff0000000000000000000016178255565b6144816080830183613e66565b61448f818360018601613f1e565b505061449e60a0830183613e66565b6144ac818360028601613f1e565b50506144bb60c083018361401a565b6144c9818360038601614241565b50506144d860e0830183613e66565b61423b818360048601613f1e565b63ffffffff831681526040602082015260006145056040830184613d42565b949350505050565b60006020828403121561451f57600080fd5b81356125938161364b565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126140b657600080fd5b60006060823603121561457057600080fd5b614578613846565b823567ffffffffffffffff8082111561459057600080fd5b9084019036601f8301126145a357600080fd5b813560206145b36139938361394e565b82815260059290921b840181019181810190368411156145d257600080fd5b948201945b838610156145f0578535825294820194908201906145d7565b8652506145fe8782016138d3565b9085015250604085013591508082111561461757600080fd5b50614624368286016138de565b60408301525092915050565b815167ffffffffffffffff81111561464a5761464a6137f1565b61465e816146588454613758565b84613ee0565b602080601f8311600181146146b1576000841561467b5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555614317565b600085815260208120601f198616915b828110156146e0578886015182559484019460019091019084016146c1565b508582101561471c57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b67ffffffffffffffff83168152604060208201526000614505604083018461341b565b6000808585111561475f57600080fd5b8386111561476c57600080fd5b5050820193919092039150565b7fffffffff0000000000000000000000000000000000000000000000000000000081358181169160048510156147b95780818660040360031b1b83161692505b505092915050565b6000602082840312156147d357600080fd5b5035919050565b8183823760009101908152919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361481b5761481b6137ab565b5060010190565b602081526000612593602083018461313c565b8681526020810186905273ffffffffffffffffffffffffffffffffffffffff8516604082015263ffffffff848116606083015260c082019061487a6080840186613101565b80841660a084015250979650505050505050565b600083516148a0818460208801612ff4565b8351908301906148b4818360208801612ff4565b01949350505050565b60208152600061259360208301846133df565b805161307481613057565b600082601f8301126148ec57600080fd5b815160206148fc6139938361394e565b8083825260208201915060208460051b87010193508684111561491e57600080fd5b602086015b84811015611c175780518352918301918301614923565b6000602080838503121561494d57600080fd5b825167ffffffffffffffff8082111561496557600080fd5b818501915085601f83011261497957600080fd5b81516149876139938261394e565b81815260059190911b830184019084810190888311156149a657600080fd5b8585015b83811015614a89578051858111156149c157600080fd5b8601610100818c03601f19018113156149d957600080fd5b6149e161386f565b6149ec8a84016148d0565b81526149fa604084016148d0565b8a820152614a0a606084016148d0565b60408201526080830151606082015260a0830151608082015260c083015160a082015260e08084015189811115614a415760008081fd5b614a4f8f8d838801016148db565b60c084015250918301519188831115614a685760008081fd5b614a768e8c858701016148db565b90820152855250509186019186016149aa565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"capabilitiesRegistry\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainSelectorNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ChainSelectorNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expectedConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"gotConfigDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"callDonId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"capabilityRegistryDonId\",\"type\":\"uint32\"}],\"name\":\"DONIdMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FChainMustBePositive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fChain\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"FRoleDON\",\"type\":\"uint256\"}],\"name\":\"FChainTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node\",\"name\":\"node\",\"type\":\"tuple\"}],\"name\":\"InvalidNode\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPluginType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"}],\"name\":\"InvalidSelector\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoOpStateTransitionNotAllowed\",\"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\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCapabilitiesRegistryCanCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RMNHomeAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RevokingZeroDigestNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManySigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ActiveConfigRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"CandidateConfigRevoked\",\"type\":\"event\"},{\"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\":\"structCCIPHome.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigPromoted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"FRoleDON\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rmnHomeAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structCCIPHome.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"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\":\"structCCIPHome.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPHome.ChainConfigArgs[]\",\"name\":\"chainConfigAdds\",\"type\":\"tuple[]\"}],\"name\":\"applyChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"update\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"beforeCapabilityConfigSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getActiveDigest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"pageIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"pageSize\",\"type\":\"uint256\"}],\"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\":\"structCCIPHome.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPHome.ChainConfigArgs[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getAllConfigs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"FRoleDON\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rmnHomeAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPHome.VersionedConfig\",\"name\":\"activeConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"FRoleDON\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rmnHomeAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPHome.VersionedConfig\",\"name\":\"candidateConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getCandidateDigest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"getCapabilityConfiguration\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"configuration\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilityRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.ChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"FRoleDON\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rmnHomeAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPHome.VersionedConfig\",\"name\":\"versionedConfig\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"ok\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getConfigDigests\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"activeConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"candidateConfigDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNumChainConfigurations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"digestToPromote\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"digestToRevoke\",\"type\":\"bytes32\"}],\"name\":\"promoteCandidateAndRevokeActive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"revokeCandidate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"FRoleDON\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rmnHomeAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"digestToOverwrite\",\"type\":\"bytes32\"}],\"name\":\"setCandidate\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"newConfigDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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: "0x60a06040526006805463ffffffff191690553480156200001e57600080fd5b5060405162004e0238038062004e0283398101604081905262000041916200014c565b336000816200006357604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038481169190911790915581161562000096576200009681620000d2565b50506001600160a01b038116620000c0576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03166080526200017e565b336001600160a01b03821603620000fc57604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200015f57600080fd5b81516001600160a01b03811681146200017757600080fd5b9392505050565b608051614c5a620001a86000396000818161019b015281816123600152612dba0152614c5a6000f3fe608060405234801561001057600080fd5b506004361061016c5760003560e01c80637ac0d41e116100cd578063b74b235611610081578063f2fde38b11610066578063f2fde38b14610391578063f442c89a146103a4578063fba64a7c146103b757600080fd5b8063b74b23561461035e578063bae4e0fa1461037e57600080fd5b80638da5cb5b116100b25780638da5cb5b1461030d578063922ea4061461032b578063b149092b1461033e57600080fd5b80637ac0d41e146102e45780638318ed5d146102ec57600080fd5b80634851d549116101245780635f1edd9c116101095780635f1edd9c146102a85780637524051a146102c957806379ba5097146102dc57600080fd5b80634851d5491461026b5780635a837f971461029357600080fd5b8063181f5a7711610155578063181f5a77146101e057806333d9704a146102295780633df45a721461024a57600080fd5b806301ffc9a714610171578063020330e614610199575b600080fd5b61018461017f366004613127565b6103ca565b60405190151581526020015b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610190565b61021c6040518060400160405280601281526020017f43434950486f6d6520312e362e302d646576000000000000000000000000000081525081565b60405161019091906131b9565b61023c610237366004613206565b610463565b60405161019092919061344d565b61025d610258366004613471565b61095d565b6040516101909291906134aa565b61027e610279366004613471565b61125d565b60408051928352602083019190915201610190565b6102a66102a13660046134cf565b611353565b005b6102bb6102b6366004613471565b611666565b604051908152602001610190565b6102a66102d7366004613206565b6116dd565b6102a66118c8565b6102bb611996565b61021c6102fa366004613515565b5060408051602081019091526000815290565b60015473ffffffffffffffffffffffffffffffffffffffff166101bb565b6102bb610339366004613471565b6119a7565b61035161034c366004613553565b6119f8565b60405161019091906135e7565b61037161036c3660046135fa565b611b32565b604051610190919061361c565b6102bb61038c3660046136ba565b611d97565b6102a661039f36600461372a565b611f95565b6102a66103b23660046137a5565b611fa9565b6102a66103c5366004613811565b612348565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f78bea72100000000000000000000000000000000000000000000000000000000148061045d57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b61046b612fb0565b6000805b600281101561094f5763ffffffff8616600090815260056020526040812085918760018111156104a1576104a1613247565b60018111156104b2576104b2613247565b815260200190815260200160002082600281106104d1576104d16138ce565b60070201600101541480156104e557508315155b156109475763ffffffff861660009081526005602052604081209086600181111561051257610512613247565b600181111561052357610523613247565b81526020019081526020016000208160028110610542576105426138ce565b6040805160608101825260079290920292909201805463ffffffff1682526001808201546020840152835161010081018552600283018054939592949386938501929190829060ff168781111561059b5761059b613247565b60018111156105ac576105ac613247565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a0100000000000000000000909104166060820152600182018054608090920191610604906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610630906138fd565b801561067d5780601f106106525761010080835404028352916020019161067d565b820191906000526020600020905b81548152906001019060200180831161066057829003601f168201915b50505050508152602001600282018054610696906138fd565b80601f01602080910402602001604051908101604052809291908181526020018280546106c2906138fd565b801561070f5780601f106106e45761010080835404028352916020019161070f565b820191906000526020600020905b8154815290600101906020018083116106f257829003601f168201915b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b8282101561089d57838290600052602060002090600302016040518060600160405290816000820154815260200160018201805461077a906138fd565b80601f01602080910402602001604051908101604052809291908181526020018280546107a6906138fd565b80156107f35780601f106107c8576101008083540402835291602001916107f3565b820191906000526020600020905b8154815290600101906020018083116107d657829003601f168201915b5050505050815260200160028201805461080c906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610838906138fd565b80156108855780601f1061085a57610100808354040283529160200191610885565b820191906000526020600020905b81548152906001019060200180831161086857829003601f168201915b5050505050815250508152602001906001019061073d565b5050505081526020016004820180546108b5906138fd565b80601f01602080910402602001604051908101604052809291908181526020018280546108e1906138fd565b801561092e5780601f106109035761010080835404028352916020019161092e565b820191906000526020600020905b81548152906001019060200180831161091157829003601f168201915b5050505050815250508152505091509250925050610955565b60010161046f565b50600090505b935093915050565b610965612fb0565b61096d612fb0565b63ffffffff841660009081526005602052604081208185600181111561099557610995613247565b60018111156109a6576109a6613247565b81526020019081526020016000206109be8686612605565b63ffffffff16600281106109d4576109d46138ce565b6040805160608101825260079290920292909201805463ffffffff1682526001808201546020840152835161010081018552600283018054949593949386019391929091839160ff90911690811115610a2f57610a2f613247565b6001811115610a4057610a40613247565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a0100000000000000000000909104166060820152600182018054608090920191610a98906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610ac4906138fd565b8015610b115780601f10610ae657610100808354040283529160200191610b11565b820191906000526020600020905b815481529060010190602001808311610af457829003601f168201915b50505050508152602001600282018054610b2a906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610b56906138fd565b8015610ba35780601f10610b7857610100808354040283529160200191610ba3565b820191906000526020600020905b815481529060010190602001808311610b8657829003601f168201915b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b82821015610d31578382906000526020600020906003020160405180606001604052908160008201548152602001600182018054610c0e906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610c3a906138fd565b8015610c875780601f10610c5c57610100808354040283529160200191610c87565b820191906000526020600020905b815481529060010190602001808311610c6a57829003601f168201915b50505050508152602001600282018054610ca0906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610ccc906138fd565b8015610d195780601f10610cee57610100808354040283529160200191610d19565b820191906000526020600020905b815481529060010190602001808311610cfc57829003601f168201915b50505050508152505081526020019060010190610bd1565b505050508152602001600482018054610d49906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610d75906138fd565b8015610dc25780601f10610d9757610100808354040283529160200191610dc2565b820191906000526020600020905b815481529060010190602001808311610da557829003601f168201915b50505091909252505050905250602081015190915015610de0578092505b63ffffffff8516600090815260056020526040812081866001811115610e0857610e08613247565b6001811115610e1957610e19613247565b8152602001908152602001600020610e31878761265c565b63ffffffff1660028110610e4757610e476138ce565b6040805160608101825260079290920292909201805463ffffffff1682526001808201546020840152835161010081018552600283018054949593949386019391929091839160ff90911690811115610ea257610ea2613247565b6001811115610eb357610eb3613247565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a0100000000000000000000909104166060820152600182018054608090920191610f0b906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610f37906138fd565b8015610f845780601f10610f5957610100808354040283529160200191610f84565b820191906000526020600020905b815481529060010190602001808311610f6757829003601f168201915b50505050508152602001600282018054610f9d906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610fc9906138fd565b80156110165780601f10610feb57610100808354040283529160200191611016565b820191906000526020600020905b815481529060010190602001808311610ff957829003601f168201915b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b828210156111a4578382906000526020600020906003020160405180606001604052908160008201548152602001600182018054611081906138fd565b80601f01602080910402602001604051908101604052809291908181526020018280546110ad906138fd565b80156110fa5780601f106110cf576101008083540402835291602001916110fa565b820191906000526020600020905b8154815290600101906020018083116110dd57829003601f168201915b50505050508152602001600282018054611113906138fd565b80601f016020809104026020016040519081016040528092919081815260200182805461113f906138fd565b801561118c5780601f106111615761010080835404028352916020019161118c565b820191906000526020600020905b81548152906001019060200180831161116f57829003601f168201915b50505050508152505081526020019060010190611044565b5050505081526020016004820180546111bc906138fd565b80601f01602080910402602001604051908101604052809291908181526020018280546111e8906138fd565b80156112355780601f1061120a57610100808354040283529160200191611235565b820191906000526020600020905b81548152906001019060200180831161121857829003601f168201915b50505091909252505050905250602081015190915015611253578092505b50505b9250929050565b63ffffffff8216600090815260056020526040812081908184600181111561128757611287613247565b600181111561129857611298613247565b81526020019081526020016000206112b08585612605565b63ffffffff16600281106112c6576112c66138ce565b6007020160010154600560008663ffffffff1663ffffffff168152602001908152602001600020600085600181111561130157611301613247565b600181111561131257611312613247565b815260200190815260200160002061132a868661265c565b63ffffffff1660028110611340576113406138ce565b6007020160010154915091509250929050565b61135b6126b7565b81158015611367575080155b1561139e576040517f7b4d1e4f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006113aa858561265c565b63ffffffff86811660009081526005602052604081209290911692508491908660018111156113db576113db613247565b60018111156113ec576113ec613247565b8152602001908152602001600020826002811061140b5761140b6138ce565b6007020160010154146114bf5763ffffffff851660009081526005602052604081209085600181111561144057611440613247565b600181111561145157611451613247565b81526020019081526020016000208160028110611470576114706138ce565b6007020160010154836040517f93df584c0000000000000000000000000000000000000000000000000000000081526004016114b6929190918252602082015260400190565b60405180910390fd5b63ffffffff85166000908152600560205260408120818660018111156114e7576114e7613247565b60018111156114f8576114f8613247565b81526020019081526020016000206115108787612605565b63ffffffff1660028110611526576115266138ce565b600702019050828160010154146115795760018101546040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018490526044016114b6565b6000600180830182905563ffffffff88168252600760205260408220909187838111156115a8576115a8613247565b60018111156115b9576115b9613247565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000811663ffffffff918216939093181691909117905582156116335760405183907f0b31c0055e2d464bef7781994b98c4ff9ef4ae0d05f59feb6a68c42de5e201b890600090a25b60405184907ffc3e98dbbd47c3fa7c1c05b6ec711caeaf70eca4554192b9ada8fc11a37f298e90600090a2505050505050565b63ffffffff821660009081526005602052604081208183600181111561168e5761168e613247565b600181111561169f5761169f613247565b81526020019081526020016000206116b78484612605565b63ffffffff16600281106116cd576116cd6138ce565b6007020160010154905092915050565b6116e56126b7565b8061171c576040517f0849d8cc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611728848461265c565b63ffffffff858116600090815260056020526040812092909116925083919085600181111561175957611759613247565b600181111561176a5761176a613247565b81526020019081526020016000208260028110611789576117896138ce565b6007020160010154146118345763ffffffff84166000908152600560205260408120908460018111156117be576117be613247565b60018111156117cf576117cf613247565b815260200190815260200160002081600281106117ee576117ee6138ce565b6007020160010154826040517f93df584c0000000000000000000000000000000000000000000000000000000081526004016114b6929190918252602082015260400190565b60405182907f53f5d9228f0a4173bea6e5931c9b3afe6eeb6692ede1d182952970f152534e3b90600090a263ffffffff841660009081526005602052604081209084600181111561188757611887613247565b600181111561189857611898613247565b815260200190815260200160002081600281106118b7576118b76138ce565b600702016001016000905550505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611919576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60006119a260036126f2565b905090565b63ffffffff82166000908152600560205260408120818360018111156119cf576119cf613247565b60018111156119e0576119e0613247565b81526020019081526020016000206116b7848461265c565b6040805160608082018352808252600060208301529181019190915267ffffffffffffffff821660009081526002602090815260409182902082518154608093810282018401909452606081018481529093919284928491840182828015611a7f57602002820191906000526020600020905b815481526020019060010190808311611a6b575b5050509183525050600182015460ff166020820152600282018054604090920191611aa9906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054611ad5906138fd565b8015611b225780601f10611af757610100808354040283529160200191611b22565b820191906000526020600020905b815481529060010190602001808311611b0557829003601f168201915b5050505050815250509050919050565b60606000611b4060036126f2565b90506000611b4e848661397f565b9050831580611b5d5750818110155b15611b9d576040805160008082526020820190925290611b93565b611b8061302c565b815260200190600190039081611b785790505b509250505061045d565b6000611ba985836139c5565b905082811115611bb65750815b6000611bc283836139d8565b67ffffffffffffffff811115611bda57611bda613996565b604051908082528060200260200182016040528015611c1357816020015b611c0061302c565b815260200190600190039081611bf85790505b509050825b82811015611d8c576000611c2d6003836126fc565b60408051808201825267ffffffffffffffff83168082526000908152600260209081529083902083518154608081850283018101909652606082018181529697509395928601949093919284929091849190840182828015611cae57602002820191906000526020600020905b815481526020019060010190808311611c9a575b5050509183525050600182015460ff166020820152600282018054604090920191611cd8906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054611d04906138fd565b8015611d515780601f10611d2657610100808354040283529160200191611d51565b820191906000526020600020905b815481529060010190602001808311611d3457829003601f168201915b50505091909252505050905283611d6887856139d8565b81518110611d7857611d786138ce565b602090810291909101015250600101611c18565b509695505050505050565b6000611da16126b7565b611db2611dad84613c06565b61270f565b6000611dbe86866119a7565b9050828114611e03576040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101829052602481018490526044016114b6565b8015611e355760405183907f53f5d9228f0a4173bea6e5931c9b3afe6eeb6692ede1d182952970f152534e3b90600090a25b60068054600091908290611e4e9063ffffffff16613d02565b91906101000a81548163ffffffff021916908363ffffffff16021790559050611e98878787604051602001611e839190613fde565b60405160208183030381529060405284612b7d565b63ffffffff881660009081526005602052604081209194509081886001811115611ec457611ec4613247565b6001811115611ed557611ed5613247565b8152602001908152602001600020611eed898961265c565b63ffffffff1660028110611f0357611f036138ce565b600702016001810185905580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff841617815590508560028201611f4d82826144c4565b905050837f94f085b7c57ec2a270befd0b7b2ec7452580040edee8bb0fb04609c81f0359c68388604051611f8292919061468b565b60405180910390a2505050949350505050565b611f9d612c3d565b611fa681612c8e565b50565b611fb1612c3d565b60005b8381101561219757611ff8858583818110611fd157611fd16138ce565b9050602002016020810190611fe69190613553565b60039067ffffffffffffffff16612d52565b6120625784848281811061200e5761200e6138ce565b90506020020160208101906120239190613553565b6040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016114b6565b60026000868684818110612078576120786138ce565b905060200201602081019061208d9190613553565b67ffffffffffffffff16815260208101919091526040016000908120906120b4828261306f565b6001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556120ec60028301600061308d565b505061212a858583818110612103576121036138ce565b90506020020160208101906121189190613553565b60039067ffffffffffffffff16612d6a565b507f2a680691fef3b2d105196805935232c661ce703e92d464ef0b94a7bc62d714f085858381811061215e5761215e6138ce565b90506020020160208101906121739190613553565b60405167ffffffffffffffff909116815260200160405180910390a1600101611fb4565b5060005b818110156123415760008383838181106121b7576121b76138ce565b90506020028101906121c991906146b2565b6121d7906020810190614227565b6121e0906146e6565b905060008484848181106121f6576121f66138ce565b905060200281019061220891906146b2565b612216906020810190613553565b90506122258260000151612d76565b816020015160ff16600003612266576040517fa9b3766e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff811660009081526002602090815260409091208351805185936122969284929101906130c7565b5060208201516001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055604082015160028201906122e390826147b8565b506122fd91506003905067ffffffffffffffff8316612e38565b507f05dd57854af2c291a94ea52e7c43d80bc3be7fa73022f98b735dea86642fa5e0818360405161232f9291906148b4565b60405180910390a1505060010161219b565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146123b7576040517fac7a7efd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006123c660048286886148d7565b6123cf91614901565b90507fffffffff0000000000000000000000000000000000000000000000000000000081167fbae4e0fa000000000000000000000000000000000000000000000000000000001480159061246557507fffffffff0000000000000000000000000000000000000000000000000000000081167f7524051a0000000000000000000000000000000000000000000000000000000014155b80156124b357507fffffffff0000000000000000000000000000000000000000000000000000000081167f5a837f970000000000000000000000000000000000000000000000000000000014155b1561250e576040517f12ba286f0000000000000000000000000000000000000000000000000000000081527fffffffff00000000000000000000000000000000000000000000000000000000821660048201526024016114b6565b600061251e6024600487896148d7565b81019061252b9190614949565b90508263ffffffff16811461257c576040517f8a6e4ce800000000000000000000000000000000000000000000000000000000815263ffffffff8083166004830152841660248201526044016114b6565b6000803073ffffffffffffffffffffffffffffffffffffffff1688886040516125a6929190614962565b6000604051808303816000865af19150503d80600081146125e3576040519150601f19603f3d011682016040523d82523d6000602084013e6125e8565b606091505b5091509150816125f9573d60208201fd5b50505050505050505050565b63ffffffff821660009081526007602052604081208183600181111561262d5761262d613247565b600181111561263e5761263e613247565b815260208101919091526040016000205463ffffffff169392505050565b63ffffffff821660009081526007602052604081208183600181111561268457612684613247565b600181111561269557612695613247565b815260208101919091526040016000205463ffffffff16600118905092915050565b3330146126f0576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600061045d825490565b60006127088383612e44565b9392505050565b806020015167ffffffffffffffff16600003612757576040517f698cf8e000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008151600181111561276c5761276c613247565b1415801561278d575060018151600181111561278a5761278a613247565b14155b156127c4576040517f3302dbd700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6080810151511580612801575060408051600060208201520160405160208183030381529060405280519060200120816080015180519060200120145b15612838576040517f358c192700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a08101515115806128755750604080516000602082015201604051602081830303815290604052805190602001208160a0015180519060200120145b156128ac576040517fdee9857400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101516128c79060039067ffffffffffffffff16612d52565b61290f5760208101516040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016114b6565b60408082015160208084015167ffffffffffffffff1660009081526002909152919091206001015460ff918216911681811115612982576040517f2db2204000000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016114b6565b60c0830151516101008111156129c4576040517f1b925da600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129cf83600361397f565b8111612a07576040517f4856694e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808267ffffffffffffffff811115612a2357612a23613996565b604051908082528060200260200182016040528015612a4c578160200160208202803683370190505b50905060005b83811015612b0c5760008760c001518281518110612a7257612a726138ce565b60200260200101519050806040015151600014612a975783612a9381614972565b9450505b6020810151511580612aa857508051155b15612ae157806040517f9fa403140000000000000000000000000000000000000000000000000000000081526004016114b691906149aa565b8060000151838381518110612af857612af86138ce565b602090810291909101015250600101612a52565b506000612b1a85600361397f565b612b259060016139c5565b905080831015612b6b576040517f548dd21f00000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044016114b6565b612b7482612d76565b50505050505050565b6040516000907dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90612bdb907f45564d000000000000000000000000000000000000000000000000000000000090469030908a908a9089906020016149bd565b60408051601f1981840301815290829052612bfa918690602001614a16565b60408051808303601f190181529190528051602090910120167e0a0000000000000000000000000000000000000000000000000000000000001795945050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146126f0576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603612cdd576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120541515612708565b60006127088383612e6e565b805115611fa6576040517f05a5196600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906305a5196690612def908490600401614a45565b600060405180830381865afa158015612e0c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e349190810190614ac2565b5050565b60006127088383612f61565b6000826000018281548110612e5b57612e5b6138ce565b9060005260206000200154905092915050565b60008181526001830160205260408120548015612f57576000612e926001836139d8565b8554909150600090612ea6906001906139d8565b9050808214612f0b576000866000018281548110612ec657612ec66138ce565b9060005260206000200154905080876000018481548110612ee957612ee96138ce565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612f1c57612f1c614c1e565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061045d565b600091505061045d565b6000818152600183016020526040812054612fa85750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561045d565b50600061045d565b60408051606081018252600080825260208201529081016130276040805161010081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff168152602001606081526020016060815260200160608152602001606081525090565b905290565b6040518060400160405280600067ffffffffffffffff168152602001613027604051806060016040528060608152602001600060ff168152602001606081525090565b5080546000825590600052602060002090810190611fa69190613112565b508054613099906138fd565b6000825580601f106130a9575050565b601f016020900490600052602060002090810190611fa69190613112565b828054828255906000526020600020908101928215613102579160200282015b828111156131025782518255916020019190600101906130e7565b5061310e929150613112565b5090565b5b8082111561310e5760008155600101613113565b60006020828403121561313957600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461270857600080fd5b60005b8381101561318457818101518382015260200161316c565b50506000910152565b600081518084526131a5816020860160208601613169565b601f01601f19169290920160200192915050565b602081526000612708602083018461318d565b63ffffffff81168114611fa657600080fd5b80356131e9816131cc565b919050565b60028110611fa657600080fd5b80356131e9816131ee565b60008060006060848603121561321b57600080fd5b8335613226816131cc565b92506020840135613236816131ee565b929592945050506040919091013590565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600281106132ad577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8051825260006020820151606060208501526132d0606085018261318d565b9050604083015184820360408601526132e9828261318d565b95945050505050565b60008282518085526020808601955060208260051b8401016020860160005b8481101561333f57601f1986840301895261332d8383516132b1565b98840198925090830190600101613311565b5090979650505050505050565b63ffffffff815116825260208101516020830152600060408201516060604085015261337c606085018251613276565b602081015167ffffffffffffffff8116608086015250604081015160ff811660a086015250606081015167ffffffffffffffff811660c08601525060808101516101008060e08701526133d361016087018361318d565b915060a08301517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa080888503018389015261340e848361318d565b935060c08501519250808885030161012089015261342c84846132f2565b935060e0850151945080888503016101408901525050506132e9818361318d565b604081526000613460604083018561334c565b905082151560208301529392505050565b6000806040838503121561348457600080fd5b823561348f816131cc565b9150602083013561349f816131ee565b809150509250929050565b6040815260006134bd604083018561334c565b82810360208401526132e9818561334c565b600080600080608085870312156134e557600080fd5b84356134f0816131cc565b93506020850135613500816131ee565b93969395505050506040820135916060013590565b60006020828403121561352757600080fd5b8135612708816131cc565b67ffffffffffffffff81168114611fa657600080fd5b80356131e981613532565b60006020828403121561356557600080fd5b813561270881613532565b60008151808452602080850194506020840160005b838110156135a157815187529582019590820190600101613585565b509495945050505050565b60008151606084526135c16060850182613570565b905060ff6020840151166020850152604083015184820360408601526132e9828261318d565b60208152600061270860208301846135ac565b6000806040838503121561360d57600080fd5b50508035926020909101359150565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b838110156136ac578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805167ffffffffffffffff168452870151878401879052613699878501826135ac565b9588019593505090860190600101613645565b509098975050505050505050565b600080600080608085870312156136d057600080fd5b84356136db816131cc565b935060208501356136eb816131ee565b9250604085013567ffffffffffffffff81111561370757600080fd5b8501610100818803121561371a57600080fd5b9396929550929360600135925050565b60006020828403121561373c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461270857600080fd5b60008083601f84011261377257600080fd5b50813567ffffffffffffffff81111561378a57600080fd5b6020830191508360208260051b850101111561125657600080fd5b600080600080604085870312156137bb57600080fd5b843567ffffffffffffffff808211156137d357600080fd5b6137df88838901613760565b909650945060208701359150808211156137f857600080fd5b5061380587828801613760565b95989497509550505050565b6000806000806000806080878903121561382a57600080fd5b863567ffffffffffffffff8082111561384257600080fd5b61384e8a838b01613760565b9098509650602089013591508082111561386757600080fd5b818901915089601f83011261387b57600080fd5b81358181111561388a57600080fd5b8a602082850101111561389c57600080fd5b6020830196508095505050506138b460408801613548565b91506138c2606088016131de565b90509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c9082168061391157607f821691505b60208210810361394a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761045d5761045d613950565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8082018082111561045d5761045d613950565b8181038181111561045d5761045d613950565b6040516060810167ffffffffffffffff81118282101715613a0e57613a0e613996565b60405290565b604051610100810167ffffffffffffffff81118282101715613a0e57613a0e613996565b604051601f8201601f1916810167ffffffffffffffff81118282101715613a6157613a61613996565b604052919050565b60ff81168114611fa657600080fd5b80356131e981613a69565b600082601f830112613a9457600080fd5b813567ffffffffffffffff811115613aae57613aae613996565b613ac16020601f19601f84011601613a38565b818152846020838601011115613ad657600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff821115613b0d57613b0d613996565b5060051b60200190565b600082601f830112613b2857600080fd5b81356020613b3d613b3883613af3565b613a38565b82815260059290921b84018101918181019086841115613b5c57600080fd5b8286015b84811015611d8c57803567ffffffffffffffff80821115613b815760008081fd5b8189019150606080601f19848d03011215613b9c5760008081fd5b613ba46139eb565b87840135815260408085013584811115613bbe5760008081fd5b613bcc8e8b83890101613a83565b838b015250918401359183831115613be45760008081fd5b613bf28d8a85880101613a83565b908201528652505050918301918301613b60565b60006101008236031215613c1957600080fd5b613c21613a14565b613c2a836131fb565b8152613c3860208401613548565b6020820152613c4960408401613a78565b6040820152613c5a60608401613548565b6060820152608083013567ffffffffffffffff80821115613c7a57600080fd5b613c8636838701613a83565b608084015260a0850135915080821115613c9f57600080fd5b613cab36838701613a83565b60a084015260c0850135915080821115613cc457600080fd5b613cd036838701613b17565b60c084015260e0850135915080821115613ce957600080fd5b50613cf636828601613a83565b60e08301525092915050565b600063ffffffff808316818103613d1b57613d1b613950565b6001019392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613d5a57600080fd5b830160208101925035905067ffffffffffffffff811115613d7a57600080fd5b80360382131561125657600080fd5b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613de957600080fd5b830160208101925035905067ffffffffffffffff811115613e0957600080fd5b8060051b360382131561125657600080fd5b60008383855260208086019550808560051b830101846000805b88811015613ed957601f19868503018a5282357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1893603018112613e77578283fd5b8801803585526060613e8b87830183613d25565b8289890152613e9d8389018284613d89565b925050506040613eaf81840184613d25565b935087830382890152613ec3838583613d89565b9d89019d97505050938601935050600101613e35565b509198975050505050505050565b6000610100613efe84613ef9856131fb565b613276565b613f0a60208401613548565b67ffffffffffffffff166020850152613f2560408401613a78565b60ff166040850152613f3960608401613548565b67ffffffffffffffff166060850152613f556080840184613d25565b826080870152613f688387018284613d89565b92505050613f7960a0840184613d25565b85830360a0870152613f8c838284613d89565b92505050613f9d60c0840184613db4565b85830360c0870152613fb0838284613e1b565b92505050613fc160e0840184613d25565b85830360e0870152613fd4838284613d89565b9695505050505050565b6020815260006127086020830184613ee7565b6000813561045d81613532565b6000813561045d81613a69565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261404057600080fd5b83018035915067ffffffffffffffff82111561405b57600080fd5b60200191503681900382131561125657600080fd5b5b81811015612e345760008155600101614071565b601f8211156140be57806000526020600020601f840160051c810160208510156140ac5750805b612341601f850160051c830182614070565b505050565b67ffffffffffffffff8311156140db576140db613996565b6140ef836140e983546138fd565b83614085565b6000601f841160018114614141576000851561410b5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355612341565b600083815260209020601f19861690835b828110156141725786850135825560209485019460019092019101614152565b50868210156141ad577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126141f457600080fd5b83018035915067ffffffffffffffff82111561420f57600080fd5b6020019150600581901b360382131561125657600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa183360301811261425b57600080fd5b9190910192915050565b61426f81546138fd565b8015612e3457601f81116001811461428957505060009055565b8260005260206000206142a7601f840160051c820160018301614070565b60008085559055505050565b81358155600180820160206142cb602086018661400b565b67ffffffffffffffff8111156142e3576142e3613996565b6142f7816142f186546138fd565b86614085565b6000601f82116001811461434957600083156143135750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600385901b1c1916600184901b1786556143be565b600086815260209020601f19841690835b82811015614377578685013582559387019390890190870161435a565b50848210156143b2577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88660031b161c19848701351681555b505060018360011b0186555b505050505050506143d2604083018361400b565b6143e08183600286016140c3565b50505050565b680100000000000000008311156143ff576143ff613996565b80548382558084101561447e5760038160030260038104831461442457614424613950565b8560030260038104871461443a5761443a613950565b6000858152602081209283019291909101905b828210156144795780825561446460018301614265565b61447060028301614265565b9083019061444d565b505050505b5060008181526020812083915b858110156144bc576144a66144a08487614227565b836142b3565b602092909201916003919091019060010161448b565b505050505050565b81356144cf816131ee565b60028110614506577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082541660ff821681178355505061457d61454360208401613ff1565b82547fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff1660089190911b68ffffffffffffffff0016178255565b6145c761458c60408401613ffe565b82547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff1660489190911b69ff00000000000000000016178255565b6146196145d660608401613ff1565b82547fffffffffffffffffffffffffffff0000000000000000ffffffffffffffffffff1660509190911b71ffffffffffffffff0000000000000000000016178255565b614626608083018361400b565b6146348183600186016140c3565b505061464360a083018361400b565b6146518183600286016140c3565b505061466060c08301836141bf565b61466e8183600386016143e6565b505061467d60e083018361400b565b6143e08183600486016140c3565b63ffffffff831681526040602082015260006146aa6040830184613ee7565b949350505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261425b57600080fd5b6000606082360312156146f857600080fd5b6147006139eb565b823567ffffffffffffffff8082111561471857600080fd5b9084019036601f83011261472b57600080fd5b8135602061473b613b3883613af3565b82815260059290921b8401810191818101903684111561475a57600080fd5b948201945b838610156147785785358252948201949082019061475f565b865250614786878201613a78565b9085015250604085013591508082111561479f57600080fd5b506147ac36828601613a83565b60408301525092915050565b815167ffffffffffffffff8111156147d2576147d2613996565b6147e6816147e084546138fd565b84614085565b602080601f83116001811461483957600084156148035750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556144bc565b600085815260208120601f198616915b8281101561486857888601518255948401946001909101908401614849565b50858210156148a457878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b67ffffffffffffffff831681526040602082015260006146aa60408301846135ac565b600080858511156148e757600080fd5b838611156148f457600080fd5b5050820193919092039150565b7fffffffff0000000000000000000000000000000000000000000000000000000081358181169160048510156149415780818660040360031b1b83161692505b505092915050565b60006020828403121561495b57600080fd5b5035919050565b8183823760009101908152919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036149a3576149a3613950565b5060010190565b60208152600061270860208301846132b1565b8681526020810186905273ffffffffffffffffffffffffffffffffffffffff8516604082015263ffffffff848116606083015260c0820190614a026080840186613276565b80841660a084015250979650505050505050565b60008351614a28818460208801613169565b835190830190614a3c818360208801613169565b01949350505050565b6020815260006127086020830184613570565b80516131e9816131cc565b600082601f830112614a7457600080fd5b81516020614a84613b3883613af3565b8083825260208201915060208460051b870101935086841115614aa657600080fd5b602086015b84811015611d8c5780518352918301918301614aab565b60006020808385031215614ad557600080fd5b825167ffffffffffffffff80821115614aed57600080fd5b818501915085601f830112614b0157600080fd5b8151614b0f613b3882613af3565b81815260059190911b83018401908481019088831115614b2e57600080fd5b8585015b83811015614c1157805185811115614b4957600080fd5b8601610100818c03601f1901811315614b6157600080fd5b614b69613a14565b614b748a8401614a58565b8152614b8260408401614a58565b8a820152614b9260608401614a58565b60408201526080830151606082015260a0830151608082015260c083015160a082015260e08084015189811115614bc95760008081fd5b614bd78f8d83880101614a63565b60c084015250918301519188831115614bf05760008081fd5b614bfe8e8c85870101614a63565b9082015285525050918601918601614b32565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var CCIPHomeABI = CCIPHomeMetaData.ABI @@ -345,6 +345,28 @@ func (_CCIPHome *CCIPHomeCallerSession) GetCapabilityRegistry() (common.Address, return _CCIPHome.Contract.GetCapabilityRegistry(&_CCIPHome.CallOpts) } +func (_CCIPHome *CCIPHomeCaller) GetChainConfig(opts *bind.CallOpts, chainSelector uint64) (CCIPHomeChainConfig, error) { + var out []interface{} + err := _CCIPHome.contract.Call(opts, &out, "getChainConfig", chainSelector) + + if err != nil { + return *new(CCIPHomeChainConfig), err + } + + out0 := *abi.ConvertType(out[0], new(CCIPHomeChainConfig)).(*CCIPHomeChainConfig) + + return out0, err + +} + +func (_CCIPHome *CCIPHomeSession) GetChainConfig(chainSelector uint64) (CCIPHomeChainConfig, error) { + return _CCIPHome.Contract.GetChainConfig(&_CCIPHome.CallOpts, chainSelector) +} + +func (_CCIPHome *CCIPHomeCallerSession) GetChainConfig(chainSelector uint64) (CCIPHomeChainConfig, error) { + return _CCIPHome.Contract.GetChainConfig(&_CCIPHome.CallOpts, chainSelector) +} + func (_CCIPHome *CCIPHomeCaller) GetConfig(opts *bind.CallOpts, donId uint32, pluginType uint8, configDigest [32]byte) (GetConfig, error) { @@ -1804,6 +1826,8 @@ type CCIPHomeInterface interface { GetCapabilityRegistry(opts *bind.CallOpts) (common.Address, error) + GetChainConfig(opts *bind.CallOpts, chainSelector uint64) (CCIPHomeChainConfig, error) + GetConfig(opts *bind.CallOpts, donId uint32, pluginType uint8, configDigest [32]byte) (GetConfig, 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 3d084f43606..e4df70b2452 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 @@ -3,7 +3,7 @@ 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 1c78cd3118b3c9ca82f8cb77ffc1137619ea4e8e503c460f2dafb659d0dd766b burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin eab9c19ef27b245e5ef0216ab1080c9dd89c96013b7dc978bf610288d5e82b00 ccip_encoding_utils: ../../../contracts/solc/v0.8.24/ICCIPEncodingUtils/ICCIPEncodingUtils.abi ../../../contracts/solc/v0.8.24/ICCIPEncodingUtils/ICCIPEncodingUtils.bin 9971fc93c34442a0989570d3dab90a125de31e6e60754ad972807ce6ad4dfba0 -ccip_home: ../../../contracts/solc/v0.8.24/CCIPHome/CCIPHome.abi ../../../contracts/solc/v0.8.24/CCIPHome/CCIPHome.bin 02cb75b4274a5be7f4006cf2b72cc09e77eb6dba4c1a9c720af86668ff8ea1df +ccip_home: ../../../contracts/solc/v0.8.24/CCIPHome/CCIPHome.abi ../../../contracts/solc/v0.8.24/CCIPHome/CCIPHome.bin 865bc25c54cf346e5f519dc3fb625260a12c80983b5ba2dcea63519a7befc660 ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin b368699ae7dbee7c21d049a641642837f18ce2cc8d4ece69509f205de673108e ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de fee_quoter: ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.abi ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.bin aee49c9246d5903e68b175516b3cdfdec5df23e25d53d604cd382b6bc0bf34f7 From 01c05a9be56b0d0daccd2b4be5793786927ae2df Mon Sep 17 00:00:00 2001 From: Street <5597260+MStreet3@users.noreply.github.com> Date: Tue, 10 Dec 2024 07:18:30 -0500 Subject: [PATCH 21/29] fix(compute): flakey cache test (#15520) --- core/capabilities/compute/cache.go | 11 ++++++----- core/capabilities/compute/cache_test.go | 9 +++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/core/capabilities/compute/cache.go b/core/capabilities/compute/cache.go index 7b7cd78aaab..dbcc42c1606 100644 --- a/core/capabilities/compute/cache.go +++ b/core/capabilities/compute/cache.go @@ -38,8 +38,9 @@ type moduleCache struct { timeout time.Duration evictAfterSize int - clock clockwork.Clock - onReaper chan struct{} + clock clockwork.Clock + reapTicker <-chan time.Time + onReaper chan struct{} } func newModuleCache(clock clockwork.Clock, tick, timeout time.Duration, evictAfterSize int) *moduleCache { @@ -49,6 +50,7 @@ func newModuleCache(clock clockwork.Clock, tick, timeout time.Duration, evictAft timeout: timeout, evictAfterSize: evictAfterSize, clock: clock, + reapTicker: clock.NewTicker(tick).Chan(), stopChan: make(chan struct{}), } } @@ -67,10 +69,9 @@ func (mc *moduleCache) close() { } func (mc *moduleCache) reapLoop() { - ticker := mc.clock.NewTicker(mc.tickInterval) for { select { - case <-ticker.Chan(): + case <-mc.reapTicker: mc.evictOlderThan(mc.timeout) if mc.onReaper != nil { mc.onReaper <- struct{}{} @@ -84,7 +85,7 @@ func (mc *moduleCache) reapLoop() { func (mc *moduleCache) add(id string, mod *module) { mc.mu.Lock() defer mc.mu.Unlock() - mod.lastFetchedAt = time.Now() + mod.lastFetchedAt = mc.clock.Now() mc.m[id] = mod moduleCacheAddition.Inc() } diff --git a/core/capabilities/compute/cache_test.go b/core/capabilities/compute/cache_test.go index 3b38cc23001..ad075f493b5 100644 --- a/core/capabilities/compute/cache_test.go +++ b/core/capabilities/compute/cache_test.go @@ -20,14 +20,17 @@ const ( binaryCmd = "core/capabilities/compute/test/simple/cmd" ) +// Verify that cache evicts an expired module. func TestCache(t *testing.T) { t.Parallel() clock := clockwork.NewFakeClock() tick := 1 * time.Second timeout := 1 * time.Second + reapTicker := make(chan time.Time) cache := newModuleCache(clock, tick, timeout, 0) cache.onReaper = make(chan struct{}, 1) + cache.reapTicker = reapTicker cache.start() defer cache.close() @@ -50,20 +53,24 @@ func TestCache(t *testing.T) { assert.Equal(t, got, mod) clock.Advance(15 * time.Second) + reapTicker <- time.Now() <-cache.onReaper _, ok = cache.get(id) assert.False(t, ok) } +// Verify that an expired module is not evicted because evictAfterSize is 1 func TestCache_EvictAfterSize(t *testing.T) { t.Parallel() ctx := tests.Context(t) clock := clockwork.NewFakeClock() tick := 1 * time.Second timeout := 1 * time.Second + reapTicker := make(chan time.Time) cache := newModuleCache(clock, tick, timeout, 1) cache.onReaper = make(chan struct{}, 1) + cache.reapTicker = reapTicker cache.start() defer cache.close() @@ -79,6 +86,7 @@ func TestCache_EvictAfterSize(t *testing.T) { module: hmod, } cache.add(id, mod) + assert.Len(t, cache.m, 1) got, ok := cache.get(id) assert.True(t, ok) @@ -86,6 +94,7 @@ func TestCache_EvictAfterSize(t *testing.T) { assert.Equal(t, got, mod) clock.Advance(15 * time.Second) + reapTicker <- time.Now() select { case <-ctx.Done(): return From 13b3ceebfe7433b66c3b51ff8585c57c12760a73 Mon Sep 17 00:00:00 2001 From: Cedric Date: Tue, 10 Dec 2024 12:57:27 +0000 Subject: [PATCH 22/29] [CAPPL] Fixes to registry syncer (#15567) * [CAPPL] Fixes to registry syncer * [fix] ID Generation * Update ContractReader mock * Error formatting --- .../capabilities/triggers/logevent/trigger.go | 5 + core/services/chainlink/application.go | 15 +- .../evm/capabilities/testutils/backend.go | 2 +- .../workflows/syncer/workflow_syncer_test.go | 249 +++++++++++++++--- core/services/workflows/engine.go | 8 + .../workflows/syncer/contract_reader_mock.go | 91 +++++++ .../workflows/syncer/engine_registry.go | 22 +- core/services/workflows/syncer/handler.go | 135 ++++++---- .../services/workflows/syncer/handler_test.go | 190 ++++++------- .../workflows/syncer/workflow_registry.go | 138 +++++++++- .../syncer/workflow_registry_test.go | 98 ++++++- 11 files changed, 742 insertions(+), 211 deletions(-) diff --git a/core/capabilities/triggers/logevent/trigger.go b/core/capabilities/triggers/logevent/trigger.go index 7ee76c6f44a..334c3c3f30e 100644 --- a/core/capabilities/triggers/logevent/trigger.go +++ b/core/capabilities/triggers/logevent/trigger.go @@ -67,6 +67,11 @@ func newLogEventTrigger(ctx context.Context, return nil, nil, err } + err = contractReader.Start(ctx) + if err != nil { + return nil, nil, err + } + // Get current block HEAD/tip of the blockchain to start polling from latestHead, err := relayer.LatestHead(ctx) if err != nil { diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 29473c4d932..d8b9777cb5a 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -312,12 +312,19 @@ func NewApplication(opts ApplicationOpts) (Application, error) { }, eventHandler) globalLogger.Debugw("Creating WorkflowRegistrySyncer") - wfSyncer := syncer.NewWorkflowRegistry(lggr, func(ctx context.Context, bytes []byte) (syncer.ContractReader, error) { - return relayer.NewContractReader(ctx, bytes) - }, cfg.Capabilities().WorkflowRegistry().Address(), + wfSyncer := syncer.NewWorkflowRegistry( + lggr, + func(ctx context.Context, bytes []byte) (syncer.ContractReader, error) { + return relayer.NewContractReader(ctx, bytes) + }, + cfg.Capabilities().WorkflowRegistry().Address(), syncer.WorkflowEventPollerConfig{ QueryCount: 100, - }, eventHandler, loader, workflowDonNotifier) + }, + eventHandler, + loader, + workflowDonNotifier, + ) srvcs = append(srvcs, fetcher, wfSyncer) } diff --git a/core/services/relay/evm/capabilities/testutils/backend.go b/core/services/relay/evm/capabilities/testutils/backend.go index e76dbc3bc73..cd04373e29e 100644 --- a/core/services/relay/evm/capabilities/testutils/backend.go +++ b/core/services/relay/evm/capabilities/testutils/backend.go @@ -118,5 +118,5 @@ func (th *EVMBackendTH) NewContractReader(ctx context.Context, t *testing.T, cfg return nil, err } - return svc, svc.Start(ctx) + return svc, err } diff --git a/core/services/relay/evm/capabilities/workflows/syncer/workflow_syncer_test.go b/core/services/relay/evm/capabilities/workflows/syncer/workflow_syncer_test.go index 3bcf8164a7b..3c6ee8a1d04 100644 --- a/core/services/relay/evm/capabilities/workflows/syncer/workflow_syncer_test.go +++ b/core/services/relay/evm/capabilities/workflows/syncer/workflow_syncer_test.go @@ -3,9 +3,10 @@ package workflow_registry_syncer_test import ( "context" "crypto/rand" + "encoding/base64" "encoding/hex" - "encoding/json" "fmt" + "strings" "testing" "time" @@ -16,15 +17,16 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/custmsg" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/workflows" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/workflow/generated/workflow_registry_wrapper" coretestutils "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/workflowkey" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/capabilities/testutils" - evmtypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" "github.com/smartcontractkit/chainlink/v2/core/services/workflows/syncer" "github.com/smartcontractkit/chainlink/v2/core/utils/crypto" @@ -157,8 +159,6 @@ func Test_SecretsWorker(t *testing.T) { fetcherFn = func(_ context.Context, _ string) ([]byte, error) { return []byte(wantContents), nil } - contractName = syncer.WorkflowRegistryContractName - forceUpdateSecretsEvent = string(syncer.ForceUpdateSecretsEvent) ) defer giveTicker.Stop() @@ -174,38 +174,6 @@ func Test_SecretsWorker(t *testing.T) { backendTH.Backend.Commit() require.NoError(t, err) - lggr.Infof("deployed workflow registry at %s\n", wfRegistryAddr.Hex()) - - // Build the ContractReader config - contractReaderCfg := evmtypes.ChainReaderConfig{ - Contracts: map[string]evmtypes.ChainContractReader{ - contractName: { - ContractPollingFilter: evmtypes.ContractPollingFilter{ - GenericEventNames: []string{forceUpdateSecretsEvent}, - }, - ContractABI: workflow_registry_wrapper.WorkflowRegistryABI, - Configs: map[string]*evmtypes.ChainReaderDefinition{ - forceUpdateSecretsEvent: { - ChainSpecificName: forceUpdateSecretsEvent, - ReadType: evmtypes.Event, - }, - syncer.GetWorkflowMetadataListByDONMethodName: { - ChainSpecificName: syncer.GetWorkflowMetadataListByDONMethodName, - }, - }, - }, - }, - } - - contractReaderCfgBytes, err := json.Marshal(contractReaderCfg) - require.NoError(t, err) - - contractReader, err := backendTH.NewContractReader(ctx, t, contractReaderCfgBytes) - require.NoError(t, err) - - err = contractReader.Bind(ctx, []types.BoundContract{{Name: contractName, Address: wfRegistryAddr.Hex()}}) - require.NoError(t, err) - // Seed the DB hash, err := crypto.Keccak256(append(backendTH.ContractsOwner.From[:], []byte(giveSecretsURL)...)) require.NoError(t, err) @@ -226,17 +194,23 @@ func Test_SecretsWorker(t *testing.T) { handler := syncer.NewEventHandler(lggr, orm, fetcherFn, nil, nil, emitter, clockwork.NewFakeClock(), workflowkey.Key{}) - worker := syncer.NewWorkflowRegistry(lggr, func(ctx context.Context, bytes []byte) (syncer.ContractReader, error) { - return contractReader, nil - }, wfRegistryAddr.Hex(), - syncer.WorkflowEventPollerConfig{ - QueryCount: 20, - }, handler, &testWorkflowRegistryContractLoader{}, &testDonNotifier{ + worker := syncer.NewWorkflowRegistry( + lggr, + func(ctx context.Context, bytes []byte) (syncer.ContractReader, error) { + return backendTH.NewContractReader(ctx, t, bytes) + }, + wfRegistryAddr.Hex(), + syncer.WorkflowEventPollerConfig{QueryCount: 20}, + handler, + &testWorkflowRegistryContractLoader{}, + &testDonNotifier{ don: capabilities.DON{ ID: donID, }, err: nil, - }, syncer.WithTicker(giveTicker.C)) + }, + syncer.WithTicker(giveTicker.C), + ) // setup contract state to allow the secrets to be updated updateAllowedDONs(t, backendTH, wfRegistryC, []uint32{donID}, true) @@ -257,6 +231,195 @@ func Test_SecretsWorker(t *testing.T) { }, 15*time.Second, time.Second) } +func Test_RegistrySyncer_WorkflowRegistered_InitiallyPaused(t *testing.T) { + var ( + ctx = coretestutils.Context(t) + lggr = logger.TestLogger(t) + emitter = custmsg.NewLabeler() + backendTH = testutils.NewEVMBackendTH(t) + db = pgtest.NewSqlxDB(t) + orm = syncer.NewWorkflowRegistryDS(db, lggr) + + giveTicker = time.NewTicker(500 * time.Millisecond) + giveBinaryURL = "https://original-url.com" + donID = uint32(1) + giveWorkflow = RegisterWorkflowCMD{ + Name: "test-wf", + DonID: donID, + Status: uint8(1), + BinaryURL: giveBinaryURL, + } + wantContents = "updated contents" + fetcherFn = func(_ context.Context, _ string) ([]byte, error) { + return []byte(base64.StdEncoding.EncodeToString([]byte(wantContents))), nil + } + ) + + defer giveTicker.Stop() + + // Deploy a test workflow_registry + wfRegistryAddr, _, wfRegistryC, err := workflow_registry_wrapper.DeployWorkflowRegistry(backendTH.ContractsOwner, backendTH.Backend.Client()) + backendTH.Backend.Commit() + require.NoError(t, err) + + from := [20]byte(backendTH.ContractsOwner.From) + id, err := workflows.GenerateWorkflowID(from[:], []byte(wantContents), []byte(""), "") + require.NoError(t, err) + giveWorkflow.ID = id + + er := syncer.NewEngineRegistry() + handler := syncer.NewEventHandler(lggr, orm, fetcherFn, nil, nil, + emitter, clockwork.NewFakeClock(), workflowkey.Key{}, syncer.WithEngineRegistry(er)) + + worker := syncer.NewWorkflowRegistry( + lggr, + func(ctx context.Context, bytes []byte) (syncer.ContractReader, error) { + return backendTH.NewContractReader(ctx, t, bytes) + }, + wfRegistryAddr.Hex(), + syncer.WorkflowEventPollerConfig{QueryCount: 20}, + handler, + &testWorkflowRegistryContractLoader{}, + &testDonNotifier{ + don: capabilities.DON{ + ID: donID, + }, + err: nil, + }, + syncer.WithTicker(giveTicker.C), + ) + + // setup contract state to allow the secrets to be updated + updateAllowedDONs(t, backendTH, wfRegistryC, []uint32{donID}, true) + updateAuthorizedAddress(t, backendTH, wfRegistryC, []common.Address{backendTH.ContractsOwner.From}, true) + + servicetest.Run(t, worker) + + // generate a log event + registerWorkflow(t, backendTH, wfRegistryC, giveWorkflow) + + // Require the secrets contents to eventually be updated + require.Eventually(t, func() bool { + _, err = er.Get("test-wf") + if err == nil { + return false + } + + owner := strings.ToLower(backendTH.ContractsOwner.From.Hex()[2:]) + _, err := orm.GetWorkflowSpec(ctx, owner, "test-wf") + return err == nil + }, 15*time.Second, time.Second) +} + +type mockService struct{} + +func (m *mockService) Start(context.Context) error { return nil } + +func (m *mockService) Close() error { return nil } + +func (m *mockService) HealthReport() map[string]error { return map[string]error{"svc": nil} } + +func (m *mockService) Ready() error { return nil } + +func (m *mockService) Name() string { return "svc" } + +type mockEngineFactory struct{} + +func (m *mockEngineFactory) new(ctx context.Context, wfid string, owner string, name string, config []byte, binary []byte) (services.Service, error) { + return &mockService{}, nil +} + +func Test_RegistrySyncer_WorkflowRegistered_InitiallyActivated(t *testing.T) { + var ( + ctx = coretestutils.Context(t) + lggr = logger.TestLogger(t) + emitter = custmsg.NewLabeler() + backendTH = testutils.NewEVMBackendTH(t) + db = pgtest.NewSqlxDB(t) + orm = syncer.NewWorkflowRegistryDS(db, lggr) + + giveTicker = time.NewTicker(500 * time.Millisecond) + giveBinaryURL = "https://original-url.com" + donID = uint32(1) + giveWorkflow = RegisterWorkflowCMD{ + Name: "test-wf", + DonID: donID, + Status: uint8(0), + BinaryURL: giveBinaryURL, + } + wantContents = "updated contents" + fetcherFn = func(_ context.Context, _ string) ([]byte, error) { + return []byte(base64.StdEncoding.EncodeToString([]byte(wantContents))), nil + } + ) + + defer giveTicker.Stop() + + // Deploy a test workflow_registry + wfRegistryAddr, _, wfRegistryC, err := workflow_registry_wrapper.DeployWorkflowRegistry(backendTH.ContractsOwner, backendTH.Backend.Client()) + backendTH.Backend.Commit() + require.NoError(t, err) + + from := [20]byte(backendTH.ContractsOwner.From) + id, err := workflows.GenerateWorkflowID(from[:], []byte(wantContents), []byte(""), "") + require.NoError(t, err) + giveWorkflow.ID = id + + mf := &mockEngineFactory{} + er := syncer.NewEngineRegistry() + handler := syncer.NewEventHandler( + lggr, + orm, + fetcherFn, + nil, + nil, + emitter, + clockwork.NewFakeClock(), + workflowkey.Key{}, + syncer.WithEngineRegistry(er), + syncer.WithEngineFactoryFn(mf.new), + ) + + worker := syncer.NewWorkflowRegistry( + lggr, + func(ctx context.Context, bytes []byte) (syncer.ContractReader, error) { + return backendTH.NewContractReader(ctx, t, bytes) + }, + wfRegistryAddr.Hex(), + syncer.WorkflowEventPollerConfig{QueryCount: 20}, + handler, + &testWorkflowRegistryContractLoader{}, + &testDonNotifier{ + don: capabilities.DON{ + ID: donID, + }, + err: nil, + }, + syncer.WithTicker(giveTicker.C), + ) + + // setup contract state to allow the secrets to be updated + updateAllowedDONs(t, backendTH, wfRegistryC, []uint32{donID}, true) + updateAuthorizedAddress(t, backendTH, wfRegistryC, []common.Address{backendTH.ContractsOwner.From}, true) + + servicetest.Run(t, worker) + + // generate a log event + registerWorkflow(t, backendTH, wfRegistryC, giveWorkflow) + + // Require the secrets contents to eventually be updated + require.Eventually(t, func() bool { + _, err := er.Get("test-wf") + if err != nil { + return err != nil + } + + owner := strings.ToLower(backendTH.ContractsOwner.From.Hex()[2:]) + _, err = orm.GetWorkflowSpec(ctx, owner, "test-wf") + return err == nil + }, 15*time.Second, time.Second) +} + func updateAuthorizedAddress( t *testing.T, th *testutils.EVMBackendTH, diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go index 11d2bdc3480..943802d1962 100644 --- a/core/services/workflows/engine.go +++ b/core/services/workflows/engine.go @@ -1179,6 +1179,14 @@ func (e *Engine) Close() error { }) } +func (e *Engine) HealthReport() map[string]error { + return map[string]error{e.Name(): nil} +} + +func (e *Engine) Name() string { + return e.logger.Name() +} + type Config struct { Workflow sdk.WorkflowSpec WorkflowID string diff --git a/core/services/workflows/syncer/contract_reader_mock.go b/core/services/workflows/syncer/contract_reader_mock.go index 391ba5eacdb..e6e7c8385f5 100644 --- a/core/services/workflows/syncer/contract_reader_mock.go +++ b/core/services/workflows/syncer/contract_reader_mock.go @@ -72,6 +72,51 @@ func (_c *MockContractReader_Bind_Call) RunAndReturn(run func(context.Context, [ return _c } +// Close provides a mock function with given fields: +func (_m *MockContractReader) Close() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Close") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockContractReader_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' +type MockContractReader_Close_Call struct { + *mock.Call +} + +// Close is a helper method to define mock.On call +func (_e *MockContractReader_Expecter) Close() *MockContractReader_Close_Call { + return &MockContractReader_Close_Call{Call: _e.mock.On("Close")} +} + +func (_c *MockContractReader_Close_Call) Run(run func()) *MockContractReader_Close_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockContractReader_Close_Call) Return(_a0 error) *MockContractReader_Close_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockContractReader_Close_Call) RunAndReturn(run func() error) *MockContractReader_Close_Call { + _c.Call.Return(run) + return _c +} + // GetLatestValueWithHeadData provides a mock function with given fields: ctx, readName, confidenceLevel, params, returnVal func (_m *MockContractReader) GetLatestValueWithHeadData(ctx context.Context, readName string, confidenceLevel primitives.ConfidenceLevel, params any, returnVal any) (*types.Head, error) { ret := _m.Called(ctx, readName, confidenceLevel, params, returnVal) @@ -196,6 +241,52 @@ func (_c *MockContractReader_QueryKey_Call) RunAndReturn(run func(context.Contex return _c } +// Start provides a mock function with given fields: ctx +func (_m *MockContractReader) Start(ctx context.Context) error { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for Start") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(ctx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockContractReader_Start_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Start' +type MockContractReader_Start_Call struct { + *mock.Call +} + +// Start is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockContractReader_Expecter) Start(ctx interface{}) *MockContractReader_Start_Call { + return &MockContractReader_Start_Call{Call: _e.mock.On("Start", ctx)} +} + +func (_c *MockContractReader_Start_Call) Run(run func(ctx context.Context)) *MockContractReader_Start_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *MockContractReader_Start_Call) Return(_a0 error) *MockContractReader_Start_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockContractReader_Start_Call) RunAndReturn(run func(context.Context) error) *MockContractReader_Start_Call { + _c.Call.Return(run) + return _c +} + // NewMockContractReader creates a new instance of MockContractReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewMockContractReader(t interface { diff --git a/core/services/workflows/syncer/engine_registry.go b/core/services/workflows/syncer/engine_registry.go index 809381c191c..fa3771c5a0f 100644 --- a/core/services/workflows/syncer/engine_registry.go +++ b/core/services/workflows/syncer/engine_registry.go @@ -4,29 +4,29 @@ import ( "errors" "sync" - "github.com/smartcontractkit/chainlink/v2/core/services/workflows" + "github.com/smartcontractkit/chainlink-common/pkg/services" ) -type engineRegistry struct { - engines map[string]*workflows.Engine +type EngineRegistry struct { + engines map[string]services.Service mu sync.RWMutex } -func newEngineRegistry() *engineRegistry { - return &engineRegistry{ - engines: make(map[string]*workflows.Engine), +func NewEngineRegistry() *EngineRegistry { + return &EngineRegistry{ + engines: make(map[string]services.Service), } } // Add adds an engine to the registry. -func (r *engineRegistry) Add(id string, engine *workflows.Engine) { +func (r *EngineRegistry) Add(id string, engine services.Service) { r.mu.Lock() defer r.mu.Unlock() r.engines[id] = engine } // Get retrieves an engine from the registry. -func (r *engineRegistry) Get(id string) (*workflows.Engine, error) { +func (r *EngineRegistry) Get(id string) (services.Service, error) { r.mu.RLock() defer r.mu.RUnlock() engine, found := r.engines[id] @@ -37,7 +37,7 @@ func (r *engineRegistry) Get(id string) (*workflows.Engine, error) { } // IsRunning is true if the engine exists and is ready. -func (r *engineRegistry) IsRunning(id string) bool { +func (r *EngineRegistry) IsRunning(id string) bool { r.mu.RLock() defer r.mu.RUnlock() engine, found := r.engines[id] @@ -49,7 +49,7 @@ func (r *engineRegistry) IsRunning(id string) bool { } // Pop removes an engine from the registry and returns the engine if found. -func (r *engineRegistry) Pop(id string) (*workflows.Engine, error) { +func (r *EngineRegistry) Pop(id string) (services.Service, error) { r.mu.Lock() defer r.mu.Unlock() engine, ok := r.engines[id] @@ -61,7 +61,7 @@ func (r *engineRegistry) Pop(id string) (*workflows.Engine, error) { } // Close closes all engines in the registry. -func (r *engineRegistry) Close() error { +func (r *EngineRegistry) Close() error { r.mu.Lock() defer r.mu.Unlock() var err error diff --git a/core/services/workflows/syncer/handler.go b/core/services/workflows/syncer/handler.go index 077dbc0cedb..1b8012145ea 100644 --- a/core/services/workflows/syncer/handler.go +++ b/core/services/workflows/syncer/handler.go @@ -3,6 +3,7 @@ package syncer import ( "bytes" "context" + "encoding/base64" "encoding/hex" "encoding/json" "errors" @@ -13,6 +14,7 @@ import ( "github.com/jonboulle/clockwork" "github.com/smartcontractkit/chainlink-common/pkg/custmsg" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types/core" pkgworkflows "github.com/smartcontractkit/chainlink-common/pkg/workflows" "github.com/smartcontractkit/chainlink-common/pkg/workflows/secrets" @@ -59,14 +61,14 @@ type WorkflowRegistryForceUpdateSecretsRequestedV1 struct { } type WorkflowRegistryWorkflowRegisteredV1 struct { - WorkflowID [32]byte - Owner []byte - DonID uint32 - Status uint8 - WorkflowName string - BinaryURL string - ConfigURL string - SecretsURL string + WorkflowID [32]byte + WorkflowOwner []byte + DonID uint32 + Status uint8 + WorkflowName string + BinaryURL string + ConfigURL string + SecretsURL string } type WorkflowRegistryWorkflowUpdatedV1 struct { @@ -125,6 +127,8 @@ func newLastFetchedAtMap() *lastFetchedAtMap { } } +type engineFactoryFn func(ctx context.Context, wfid string, owner string, name string, config []byte, binary []byte) (services.Service, error) + // eventHandler is a handler for WorkflowRegistryEvent events. Each event type has a corresponding // method that handles the event. type eventHandler struct { @@ -133,12 +137,13 @@ type eventHandler struct { fetcher FetcherFunc workflowStore store.Store capRegistry core.CapabilitiesRegistry - engineRegistry *engineRegistry + engineRegistry *EngineRegistry emitter custmsg.MessageEmitter lastFetchedAtMap *lastFetchedAtMap clock clockwork.Clock secretsFreshnessDuration time.Duration encryptionKey workflowkey.Key + engineFactory engineFactoryFn } type Event interface { @@ -148,6 +153,18 @@ type Event interface { var defaultSecretsFreshnessDuration = 24 * time.Hour +func WithEngineRegistry(er *EngineRegistry) func(*eventHandler) { + return func(e *eventHandler) { + e.engineRegistry = er + } +} + +func WithEngineFactoryFn(efn engineFactoryFn) func(*eventHandler) { + return func(e *eventHandler) { + e.engineFactory = efn + } +} + // NewEventHandler returns a new eventHandler instance. func NewEventHandler( lggr logger.Logger, @@ -158,20 +175,26 @@ func NewEventHandler( emitter custmsg.MessageEmitter, clock clockwork.Clock, encryptionKey workflowkey.Key, + opts ...func(*eventHandler), ) *eventHandler { - return &eventHandler{ + eh := &eventHandler{ lggr: lggr, orm: orm, fetcher: gateway, workflowStore: workflowStore, capRegistry: capRegistry, - engineRegistry: newEngineRegistry(), + engineRegistry: NewEngineRegistry(), emitter: emitter, lastFetchedAtMap: newLastFetchedAtMap(), clock: clock, secretsFreshnessDuration: defaultSecretsFreshnessDuration, encryptionKey: encryptionKey, } + eh.engineFactory = eh.engineFactoryFn + for _, o := range opts { + o(eh) + } + return eh } func (h *eventHandler) refreshSecrets(ctx context.Context, workflowOwner, workflowName, workflowID, secretsURLHash string) (string, error) { @@ -276,7 +299,7 @@ func (h *eventHandler) Handle(ctx context.Context, event Event) error { cma := h.emitter.With( platform.KeyWorkflowID, wfID, platform.KeyWorkflowName, payload.WorkflowName, - platform.KeyWorkflowOwner, hex.EncodeToString(payload.Owner), + platform.KeyWorkflowOwner, hex.EncodeToString(payload.WorkflowOwner), ) if err := h.workflowRegisteredEvent(ctx, payload); err != nil { @@ -383,6 +406,11 @@ func (h *eventHandler) workflowRegisteredEvent( return fmt.Errorf("failed to fetch binary from %s : %w", payload.BinaryURL, err) } + decodedBinary, err := base64.StdEncoding.DecodeString(string(binary)) + if err != nil { + return fmt.Errorf("failed to decode binary: %w", err) + } + var config []byte if payload.ConfigURL != "" { config, err = h.fetcher(ctx, payload.ConfigURL) @@ -400,7 +428,7 @@ func (h *eventHandler) workflowRegisteredEvent( } // Calculate the hash of the binary and config files - hash, err := pkgworkflows.GenerateWorkflowID(payload.Owner, binary, config, payload.SecretsURL) + hash, err := pkgworkflows.GenerateWorkflowID(payload.WorkflowOwner, decodedBinary, config, payload.SecretsURL) if err != nil { return fmt.Errorf("failed to generate workflow id: %w", err) } @@ -411,7 +439,7 @@ func (h *eventHandler) workflowRegisteredEvent( } // Save the workflow secrets - urlHash, err := h.orm.GetSecretsURLHash(payload.Owner, []byte(payload.SecretsURL)) + urlHash, err := h.orm.GetSecretsURLHash(payload.WorkflowOwner, []byte(payload.SecretsURL)) if err != nil { return fmt.Errorf("failed to get secrets URL hash: %w", err) } @@ -424,11 +452,11 @@ func (h *eventHandler) workflowRegisteredEvent( wfID := hex.EncodeToString(payload.WorkflowID[:]) entry := &job.WorkflowSpec{ - Workflow: hex.EncodeToString(binary), + Workflow: hex.EncodeToString(decodedBinary), Config: string(config), WorkflowID: wfID, Status: status, - WorkflowOwner: hex.EncodeToString(payload.Owner), + WorkflowOwner: hex.EncodeToString(payload.WorkflowOwner), WorkflowName: payload.WorkflowName, SpecType: job.WASMFile, BinaryURL: payload.BinaryURL, @@ -444,36 +472,47 @@ func (h *eventHandler) workflowRegisteredEvent( } // If status == active, start a new WorkflowEngine instance, and add it to local engine registry + engine, err := h.engineFactory( + ctx, + wfID, + string(payload.WorkflowOwner), + payload.WorkflowName, + config, + decodedBinary, + ) + if err != nil { + return fmt.Errorf("failed to create workflow engine: %w", err) + } + + if err := engine.Start(ctx); err != nil { + return fmt.Errorf("failed to start workflow engine: %w", err) + } + + h.engineRegistry.Add(wfID, engine) + + return nil +} + +func (h *eventHandler) engineFactoryFn(ctx context.Context, id string, owner string, name string, config []byte, binary []byte) (services.Service, error) { moduleConfig := &host.ModuleConfig{Logger: h.lggr, Labeler: h.emitter} sdkSpec, err := host.GetWorkflowSpec(ctx, moduleConfig, binary, config) if err != nil { - return fmt.Errorf("failed to get workflow sdk spec: %w", err) + return nil, fmt.Errorf("failed to get workflow sdk spec: %w", err) } cfg := workflows.Config{ Lggr: h.lggr, Workflow: *sdkSpec, - WorkflowID: wfID, - WorkflowOwner: string(payload.Owner), // this gets hex encoded in the engine. - WorkflowName: payload.WorkflowName, + WorkflowID: id, + WorkflowOwner: owner, // this gets hex encoded in the engine. + WorkflowName: name, Registry: h.capRegistry, Store: h.workflowStore, Config: config, Binary: binary, SecretsFetcher: h, } - e, err := workflows.NewEngine(ctx, cfg) - if err != nil { - return fmt.Errorf("failed to create workflow engine: %w", err) - } - - if err := e.Start(ctx); err != nil { - return fmt.Errorf("failed to start workflow engine: %w", err) - } - - h.engineRegistry.Add(wfID, e) - - return nil + return workflows.NewEngine(ctx, cfg) } // workflowUpdatedEvent handles the WorkflowUpdatedEvent event type by first finding the @@ -489,14 +528,14 @@ func (h *eventHandler) workflowUpdatedEvent( } registeredEvent := WorkflowRegistryWorkflowRegisteredV1{ - WorkflowID: payload.NewWorkflowID, - Owner: payload.WorkflowOwner, - DonID: payload.DonID, - Status: 0, - WorkflowName: payload.WorkflowName, - BinaryURL: payload.BinaryURL, - ConfigURL: payload.ConfigURL, - SecretsURL: payload.SecretsURL, + WorkflowID: payload.NewWorkflowID, + WorkflowOwner: payload.WorkflowOwner, + DonID: payload.DonID, + Status: 0, + WorkflowName: payload.WorkflowName, + BinaryURL: payload.BinaryURL, + ConfigURL: payload.ConfigURL, + SecretsURL: payload.SecretsURL, } return h.workflowRegisteredEvent(ctx, registeredEvent) @@ -551,14 +590,14 @@ func (h *eventHandler) workflowActivatedEvent( // start a new workflow engine registeredEvent := WorkflowRegistryWorkflowRegisteredV1{ - WorkflowID: payload.WorkflowID, - Owner: payload.WorkflowOwner, - DonID: payload.DonID, - Status: 0, - WorkflowName: payload.WorkflowName, - BinaryURL: spec.BinaryURL, - ConfigURL: spec.ConfigURL, - SecretsURL: secretsURL, + WorkflowID: payload.WorkflowID, + WorkflowOwner: payload.WorkflowOwner, + DonID: payload.DonID, + Status: 0, + WorkflowName: payload.WorkflowName, + BinaryURL: spec.BinaryURL, + ConfigURL: spec.ConfigURL, + SecretsURL: secretsURL, } return h.workflowRegisteredEvent(ctx, registeredEvent) diff --git a/core/services/workflows/syncer/handler_test.go b/core/services/workflows/syncer/handler_test.go index 7d11d347a02..8b0afab5b4a 100644 --- a/core/services/workflows/syncer/handler_test.go +++ b/core/services/workflows/syncer/handler_test.go @@ -3,6 +3,7 @@ package syncer import ( "context" "database/sql" + "encoding/base64" "encoding/hex" "encoding/json" "errors" @@ -179,6 +180,7 @@ func Test_workflowRegisteredHandler(t *testing.T) { var config = []byte("") var wfOwner = []byte("0xOwner") var binary = wasmtest.CreateTestBinary(binaryCmd, binaryLocation, true, t) + var encodedBinary = []byte(base64.StdEncoding.EncodeToString(binary)) defaultValidationFn := func(t *testing.T, ctx context.Context, h *eventHandler, wfOwner []byte, wfName string, wfID string) { // Verify the record is updated in the database dbSpec, err := h.orm.GetWorkflowSpec(ctx, hex.EncodeToString(wfOwner), "workflow-name") @@ -198,7 +200,7 @@ func Test_workflowRegisteredHandler(t *testing.T) { { Name: "success with active workflow registered", fetcher: newMockFetcher(map[string]mockFetchResp{ - binaryURL: {Body: binary, Err: nil}, + binaryURL: {Body: encodedBinary, Err: nil}, configURL: {Body: config, Err: nil}, secretsURL: {Body: []byte("secrets"), Err: nil}, }), @@ -210,13 +212,13 @@ func Test_workflowRegisteredHandler(t *testing.T) { WFOwner: wfOwner, Event: func(wfID []byte) WorkflowRegistryWorkflowRegisteredV1 { return WorkflowRegistryWorkflowRegisteredV1{ - Status: uint8(0), - WorkflowID: [32]byte(wfID), - Owner: wfOwner, - WorkflowName: "workflow-name", - BinaryURL: binaryURL, - ConfigURL: configURL, - SecretsURL: secretsURL, + Status: uint8(0), + WorkflowID: [32]byte(wfID), + WorkflowOwner: wfOwner, + WorkflowName: "workflow-name", + BinaryURL: binaryURL, + ConfigURL: configURL, + SecretsURL: secretsURL, } }, validationFn: defaultValidationFn, @@ -224,7 +226,7 @@ func Test_workflowRegisteredHandler(t *testing.T) { { Name: "success with paused workflow registered", fetcher: newMockFetcher(map[string]mockFetchResp{ - binaryURL: {Body: binary, Err: nil}, + binaryURL: {Body: encodedBinary, Err: nil}, configURL: {Body: config, Err: nil}, secretsURL: {Body: []byte("secrets"), Err: nil}, }), @@ -236,13 +238,13 @@ func Test_workflowRegisteredHandler(t *testing.T) { WFOwner: wfOwner, Event: func(wfID []byte) WorkflowRegistryWorkflowRegisteredV1 { return WorkflowRegistryWorkflowRegisteredV1{ - Status: uint8(1), - WorkflowID: [32]byte(wfID), - Owner: wfOwner, - WorkflowName: "workflow-name", - BinaryURL: binaryURL, - ConfigURL: configURL, - SecretsURL: secretsURL, + Status: uint8(1), + WorkflowID: [32]byte(wfID), + WorkflowOwner: wfOwner, + WorkflowName: "workflow-name", + BinaryURL: binaryURL, + ConfigURL: configURL, + SecretsURL: secretsURL, } }, validationFn: func(t *testing.T, ctx context.Context, h *eventHandler, wfOwner []byte, wfName string, wfID string) { @@ -267,18 +269,18 @@ func Test_workflowRegisteredHandler(t *testing.T) { GiveBinary: binary, WFOwner: wfOwner, fetcher: newMockFetcher(map[string]mockFetchResp{ - binaryURL: {Body: binary, Err: nil}, + binaryURL: {Body: encodedBinary, Err: nil}, secretsURL: {Body: []byte("secrets"), Err: nil}, }), validationFn: defaultValidationFn, Event: func(wfID []byte) WorkflowRegistryWorkflowRegisteredV1 { return WorkflowRegistryWorkflowRegisteredV1{ - Status: uint8(0), - WorkflowID: [32]byte(wfID), - Owner: wfOwner, - WorkflowName: "workflow-name", - BinaryURL: binaryURL, - SecretsURL: secretsURL, + Status: uint8(0), + WorkflowID: [32]byte(wfID), + WorkflowOwner: wfOwner, + WorkflowName: "workflow-name", + BinaryURL: binaryURL, + SecretsURL: secretsURL, } }, }, @@ -290,18 +292,18 @@ func Test_workflowRegisteredHandler(t *testing.T) { GiveBinary: binary, WFOwner: wfOwner, fetcher: newMockFetcher(map[string]mockFetchResp{ - binaryURL: {Body: binary, Err: nil}, + binaryURL: {Body: encodedBinary, Err: nil}, configURL: {Body: config, Err: nil}, }), validationFn: defaultValidationFn, Event: func(wfID []byte) WorkflowRegistryWorkflowRegisteredV1 { return WorkflowRegistryWorkflowRegisteredV1{ - Status: uint8(0), - WorkflowID: [32]byte(wfID), - Owner: wfOwner, - WorkflowName: "workflow-name", - BinaryURL: binaryURL, - ConfigURL: configURL, + Status: uint8(0), + WorkflowID: [32]byte(wfID), + WorkflowOwner: wfOwner, + WorkflowName: "workflow-name", + BinaryURL: binaryURL, + ConfigURL: configURL, } }, }, @@ -350,19 +352,21 @@ func testRunningWorkflow(t *testing.T, cmd testCase) { event := cmd.Event(giveWFID[:]) - er := newEngineRegistry() + er := NewEngineRegistry() store := wfstore.NewDBStore(db, lggr, clockwork.NewFakeClock()) registry := capabilities.NewRegistry(lggr) registry.SetLocalRegistry(&capabilities.TestMetadataRegistry{}) - h := &eventHandler{ - lggr: lggr, - orm: orm, - fetcher: fetcher, - emitter: emitter, - engineRegistry: er, - capRegistry: registry, - workflowStore: store, - } + h := NewEventHandler( + lggr, + orm, + fetcher, + store, + registry, + emitter, + clockwork.NewFakeClock(), + workflowkey.Key{}, + WithEngineRegistry(er), + ) err = h.workflowRegisteredEvent(ctx, event) require.NoError(t, err) @@ -379,15 +383,16 @@ func Test_workflowDeletedHandler(t *testing.T) { orm = NewWorkflowRegistryDS(db, lggr) emitter = custmsg.NewLabeler() - binary = wasmtest.CreateTestBinary(binaryCmd, binaryLocation, true, t) - config = []byte("") - secretsURL = "http://example.com" - binaryURL = "http://example.com/binary" - configURL = "http://example.com/config" - wfOwner = []byte("0xOwner") + binary = wasmtest.CreateTestBinary(binaryCmd, binaryLocation, true, t) + encodedBinary = []byte(base64.StdEncoding.EncodeToString(binary)) + config = []byte("") + secretsURL = "http://example.com" + binaryURL = "http://example.com/binary" + configURL = "http://example.com/config" + wfOwner = []byte("0xOwner") fetcher = newMockFetcher(map[string]mockFetchResp{ - binaryURL: {Body: binary, Err: nil}, + binaryURL: {Body: encodedBinary, Err: nil}, configURL: {Body: config, Err: nil}, secretsURL: {Body: []byte("secrets"), Err: nil}, }) @@ -399,28 +404,30 @@ func Test_workflowDeletedHandler(t *testing.T) { wfIDs := hex.EncodeToString(giveWFID[:]) active := WorkflowRegistryWorkflowRegisteredV1{ - Status: uint8(0), - WorkflowID: giveWFID, - Owner: wfOwner, - WorkflowName: "workflow-name", - BinaryURL: binaryURL, - ConfigURL: configURL, - SecretsURL: secretsURL, + Status: uint8(0), + WorkflowID: giveWFID, + WorkflowOwner: wfOwner, + WorkflowName: "workflow-name", + BinaryURL: binaryURL, + ConfigURL: configURL, + SecretsURL: secretsURL, } - er := newEngineRegistry() + er := NewEngineRegistry() store := wfstore.NewDBStore(db, lggr, clockwork.NewFakeClock()) registry := capabilities.NewRegistry(lggr) registry.SetLocalRegistry(&capabilities.TestMetadataRegistry{}) - h := &eventHandler{ - lggr: lggr, - orm: orm, - fetcher: fetcher, - emitter: emitter, - engineRegistry: er, - capRegistry: registry, - workflowStore: store, - } + h := NewEventHandler( + lggr, + orm, + fetcher, + store, + registry, + emitter, + clockwork.NewFakeClock(), + workflowkey.Key{}, + WithEngineRegistry(er), + ) err = h.workflowRegisteredEvent(ctx, active) require.NoError(t, err) @@ -465,17 +472,18 @@ func Test_workflowPausedActivatedUpdatedHandler(t *testing.T) { orm = NewWorkflowRegistryDS(db, lggr) emitter = custmsg.NewLabeler() - binary = wasmtest.CreateTestBinary(binaryCmd, binaryLocation, true, t) - config = []byte("") - updateConfig = []byte("updated") - secretsURL = "http://example.com" - binaryURL = "http://example.com/binary" - configURL = "http://example.com/config" - newConfigURL = "http://example.com/new-config" - wfOwner = []byte("0xOwner") + binary = wasmtest.CreateTestBinary(binaryCmd, binaryLocation, true, t) + encodedBinary = []byte(base64.StdEncoding.EncodeToString(binary)) + config = []byte("") + updateConfig = []byte("updated") + secretsURL = "http://example.com" + binaryURL = "http://example.com/binary" + configURL = "http://example.com/config" + newConfigURL = "http://example.com/new-config" + wfOwner = []byte("0xOwner") fetcher = newMockFetcher(map[string]mockFetchResp{ - binaryURL: {Body: binary, Err: nil}, + binaryURL: {Body: encodedBinary, Err: nil}, configURL: {Body: config, Err: nil}, newConfigURL: {Body: updateConfig, Err: nil}, secretsURL: {Body: []byte("secrets"), Err: nil}, @@ -494,28 +502,30 @@ func Test_workflowPausedActivatedUpdatedHandler(t *testing.T) { newWFIDs := hex.EncodeToString(updatedWFID[:]) active := WorkflowRegistryWorkflowRegisteredV1{ - Status: uint8(0), - WorkflowID: giveWFID, - Owner: wfOwner, - WorkflowName: "workflow-name", - BinaryURL: binaryURL, - ConfigURL: configURL, - SecretsURL: secretsURL, + Status: uint8(0), + WorkflowID: giveWFID, + WorkflowOwner: wfOwner, + WorkflowName: "workflow-name", + BinaryURL: binaryURL, + ConfigURL: configURL, + SecretsURL: secretsURL, } - er := newEngineRegistry() + er := NewEngineRegistry() store := wfstore.NewDBStore(db, lggr, clockwork.NewFakeClock()) registry := capabilities.NewRegistry(lggr) registry.SetLocalRegistry(&capabilities.TestMetadataRegistry{}) - h := &eventHandler{ - lggr: lggr, - orm: orm, - fetcher: fetcher, - emitter: emitter, - engineRegistry: er, - capRegistry: registry, - workflowStore: store, - } + h := NewEventHandler( + lggr, + orm, + fetcher, + store, + registry, + emitter, + clockwork.NewFakeClock(), + workflowkey.Key{}, + WithEngineRegistry(er), + ) err = h.workflowRegisteredEvent(ctx, active) require.NoError(t, err) diff --git a/core/services/workflows/syncer/workflow_registry.go b/core/services/workflows/syncer/workflow_registry.go index 024975539af..75fcc9735ad 100644 --- a/core/services/workflows/syncer/workflow_registry.go +++ b/core/services/workflows/syncer/workflow_registry.go @@ -39,8 +39,19 @@ type GetWorkflowMetadataListByDONParams struct { Limit uint64 } +type GetWorkflowMetadata struct { + WorkflowID [32]byte + Owner []byte + DonID uint32 + Status uint8 + WorkflowName string + BinaryURL string + ConfigURL string + SecretsURL string +} + type GetWorkflowMetadataListByDONReturnVal struct { - WorkflowMetadataList []WorkflowRegistryWorkflowRegisteredV1 + WorkflowMetadataList []GetWorkflowMetadata } // WorkflowRegistryEvent is an event emitted by the WorkflowRegistry. Each event is typed @@ -85,6 +96,8 @@ type ContractReaderFactory interface { // ContractReader is a subset of types.ContractReader defined locally to enable mocking. type ContractReader interface { + Start(ctx context.Context) error + Close() error Bind(context.Context, []types.BoundContract) error QueryKey(context.Context, types.BoundContract, query.KeyFilter, query.LimitAndSort, any) ([]types.Sequence, error) GetLatestValueWithHeadData(ctx context.Context, readName string, confidenceLevel primitives.ConfidenceLevel, params any, returnVal any) (head *types.Head, err error) @@ -171,7 +184,14 @@ func NewWorkflowRegistry( workflowDonNotifier donNotifier, opts ...func(*workflowRegistry), ) *workflowRegistry { - ets := []WorkflowRegistryEventType{ForceUpdateSecretsEvent} + ets := []WorkflowRegistryEventType{ + ForceUpdateSecretsEvent, + WorkflowActivatedEvent, + WorkflowDeletedEvent, + WorkflowPausedEvent, + WorkflowRegisteredEvent, + WorkflowUpdatedEvent, + } wr := &workflowRegistry{ lggr: lggr, newContractReaderFn: newContractReaderFn, @@ -207,14 +227,14 @@ func (w *workflowRegistry) Start(_ context.Context) error { w.lggr.Debugw("Waiting for DON...") don, err := w.workflowDonNotifier.WaitForDon(ctx) if err != nil { - w.lggr.Errorf("failed to wait for don: %v", err) + w.lggr.Errorw("failed to wait for don", "err", err) return } w.lggr.Debugw("Loading initial workflows for DON", "DON", don.ID) loadWorkflowsHead, err := w.initialWorkflowsStateLoader.LoadWorkflows(ctx, don) if err != nil { - w.lggr.Errorf("failed to load workflows: %v", err) + w.lggr.Errorw("failed to load workflows", "err", err) return } @@ -265,14 +285,14 @@ func (w *workflowRegistry) handlerLoop(ctx context.Context) { } if resp.Err != nil || resp.Event == nil { - w.lggr.Errorf("failed to handle event: %+v", resp.Err) + w.lggr.Errorw("failed to handle event", "err", resp.Err) continue } event := resp.Event w.lggr.Debugf("handling event: %+v", event) if err := w.handler.Handle(ctx, *event); err != nil { - w.lggr.Errorf("failed to handle event: %+v", event) + w.lggr.Errorw("failed to handle event", "event", event, "err", err) continue } } @@ -438,10 +458,9 @@ func queryEvent( ) { // create query var ( - responseBatch []WorkflowRegistryEventResponse - logData values.Value - cursor = "" - limitAndSort = query.LimitAndSort{ + logData values.Value + cursor = "" + limitAndSort = query.LimitAndSort{ SortBy: []query.SortBy{query.NewSortByTimestamp(query.Asc)}, Limit: query.Limit{Count: cfg.QueryCount}, } @@ -457,6 +476,8 @@ func queryEvent( case <-ctx.Done(): return case <-ticker: + responseBatch := []WorkflowRegistryEventResponse{} + if cursor != "" { limitAndSort.Limit = query.CursorLimit(cursor, query.CursorFollowing, cfg.QueryCount) } @@ -468,12 +489,17 @@ func queryEvent( Key: string(et), Expressions: []query.Expression{ query.Confidence(primitives.Finalized), - query.Block(lastReadBlockNumber, primitives.Gt), + query.Block(lastReadBlockNumber, primitives.Gte), }, }, limitAndSort, &logData, ) + lcursor := cursor + if lcursor == "" { + lcursor = "empty" + } + lggr.Debugw("QueryKeys called", "logs", len(logs), "eventType", et, "lastReadBlockNumber", lastReadBlockNumber, "logCursor", lcursor) if err != nil { lggr.Errorw("QueryKey failure", "err", err) @@ -511,7 +537,14 @@ func getWorkflowRegistryEventReader( Contracts: map[string]evmtypes.ChainContractReader{ WorkflowRegistryContractName: { ContractPollingFilter: evmtypes.ContractPollingFilter{ - GenericEventNames: []string{string(ForceUpdateSecretsEvent)}, + GenericEventNames: []string{ + string(ForceUpdateSecretsEvent), + string(WorkflowActivatedEvent), + string(WorkflowDeletedEvent), + string(WorkflowPausedEvent), + string(WorkflowRegisteredEvent), + string(WorkflowUpdatedEvent), + }, }, ContractABI: workflow_registry_wrapper.WorkflowRegistryABI, Configs: map[string]*evmtypes.ChainReaderDefinition{ @@ -519,6 +552,26 @@ func getWorkflowRegistryEventReader( ChainSpecificName: string(ForceUpdateSecretsEvent), ReadType: evmtypes.Event, }, + string(WorkflowActivatedEvent): { + ChainSpecificName: string(WorkflowActivatedEvent), + ReadType: evmtypes.Event, + }, + string(WorkflowDeletedEvent): { + ChainSpecificName: string(WorkflowDeletedEvent), + ReadType: evmtypes.Event, + }, + string(WorkflowPausedEvent): { + ChainSpecificName: string(WorkflowPausedEvent), + ReadType: evmtypes.Event, + }, + string(WorkflowRegisteredEvent): { + ChainSpecificName: string(WorkflowRegisteredEvent), + ReadType: evmtypes.Event, + }, + string(WorkflowUpdatedEvent): { + ChainSpecificName: string(WorkflowUpdatedEvent), + ReadType: evmtypes.Event, + }, }, }, }, @@ -539,6 +592,10 @@ func getWorkflowRegistryEventReader( return nil, err } + if err := reader.Start(ctx); err != nil { + return nil, err + } + return reader, nil } @@ -629,8 +686,18 @@ func (l *workflowRegistryContractLoader) LoadWorkflows(ctx context.Context, don l.lggr.Debugw("Rehydrating existing workflows", "len", len(workflows.WorkflowMetadataList)) for _, workflow := range workflows.WorkflowMetadataList { + toRegisteredEvent := WorkflowRegistryWorkflowRegisteredV1{ + WorkflowID: workflow.WorkflowID, + WorkflowOwner: workflow.Owner, + DonID: workflow.DonID, + Status: workflow.Status, + WorkflowName: workflow.WorkflowName, + BinaryURL: workflow.BinaryURL, + ConfigURL: workflow.ConfigURL, + SecretsURL: workflow.SecretsURL, + } if err = l.handler.Handle(ctx, workflowAsEvent{ - Data: workflow, + Data: toRegisteredEvent, EventType: WorkflowRegisteredEvent, }); err != nil { l.lggr.Errorf("failed to handle workflow registration: %s", err) @@ -682,6 +749,51 @@ func toWorkflowRegistryEventResponse( return resp } resp.Event.Data = data + case WorkflowRegisteredEvent: + var data WorkflowRegistryWorkflowRegisteredV1 + if err := dataAsValuesMap.UnwrapTo(&data); err != nil { + lggr.Errorf("failed to unwrap data: %+v", log.Data) + resp.Event = nil + resp.Err = err + return resp + } + resp.Event.Data = data + case WorkflowUpdatedEvent: + var data WorkflowRegistryWorkflowUpdatedV1 + if err := dataAsValuesMap.UnwrapTo(&data); err != nil { + lggr.Errorf("failed to unwrap data: %+v", log.Data) + resp.Event = nil + resp.Err = err + return resp + } + resp.Event.Data = data + case WorkflowPausedEvent: + var data WorkflowRegistryWorkflowPausedV1 + if err := dataAsValuesMap.UnwrapTo(&data); err != nil { + lggr.Errorf("failed to unwrap data: %+v", log.Data) + resp.Event = nil + resp.Err = err + return resp + } + resp.Event.Data = data + case WorkflowActivatedEvent: + var data WorkflowRegistryWorkflowActivatedV1 + if err := dataAsValuesMap.UnwrapTo(&data); err != nil { + lggr.Errorf("failed to unwrap data: %+v", log.Data) + resp.Event = nil + resp.Err = err + return resp + } + resp.Event.Data = data + case WorkflowDeletedEvent: + var data WorkflowRegistryWorkflowDeletedV1 + if err := dataAsValuesMap.UnwrapTo(&data); err != nil { + lggr.Errorf("failed to unwrap data: %+v", log.Data) + resp.Event = nil + resp.Err = err + return resp + } + resp.Event.Data = data default: lggr.Errorf("unknown event type: %s", evt) resp.Event = nil diff --git a/core/services/workflows/syncer/workflow_registry_test.go b/core/services/workflows/syncer/workflow_registry_test.go index 8a7c3bb0a7c..621d3d123d5 100644 --- a/core/services/workflows/syncer/workflow_registry_test.go +++ b/core/services/workflows/syncer/workflow_registry_test.go @@ -109,7 +109,7 @@ func Test_Workflow_Registry_Syncer(t *testing.T) { Key: string(ForceUpdateSecretsEvent), Expressions: []query.Expression{ query.Confidence(primitives.Finalized), - query.Block("0", primitives.Gt), + query.Block("0", primitives.Gte), }, }, query.LimitAndSort{ @@ -118,9 +118,105 @@ func Test_Workflow_Registry_Syncer(t *testing.T) { }, new(values.Value), ).Return([]types.Sequence{giveLog}, nil) + reader.EXPECT().QueryKey( + matches.AnyContext, + types.BoundContract{ + Name: WorkflowRegistryContractName, + Address: contractAddress, + }, + query.KeyFilter{ + Key: string(WorkflowPausedEvent), + Expressions: []query.Expression{ + query.Confidence(primitives.Finalized), + query.Block("0", primitives.Gte), + }, + }, + query.LimitAndSort{ + SortBy: []query.SortBy{query.NewSortByTimestamp(query.Asc)}, + Limit: query.Limit{Count: giveCfg.QueryCount}, + }, + new(values.Value), + ).Return([]types.Sequence{}, nil) + reader.EXPECT().QueryKey( + matches.AnyContext, + types.BoundContract{ + Name: WorkflowRegistryContractName, + Address: contractAddress, + }, + query.KeyFilter{ + Key: string(WorkflowDeletedEvent), + Expressions: []query.Expression{ + query.Confidence(primitives.Finalized), + query.Block("0", primitives.Gte), + }, + }, + query.LimitAndSort{ + SortBy: []query.SortBy{query.NewSortByTimestamp(query.Asc)}, + Limit: query.Limit{Count: giveCfg.QueryCount}, + }, + new(values.Value), + ).Return([]types.Sequence{}, nil) + reader.EXPECT().QueryKey( + matches.AnyContext, + types.BoundContract{ + Name: WorkflowRegistryContractName, + Address: contractAddress, + }, + query.KeyFilter{ + Key: string(WorkflowActivatedEvent), + Expressions: []query.Expression{ + query.Confidence(primitives.Finalized), + query.Block("0", primitives.Gte), + }, + }, + query.LimitAndSort{ + SortBy: []query.SortBy{query.NewSortByTimestamp(query.Asc)}, + Limit: query.Limit{Count: giveCfg.QueryCount}, + }, + new(values.Value), + ).Return([]types.Sequence{}, nil) + reader.EXPECT().QueryKey( + matches.AnyContext, + types.BoundContract{ + Name: WorkflowRegistryContractName, + Address: contractAddress, + }, + query.KeyFilter{ + Key: string(WorkflowUpdatedEvent), + Expressions: []query.Expression{ + query.Confidence(primitives.Finalized), + query.Block("0", primitives.Gte), + }, + }, + query.LimitAndSort{ + SortBy: []query.SortBy{query.NewSortByTimestamp(query.Asc)}, + Limit: query.Limit{Count: giveCfg.QueryCount}, + }, + new(values.Value), + ).Return([]types.Sequence{}, nil) + reader.EXPECT().QueryKey( + matches.AnyContext, + types.BoundContract{ + Name: WorkflowRegistryContractName, + Address: contractAddress, + }, + query.KeyFilter{ + Key: string(WorkflowRegisteredEvent), + Expressions: []query.Expression{ + query.Confidence(primitives.Finalized), + query.Block("0", primitives.Gte), + }, + }, + query.LimitAndSort{ + SortBy: []query.SortBy{query.NewSortByTimestamp(query.Asc)}, + Limit: query.Limit{Count: giveCfg.QueryCount}, + }, + new(values.Value), + ).Return([]types.Sequence{}, nil) reader.EXPECT().GetLatestValueWithHeadData(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(&types.Head{ Height: "0", }, nil) + reader.EXPECT().Start(mock.Anything).Return(nil) reader.EXPECT().Bind(mock.Anything, mock.Anything).Return(nil) // Go run the worker From caf0c5bd16e4d797a67f2603a1abc5209bf0489f Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Tue, 10 Dec 2024 14:18:52 +0100 Subject: [PATCH 23/29] bump foundry (#15592) * bump foundry * reduce foundry cov req for liqman --- .github/workflows/solidity-foundry.yml | 2 +- contracts/GNUmakefile | 2 +- contracts/gas-snapshots/workflow.gas-snapshot | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/solidity-foundry.yml b/.github/workflows/solidity-foundry.yml index 850374b0cd3..f94ef29a3b8 100644 --- a/.github/workflows/solidity-foundry.yml +++ b/.github/workflows/solidity-foundry.yml @@ -34,7 +34,7 @@ jobs: { "name": "functions", "setup": { "run-coverage": false, "min-coverage": 98.5, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "keystone", "setup": { "run-coverage": true, "min-coverage": 72.8, "run-gas-snapshot": false, "run-forge-fmt": false }}, { "name": "l2ep", "setup": { "run-coverage": true, "min-coverage": 65.0, "run-gas-snapshot": true, "run-forge-fmt": false }}, - { "name": "liquiditymanager", "setup": { "run-coverage": true, "min-coverage": 44, "run-gas-snapshot": true, "run-forge-fmt": false }}, + { "name": "liquiditymanager", "setup": { "run-coverage": true, "min-coverage": 40, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "llo-feeds", "setup": { "run-coverage": true, "min-coverage": 49.3, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "operatorforwarder", "setup": { "run-coverage": true, "min-coverage": 55.7, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "shared", "setup": { "run-coverage": true, "extra-coverage-params": "--no-match-path='*CallWithExactGas*' --ir-minimum", "min-coverage": 32.6, "run-gas-snapshot": true, "run-forge-fmt": false }}, diff --git a/contracts/GNUmakefile b/contracts/GNUmakefile index 4066c76037e..673198bb1e2 100644 --- a/contracts/GNUmakefile +++ b/contracts/GNUmakefile @@ -43,7 +43,7 @@ mockery: $(mockery) ## Install mockery. .PHONY: foundry foundry: ## Install foundry. - foundryup --version nightly-fb5f0e1c4d9b9b0861be3e3bd07963524c5ac08e + foundryup --version nightly-aa69ed1e46dd61fbf9d73399396a4db4dd527431 .PHONY: foundry-refresh foundry-refresh: foundry diff --git a/contracts/gas-snapshots/workflow.gas-snapshot b/contracts/gas-snapshots/workflow.gas-snapshot index 73fdfbf7187..9195c401ef3 100644 --- a/contracts/gas-snapshots/workflow.gas-snapshot +++ b/contracts/gas-snapshots/workflow.gas-snapshot @@ -61,4 +61,4 @@ WorkflowRegistry_updateAllowedDONs:test_WhenTheBoolInputIsFalse() (gas: 29739) WorkflowRegistry_updateAllowedDONs:test_WhenTheBoolInputIsTrue() (gas: 170296) WorkflowRegistry_updateAuthorizedAddresses:test_WhenTheBoolInputIsFalse() (gas: 30278) WorkflowRegistry_updateAuthorizedAddresses:test_WhenTheBoolInputIsTrue() (gas: 175515) -WorkflowRegistry_updateWorkflow:test_WhenTheWorkflowInputsAreAllValid() (gas: 479601) +WorkflowRegistry_updateWorkflow:test_WhenTheWorkflowInputsAreAllValid() (gas: 479601) \ No newline at end of file From 5f26fd3438c5418ce845ca7376f07a03d8584e79 Mon Sep 17 00:00:00 2001 From: Bolek <1416262+bolekk@users.noreply.github.com> Date: Tue, 10 Dec 2024 05:23:36 -0800 Subject: [PATCH 24/29] Increase default timeout of remote Executable requests (#15587) --- core/capabilities/launcher.go | 3 ++- core/capabilities/remote/executable/client.go | 10 ++++++++-- core/capabilities/remote/executable/endtoend_test.go | 2 +- core/capabilities/remote/executable/server.go | 8 ++++++-- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/core/capabilities/launcher.go b/core/capabilities/launcher.go index 27c43fe0a53..98318853e2a 100644 --- a/core/capabilities/launcher.go +++ b/core/capabilities/launcher.go @@ -398,7 +398,8 @@ func (w *launcher) addToRegistryAndSetDispatcher(ctx context.Context, capability } var ( - defaultTargetRequestTimeout = time.Minute + // TODO: make this configurable + defaultTargetRequestTimeout = 8 * time.Minute ) func (w *launcher) exposeCapabilities(ctx context.Context, myPeerID p2ptypes.PeerID, don registrysyncer.DON, state *registrysyncer.LocalRegistry, remoteWorkflowDONs []registrysyncer.DON) error { diff --git a/core/capabilities/remote/executable/client.go b/core/capabilities/remote/executable/client.go index 9af32eb5f8e..776ddb692ad 100644 --- a/core/capabilities/remote/executable/client.go +++ b/core/capabilities/remote/executable/client.go @@ -41,6 +41,8 @@ var _ commoncap.ExecutableCapability = &client{} var _ types.Receiver = &client{} var _ services.Service = &client{} +const expiryCheckInterval = 30 * time.Second + func NewClient(remoteCapabilityInfo commoncap.CapabilityInfo, localDonInfo commoncap.DON, dispatcher types.Dispatcher, requestTimeout time.Duration, lggr logger.Logger) *client { return &client{ @@ -98,7 +100,11 @@ func (c *client) checkDispatcherReady() { } func (c *client) checkForExpiredRequests() { - ticker := time.NewTicker(c.requestTimeout) + tickerInterval := expiryCheckInterval + if c.requestTimeout < tickerInterval { + tickerInterval = c.requestTimeout + } + ticker := time.NewTicker(tickerInterval) defer ticker.Stop() for { select { @@ -116,7 +122,7 @@ func (c *client) expireRequests() { for messageID, req := range c.requestIDToCallerRequest { if req.Expired() { - req.Cancel(errors.New("request expired")) + req.Cancel(errors.New("request expired by executable client")) delete(c.requestIDToCallerRequest, messageID) } diff --git a/core/capabilities/remote/executable/endtoend_test.go b/core/capabilities/remote/executable/endtoend_test.go index 4e78fead87e..8be92e878ad 100644 --- a/core/capabilities/remote/executable/endtoend_test.go +++ b/core/capabilities/remote/executable/endtoend_test.go @@ -102,7 +102,7 @@ func Test_RemoteExecutableCapability_RandomCapabilityError(t *testing.T) { methods = append(methods, func(ctx context.Context, caller commoncap.ExecutableCapability) { executeCapability(ctx, t, caller, transmissionSchedule, func(t *testing.T, responseCh commoncap.CapabilityResponse, responseError error) { - assert.Equal(t, "error executing request: request expired", responseError.Error()) + assert.Equal(t, "error executing request: request expired by executable client", responseError.Error()) }) }) diff --git a/core/capabilities/remote/executable/server.go b/core/capabilities/remote/executable/server.go index b767a2d7030..d43c7ab5c41 100644 --- a/core/capabilities/remote/executable/server.go +++ b/core/capabilities/remote/executable/server.go @@ -87,7 +87,11 @@ func (r *server) Start(ctx context.Context) error { r.wg.Add(1) go func() { defer r.wg.Done() - ticker := time.NewTicker(r.requestTimeout) + tickerInterval := expiryCheckInterval + if r.requestTimeout < tickerInterval { + tickerInterval = r.requestTimeout + } + ticker := time.NewTicker(tickerInterval) defer ticker.Stop() r.lggr.Info("executable capability server started") for { @@ -118,7 +122,7 @@ func (r *server) expireRequests() { for requestID, executeReq := range r.requestIDToRequest { if executeReq.request.Expired() { - err := executeReq.request.Cancel(types.Error_TIMEOUT, "request expired") + err := executeReq.request.Cancel(types.Error_TIMEOUT, "request expired by executable server") if err != nil { r.lggr.Errorw("failed to cancel request", "request", executeReq, "err", err) } From ef0dd1c1b9c9650a3dba7b5c3d5f2e81db90a555 Mon Sep 17 00:00:00 2001 From: Suryansh <39276431+0xsuryansh@users.noreply.github.com> Date: Tue, 10 Dec 2024 19:15:29 +0530 Subject: [PATCH 25/29] CCIP-4477 : make gas for call exact check immutable (#15575) * feat: make gas for call exact check immutable * [Bot] Update changeset file with jira issues * fix comment * fix --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- contracts/.changeset/yellow-mugs-explode.md | 9 +++++++ contracts/gas-snapshots/ccip.gas-snapshot | 26 +++++++++---------- .../src/v0.8/ccip/libraries/Internal.sol | 4 --- contracts/src/v0.8/ccip/offRamp/OffRamp.sol | 21 ++++++++------- contracts/src/v0.8/ccip/test/BaseTest.t.sol | 2 +- .../OffRamp/OffRamp.afterOC3ConfigSet.t.sol | 1 + .../offRamp/OffRamp/OffRamp.constructor.t.sol | 7 +++++ .../OffRamp.executeSingleMessage.t.sol | 2 +- .../test/offRamp/OffRamp/OffRampSetup.t.sol | 2 ++ .../ccip/deployment_test/deployment_test.go | 9 ++++--- .../ccip/generated/offramp/offramp.go | 15 ++++++----- ...rapper-dependency-versions-do-not-edit.txt | 2 +- deployment/ccip/changeset/cs_deploy_chain.go | 9 ++++--- 13 files changed, 65 insertions(+), 44 deletions(-) create mode 100644 contracts/.changeset/yellow-mugs-explode.md diff --git a/contracts/.changeset/yellow-mugs-explode.md b/contracts/.changeset/yellow-mugs-explode.md new file mode 100644 index 00000000000..bd488e559ef --- /dev/null +++ b/contracts/.changeset/yellow-mugs-explode.md @@ -0,0 +1,9 @@ +--- +'@chainlink/contracts': minor +--- + +#internal make gas for call exact check immutable + +PR issue: CCIP-4477 + +Solidity Review issue: CCIP-3966 \ No newline at end of file diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index fd008698d52..4932473e38e 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -369,7 +369,7 @@ NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySet_overrideAllow NonceManager_applyPreviousRampsUpdates:test_SingleRampUpdate_success() (gas: 66889) NonceManager_applyPreviousRampsUpdates:test_ZeroInput_success() (gas: 12213) NonceManager_typeAndVersion:test_typeAndVersion() (gas: 9705) -OffRamp_afterOC3ConfigSet:test_afterOCR3ConfigSet_SignatureVerificationDisabled_Revert() (gas: 5872422) +OffRamp_afterOC3ConfigSet:test_afterOCR3ConfigSet_SignatureVerificationDisabled_Revert() (gas: 5903354) OffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 626094) OffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 166505) OffRamp_applySourceChainConfigUpdates:test_ApplyZeroUpdates_Success() (gas: 16719) @@ -393,8 +393,8 @@ OffRamp_commit:test_FailedRMNVerification_Reverts() (gas: 63117) OffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 69655) OffRamp_commit:test_InvalidInterval_Revert() (gas: 65803) OffRamp_commit:test_InvalidRootRevert() (gas: 64898) -OffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6633259) -OffRamp_commit:test_NoConfig_Revert() (gas: 6216677) +OffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6664144) +OffRamp_commit:test_NoConfig_Revert() (gas: 6247562) OffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 112728) OffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 120561) OffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 112660) @@ -409,23 +409,23 @@ OffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 125027) OffRamp_commit:test_Unhealthy_Revert() (gas: 60177) OffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 206221) OffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 53305) -OffRamp_constructor:test_Constructor_Success() (gas: 6179080) -OffRamp_constructor:test_SourceChainSelector_Revert() (gas: 136555) -OffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103592) -OffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101441) -OffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 162036) -OffRamp_constructor:test_ZeroRMNRemote_Revert() (gas: 101358) -OffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101362) +OffRamp_constructor:test_Constructor_Success() (gas: 6210339) +OffRamp_constructor:test_SourceChainSelector_Revert() (gas: 137118) +OffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103828) +OffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101677) +OffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 162599) +OffRamp_constructor:test_ZeroRMNRemote_Revert() (gas: 101597) +OffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101598) OffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17532) OffRamp_execute:test_LargeBatch_Success() (gas: 3378447) OffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 371209) OffRamp_execute:test_MultipleReports_Success() (gas: 298806) -OffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 7041684) -OffRamp_execute:test_NoConfig_Revert() (gas: 6266154) +OffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 7072622) +OffRamp_execute:test_NoConfig_Revert() (gas: 6297092) OffRamp_execute:test_NonArray_Revert() (gas: 27572) OffRamp_execute:test_SingleReport_Success() (gas: 175631) OffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 147790) -OffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6933352) +OffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6964290) OffRamp_execute:test_ZeroReports_Revert() (gas: 17248) OffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens() (gas: 56213) OffRamp_executeSingleMessage:test_executeSingleMessage_NonContract() (gas: 20508) diff --git a/contracts/src/v0.8/ccip/libraries/Internal.sol b/contracts/src/v0.8/ccip/libraries/Internal.sol index f5bcdd434f7..6e0152c8cf5 100644 --- a/contracts/src/v0.8/ccip/libraries/Internal.sol +++ b/contracts/src/v0.8/ccip/libraries/Internal.sol @@ -7,10 +7,6 @@ import {MerkleMultiProof} from "../libraries/MerkleMultiProof.sol"; library Internal { error InvalidEVMAddress(bytes encodedAddress); - /// @dev The minimum amount of gas to perform the call with exact gas. - /// We include this in the offramp so that we can redeploy to adjust it should a hardfork change the gas costs of - /// relevant opcodes in callWithExactGas. - uint16 internal constant GAS_FOR_CALL_EXACT_CHECK = 5_000; /// @dev We limit return data to a selector plus 4 words. This is to avoid malicious contracts from returning /// large amounts of data and causing repeated out-of-gas scenarios. uint16 internal constant MAX_RET_BYTES = 4 + 4 * 32; diff --git a/contracts/src/v0.8/ccip/offRamp/OffRamp.sol b/contracts/src/v0.8/ccip/offRamp/OffRamp.sol index d276ce26a96..f3c171ce462 100644 --- a/contracts/src/v0.8/ccip/offRamp/OffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/OffRamp.sol @@ -92,8 +92,9 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. // solhint-disable-next-line gas-struct-packing struct StaticConfig { - uint64 chainSelector; // ────╮ Destination chainSelector - IRMNRemote rmnRemote; // ────╯ RMN Verification Contract + uint64 chainSelector; // ───────╮ Destination chainSelector + uint16 gasForCallExactCheck; // | Gas for call exact check + IRMNRemote rmnRemote; // ───────╯ RMN Verification Contract address tokenAdminRegistry; // Token admin registry address address nonceManager; // Nonce manager address } @@ -151,6 +152,10 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { address internal immutable i_tokenAdminRegistry; /// @dev The address of the nonce manager. address internal immutable i_nonceManager; + /// @dev The minimum amount of gas to perform the call with exact gas. + /// We include this in the offramp so that we can redeploy to adjust it should a hardfork change the gas costs of + /// relevant opcodes in callWithExactGas. + uint16 internal immutable i_gasForCallExactCheck; // DYNAMIC CONFIG DynamicConfig internal s_dynamicConfig; @@ -193,6 +198,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { i_rmnRemote = staticConfig.rmnRemote; i_tokenAdminRegistry = staticConfig.tokenAdminRegistry; i_nonceManager = staticConfig.nonceManager; + i_gasForCallExactCheck = staticConfig.gasForCallExactCheck; emit StaticConfigSet(staticConfig); _setDynamicConfig(dynamicConfig); @@ -601,7 +607,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { (bool success, bytes memory returnData,) = s_sourceChainConfigs[message.header.sourceChainSelector] .router - .routeMessage(any2EvmMessage, Internal.GAS_FOR_CALL_EXACT_CHECK, message.gasLimit, message.receiver); + .routeMessage(any2EvmMessage, i_gasForCallExactCheck, message.gasLimit, message.receiver); // If CCIP receiver execution is not successful, revert the call including token transfers. if (!success) revert ReceiverError(returnData); } @@ -665,7 +671,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { ), localPoolAddress, gasLeft, - Internal.GAS_FOR_CALL_EXACT_CHECK, + i_gasForCallExactCheck, Internal.MAX_RET_BYTES ); @@ -705,11 +711,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { uint256 gasLimit ) internal returns (uint256 balance, uint256 gasLeft) { (bool success, bytes memory returnData, uint256 gasUsed) = CallWithExactGas._callWithExactGasSafeReturnData( - abi.encodeCall(IERC20.balanceOf, (receiver)), - token, - gasLimit, - Internal.GAS_FOR_CALL_EXACT_CHECK, - Internal.MAX_RET_BYTES + abi.encodeCall(IERC20.balanceOf, (receiver)), token, gasLimit, i_gasForCallExactCheck, Internal.MAX_RET_BYTES ); if (!success) revert TokenHandlingError(token, returnData); @@ -906,6 +908,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { function getStaticConfig() external view returns (StaticConfig memory) { return StaticConfig({ chainSelector: i_chainSelector, + gasForCallExactCheck: i_gasForCallExactCheck, rmnRemote: i_rmnRemote, tokenAdminRegistry: i_tokenAdminRegistry, nonceManager: i_nonceManager diff --git a/contracts/src/v0.8/ccip/test/BaseTest.t.sol b/contracts/src/v0.8/ccip/test/BaseTest.t.sol index dfc9e4e1eb1..1e9fcdd2fa5 100644 --- a/contracts/src/v0.8/ccip/test/BaseTest.t.sol +++ b/contracts/src/v0.8/ccip/test/BaseTest.t.sol @@ -41,7 +41,7 @@ contract BaseTest is Test { // OffRamp uint32 internal constant MAX_DATA_SIZE = 30_000; uint16 internal constant MAX_TOKENS_LENGTH = 5; - uint16 internal constant GAS_FOR_CALL_EXACT_CHECK = 5000; + uint16 internal constant GAS_FOR_CALL_EXACT_CHECK = 5_000; uint32 internal constant MAX_GAS_LIMIT = 4_000_000; MockRMN internal s_mockRMN; diff --git a/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.afterOC3ConfigSet.t.sol b/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.afterOC3ConfigSet.t.sol index 91694dbcb05..d2edb7a261a 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.afterOC3ConfigSet.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.afterOC3ConfigSet.t.sol @@ -12,6 +12,7 @@ contract OffRamp_afterOC3ConfigSet is OffRampSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, + gasForCallExactCheck: GAS_FOR_CALL_EXACT_CHECK, rmnRemote: s_mockRMNRemote, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) diff --git a/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.constructor.t.sol b/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.constructor.t.sol index bd7bb94344c..d31b7939d9c 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.constructor.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.constructor.t.sol @@ -13,6 +13,7 @@ contract OffRamp_constructor is OffRampSetup { function test_Constructor_Success() public { OffRamp.StaticConfig memory staticConfig = OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, + gasForCallExactCheck: GAS_FOR_CALL_EXACT_CHECK, rmnRemote: s_mockRMNRemote, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) @@ -142,6 +143,7 @@ contract OffRamp_constructor is OffRampSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, + gasForCallExactCheck: GAS_FOR_CALL_EXACT_CHECK, rmnRemote: s_mockRMNRemote, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) @@ -168,6 +170,7 @@ contract OffRamp_constructor is OffRampSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, + gasForCallExactCheck: GAS_FOR_CALL_EXACT_CHECK, rmnRemote: s_mockRMNRemote, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) @@ -188,6 +191,7 @@ contract OffRamp_constructor is OffRampSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, + gasForCallExactCheck: GAS_FOR_CALL_EXACT_CHECK, rmnRemote: IRMNRemote(address(0)), tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) @@ -208,6 +212,7 @@ contract OffRamp_constructor is OffRampSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: 0, + gasForCallExactCheck: GAS_FOR_CALL_EXACT_CHECK, rmnRemote: s_mockRMNRemote, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) @@ -228,6 +233,7 @@ contract OffRamp_constructor is OffRampSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, + gasForCallExactCheck: GAS_FOR_CALL_EXACT_CHECK, rmnRemote: s_mockRMNRemote, tokenAdminRegistry: address(0), nonceManager: address(s_inboundNonceManager) @@ -248,6 +254,7 @@ contract OffRamp_constructor is OffRampSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, + gasForCallExactCheck: GAS_FOR_CALL_EXACT_CHECK, rmnRemote: s_mockRMNRemote, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(0) diff --git a/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.executeSingleMessage.t.sol b/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.executeSingleMessage.t.sol index 727a7c63bb1..20b711f529e 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.executeSingleMessage.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.executeSingleMessage.t.sol @@ -36,7 +36,7 @@ contract OffRamp_executeSingleMessage is OffRampSetup { abi.encodeWithSelector( IRouter.routeMessage.selector, expectedAny2EvmMessage, - Internal.GAS_FOR_CALL_EXACT_CHECK, + GAS_FOR_CALL_EXACT_CHECK, message.gasLimit, message.receiver ) diff --git a/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRampSetup.t.sol index 858ee9e4a45..f8b70ebf283 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRampSetup.t.sol @@ -70,6 +70,7 @@ contract OffRampSetup is FeeQuoterSetup, MultiOCR3BaseSetup { OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, rmnRemote: rmnRemote, + gasForCallExactCheck: GAS_FOR_CALL_EXACT_CHECK, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(nonceManager) }), @@ -348,6 +349,7 @@ contract OffRampSetup is FeeQuoterSetup, MultiOCR3BaseSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, + gasForCallExactCheck: GAS_FOR_CALL_EXACT_CHECK, rmnRemote: s_mockRMNRemote, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) diff --git a/core/gethwrappers/ccip/deployment_test/deployment_test.go b/core/gethwrappers/ccip/deployment_test/deployment_test.go index 02f00483651..162c0df1946 100644 --- a/core/gethwrappers/ccip/deployment_test/deployment_test.go +++ b/core/gethwrappers/ccip/deployment_test/deployment_test.go @@ -41,10 +41,11 @@ func TestDeployAllV1_6(t *testing.T) { // offramp _, _, _, err = offramp.DeployOffRamp(owner, chain, offramp.OffRampStaticConfig{ - ChainSelector: 1, - RmnRemote: common.HexToAddress("0x1"), - TokenAdminRegistry: common.HexToAddress("0x2"), - NonceManager: common.HexToAddress("0x3"), + ChainSelector: 1, + GasForCallExactCheck: 5_000, + RmnRemote: common.HexToAddress("0x1"), + TokenAdminRegistry: common.HexToAddress("0x2"), + NonceManager: common.HexToAddress("0x3"), }, offramp.OffRampDynamicConfig{ FeeQuoter: common.HexToAddress("0x4"), PermissionLessExecutionThresholdSeconds: uint32((8 * time.Hour).Seconds()), diff --git a/core/gethwrappers/ccip/generated/offramp/offramp.go b/core/gethwrappers/ccip/generated/offramp/offramp.go index b582b60cff6..830dcaf7bf4 100644 --- a/core/gethwrappers/ccip/generated/offramp/offramp.go +++ b/core/gethwrappers/ccip/generated/offramp/offramp.go @@ -148,15 +148,16 @@ type OffRampSourceChainConfigArgs struct { } type OffRampStaticConfig struct { - ChainSelector uint64 - RmnRemote common.Address - TokenAdminRegistry common.Address - NonceManager common.Address + ChainSelector uint64 + GasForCallExactCheck uint16 + RmnRemote common.Address + TokenAdminRegistry common.Address + NonceManager common.Address } var OffRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRMNRemote\",\"name\":\"rmnRemote\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isRMNVerificationDisabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"messageInterceptor\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reportOnRamp\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"configOnRamp\",\"type\":\"bytes\"}],\"name\":\"CommitOnRampMismatch\",\"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\":\"EmptyBatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"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\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"tokenIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"oldLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenGasOverride\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionTokenGasOverride\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"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\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidOnRampUpdate\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionGasAmountCountMismatch\",\"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\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"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\":\"SignatureVerificationNotAllowedInExecutionPlugin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignatureVerificationRequiredInCommitPlugin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"reportSourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"messageSourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorMismatch\",\"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\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"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\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRampAddress\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"maxSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structInternal.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"},{\"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[]\"}],\"indexed\":false,\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"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\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isRMNVerificationDisabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"messageInterceptor\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.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\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"name\":\"ExecutionStateChanged\",\"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\"}],\"name\":\"SkippedReportExecution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structOffRamp.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\":\"contractIRMNRemote\",\"name\":\"rmnRemote\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.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\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.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[2]\",\"name\":\"reportContext\",\"type\":\"bytes32[2]\"},{\"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[2]\",\"name\":\"reportContext\",\"type\":\"bytes32[2]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"destTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destGasAmount\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.Any2EVMTokenTransfer[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"uint32[]\",\"name\":\"tokenGasOverrides\",\"type\":\"uint32[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllSourceChainConfigs\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isRMNVerificationDisabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"messageInterceptor\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.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\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRMNRemote\",\"name\":\"rmnRemote\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"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\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"destTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destGasAmount\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.Any2EVMTokenTransfer[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receiverExecutionGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint32[]\",\"name\":\"tokenGasOverrides\",\"type\":\"uint32[]\"}],\"internalType\":\"structOffRamp.GasLimitOverride[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"tuple[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isRMNVerificationDisabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"messageInterceptor\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"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: "0x6101206040523480156200001257600080fd5b5060405162006be738038062006be7833981016040819052620000359162000880565b336000816200005757604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008a576200008a81620001c4565b50504660805260208301516001600160a01b03161580620000b6575060408301516001600160a01b0316155b80620000cd575060608301516001600160a01b0316155b15620000ec576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b0316600003620001185760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001b0826200023e565b620001bb816200032c565b50505062000c72565b336001600160a01b03821603620001ee57604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b031662000267576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516001600160a01b039889166001600160c01b03199097168717600160a01b63ffffffff958616021760ff60c01b1916600160c01b911515919091021790965560608089018051600580546001600160a01b031916918b169190911790558251968752935190921693850193909352935115159183019190915251909216908201527fcbb53bda7106a610de67df506ac86b65c44d5afac0fd2b11070dc2d61a6f2dee9060800160405180910390a150565b60005b8151811015620005c1576000828281518110620003505762000350620009aa565b60200260200101519050600081602001519050806001600160401b03166000036200038e5760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b0316620003b7576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b03811660009081526008602052604090206060830151600182018054620003e590620009c0565b905060000362000448578154600160a81b600160e81b031916600160a81b1782556040516001600160401b03841681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620004b9565b8154600160a81b90046001600160401b03166001148015906200048b57508051602082012060405162000480906001850190620009fc565b604051809103902014155b15620004b957604051632105803760e11b81526001600160401b038416600482015260240160405180910390fd5b80511580620004ef5750604080516000602082015201604051602081830303815290604052805190602001208180519060200120145b156200050e576040516342bcdf7f60e11b815260040160405180910390fd5b600182016200051e828262000acf565b506040840151825485516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b0319909116171782556200056d60066001600160401b038516620005c5565b50826001600160401b03167f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b83604051620005a9919062000b9b565b60405180910390a2505050508060010190506200032f565b5050565b6000620005d38383620005dc565b90505b92915050565b60008181526001830160205260408120546200062557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620005d6565b506000620005d6565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b03811182821017156200066957620006696200062e565b60405290565b604051601f8201601f191681016001600160401b03811182821017156200069a576200069a6200062e565b604052919050565b80516001600160401b0381168114620006ba57600080fd5b919050565b6001600160a01b0381168114620006d557600080fd5b50565b80518015158114620006ba57600080fd5b6000601f83601f840112620006fd57600080fd5b825160206001600160401b03808311156200071c576200071c6200062e565b8260051b6200072d8382016200066f565b93845286810183019383810190898611156200074857600080fd5b84890192505b858310156200087357825184811115620007685760008081fd5b89016080601f19828d038101821315620007825760008081fd5b6200078c62000644565b888401516200079b81620006bf565b81526040620007ac858201620006a2565b8a8301526060620007bf818701620006d8565b83830152938501519389851115620007d75760008081fd5b84860195508f603f870112620007ef57600094508485fd5b8a8601519450898511156200080857620008086200062e565b620008198b858f880116016200066f565b93508484528f82868801011115620008315760008081fd5b60005b8581101562000851578681018301518582018d01528b0162000834565b5060009484018b0194909452509182015283525091840191908401906200074e565b9998505050505050505050565b60008060008385036101208112156200089857600080fd5b6080811215620008a757600080fd5b620008b162000644565b620008bc86620006a2565b81526020860151620008ce81620006bf565b60208201526040860151620008e381620006bf565b60408201526060860151620008f881620006bf565b606082015293506080607f19820112156200091257600080fd5b506200091d62000644565b60808501516200092d81620006bf565b815260a085015163ffffffff811681146200094757600080fd5b60208201526200095a60c08601620006d8565b604082015260e08501516200096f81620006bf565b60608201526101008501519092506001600160401b038111156200099257600080fd5b620009a086828701620006e9565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c90821680620009d557607f821691505b602082108103620009f657634e487b7160e01b600052602260045260246000fd5b50919050565b600080835462000a0c81620009c0565b6001828116801562000a27576001811462000a3d5762000a6e565b60ff198416875282151583028701945062000a6e565b8760005260208060002060005b8581101562000a655781548a82015290840190820162000a4a565b50505082870194505b50929695505050505050565b601f82111562000aca576000816000526020600020601f850160051c8101602086101562000aa55750805b601f850160051c820191505b8181101562000ac65782815560010162000ab1565b5050505b505050565b81516001600160401b0381111562000aeb5762000aeb6200062e565b62000b038162000afc8454620009c0565b8462000a7a565b602080601f83116001811462000b3b576000841562000b225750858301515b600019600386901b1c1916600185901b17855562000ac6565b600085815260208120601f198616915b8281101562000b6c5788860151825594840194600190910190840162000b4b565b508582101562000b8b5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000bf081620009c0565b8060a089015260c0600183166000811462000c14576001811462000c315762000c63565b60ff19841660c08b015260c083151560051b8b0101945062000c63565b85600052602060002060005b8481101562000c5a5781548c820185015290880190890162000c3d565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615ef862000cef600039600081816102070152612a4a0152600081816101d80152612cf20152600081816101a901528181610f7501528181611125015261244a01526000818161017a015281816125f501526126ac01526000818161190401526119370152615ef86000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c80637edf52f4116100ad578063de5e0b9a11610071578063de5e0b9a146104b2578063e9d68a8e146104c5578063f2fde38b146104e5578063f58e03fc146104f8578063f716f99f1461050b57600080fd5b80637edf52f41461041257806385572ffb146104255780638da5cb5b14610433578063c673e5841461044e578063ccd37ba31461046e57600080fd5b80635e36480c116100f45780635e36480c146103075780635e7bb0081461032757806360987c201461033a5780637437ff9f1461034d57806379ba50971461040a57600080fd5b806304666f9c1461013157806306285c6914610146578063181f5a771461028d5780633f4b04aa146102d65780635215505b146102f1575b600080fd5b61014461013f366004613e1c565b61051e565b005b61023760408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160401b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b604051610284919081516001600160401b031681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6102c96040518060400160405280601181526020017f4f666652616d7020312e362e302d64657600000000000000000000000000000081525081565b6040516102849190613f8a565b600b546040516001600160401b039091168152602001610284565b6102f9610532565b604051610284929190613fe4565b61031a610315366004614085565b61078d565b60405161028491906140e2565b61014461033536600461464b565b6107e2565b6101446103483660046148da565b610a76565b6103c360408051608081018252600080825260208201819052918101829052606081019190915250604080516080810182526004546001600160a01b038082168352600160a01b820463ffffffff166020840152600160c01b90910460ff16151592820192909252600554909116606082015290565b604051610284919081516001600160a01b03908116825260208084015163ffffffff1690830152604080840151151590830152606092830151169181019190915260800190565b610144610d33565b61014461042036600461496e565b610db6565b61014461012c3660046149d3565b6001546040516001600160a01b039091168152602001610284565b61046161045c366004614a1e565b610dc7565b6040516102849190614a7e565b6104a461047c366004614af3565b6001600160401b03919091166000908152600a60209081526040808320938352929052205490565b604051908152602001610284565b6101446104c0366004614b6f565b610f25565b6104d86104d3366004614c21565b611428565b6040516102849190614c3c565b6101446104f3366004614c4f565b611534565b610144610506366004614c6c565b611545565b610144610519366004614d27565b6115ae565b6105266115f0565b61052f8161161d565b50565b606080600061054160066118a6565b6001600160401b0381111561055857610558613c3c565b6040519080825280602002602001820160405280156105a957816020015b60408051608081018252600080825260208083018290529282015260608082015282526000199092019101816105765790505b50905060006105b860066118a6565b6001600160401b038111156105cf576105cf613c3c565b6040519080825280602002602001820160405280156105f8578160200160208202803683370190505b50905060005b61060860066118a6565b8110156107845761061a6006826118b0565b82828151811061062c5761062c614e64565b60200260200101906001600160401b031690816001600160401b0316815250506008600083838151811061066257610662614e64565b6020908102919091018101516001600160401b039081168352828201939093526040918201600020825160808101845281546001600160a01b038116825260ff600160a01b820416151593820193909352600160a81b909204909316918101919091526001820180549192916060840191906106dd90614e7a565b80601f016020809104026020016040519081016040528092919081815260200182805461070990614e7a565b80156107565780601f1061072b57610100808354040283529160200191610756565b820191906000526020600020905b81548152906001019060200180831161073957829003601f168201915b50505050508152505083828151811061077157610771614e64565b60209081029190910101526001016105fe565b50939092509050565b600061079b60016004614eca565b60026107a8608085614ef3565b6001600160401b03166107bb9190614f19565b6107c585856118bc565b901c1660038111156107d9576107d96140b8565b90505b92915050565b6107ea611901565b81518151811461080d576040516320f8fd5960e21b815260040160405180910390fd5b60005b81811015610a6657600084828151811061082c5761082c614e64565b6020026020010151905060008160200151519050600085848151811061085457610854614e64565b602002602001015190508051821461087f576040516320f8fd5960e21b815260040160405180910390fd5b60005b82811015610a5757600082828151811061089e5761089e614e64565b60200260200101516000015190506000856020015183815181106108c4576108c4614e64565b602002602001015190508160001461091d57806080015182101561091d578551815151604051633a98d46360e11b81526001600160401b0390921660048301526024820152604481018390526064015b60405180910390fd5b83838151811061092f5761092f614e64565b602002602001015160200151518160a00151511461097c57805180516060909101516040516370a193fd60e01b815260048101929092526001600160401b03166024820152604401610914565b60005b8160a0015151811015610a495760008585815181106109a0576109a0614e64565b60200260200101516020015182815181106109bd576109bd614e64565b602002602001015163ffffffff16905080600014610a405760008360a0015183815181106109ed576109ed614e64565b60200260200101516040015163ffffffff16905080821015610a3e578351516040516348e617b360e01b81526004810191909152602481018490526044810182905260648101839052608401610914565b505b5060010161097f565b505050806001019050610882565b50505050806001019050610810565b50610a718383611969565b505050565b333014610a96576040516306e34e6560e31b815260040160405180910390fd5b6040805160008082526020820190925281610ad3565b6040805180820190915260008082526020820152815260200190600190039081610aac5790505b5060a08701515190915015610b0957610b068660a001518760200151886060015189600001516020015189898989611a2c565b90505b6040805160a081018252875151815287516020908101516001600160401b03168183015288015181830152908701516060820152608081018290526005546001600160a01b03168015610bfc576040516308d450a160e01b81526001600160a01b038216906308d450a190610b82908590600401614fdd565b600060405180830381600087803b158015610b9c57600080fd5b505af1925050508015610bad575060015b610bfc573d808015610bdb576040519150601f19603f3d011682016040523d82523d6000602084013e610be0565b606091505b50806040516309c2532560e01b81526004016109149190613f8a565b604088015151158015610c1157506080880151155b80610c28575060608801516001600160a01b03163b155b80610c4f57506060880151610c4d906001600160a01b03166385572ffb60e01b611bdd565b155b15610c5c57505050610d2c565b87516020908101516001600160401b03166000908152600890915260408082205460808b015160608c01519251633cf9798360e01b815284936001600160a01b0390931692633cf9798392610cba9289926113889291600401614ff0565b6000604051808303816000875af1158015610cd9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d01919081019061502c565b509150915081610d2657806040516302a35ba360e21b81526004016109149190613f8a565b50505050505b5050505050565b6000546001600160a01b03163314610d5e5760405163015aa1e360e11b815260040160405180910390fd5b600180546001600160a01b0319808216339081179093556000805490911681556040516001600160a01b03909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610dbe6115f0565b61052f81611bf9565b610e0a6040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610eb357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e95575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610f1557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610ef7575b5050505050815250509050919050565b6000610f33878901896152d9565b6004805491925090600160c01b900460ff16610fdd5760208201515115610fdd5760208201516040808401519051633854844f60e11b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016926370a9089e92610fac9230929190600401615501565b60006040518083038186803b158015610fc457600080fd5b505afa158015610fd8573d6000803e3d6000fd5b505050505b81515151151580610ff357508151602001515115155b156110be57600b5460208b0135906001600160401b038083169116101561109657600b805467ffffffffffffffff19166001600160401b03831617905581548351604051633937306f60e01b81526001600160a01b0390921691633937306f9161105f91600401615614565b600060405180830381600087803b15801561107957600080fd5b505af115801561108d573d6000803e3d6000fd5b505050506110bc565b8260200151516000036110bc57604051632261116760e01b815260040160405180910390fd5b505b60005b826020015151811015611374576000836020015182815181106110e6576110e6614e64565b60209081029190910101518051604051632cbc26bb60e01b815267ffffffffffffffff60801b608083901b166004820152919250906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa15801561116c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111909190615627565b156111b957604051637edeb53960e11b81526001600160401b0382166004820152602401610914565b60006111c482611cfe565b9050806001016040516111d79190615644565b6040518091039020836020015180519060200120146112145782602001518160010160405163b80d8fa960e01b8152600401610914929190615737565b60408301518154600160a81b90046001600160401b039081169116141580611255575082606001516001600160401b031683604001516001600160401b0316115b1561129a57825160408085015160608601519151636af0786b60e11b81526001600160401b039384166004820152908316602482015291166044820152606401610914565b6080830151806112bd5760405163504570e360e01b815260040160405180910390fd5b83516001600160401b03166000908152600a60209081526040808320848452909152902054156113155783516040516332cf0cbf60e01b81526001600160401b03909116600482015260248101829052604401610914565b606084015161132590600161575c565b825467ffffffffffffffff60a81b1916600160a81b6001600160401b0392831602179092559251166000908152600a6020908152604080832094835293905291909120429055506001016110c1565b50602082015182516040517f35c02761bcd3ef995c6a601a1981f4ed3934dcbe5041e24e286c89f5531d17e4926113ac929091615783565b60405180910390a1610d2660008b8b8b8b8b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808f0282810182019093528e82529093508e92508d9182918501908490808284376000920191909152508c9250611d4a915050565b60408051608080820183526000808352602080840182905283850182905260608085018190526001600160401b03878116845260088352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b9092049092169483019490945260018401805493949293918401916114b490614e7a565b80601f01602080910402602001604051908101604052809291908181526020018280546114e090614e7a565b8015610f155780601f1061150257610100808354040283529160200191610f15565b820191906000526020600020905b81548152906001019060200180831161151057505050919092525091949350505050565b61153c6115f0565b61052f81612043565b611585611554828401846157a8565b604080516000808252602082019092529061157f565b606081526020019060019003908161156a5790505b50611969565b6040805160008082526020820190925290506115a8600185858585866000611d4a565b50505050565b6115b66115f0565b60005b81518110156115ec576115e48282815181106115d7576115d7614e64565b60200260200101516120bc565b6001016115b9565b5050565b6001546001600160a01b0316331461161b576040516315ae3a6f60e11b815260040160405180910390fd5b565b60005b81518110156115ec57600082828151811061163d5761163d614e64565b60200260200101519050600081602001519050806001600160401b031660000361167a5760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166116a2576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b038116600090815260086020526040902060608301516001820180546116ce90614e7a565b905060000361173057815467ffffffffffffffff60a81b1916600160a81b1782556040516001600160401b03841681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611799565b8154600160a81b90046001600160401b0316600114801590611770575080516020820120604051611765906001850190615644565b604051809103902014155b1561179957604051632105803760e11b81526001600160401b0384166004820152602401610914565b805115806117ce5750604080516000602082015201604051602081830303815290604052805190602001208180519060200120145b156117ec576040516342bcdf7f60e11b815260040160405180910390fd5b600182016117fa828261582c565b506040840151825485516001600160a01b03166001600160a01b0319921515600160a01b029290921674ffffffffffffffffffffffffffffffffffffffffff199091161717825561185560066001600160401b0385166123e6565b50826001600160401b03167f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b8360405161188f91906158eb565b60405180910390a250505050806001019050611620565b60006107dc825490565b60006107d983836123f2565b6001600160401b0382166000908152600960205260408120816118e0608085615939565b6001600160401b031681526020810191909152604001600020549392505050565b467f00000000000000000000000000000000000000000000000000000000000000001461161b57604051630f01ce8560e01b81527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610914565b815160000361198b5760405163c2e5347d60e01b815260040160405180910390fd5b805160408051600080825260208201909252911591816119ce565b6040805180820190915260008152606060208201528152602001906001900390816119a65790505b50905060005b8451811015610d2c57611a248582815181106119f2576119f2614e64565b602002602001015184611a1e57858381518110611a1157611a11614e64565b602002602001015161241c565b8361241c565b6001016119d4565b606088516001600160401b03811115611a4757611a47613c3c565b604051908082528060200260200182016040528015611a8c57816020015b6040805180820190915260008082526020820152815260200190600190039081611a655790505b509050811560005b8a51811015611bcf5781611b2c57848482818110611ab457611ab4614e64565b9050602002016020810190611ac9919061595f565b63ffffffff1615611b2c57848482818110611ae657611ae6614e64565b9050602002016020810190611afb919061595f565b8b8281518110611b0d57611b0d614e64565b60200260200101516040019063ffffffff16908163ffffffff16815250505b611baa8b8281518110611b4157611b41614e64565b60200260200101518b8b8b8b8b87818110611b5e57611b5e614e64565b9050602002810190611b70919061597a565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612cb792505050565b838281518110611bbc57611bbc614e64565b6020908102919091010152600101611a94565b505098975050505050505050565b6000611be883612f99565b80156107d957506107d98383612fcc565b80516001600160a01b0316611c21576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516001600160a01b039889167fffffffffffffffff0000000000000000000000000000000000000000000000009097168717600160a01b63ffffffff958616021760ff60c01b1916600160c01b911515919091021790965560608089018051600580546001600160a01b031916918b169190911790558251968752935190921693850193909352935115159183019190915251909216908201527fcbb53bda7106a610de67df506ac86b65c44d5afac0fd2b11070dc2d61a6f2dee9060800160405180910390a150565b6001600160401b03811660009081526008602052604081208054600160a01b900460ff166107dc5760405163ed053c5960e01b81526001600160401b0384166004820152602401610914565b60ff87811660009081526002602090815260408083208151608081018352815481526001909101548086169382019390935261010083048516918101919091526201000090910490921615156060830152873590611da98760846159c0565b9050826060015115611df1578451611dc2906020614f19565b8651611dcf906020614f19565b611dda9060a06159c0565b611de491906159c0565b611dee90826159c0565b90505b368114611e1a57604051638e1192e160e01b815260048101829052366024820152604401610914565b5081518114611e495781516040516324f7d61360e21b8152600481019190915260248101829052604401610914565b611e51611901565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611e9f57611e9f6140b8565b6002811115611eb057611eb06140b8565b9052509050600281602001516002811115611ecd57611ecd6140b8565b148015611f215750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611f0957611f09614e64565b6000918252602090912001546001600160a01b031633145b611f3e57604051631b41e11d60e31b815260040160405180910390fd5b50816060015115611fee576020820151611f599060016159d3565b60ff16855114611f7c576040516371253a2560e01b815260040160405180910390fd5b8351855114611f9e5760405163a75d88af60e01b815260040160405180910390fd5b60008787604051611fb09291906159ec565b604051908190038120611fc7918b906020016159fc565b604051602081830303815290604052805190602001209050611fec8a82888888613056565b505b6040805182815260208a8101356001600160401b03169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b336001600160a01b0382160361206c57604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff166000036120e7576000604051631b3fab5160e11b81526004016109149190615a10565b60208082015160ff80821660009081526002909352604083206001810154929390928392169003612138576060840151600182018054911515620100000262ff000019909216919091179055612174565b6060840151600182015460ff6201000090910416151590151514612174576040516321fd80df60e21b815260ff84166004820152602401610914565b60a0840151805161010010156121a0576001604051631b3fab5160e11b81526004016109149190615a10565b80516000036121c5576005604051631b3fab5160e11b81526004016109149190615a10565b61222b848460030180548060200260200160405190810160405280929190818152602001828054801561222157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612203575b5050505050613209565b84606001511561235b576122998484600201805480602002602001604051908101604052809291908181526020018280548015612221576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311612203575050505050613209565b6080850151805161010010156122c5576002604051631b3fab5160e11b81526004016109149190615a10565b60408601516122d5906003615a2a565b60ff168151116122fb576003604051631b3fab5160e11b81526004016109149190615a10565b815181511015612321576001604051631b3fab5160e11b81526004016109149190615a10565b805160018401805461ff00191661010060ff84160217905561234c9060028601906020840190613bc2565b5061235985826001613272565b505b61236784826002613272565b805161237c9060038501906020840190613bc2565b5060408581015160018401805460ff191660ff8316179055865180855560a088015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547936123d59389939260028a01929190615a46565b60405180910390a1610d2c846133cd565b60006107d98383613450565b600082600001828154811061240957612409614e64565b9060005260206000200154905092915050565b81518151604051632cbc26bb60e01b8152608083901b67ffffffffffffffff60801b166004820152901515907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015612499573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124bd9190615627565b1561252e5780156124ec57604051637edeb53960e11b81526001600160401b0383166004820152602401610914565b6040516001600160401b03831681527faab522ed53d887e56ed53dd37398a01aeef6a58e0fa77c2173beb9512d8949339060200160405180910390a150505050565b602084015151600081900361256457845160405163676cf24b60e11b81526001600160401b039091166004820152602401610914565b8460400151518114612589576040516357e0e08360e01b815260040160405180910390fd5b6000816001600160401b038111156125a3576125a3613c3c565b6040519080825280602002602001820160405280156125cc578160200160208202803683370190505b50905060007f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f857f000000000000000000000000000000000000000000000000000000000000000061261d88611cfe565b60010160405161262d9190615644565b604051908190038120612665949392916020019384526001600160401b03928316602085015291166040830152606082015260800190565b60405160208183030381529060405280519060200120905060005b8381101561279b576000886020015182815181106126a0576126a0614e64565b602002602001015190507f00000000000000000000000000000000000000000000000000000000000000006001600160401b03168160000151604001516001600160401b0316146127175780516040908101519051631c21951160e11b81526001600160401b039091166004820152602401610914565b866001600160401b03168160000151602001516001600160401b03161461276b57805160200151604051636c95f1eb60e01b81526001600160401b03808a1660048301529091166024820152604401610914565b612775818461349f565b84838151811061278757612787614e64565b602090810291909101015250600101612680565b505060006127b3858389606001518a608001516135a7565b9050806000036127e157604051633ee8bd3f60e11b81526001600160401b0386166004820152602401610914565b60005b83811015612cad5760005a905060008960200151838151811061280957612809614e64565b6020026020010151905060006128278983600001516060015161078d565b9050600081600381111561283d5761283d6140b8565b148061285a57506003816003811115612858576128586140b8565b145b6128b057815160600151604080516001600160401b03808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c910160405180910390a1505050612ca5565b6060881561298f578a85815181106128ca576128ca614e64565b6020908102919091018101510151600454909150600090600160a01b900463ffffffff166128f88842614eca565b119050808061291857506003836003811115612916576129166140b8565b145b612940576040516354e7e43160e11b81526001600160401b038c166004820152602401610914565b8b868151811061295257612952614e64565b602002602001015160000151600014612989578b868151811061297757612977614e64565b60209081029190910101515160808501525b506129fb565b60008260038111156129a3576129a36140b8565b146129fb57825160600151604080516001600160401b03808e16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe65120910160405180910390a150505050612ca5565b8251608001516001600160401b031615612ad1576000826003811115612a2357612a236140b8565b03612ad15782516080015160208401516040516370701e5760e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612a81928f929190600401615af8565b6020604051808303816000875af1158015612aa0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ac49190615627565b612ad15750505050612ca5565b60008c604001518681518110612ae957612ae9614e64565b6020026020010151905080518460a001515114612b3357835160600151604051631cfe6d8b60e01b81526001600160401b03808e1660048301529091166024820152604401610914565b612b478b85600001516060015160016135e4565b600080612b55868486613689565b91509150612b6c8d876000015160600151846135e4565b8b15612bc3576003826003811115612b8657612b866140b8565b03612bc3576000856003811115612b9f57612b9f6140b8565b14612bc357855151604051632b11b8d960e01b815261091491908390600401615b24565b6002826003811115612bd757612bd76140b8565b14612c18576003826003811115612bf057612bf06140b8565b14612c18578551606001516040516349362d1f60e11b8152610914918f918590600401615b3d565b8560000151600001518660000151606001516001600160401b03168e6001600160401b03167f05665fe9ad095383d018353f4cbcba77e84db27dd215081bbf7cdf9ae6fbe48b8d8c81518110612c7057612c70614e64565b602002602001015186865a612c85908f614eca565b604051612c959493929190615b62565b60405180910390a4505050505050505b6001016127e4565b5050505050505050565b6040805180820190915260008082526020820152602086015160405163bbe4f6db60e01b81526001600160a01b0380831660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa158015612d3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d5f9190615b99565b90506001600160a01b0381161580612d8e5750612d8c6001600160a01b03821663aff2afbf60e01b611bdd565b155b15612db75760405163ae9b4ce960e01b81526001600160a01b0382166004820152602401610914565b600080612dcf88858c6040015163ffffffff1661373d565b915091506000806000612e826040518061010001604052808e81526020018c6001600160401b031681526020018d6001600160a01b031681526020018f608001518152602001896001600160a01b031681526020018f6000015181526020018f6060015181526020018b815250604051602401612e4c9190615bb6565b60408051601f198184030181529190526020810180516001600160e01b0316633907753760e01b17905287866113886084613822565b92509250925082612eaa578582604051634ff17cad60e11b8152600401610914929190615c82565b8151602014612ed9578151604051631e3be00960e21b8152602060048201526024810191909152604401610914565b600082806020019051810190612eef9190615ca4565b9050866001600160a01b03168c6001600160a01b031614612f6b576000612f208d8a612f1b868a614eca565b61373d565b50905086811080612f3a575081612f378883614eca565b14155b15612f695760405163a966e21f60e01b8152600481018390526024810188905260448101829052606401610914565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b6000612fac826301ffc9a760e01b612fcc565b80156107dc5750612fc5826001600160e01b0319612fcc565b1592915050565b6040516001600160e01b031982166024820152600090819060440160408051601f19818403018152919052602080820180516001600160e01b03166301ffc9a760e01b178152825192935060009283928392909183918a617530fa92503d9150600051905082801561303f575060208210155b801561304b5750600081115b979650505050505050565b8251600090815b81811015612cad57600060018886846020811061307c5761307c614e64565b61308991901a601b6159d3565b89858151811061309b5761309b614e64565b60200260200101518986815181106130b5576130b5614e64565b6020026020010151604051600081526020016040526040516130f3949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015613115573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b03851683528152858220858701909652855480841686529397509095509293928401916101009004166002811115613176576131766140b8565b6002811115613187576131876140b8565b90525090506001816020015160028111156131a4576131a46140b8565b146131c257604051636518c33d60e11b815260040160405180910390fd5b8051600160ff9091161b8516156131ec57604051633d9ef1f160e21b815260040160405180910390fd5b806000015160ff166001901b85179450505080600101905061305d565b60005b8151811015610a715760ff83166000908152600360205260408120835190919084908490811061323e5761323e614e64565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff1916905560010161320c565b60005b82518110156115a857600083828151811061329257613292614e64565b60200260200101519050600060028111156132af576132af6140b8565b60ff80871660009081526003602090815260408083206001600160a01b038716845290915290205461010090041660028111156132ee576132ee6140b8565b1461330f576004604051631b3fab5160e11b81526004016109149190615a10565b6001600160a01b0381166133365760405163d6c62c9b60e01b815260040160405180910390fd5b60405180604001604052808360ff16815260200184600281111561335c5761335c6140b8565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff1916176101008360028111156133b9576133b96140b8565b021790555090505050806001019050613275565b60ff818116600081815260026020526040902060010154620100009004909116906134255780613410576040516317bd8dd160e11b815260040160405180910390fd5b600b805467ffffffffffffffff191690555050565b60001960ff8316016115ec5780156115ec576040516307b8c74d60e51b815260040160405180910390fd5b6000818152600183016020526040812054613497575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556107dc565b5060006107dc565b81518051606080850151908301516080808701519401516040516000958695889561350395919490939192916020019485526001600160a01b039390931660208501526001600160401b039182166040850152606084015216608082015260a00190565b604051602081830303815290604052805190602001208560200151805190602001208660400151805190602001208760a001516040516020016135469190615d5e565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e0015b60405160208183030381529060405280519060200120905092915050565b6000806135b58585856138fc565b6001600160401b0387166000908152600a6020908152604080832093835292905220549150505b949350505050565b600060026135f3608085614ef3565b6001600160401b03166136069190614f19565b9050600061361485856118bc565b90508161362360016004614eca565b901b19168183600381111561363a5761363a6140b8565b6001600160401b03871660009081526009602052604081209190921b92909217918291613668608088615939565b6001600160401b031681526020810191909152604001600020555050505050565b604051630304c3e160e51b815260009060609030906360987c20906136b690889088908890600401615df5565b600060405180830381600087803b1580156136d057600080fd5b505af19250505080156136e1575060015b613720573d80801561370f576040519150601f19603f3d011682016040523d82523d6000602084013e613714565b606091505b50600392509050613735565b50506040805160208101909152600081526002905b935093915050565b600080600080600061379e8860405160240161376891906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166370a0823160e01b17905288886113886084613822565b925092509250826137c6578682604051634ff17cad60e11b8152600401610914929190615c82565b60208251146137f5578151604051631e3be00960e21b8152602060048201526024810191909152604401610914565b818060200190518101906138099190615ca4565b6138138288614eca565b94509450505050935093915050565b6000606060008361ffff166001600160401b0381111561384457613844613c3c565b6040519080825280601f01601f19166020018201604052801561386e576020820181803683370190505b509150863b6138885763030ed58f60e21b60005260046000fd5b5a858110156138a257632be8ca8b60e21b60005260046000fd5b85900360408104810387106138c2576337c3be2960e01b60005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d848111156138e55750835b808352806000602085013e50955095509592505050565b825182516000919081830361392457604051630469ac9960e21b815260040160405180910390fd5b610101821180159061393857506101018111155b613955576040516309bde33960e01b815260040160405180910390fd5b6000198282010161010081111561397f576040516309bde33960e01b815260040160405180910390fd5b806000036139ac578660008151811061399a5761399a614e64565b60200260200101519350505050613b7a565b6000816001600160401b038111156139c6576139c6613c3c565b6040519080825280602002602001820160405280156139ef578160200160208202803683370190505b50905060008080805b85811015613b195760006001821b8b811603613a535788851015613a3c578c5160018601958e918110613a2d57613a2d614e64565b60200260200101519050613a75565b8551600185019487918110613a2d57613a2d614e64565b8b5160018401938d918110613a6a57613a6a614e64565b602002602001015190505b600089861015613aa5578d5160018701968f918110613a9657613a96614e64565b60200260200101519050613ac7565b8651600186019588918110613abc57613abc614e64565b602002602001015190505b82851115613ae8576040516309bde33960e01b815260040160405180910390fd5b613af28282613b81565b878481518110613b0457613b04614e64565b602090810291909101015250506001016139f8565b506001850382148015613b2b57508683145b8015613b3657508581145b613b53576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613b6857613b68614e64565b60200260200101519750505050505050505b9392505050565b6000818310613b9957613b948284613b9f565b6107d9565b6107d983835b604080516001602082015290810183905260608101829052600090608001613589565b828054828255906000526020600020908101928215613c17579160200282015b82811115613c1757825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613be2565b50613c23929150613c27565b5090565b5b80821115613c235760008155600101613c28565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715613c7457613c74613c3c565b60405290565b60405160a081016001600160401b0381118282101715613c7457613c74613c3c565b60405160c081016001600160401b0381118282101715613c7457613c74613c3c565b604080519081016001600160401b0381118282101715613c7457613c74613c3c565b604051606081016001600160401b0381118282101715613c7457613c74613c3c565b604051601f8201601f191681016001600160401b0381118282101715613d2a57613d2a613c3c565b604052919050565b60006001600160401b03821115613d4b57613d4b613c3c565b5060051b60200190565b6001600160a01b038116811461052f57600080fd5b80356001600160401b0381168114613d8157600080fd5b919050565b801515811461052f57600080fd5b8035613d8181613d86565b60006001600160401b03821115613db857613db8613c3c565b50601f01601f191660200190565b600082601f830112613dd757600080fd5b8135613dea613de582613d9f565b613d02565b818152846020838601011115613dff57600080fd5b816020850160208301376000918101602001919091529392505050565b60006020808385031215613e2f57600080fd5b82356001600160401b0380821115613e4657600080fd5b818501915085601f830112613e5a57600080fd5b8135613e68613de582613d32565b81815260059190911b83018401908481019088831115613e8757600080fd5b8585015b83811015613f2d57803585811115613ea35760008081fd5b86016080818c03601f1901811315613ebb5760008081fd5b613ec3613c52565b89830135613ed081613d55565b81526040613edf848201613d6a565b8b830152606080850135613ef281613d86565b83830152928401359289841115613f0b57600091508182fd5b613f198f8d86880101613dc6565b908301525085525050918601918601613e8b565b5098975050505050505050565b60005b83811015613f55578181015183820152602001613f3d565b50506000910152565b60008151808452613f76816020860160208601613f3a565b601f01601f19169290920160200192915050565b6020815260006107d96020830184613f5e565b6001600160a01b0381511682526020810151151560208301526001600160401b03604082015116604083015260006060820151608060608501526135dc6080850182613f5e565b604080825283519082018190526000906020906060840190828701845b828110156140265781516001600160401b031684529284019290840190600101614001565b50505083810382850152845180825282820190600581901b8301840187850160005b8381101561407657601f19868403018552614064838351613f9d565b94870194925090860190600101614048565b50909998505050505050505050565b6000806040838503121561409857600080fd5b6140a183613d6a565b91506140af60208401613d6a565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b600481106140de576140de6140b8565b9052565b602081016107dc82846140ce565b600060a0828403121561410257600080fd5b61410a613c7a565b90508135815261411c60208301613d6a565b602082015261412d60408301613d6a565b604082015261413e60608301613d6a565b606082015261414f60808301613d6a565b608082015292915050565b8035613d8181613d55565b803563ffffffff81168114613d8157600080fd5b600082601f83011261418a57600080fd5b8135602061419a613de583613d32565b82815260059290921b840181019181810190868411156141b957600080fd5b8286015b848110156142895780356001600160401b03808211156141dd5760008081fd5b9088019060a0828b03601f19018113156141f75760008081fd5b6141ff613c7a565b87840135838111156142115760008081fd5b61421f8d8a83880101613dc6565b82525060408085013561423181613d55565b828a01526060614242868201614165565b8284015260809150818601358581111561425c5760008081fd5b61426a8f8c838a0101613dc6565b91840191909152509190930135908301525083529183019183016141bd565b509695505050505050565b600061014082840312156142a757600080fd5b6142af613c9c565b90506142bb83836140f0565b815260a08201356001600160401b03808211156142d757600080fd5b6142e385838601613dc6565b602084015260c08401359150808211156142fc57600080fd5b61430885838601613dc6565b604084015261431960e0850161415a565b6060840152610100840135608084015261012084013591508082111561433e57600080fd5b5061434b84828501614179565b60a08301525092915050565b600082601f83011261436857600080fd5b81356020614378613de583613d32565b82815260059290921b8401810191818101908684111561439757600080fd5b8286015b848110156142895780356001600160401b038111156143ba5760008081fd5b6143c88986838b0101614294565b84525091830191830161439b565b600082601f8301126143e757600080fd5b813560206143f7613de583613d32565b82815260059290921b8401810191818101908684111561441657600080fd5b8286015b848110156142895780356001600160401b038082111561443957600080fd5b818901915089603f83011261444d57600080fd5b8582013561445d613de582613d32565b81815260059190911b830160400190878101908c83111561447d57600080fd5b604085015b838110156144b65780358581111561449957600080fd5b6144a88f6040838a0101613dc6565b845250918901918901614482565b5087525050509284019250830161441a565b600082601f8301126144d957600080fd5b813560206144e9613de583613d32565b8083825260208201915060208460051b87010193508684111561450b57600080fd5b602086015b848110156142895780358352918301918301614510565b600082601f83011261453857600080fd5b81356020614548613de583613d32565b82815260059290921b8401810191818101908684111561456757600080fd5b8286015b848110156142895780356001600160401b038082111561458b5760008081fd5b9088019060a0828b03601f19018113156145a55760008081fd5b6145ad613c7a565b6145b8888501613d6a565b8152604080850135848111156145ce5760008081fd5b6145dc8e8b83890101614357565b8a84015250606080860135858111156145f55760008081fd5b6146038f8c838a01016143d6565b838501525060809150818601358581111561461e5760008081fd5b61462c8f8c838a01016144c8565b918401919091525091909301359083015250835291830191830161456b565b6000806040838503121561465e57600080fd5b6001600160401b038335111561467357600080fd5b6146808484358501614527565b91506001600160401b036020840135111561469a57600080fd5b6020830135830184601f8201126146b057600080fd5b6146bd613de58235613d32565b81358082526020808301929160051b8401018710156146db57600080fd5b602083015b6020843560051b850101811015614881576001600160401b038135111561470657600080fd5b87603f82358601011261471857600080fd5b61472b613de56020833587010135613d32565b81358501602081810135808452908301929160059190911b016040018a101561475357600080fd5b604083358701015b83358701602081013560051b01604001811015614871576001600160401b038135111561478757600080fd5b833587018135016040818d03603f190112156147a257600080fd5b6147aa613cbe565b604082013581526001600160401b03606083013511156147c957600080fd5b8c605f6060840135840101126147de57600080fd5b60406060830135830101356147f5613de582613d32565b808282526020820191508f60608460051b606088013588010101111561481a57600080fd5b6060808601358601015b60608460051b6060880135880101018110156148515761484381614165565b835260209283019201614824565b50806020850152505050808552505060208301925060208101905061475b565b50845250602092830192016146e0565b508093505050509250929050565b60008083601f8401126148a157600080fd5b5081356001600160401b038111156148b857600080fd5b6020830191508360208260051b85010111156148d357600080fd5b9250929050565b6000806000806000606086880312156148f257600080fd5b85356001600160401b038082111561490957600080fd5b61491589838a01614294565b9650602088013591508082111561492b57600080fd5b61493789838a0161488f565b9096509450604088013591508082111561495057600080fd5b5061495d8882890161488f565b969995985093965092949392505050565b60006080828403121561498057600080fd5b614988613c52565b823561499381613d55565b81526149a160208401614165565b602082015260408301356149b481613d86565b604082015260608301356149c781613d55565b60608201529392505050565b6000602082840312156149e557600080fd5b81356001600160401b038111156149fb57600080fd5b820160a08185031215613b7a57600080fd5b803560ff81168114613d8157600080fd5b600060208284031215614a3057600080fd5b6107d982614a0d565b60008151808452602080850194506020840160005b83811015614a735781516001600160a01b031687529582019590820190600101614a4e565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614acd60e0840182614a39565b90506040840151601f198483030160c0850152614aea8282614a39565b95945050505050565b60008060408385031215614b0657600080fd5b614b0f83613d6a565b946020939093013593505050565b80604081018310156107dc57600080fd5b60008083601f840112614b4057600080fd5b5081356001600160401b03811115614b5757600080fd5b6020830191508360208285010111156148d357600080fd5b60008060008060008060008060c0898b031215614b8b57600080fd5b614b958a8a614b1d565b975060408901356001600160401b0380821115614bb157600080fd5b614bbd8c838d01614b2e565b909950975060608b0135915080821115614bd657600080fd5b614be28c838d0161488f565b909750955060808b0135915080821115614bfb57600080fd5b50614c088b828c0161488f565b999c989b50969995989497949560a00135949350505050565b600060208284031215614c3357600080fd5b6107d982613d6a565b6020815260006107d96020830184613f9d565b600060208284031215614c6157600080fd5b8135613b7a81613d55565b600080600060608486031215614c8157600080fd5b614c8b8585614b1d565b925060408401356001600160401b03811115614ca657600080fd5b614cb286828701614b2e565b9497909650939450505050565b600082601f830112614cd057600080fd5b81356020614ce0613de583613d32565b8083825260208201915060208460051b870101935086841115614d0257600080fd5b602086015b84811015614289578035614d1a81613d55565b8352918301918301614d07565b60006020808385031215614d3a57600080fd5b82356001600160401b0380821115614d5157600080fd5b818501915085601f830112614d6557600080fd5b8135614d73613de582613d32565b81815260059190911b83018401908481019088831115614d9257600080fd5b8585015b83811015613f2d57803585811115614dad57600080fd5b860160c0818c03601f19011215614dc45760008081fd5b614dcc613c9c565b8882013581526040614ddf818401614a0d565b8a8301526060614df0818501614a0d565b8284015260809150614e03828501613d94565b9083015260a08381013589811115614e1b5760008081fd5b614e298f8d83880101614cbf565b838501525060c0840135915088821115614e435760008081fd5b614e518e8c84870101614cbf565b9083015250845250918601918601614d96565b634e487b7160e01b600052603260045260246000fd5b600181811c90821680614e8e57607f821691505b602082108103614eae57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b818103818111156107dc576107dc614eb4565b634e487b7160e01b600052601260045260246000fd5b60006001600160401b0380841680614f0d57614f0d614edd565b92169190910692915050565b80820281158282048414176107dc576107dc614eb4565b80518252600060206001600160401b0381840151168185015260408084015160a06040870152614f6360a0870182613f5e565b905060608501518682036060880152614f7c8282613f5e565b608087810151898303918a01919091528051808352908601935060009250908501905b80831015614fd157835180516001600160a01b0316835286015186830152928501926001929092019190840190614f9f565b50979650505050505050565b6020815260006107d96020830184614f30565b6080815260006150036080830187614f30565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b60008060006060848603121561504157600080fd5b835161504c81613d86565b60208501519093506001600160401b0381111561506857600080fd5b8401601f8101861361507957600080fd5b8051615087613de582613d9f565b81815287602083850101111561509c57600080fd5b6150ad826020830160208601613f3a565b809450505050604084015190509250925092565b80356001600160e01b0381168114613d8157600080fd5b600082601f8301126150e957600080fd5b813560206150f9613de583613d32565b82815260069290921b8401810191818101908684111561511857600080fd5b8286015b8481101561428957604081890312156151355760008081fd5b61513d613cbe565b61514682613d6a565b81526151538583016150c1565b8186015283529183019160400161511c565b600082601f83011261517657600080fd5b81356020615186613de583613d32565b82815260059290921b840181019181810190868411156151a557600080fd5b8286015b848110156142895780356001600160401b03808211156151c95760008081fd5b9088019060a0828b03601f19018113156151e35760008081fd5b6151eb613c7a565b6151f6888501613d6a565b81526040808501358481111561520c5760008081fd5b61521a8e8b83890101613dc6565b8a840152506060935061522e848601613d6a565b90820152608061523f858201613d6a565b938201939093529201359082015283529183019183016151a9565b600082601f83011261526b57600080fd5b8135602061527b613de583613d32565b82815260069290921b8401810191818101908684111561529a57600080fd5b8286015b8481101561428957604081890312156152b75760008081fd5b6152bf613cbe565b81358152848201358582015283529183019160400161529e565b600060208083850312156152ec57600080fd5b82356001600160401b038082111561530357600080fd5b908401906060828703121561531757600080fd5b61531f613ce0565b82358281111561532e57600080fd5b8301604081890381131561534157600080fd5b615349613cbe565b82358581111561535857600080fd5b8301601f81018b1361536957600080fd5b8035615377613de582613d32565b81815260069190911b8201890190898101908d83111561539657600080fd5b928a01925b828410156153e65785848f0312156153b35760008081fd5b6153bb613cbe565b84356153c681613d55565b81526153d3858d016150c1565b818d0152825292850192908a019061539b565b8452505050828701359150848211156153fe57600080fd5b61540a8a8385016150d8565b8188015283525050828401358281111561542357600080fd5b61542f88828601615165565b8583015250604083013593508184111561544857600080fd5b6154548785850161525a565b60408201529695505050505050565b600082825180855260208086019550808260051b84010181860160005b848110156154f457601f19868403018952815160a06001600160401b038083511686528683015182888801526154b883880182613f5e565b60408581015184169089015260608086015190931692880192909252506080928301519290950191909152509783019790830190600101615480565b5090979650505050505050565b6001600160a01b0384168152600060206060818401526155246060840186615463565b83810360408581019190915285518083528387019284019060005b818110156140765784518051845286015186840152938501939183019160010161553f565b805160408084528151848201819052600092602091908201906060870190855b818110156155bb57835180516001600160a01b031684528501516001600160e01b0316858401529284019291850191600101615584565b50508583015187820388850152805180835290840192506000918401905b80831015614fd157835180516001600160401b031683528501516001600160e01b0316858301529284019260019290920191908501906155d9565b6020815260006107d96020830184615564565b60006020828403121561563957600080fd5b8151613b7a81613d86565b600080835461565281614e7a565b6001828116801561566a576001811461567f576156ae565b60ff19841687528215158302870194506156ae565b8760005260208060002060005b858110156156a55781548a82015290840190820161568c565b50505082870194505b50929695505050505050565b600081546156c781614e7a565b8085526020600183811680156156e457600181146156fe5761572c565b60ff1985168884015283151560051b88018301955061572c565b866000528260002060005b858110156157245781548a8201860152908301908401615709565b890184019650505b505050505092915050565b60408152600061574a6040830185613f5e565b8281036020840152614aea81856156ba565b6001600160401b0381811683821601908082111561577c5761577c614eb4565b5092915050565b6040815260006157966040830185615463565b8281036020840152614aea8185615564565b6000602082840312156157ba57600080fd5b81356001600160401b038111156157d057600080fd5b6135dc84828501614527565b601f821115610a71576000816000526020600020601f850160051c810160208610156158055750805b601f850160051c820191505b8181101561582457828155600101615811565b505050505050565b81516001600160401b0381111561584557615845613c3c565b615859816158538454614e7a565b846157dc565b602080601f83116001811461588e57600084156158765750858301515b600019600386901b1c1916600185901b178555615824565b600085815260208120601f198616915b828110156158bd5788860151825594840194600190910190840161589e565b50858210156158db5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60208152600082546001600160a01b038116602084015260ff8160a01c16151560408401526001600160401b038160a81c166060840152506080808301526107d960a08301600185016156ba565b60006001600160401b038084168061595357615953614edd565b92169190910492915050565b60006020828403121561597157600080fd5b6107d982614165565b6000808335601e1984360301811261599157600080fd5b8301803591506001600160401b038211156159ab57600080fd5b6020019150368190038213156148d357600080fd5b808201808211156107dc576107dc614eb4565b60ff81811683821601908111156107dc576107dc614eb4565b8183823760009101908152919050565b828152604082602083013760600192915050565b6020810160068310615a2457615a246140b8565b91905290565b60ff818116838216029081169081811461577c5761577c614eb4565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615a9e5784546001600160a01b031683526001948501949284019201615a79565b50508481036060860152865180825290820192508187019060005b81811015615ade5782516001600160a01b031685529383019391830191600101615ab9565b50505060ff851660808501525090505b9695505050505050565b60006001600160401b03808616835280851660208401525060606040830152614aea6060830184613f5e565b8281526040602082015260006135dc6040830184613f5e565b6001600160401b03848116825283166020820152606081016135dc60408301846140ce565b848152615b7260208201856140ce565b608060408201526000615b886080830185613f5e565b905082606083015295945050505050565b600060208284031215615bab57600080fd5b8151613b7a81613d55565b6020815260008251610100806020850152615bd5610120850183613f5e565b91506020850151615bf160408601826001600160401b03169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615c2b60a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615c488483613f5e565b935060c08701519150808685030160e0870152615c658483613f5e565b935060e0870151915080868503018387015250615aee8382613f5e565b6001600160a01b03831681526040602082015260006135dc6040830184613f5e565b600060208284031215615cb657600080fd5b5051919050565b600082825180855260208086019550808260051b84010181860160005b848110156154f457601f19868403018952815160a08151818652615d0082870182613f5e565b9150506001600160a01b03868301511686860152604063ffffffff8184015116818701525060608083015186830382880152615d3c8382613f5e565b6080948501519790940196909652505098840198925090830190600101615cda565b6020815260006107d96020830184615cbd565b60008282518085526020808601955060208260051b8401016020860160005b848110156154f457601f19868403018952615dac838351613f5e565b98840198925090830190600101615d90565b60008151808452602080850194506020840160005b83811015614a7357815163ffffffff1687529582019590820190600101615dd3565b60608152600084518051606084015260208101516001600160401b0380821660808601528060408401511660a08601528060608401511660c08601528060808401511660e0860152505050602085015161014080610100850152615e5d6101a0850183613f5e565b91506040870151605f198086850301610120870152615e7c8483613f5e565b935060608901519150615e99838701836001600160a01b03169052565b608089015161016087015260a0890151925080868503016101808701525050615ec28282615cbd565b9150508281036020840152615ed78186615d71565b90508281036040840152615aee8185615dbe56fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"contractIRMNRemote\",\"name\":\"rmnRemote\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isRMNVerificationDisabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"messageInterceptor\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reportOnRamp\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"configOnRamp\",\"type\":\"bytes\"}],\"name\":\"CommitOnRampMismatch\",\"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\":\"EmptyBatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"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\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"tokenIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"oldLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenGasOverride\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionTokenGasOverride\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"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\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidOnRampUpdate\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionGasAmountCountMismatch\",\"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\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"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\":\"SignatureVerificationNotAllowedInExecutionPlugin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignatureVerificationRequiredInCommitPlugin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"reportSourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"messageSourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorMismatch\",\"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\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"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\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRampAddress\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"maxSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structInternal.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"},{\"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[]\"}],\"indexed\":false,\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"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\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isRMNVerificationDisabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"messageInterceptor\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.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\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"name\":\"ExecutionStateChanged\",\"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\"}],\"name\":\"SkippedReportExecution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structOffRamp.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\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"contractIRMNRemote\",\"name\":\"rmnRemote\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.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\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.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[2]\",\"name\":\"reportContext\",\"type\":\"bytes32[2]\"},{\"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[2]\",\"name\":\"reportContext\",\"type\":\"bytes32[2]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"destTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destGasAmount\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.Any2EVMTokenTransfer[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"uint32[]\",\"name\":\"tokenGasOverrides\",\"type\":\"uint32[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllSourceChainConfigs\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isRMNVerificationDisabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"messageInterceptor\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.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\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"contractIRMNRemote\",\"name\":\"rmnRemote\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"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\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"destTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destGasAmount\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.Any2EVMTokenTransfer[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receiverExecutionGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint32[]\",\"name\":\"tokenGasOverrides\",\"type\":\"uint32[]\"}],\"internalType\":\"structOffRamp.GasLimitOverride[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"tuple[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isRMNVerificationDisabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"messageInterceptor\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"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: "0x6101406040523480156200001257600080fd5b5060405162006d0638038062006d06833981016040819052620000359162000936565b336000816200005757604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008a576200008a81620001dc565b50504660805260408301516001600160a01b03161580620000b6575060608301516001600160a01b0316155b80620000cd575060808301516001600160a01b0316155b15620000ec576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b0316600003620001185760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a0908152604080860180516001600160a01b0390811660c05260608089018051831660e0526080808b0180518516610100526020808d01805161ffff9081166101205289518f51909c168c52905116908a0152945184169588019590955251821690860152905116908301527fb0fa1fb01508c5097c502ad056fd77018870c9be9a86d9e56b6b471862d7c5b7910160405180910390a1620001c88262000256565b620001d38162000344565b50505062000cde565b336001600160a01b038216036200020657604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03166200027f576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516001600160a01b039889166001600160c01b03199097168717600160a01b63ffffffff958616021760ff60c01b1916600160c01b911515919091021790965560608089018051600580546001600160a01b031916918b169190911790558251968752935190921693850193909352935115159183019190915251909216908201527fcbb53bda7106a610de67df506ac86b65c44d5afac0fd2b11070dc2d61a6f2dee9060800160405180910390a150565b60005b8151811015620005d957600082828151811062000368576200036862000a16565b60200260200101519050600081602001519050806001600160401b0316600003620003a65760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b0316620003cf576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b03811660009081526008602052604090206060830151600182018054620003fd9062000a2c565b905060000362000460578154600160a81b600160e81b031916600160a81b1782556040516001600160401b03841681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620004d1565b8154600160a81b90046001600160401b0316600114801590620004a35750805160208201206040516200049890600185019062000a68565b604051809103902014155b15620004d157604051632105803760e11b81526001600160401b038416600482015260240160405180910390fd5b80511580620005075750604080516000602082015201604051602081830303815290604052805190602001208180519060200120145b1562000526576040516342bcdf7f60e11b815260040160405180910390fd5b6001820162000536828262000b3b565b506040840151825485516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b0319909116171782556200058560066001600160401b038516620005dd565b50826001600160401b03167f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b83604051620005c1919062000c07565b60405180910390a25050505080600101905062000347565b5050565b6000620005eb8383620005f4565b90505b92915050565b60008181526001830160205260408120546200063d57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620005ee565b506000620005ee565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b038111828210171562000681576200068162000646565b60405290565b60405160a081016001600160401b038111828210171562000681576200068162000646565b604051601f8201601f191681016001600160401b0381118282101715620006d757620006d762000646565b604052919050565b80516001600160401b0381168114620006f757600080fd5b919050565b6001600160a01b03811681146200071257600080fd5b50565b80518015158114620006f757600080fd5b6000608082840312156200073957600080fd5b620007436200065c565b905081516200075281620006fc565b8152602082015163ffffffff811681146200076c57600080fd5b60208201526200077f6040830162000715565b604082015260608201516200079481620006fc565b606082015292915050565b6000601f83601f840112620007b357600080fd5b825160206001600160401b0380831115620007d257620007d262000646565b8260051b620007e3838201620006ac565b9384528681018301938381019089861115620007fe57600080fd5b84890192505b8583101562000929578251848111156200081e5760008081fd5b89016080601f19828d038101821315620008385760008081fd5b620008426200065c565b888401516200085181620006fc565b8152604062000862858201620006df565b8a83015260606200087581870162000715565b838301529385015193898511156200088d5760008081fd5b84860195508f603f870112620008a557600094508485fd5b8a860151945089851115620008be57620008be62000646565b620008cf8b858f88011601620006ac565b93508484528f82868801011115620008e75760008081fd5b60005b8581101562000907578681018301518582018d01528b01620008ea565b5060009484018b01949094525091820152835250918401919084019062000804565b9998505050505050505050565b60008060008385036101408112156200094e57600080fd5b60a08112156200095d57600080fd5b506200096862000687565b6200097385620006df565b8152602085015161ffff811681146200098b57600080fd5b60208201526040850151620009a081620006fc565b60408201526060850151620009b581620006fc565b60608201526080850151620009ca81620006fc565b60808201529250620009e08560a0860162000726565b6101208501519092506001600160401b03811115620009fe57600080fd5b62000a0c868287016200079f565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4157607f821691505b60208210810362000a6257634e487b7160e01b600052602260045260246000fd5b50919050565b600080835462000a788162000a2c565b6001828116801562000a93576001811462000aa95762000ada565b60ff198416875282151583028701945062000ada565b8760005260208060002060005b8581101562000ad15781548a82015290840190820162000ab6565b50505082870194505b50929695505050505050565b601f82111562000b36576000816000526020600020601f850160051c8101602086101562000b115750805b601f850160051c820191505b8181101562000b325782815560010162000b1d565b5050505b505050565b81516001600160401b0381111562000b575762000b5762000646565b62000b6f8162000b68845462000a2c565b8462000ae6565b602080601f83116001811462000ba7576000841562000b8e5750858301515b600019600386901b1c1916600185901b17855562000b32565b600085815260208120601f198616915b8281101562000bd85788860151825594840194600190910190840162000bb7565b508582101562000bf75787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000c5c8162000a2c565b8060a089015260c0600183166000811462000c80576001811462000c9d5762000ccf565b60ff19841660c08b015260c083151560051b8b0101945062000ccf565b85600052602060002060005b8481101562000cc65781548c820185015290880190890162000ca9565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e0516101005161012051615f8b62000d7b600039600081816101b001528181610ce801528181612ed1015261380b0152600081816102380152612aa10152600081816102090152612d490152600081816101da01528181610fcc0152818161117c01526124a10152600081816101810152818161264c015261270301526000818161195b015261198e0152615f8b6000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c80637edf52f4116100ad578063de5e0b9a11610071578063de5e0b9a146104eb578063e9d68a8e146104fe578063f2fde38b1461051e578063f58e03fc14610531578063f716f99f1461054457600080fd5b80637edf52f41461044b57806385572ffb1461045e5780638da5cb5b1461046c578063c673e58414610487578063ccd37ba3146104a757600080fd5b80635e36480c116100f45780635e36480c146103405780635e7bb0081461036057806360987c20146103735780637437ff9f1461038657806379ba50971461044357600080fd5b806304666f9c1461013157806306285c6914610146578063181f5a77146102c65780633f4b04aa1461030f5780635215505b1461032a575b600080fd5b61014461013f366004613eaf565b610557565b005b6102686040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040518060a001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160401b031681526020017f000000000000000000000000000000000000000000000000000000000000000061ffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040805182516001600160401b0316815260208084015161ffff1690820152828201516001600160a01b03908116928201929092526060808401518316908201526080928301519091169181019190915260a0015b60405180910390f35b6103026040518060400160405280601181526020017f4f666652616d7020312e362e302d64657600000000000000000000000000000081525081565b6040516102bd919061401d565b600b546040516001600160401b0390911681526020016102bd565b61033261056b565b6040516102bd929190614077565b61035361034e366004614118565b6107c6565b6040516102bd9190614175565b61014461036e3660046146de565b61081b565b61014461038136600461496d565b610aaf565b6103fc60408051608081018252600080825260208201819052918101829052606081019190915250604080516080810182526004546001600160a01b038082168352600160a01b820463ffffffff166020840152600160c01b90910460ff16151592820192909252600554909116606082015290565b6040516102bd919081516001600160a01b03908116825260208084015163ffffffff1690830152604080840151151590830152606092830151169181019190915260800190565b610144610d8a565b610144610459366004614a01565b610e0d565b61014461012c366004614a66565b6001546040516001600160a01b0390911681526020016102bd565b61049a610495366004614ab1565b610e1e565b6040516102bd9190614b11565b6104dd6104b5366004614b86565b6001600160401b03919091166000908152600a60209081526040808320938352929052205490565b6040519081526020016102bd565b6101446104f9366004614c02565b610f7c565b61051161050c366004614cb4565b61147f565b6040516102bd9190614ccf565b61014461052c366004614ce2565b61158b565b61014461053f366004614cff565b61159c565b610144610552366004614dba565b611605565b61055f611647565b61056881611674565b50565b606080600061057a60066118fd565b6001600160401b0381111561059157610591613ccf565b6040519080825280602002602001820160405280156105e257816020015b60408051608081018252600080825260208083018290529282015260608082015282526000199092019101816105af5790505b50905060006105f160066118fd565b6001600160401b0381111561060857610608613ccf565b604051908082528060200260200182016040528015610631578160200160208202803683370190505b50905060005b61064160066118fd565b8110156107bd57610653600682611907565b82828151811061066557610665614ef7565b60200260200101906001600160401b031690816001600160401b0316815250506008600083838151811061069b5761069b614ef7565b6020908102919091018101516001600160401b039081168352828201939093526040918201600020825160808101845281546001600160a01b038116825260ff600160a01b820416151593820193909352600160a81b9092049093169181019190915260018201805491929160608401919061071690614f0d565b80601f016020809104026020016040519081016040528092919081815260200182805461074290614f0d565b801561078f5780601f106107645761010080835404028352916020019161078f565b820191906000526020600020905b81548152906001019060200180831161077257829003601f168201915b5050505050815250508382815181106107aa576107aa614ef7565b6020908102919091010152600101610637565b50939092509050565b60006107d460016004614f5d565b60026107e1608085614f86565b6001600160401b03166107f49190614fac565b6107fe8585611913565b901c1660038111156108125761081261414b565b90505b92915050565b610823611958565b815181518114610846576040516320f8fd5960e21b815260040160405180910390fd5b60005b81811015610a9f57600084828151811061086557610865614ef7565b6020026020010151905060008160200151519050600085848151811061088d5761088d614ef7565b60200260200101519050805182146108b8576040516320f8fd5960e21b815260040160405180910390fd5b60005b82811015610a905760008282815181106108d7576108d7614ef7565b60200260200101516000015190506000856020015183815181106108fd576108fd614ef7565b6020026020010151905081600014610956578060800151821015610956578551815151604051633a98d46360e11b81526001600160401b0390921660048301526024820152604481018390526064015b60405180910390fd5b83838151811061096857610968614ef7565b602002602001015160200151518160a0015151146109b557805180516060909101516040516370a193fd60e01b815260048101929092526001600160401b0316602482015260440161094d565b60005b8160a0015151811015610a825760008585815181106109d9576109d9614ef7565b60200260200101516020015182815181106109f6576109f6614ef7565b602002602001015163ffffffff16905080600014610a795760008360a001518381518110610a2657610a26614ef7565b60200260200101516040015163ffffffff16905080821015610a77578351516040516348e617b360e01b8152600481019190915260248101849052604481018290526064810183905260840161094d565b505b506001016109b8565b5050508060010190506108bb565b50505050806001019050610849565b50610aaa83836119c0565b505050565b333014610acf576040516306e34e6560e31b815260040160405180910390fd5b6040805160008082526020820190925281610b0c565b6040805180820190915260008082526020820152815260200190600190039081610ae55790505b5060a08701515190915015610b4257610b3f8660a001518760200151886060015189600001516020015189898989611a83565b90505b6040805160a081018252875151815287516020908101516001600160401b03168183015288015181830152908701516060820152608081018290526005546001600160a01b03168015610c35576040516308d450a160e01b81526001600160a01b038216906308d450a190610bbb908590600401615070565b600060405180830381600087803b158015610bd557600080fd5b505af1925050508015610be6575060015b610c35573d808015610c14576040519150601f19603f3d011682016040523d82523d6000602084013e610c19565b606091505b50806040516309c2532560e01b815260040161094d919061401d565b604088015151158015610c4a57506080880151155b80610c61575060608801516001600160a01b03163b155b80610c8857506060880151610c86906001600160a01b03166385572ffb60e01b611c34565b155b15610c9557505050610d83565b87516020908101516001600160401b03166000908152600890915260408082205460808b015160608c01519251633cf9798360e01b815284936001600160a01b0390931692633cf9798392610d119289927f00000000000000000000000000000000000000000000000000000000000000009291600401615083565b6000604051808303816000875af1158015610d30573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d5891908101906150bf565b509150915081610d7d57806040516302a35ba360e21b815260040161094d919061401d565b50505050505b5050505050565b6000546001600160a01b03163314610db55760405163015aa1e360e11b815260040160405180910390fd5b600180546001600160a01b0319808216339081179093556000805490911681556040516001600160a01b03909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e15611647565b61056881611c50565b610e616040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610f0a57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610eec575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610f6c57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610f4e575b5050505050815250509050919050565b6000610f8a8789018961536c565b6004805491925090600160c01b900460ff1661103457602082015151156110345760208201516040808401519051633854844f60e11b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016926370a9089e926110039230929190600401615594565b60006040518083038186803b15801561101b57600080fd5b505afa15801561102f573d6000803e3d6000fd5b505050505b8151515115158061104a57508151602001515115155b1561111557600b5460208b0135906001600160401b03808316911610156110ed57600b805467ffffffffffffffff19166001600160401b03831617905581548351604051633937306f60e01b81526001600160a01b0390921691633937306f916110b6916004016156a7565b600060405180830381600087803b1580156110d057600080fd5b505af11580156110e4573d6000803e3d6000fd5b50505050611113565b82602001515160000361111357604051632261116760e01b815260040160405180910390fd5b505b60005b8260200151518110156113cb5760008360200151828151811061113d5761113d614ef7565b60209081029190910101518051604051632cbc26bb60e01b815267ffffffffffffffff60801b608083901b166004820152919250906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa1580156111c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e791906156ba565b1561121057604051637edeb53960e11b81526001600160401b038216600482015260240161094d565b600061121b82611d55565b90508060010160405161122e91906156d7565b60405180910390208360200151805190602001201461126b5782602001518160010160405163b80d8fa960e01b815260040161094d9291906157ca565b60408301518154600160a81b90046001600160401b0390811691161415806112ac575082606001516001600160401b031683604001516001600160401b0316115b156112f157825160408085015160608601519151636af0786b60e11b81526001600160401b03938416600482015290831660248201529116604482015260640161094d565b6080830151806113145760405163504570e360e01b815260040160405180910390fd5b83516001600160401b03166000908152600a602090815260408083208484529091529020541561136c5783516040516332cf0cbf60e01b81526001600160401b0390911660048201526024810182905260440161094d565b606084015161137c9060016157ef565b825467ffffffffffffffff60a81b1916600160a81b6001600160401b0392831602179092559251166000908152600a602090815260408083209483529390529190912042905550600101611118565b50602082015182516040517f35c02761bcd3ef995c6a601a1981f4ed3934dcbe5041e24e286c89f5531d17e492611403929091615816565b60405180910390a1610d7d60008b8b8b8b8b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808f0282810182019093528e82529093508e92508d9182918501908490808284376000920191909152508c9250611da1915050565b60408051608080820183526000808352602080840182905283850182905260608085018190526001600160401b03878116845260088352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b90920490921694830194909452600184018054939492939184019161150b90614f0d565b80601f016020809104026020016040519081016040528092919081815260200182805461153790614f0d565b8015610f6c5780601f1061155957610100808354040283529160200191610f6c565b820191906000526020600020905b81548152906001019060200180831161156757505050919092525091949350505050565b611593611647565b6105688161209a565b6115dc6115ab8284018461583b565b60408051600080825260208201909252906115d6565b60608152602001906001900390816115c15790505b506119c0565b6040805160008082526020820190925290506115ff600185858585866000611da1565b50505050565b61160d611647565b60005b81518110156116435761163b82828151811061162e5761162e614ef7565b6020026020010151612113565b600101611610565b5050565b6001546001600160a01b03163314611672576040516315ae3a6f60e11b815260040160405180910390fd5b565b60005b815181101561164357600082828151811061169457611694614ef7565b60200260200101519050600081602001519050806001600160401b03166000036116d15760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166116f9576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600860205260409020606083015160018201805461172590614f0d565b905060000361178757815467ffffffffffffffff60a81b1916600160a81b1782556040516001600160401b03841681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a16117f0565b8154600160a81b90046001600160401b03166001148015906117c75750805160208201206040516117bc9060018501906156d7565b604051809103902014155b156117f057604051632105803760e11b81526001600160401b038416600482015260240161094d565b805115806118255750604080516000602082015201604051602081830303815290604052805190602001208180519060200120145b15611843576040516342bcdf7f60e11b815260040160405180910390fd5b6001820161185182826158bf565b506040840151825485516001600160a01b03166001600160a01b0319921515600160a01b029290921674ffffffffffffffffffffffffffffffffffffffffff19909116171782556118ac60066001600160401b03851661243d565b50826001600160401b03167f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b836040516118e6919061597e565b60405180910390a250505050806001019050611677565b6000610815825490565b60006108128383612449565b6001600160401b0382166000908152600960205260408120816119376080856159cc565b6001600160401b031681526020810191909152604001600020549392505050565b467f00000000000000000000000000000000000000000000000000000000000000001461167257604051630f01ce8560e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015246602482015260440161094d565b81516000036119e25760405163c2e5347d60e01b815260040160405180910390fd5b80516040805160008082526020820190925291159181611a25565b6040805180820190915260008152606060208201528152602001906001900390816119fd5790505b50905060005b8451811015610d8357611a7b858281518110611a4957611a49614ef7565b602002602001015184611a7557858381518110611a6857611a68614ef7565b6020026020010151612473565b83612473565b600101611a2b565b606088516001600160401b03811115611a9e57611a9e613ccf565b604051908082528060200260200182016040528015611ae357816020015b6040805180820190915260008082526020820152815260200190600190039081611abc5790505b509050811560005b8a51811015611c265781611b8357848482818110611b0b57611b0b614ef7565b9050602002016020810190611b2091906159f2565b63ffffffff1615611b8357848482818110611b3d57611b3d614ef7565b9050602002016020810190611b5291906159f2565b8b8281518110611b6457611b64614ef7565b60200260200101516040019063ffffffff16908163ffffffff16815250505b611c018b8281518110611b9857611b98614ef7565b60200260200101518b8b8b8b8b87818110611bb557611bb5614ef7565b9050602002810190611bc79190615a0d565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612d0e92505050565b838281518110611c1357611c13614ef7565b6020908102919091010152600101611aeb565b505098975050505050505050565b6000611c3f8361300e565b801561081257506108128383613041565b80516001600160a01b0316611c78576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516001600160a01b039889167fffffffffffffffff0000000000000000000000000000000000000000000000009097168717600160a01b63ffffffff958616021760ff60c01b1916600160c01b911515919091021790965560608089018051600580546001600160a01b031916918b169190911790558251968752935190921693850193909352935115159183019190915251909216908201527fcbb53bda7106a610de67df506ac86b65c44d5afac0fd2b11070dc2d61a6f2dee9060800160405180910390a150565b6001600160401b03811660009081526008602052604081208054600160a01b900460ff166108155760405163ed053c5960e01b81526001600160401b038416600482015260240161094d565b60ff87811660009081526002602090815260408083208151608081018352815481526001909101548086169382019390935261010083048516918101919091526201000090910490921615156060830152873590611e00876084615a53565b9050826060015115611e48578451611e19906020614fac565b8651611e26906020614fac565b611e319060a0615a53565b611e3b9190615a53565b611e459082615a53565b90505b368114611e7157604051638e1192e160e01b81526004810182905236602482015260440161094d565b5081518114611ea05781516040516324f7d61360e21b815260048101919091526024810182905260440161094d565b611ea8611958565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611ef657611ef661414b565b6002811115611f0757611f0761414b565b9052509050600281602001516002811115611f2457611f2461414b565b148015611f785750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611f6057611f60614ef7565b6000918252602090912001546001600160a01b031633145b611f9557604051631b41e11d60e31b815260040160405180910390fd5b50816060015115612045576020820151611fb0906001615a66565b60ff16855114611fd3576040516371253a2560e01b815260040160405180910390fd5b8351855114611ff55760405163a75d88af60e01b815260040160405180910390fd5b60008787604051612007929190615a7f565b60405190819003812061201e918b90602001615a8f565b6040516020818303038152906040528051906020012090506120438a828888886130cb565b505b6040805182815260208a8101356001600160401b03169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b336001600160a01b038216036120c357604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff1660000361213e576000604051631b3fab5160e11b815260040161094d9190615aa3565b60208082015160ff8082166000908152600290935260408320600181015492939092839216900361218f576060840151600182018054911515620100000262ff0000199092169190911790556121cb565b6060840151600182015460ff62010000909104161515901515146121cb576040516321fd80df60e21b815260ff8416600482015260240161094d565b60a0840151805161010010156121f7576001604051631b3fab5160e11b815260040161094d9190615aa3565b805160000361221c576005604051631b3fab5160e11b815260040161094d9190615aa3565b612282848460030180548060200260200160405190810160405280929190818152602001828054801561227857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161225a575b505050505061327e565b8460600151156123b2576122f08484600201805480602002602001604051908101604052809291908181526020018280548015612278576020028201919060005260206000209081546001600160a01b0316815260019091019060200180831161225a57505050505061327e565b60808501518051610100101561231c576002604051631b3fab5160e11b815260040161094d9190615aa3565b604086015161232c906003615abd565b60ff16815111612352576003604051631b3fab5160e11b815260040161094d9190615aa3565b815181511015612378576001604051631b3fab5160e11b815260040161094d9190615aa3565b805160018401805461ff00191661010060ff8416021790556123a39060028601906020840190613c55565b506123b0858260016132e7565b505b6123be848260026132e7565b80516123d39060038501906020840190613c55565b5060408581015160018401805460ff191660ff8316179055865180855560a088015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f5479361242c9389939260028a01929190615ad9565b60405180910390a1610d8384613442565b600061081283836134c5565b600082600001828154811061246057612460614ef7565b9060005260206000200154905092915050565b81518151604051632cbc26bb60e01b8152608083901b67ffffffffffffffff60801b166004820152901515907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa1580156124f0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061251491906156ba565b1561258557801561254357604051637edeb53960e11b81526001600160401b038316600482015260240161094d565b6040516001600160401b03831681527faab522ed53d887e56ed53dd37398a01aeef6a58e0fa77c2173beb9512d8949339060200160405180910390a150505050565b60208401515160008190036125bb57845160405163676cf24b60e11b81526001600160401b03909116600482015260240161094d565b84604001515181146125e0576040516357e0e08360e01b815260040160405180910390fd5b6000816001600160401b038111156125fa576125fa613ccf565b604051908082528060200260200182016040528015612623578160200160208202803683370190505b50905060007f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f857f000000000000000000000000000000000000000000000000000000000000000061267488611d55565b60010160405161268491906156d7565b6040519081900381206126bc949392916020019384526001600160401b03928316602085015291166040830152606082015260800190565b60405160208183030381529060405280519060200120905060005b838110156127f2576000886020015182815181106126f7576126f7614ef7565b602002602001015190507f00000000000000000000000000000000000000000000000000000000000000006001600160401b03168160000151604001516001600160401b03161461276e5780516040908101519051631c21951160e11b81526001600160401b03909116600482015260240161094d565b866001600160401b03168160000151602001516001600160401b0316146127c257805160200151604051636c95f1eb60e01b81526001600160401b03808a166004830152909116602482015260440161094d565b6127cc8184613514565b8483815181106127de576127de614ef7565b6020908102919091010152506001016126d7565b5050600061280a858389606001518a6080015161361c565b90508060000361283857604051633ee8bd3f60e11b81526001600160401b038616600482015260240161094d565b60005b83811015612d045760005a905060008960200151838151811061286057612860614ef7565b60200260200101519050600061287e898360000151606001516107c6565b905060008160038111156128945761289461414b565b14806128b1575060038160038111156128af576128af61414b565b145b61290757815160600151604080516001600160401b03808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c910160405180910390a1505050612cfc565b606088156129e6578a858151811061292157612921614ef7565b6020908102919091018101510151600454909150600090600160a01b900463ffffffff1661294f8842614f5d565b119050808061296f5750600383600381111561296d5761296d61414b565b145b612997576040516354e7e43160e11b81526001600160401b038c16600482015260240161094d565b8b86815181106129a9576129a9614ef7565b6020026020010151600001516000146129e0578b86815181106129ce576129ce614ef7565b60209081029190910101515160808501525b50612a52565b60008260038111156129fa576129fa61414b565b14612a5257825160600151604080516001600160401b03808e16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe65120910160405180910390a150505050612cfc565b8251608001516001600160401b031615612b28576000826003811115612a7a57612a7a61414b565b03612b285782516080015160208401516040516370701e5760e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612ad8928f929190600401615b8b565b6020604051808303816000875af1158015612af7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b1b91906156ba565b612b285750505050612cfc565b60008c604001518681518110612b4057612b40614ef7565b6020026020010151905080518460a001515114612b8a57835160600151604051631cfe6d8b60e01b81526001600160401b03808e166004830152909116602482015260440161094d565b612b9e8b8560000151606001516001613659565b600080612bac8684866136fe565b91509150612bc38d87600001516060015184613659565b8b15612c1a576003826003811115612bdd57612bdd61414b565b03612c1a576000856003811115612bf657612bf661414b565b14612c1a57855151604051632b11b8d960e01b815261094d91908390600401615bb7565b6002826003811115612c2e57612c2e61414b565b14612c6f576003826003811115612c4757612c4761414b565b14612c6f578551606001516040516349362d1f60e11b815261094d918f918590600401615bd0565b8560000151600001518660000151606001516001600160401b03168e6001600160401b03167f05665fe9ad095383d018353f4cbcba77e84db27dd215081bbf7cdf9ae6fbe48b8d8c81518110612cc757612cc7614ef7565b602002602001015186865a612cdc908f614f5d565b604051612cec9493929190615bf5565b60405180910390a4505050505050505b60010161283b565b5050505050505050565b6040805180820190915260008082526020820152602086015160405163bbe4f6db60e01b81526001600160a01b0380831660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa158015612d92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612db69190615c2c565b90506001600160a01b0381161580612de55750612de36001600160a01b03821663aff2afbf60e01b611c34565b155b15612e0e5760405163ae9b4ce960e01b81526001600160a01b038216600482015260240161094d565b600080612e2688858c6040015163ffffffff166137b2565b915091506000806000612ef76040518061010001604052808e81526020018c6001600160401b031681526020018d6001600160a01b031681526020018f608001518152602001896001600160a01b031681526020018f6000015181526020018f6060015181526020018b815250604051602401612ea39190615c49565b60408051601f198184030181529190526020810180516001600160e01b0316633907753760e01b17905287867f000000000000000000000000000000000000000000000000000000000000000060846138b5565b92509250925082612f1f578582604051634ff17cad60e11b815260040161094d929190615d15565b8151602014612f4e578151604051631e3be00960e21b815260206004820152602481019190915260440161094d565b600082806020019051810190612f649190615d37565b9050866001600160a01b03168c6001600160a01b031614612fe0576000612f958d8a612f90868a614f5d565b6137b2565b50905086811080612faf575081612fac8883614f5d565b14155b15612fde5760405163a966e21f60e01b815260048101839052602481018890526044810182905260640161094d565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b6000613021826301ffc9a760e01b613041565b8015610815575061303a826001600160e01b0319613041565b1592915050565b6040516001600160e01b031982166024820152600090819060440160408051601f19818403018152919052602080820180516001600160e01b03166301ffc9a760e01b178152825192935060009283928392909183918a617530fa92503d915060005190508280156130b4575060208210155b80156130c05750600081115b979650505050505050565b8251600090815b81811015612d045760006001888684602081106130f1576130f1614ef7565b6130fe91901a601b615a66565b89858151811061311057613110614ef7565b602002602001015189868151811061312a5761312a614ef7565b602002602001015160405160008152602001604052604051613168949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561318a573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b038516835281528582208587019096528554808416865293975090955092939284019161010090041660028111156131eb576131eb61414b565b60028111156131fc576131fc61414b565b90525090506001816020015160028111156132195761321961414b565b1461323757604051636518c33d60e11b815260040160405180910390fd5b8051600160ff9091161b85161561326157604051633d9ef1f160e21b815260040160405180910390fd5b806000015160ff166001901b8517945050508060010190506130d2565b60005b8151811015610aaa5760ff8316600090815260036020526040812083519091908490849081106132b3576132b3614ef7565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff19169055600101613281565b60005b82518110156115ff57600083828151811061330757613307614ef7565b60200260200101519050600060028111156133245761332461414b565b60ff80871660009081526003602090815260408083206001600160a01b038716845290915290205461010090041660028111156133635761336361414b565b14613384576004604051631b3fab5160e11b815260040161094d9190615aa3565b6001600160a01b0381166133ab5760405163d6c62c9b60e01b815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156133d1576133d161414b565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff19161761010083600281111561342e5761342e61414b565b0217905550905050508060010190506132ea565b60ff8181166000818152600260205260409020600101546201000090049091169061349a5780613485576040516317bd8dd160e11b815260040160405180910390fd5b600b805467ffffffffffffffff191690555050565b60001960ff831601611643578015611643576040516307b8c74d60e51b815260040160405180910390fd5b600081815260018301602052604081205461350c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610815565b506000610815565b81518051606080850151908301516080808701519401516040516000958695889561357895919490939192916020019485526001600160a01b039390931660208501526001600160401b039182166040850152606084015216608082015260a00190565b604051602081830303815290604052805190602001208560200151805190602001208660400151805190602001208760a001516040516020016135bb9190615df1565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e0015b60405160208183030381529060405280519060200120905092915050565b60008061362a85858561398f565b6001600160401b0387166000908152600a6020908152604080832093835292905220549150505b949350505050565b60006002613668608085614f86565b6001600160401b031661367b9190614fac565b905060006136898585611913565b90508161369860016004614f5d565b901b1916818360038111156136af576136af61414b565b6001600160401b03871660009081526009602052604081209190921b929092179182916136dd6080886159cc565b6001600160401b031681526020810191909152604001600020555050505050565b604051630304c3e160e51b815260009060609030906360987c209061372b90889088908890600401615e88565b600060405180830381600087803b15801561374557600080fd5b505af1925050508015613756575060015b613795573d808015613784576040519150601f19603f3d011682016040523d82523d6000602084013e613789565b606091505b506003925090506137aa565b50506040805160208101909152600081526002905b935093915050565b6000806000806000613831886040516024016137dd91906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166370a0823160e01b17905288887f000000000000000000000000000000000000000000000000000000000000000060846138b5565b92509250925082613859578682604051634ff17cad60e11b815260040161094d929190615d15565b6020825114613888578151604051631e3be00960e21b815260206004820152602481019190915260440161094d565b8180602001905181019061389c9190615d37565b6138a68288614f5d565b94509450505050935093915050565b6000606060008361ffff166001600160401b038111156138d7576138d7613ccf565b6040519080825280601f01601f191660200182016040528015613901576020820181803683370190505b509150863b61391b5763030ed58f60e21b60005260046000fd5b5a8581101561393557632be8ca8b60e21b60005260046000fd5b8590036040810481038710613955576337c3be2960e01b60005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d848111156139785750835b808352806000602085013e50955095509592505050565b82518251600091908183036139b757604051630469ac9960e21b815260040160405180910390fd5b61010182118015906139cb57506101018111155b6139e8576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613a12576040516309bde33960e01b815260040160405180910390fd5b80600003613a3f5786600081518110613a2d57613a2d614ef7565b60200260200101519350505050613c0d565b6000816001600160401b03811115613a5957613a59613ccf565b604051908082528060200260200182016040528015613a82578160200160208202803683370190505b50905060008080805b85811015613bac5760006001821b8b811603613ae65788851015613acf578c5160018601958e918110613ac057613ac0614ef7565b60200260200101519050613b08565b8551600185019487918110613ac057613ac0614ef7565b8b5160018401938d918110613afd57613afd614ef7565b602002602001015190505b600089861015613b38578d5160018701968f918110613b2957613b29614ef7565b60200260200101519050613b5a565b8651600186019588918110613b4f57613b4f614ef7565b602002602001015190505b82851115613b7b576040516309bde33960e01b815260040160405180910390fd5b613b858282613c14565b878481518110613b9757613b97614ef7565b60209081029190910101525050600101613a8b565b506001850382148015613bbe57508683145b8015613bc957508581145b613be6576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613bfb57613bfb614ef7565b60200260200101519750505050505050505b9392505050565b6000818310613c2c57613c278284613c32565b610812565b61081283835b6040805160016020820152908101839052606081018290526000906080016135fe565b828054828255906000526020600020908101928215613caa579160200282015b82811115613caa57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613c75565b50613cb6929150613cba565b5090565b5b80821115613cb65760008155600101613cbb565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715613d0757613d07613ccf565b60405290565b60405160a081016001600160401b0381118282101715613d0757613d07613ccf565b60405160c081016001600160401b0381118282101715613d0757613d07613ccf565b604080519081016001600160401b0381118282101715613d0757613d07613ccf565b604051606081016001600160401b0381118282101715613d0757613d07613ccf565b604051601f8201601f191681016001600160401b0381118282101715613dbd57613dbd613ccf565b604052919050565b60006001600160401b03821115613dde57613dde613ccf565b5060051b60200190565b6001600160a01b038116811461056857600080fd5b80356001600160401b0381168114613e1457600080fd5b919050565b801515811461056857600080fd5b8035613e1481613e19565b60006001600160401b03821115613e4b57613e4b613ccf565b50601f01601f191660200190565b600082601f830112613e6a57600080fd5b8135613e7d613e7882613e32565b613d95565b818152846020838601011115613e9257600080fd5b816020850160208301376000918101602001919091529392505050565b60006020808385031215613ec257600080fd5b82356001600160401b0380821115613ed957600080fd5b818501915085601f830112613eed57600080fd5b8135613efb613e7882613dc5565b81815260059190911b83018401908481019088831115613f1a57600080fd5b8585015b83811015613fc057803585811115613f365760008081fd5b86016080818c03601f1901811315613f4e5760008081fd5b613f56613ce5565b89830135613f6381613de8565b81526040613f72848201613dfd565b8b830152606080850135613f8581613e19565b83830152928401359289841115613f9e57600091508182fd5b613fac8f8d86880101613e59565b908301525085525050918601918601613f1e565b5098975050505050505050565b60005b83811015613fe8578181015183820152602001613fd0565b50506000910152565b60008151808452614009816020860160208601613fcd565b601f01601f19169290920160200192915050565b6020815260006108126020830184613ff1565b6001600160a01b0381511682526020810151151560208301526001600160401b03604082015116604083015260006060820151608060608501526136516080850182613ff1565b604080825283519082018190526000906020906060840190828701845b828110156140b95781516001600160401b031684529284019290840190600101614094565b50505083810382850152845180825282820190600581901b8301840187850160005b8381101561410957601f198684030185526140f7838351614030565b948701949250908601906001016140db565b50909998505050505050505050565b6000806040838503121561412b57600080fd5b61413483613dfd565b915061414260208401613dfd565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b600481106141715761417161414b565b9052565b602081016108158284614161565b600060a0828403121561419557600080fd5b61419d613d0d565b9050813581526141af60208301613dfd565b60208201526141c060408301613dfd565b60408201526141d160608301613dfd565b60608201526141e260808301613dfd565b608082015292915050565b8035613e1481613de8565b803563ffffffff81168114613e1457600080fd5b600082601f83011261421d57600080fd5b8135602061422d613e7883613dc5565b82815260059290921b8401810191818101908684111561424c57600080fd5b8286015b8481101561431c5780356001600160401b03808211156142705760008081fd5b9088019060a0828b03601f190181131561428a5760008081fd5b614292613d0d565b87840135838111156142a45760008081fd5b6142b28d8a83880101613e59565b8252506040808501356142c481613de8565b828a015260606142d58682016141f8565b828401526080915081860135858111156142ef5760008081fd5b6142fd8f8c838a0101613e59565b9184019190915250919093013590830152508352918301918301614250565b509695505050505050565b6000610140828403121561433a57600080fd5b614342613d2f565b905061434e8383614183565b815260a08201356001600160401b038082111561436a57600080fd5b61437685838601613e59565b602084015260c084013591508082111561438f57600080fd5b61439b85838601613e59565b60408401526143ac60e085016141ed565b606084015261010084013560808401526101208401359150808211156143d157600080fd5b506143de8482850161420c565b60a08301525092915050565b600082601f8301126143fb57600080fd5b8135602061440b613e7883613dc5565b82815260059290921b8401810191818101908684111561442a57600080fd5b8286015b8481101561431c5780356001600160401b0381111561444d5760008081fd5b61445b8986838b0101614327565b84525091830191830161442e565b600082601f83011261447a57600080fd5b8135602061448a613e7883613dc5565b82815260059290921b840181019181810190868411156144a957600080fd5b8286015b8481101561431c5780356001600160401b03808211156144cc57600080fd5b818901915089603f8301126144e057600080fd5b858201356144f0613e7882613dc5565b81815260059190911b830160400190878101908c83111561451057600080fd5b604085015b838110156145495780358581111561452c57600080fd5b61453b8f6040838a0101613e59565b845250918901918901614515565b508752505050928401925083016144ad565b600082601f83011261456c57600080fd5b8135602061457c613e7883613dc5565b8083825260208201915060208460051b87010193508684111561459e57600080fd5b602086015b8481101561431c57803583529183019183016145a3565b600082601f8301126145cb57600080fd5b813560206145db613e7883613dc5565b82815260059290921b840181019181810190868411156145fa57600080fd5b8286015b8481101561431c5780356001600160401b038082111561461e5760008081fd5b9088019060a0828b03601f19018113156146385760008081fd5b614640613d0d565b61464b888501613dfd565b8152604080850135848111156146615760008081fd5b61466f8e8b838901016143ea565b8a84015250606080860135858111156146885760008081fd5b6146968f8c838a0101614469565b83850152506080915081860135858111156146b15760008081fd5b6146bf8f8c838a010161455b565b91840191909152509190930135908301525083529183019183016145fe565b600080604083850312156146f157600080fd5b6001600160401b038335111561470657600080fd5b61471384843585016145ba565b91506001600160401b036020840135111561472d57600080fd5b6020830135830184601f82011261474357600080fd5b614750613e788235613dc5565b81358082526020808301929160051b84010187101561476e57600080fd5b602083015b6020843560051b850101811015614914576001600160401b038135111561479957600080fd5b87603f8235860101126147ab57600080fd5b6147be613e786020833587010135613dc5565b81358501602081810135808452908301929160059190911b016040018a10156147e657600080fd5b604083358701015b83358701602081013560051b01604001811015614904576001600160401b038135111561481a57600080fd5b833587018135016040818d03603f1901121561483557600080fd5b61483d613d51565b604082013581526001600160401b036060830135111561485c57600080fd5b8c605f60608401358401011261487157600080fd5b6040606083013583010135614888613e7882613dc5565b808282526020820191508f60608460051b60608801358801010111156148ad57600080fd5b6060808601358601015b60608460051b6060880135880101018110156148e4576148d6816141f8565b8352602092830192016148b7565b5080602085015250505080855250506020830192506020810190506147ee565b5084525060209283019201614773565b508093505050509250929050565b60008083601f84011261493457600080fd5b5081356001600160401b0381111561494b57600080fd5b6020830191508360208260051b850101111561496657600080fd5b9250929050565b60008060008060006060868803121561498557600080fd5b85356001600160401b038082111561499c57600080fd5b6149a889838a01614327565b965060208801359150808211156149be57600080fd5b6149ca89838a01614922565b909650945060408801359150808211156149e357600080fd5b506149f088828901614922565b969995985093965092949392505050565b600060808284031215614a1357600080fd5b614a1b613ce5565b8235614a2681613de8565b8152614a34602084016141f8565b60208201526040830135614a4781613e19565b60408201526060830135614a5a81613de8565b60608201529392505050565b600060208284031215614a7857600080fd5b81356001600160401b03811115614a8e57600080fd5b820160a08185031215613c0d57600080fd5b803560ff81168114613e1457600080fd5b600060208284031215614ac357600080fd5b61081282614aa0565b60008151808452602080850194506020840160005b83811015614b065781516001600160a01b031687529582019590820190600101614ae1565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614b6060e0840182614acc565b90506040840151601f198483030160c0850152614b7d8282614acc565b95945050505050565b60008060408385031215614b9957600080fd5b614ba283613dfd565b946020939093013593505050565b806040810183101561081557600080fd5b60008083601f840112614bd357600080fd5b5081356001600160401b03811115614bea57600080fd5b60208301915083602082850101111561496657600080fd5b60008060008060008060008060c0898b031215614c1e57600080fd5b614c288a8a614bb0565b975060408901356001600160401b0380821115614c4457600080fd5b614c508c838d01614bc1565b909950975060608b0135915080821115614c6957600080fd5b614c758c838d01614922565b909750955060808b0135915080821115614c8e57600080fd5b50614c9b8b828c01614922565b999c989b50969995989497949560a00135949350505050565b600060208284031215614cc657600080fd5b61081282613dfd565b6020815260006108126020830184614030565b600060208284031215614cf457600080fd5b8135613c0d81613de8565b600080600060608486031215614d1457600080fd5b614d1e8585614bb0565b925060408401356001600160401b03811115614d3957600080fd5b614d4586828701614bc1565b9497909650939450505050565b600082601f830112614d6357600080fd5b81356020614d73613e7883613dc5565b8083825260208201915060208460051b870101935086841115614d9557600080fd5b602086015b8481101561431c578035614dad81613de8565b8352918301918301614d9a565b60006020808385031215614dcd57600080fd5b82356001600160401b0380821115614de457600080fd5b818501915085601f830112614df857600080fd5b8135614e06613e7882613dc5565b81815260059190911b83018401908481019088831115614e2557600080fd5b8585015b83811015613fc057803585811115614e4057600080fd5b860160c0818c03601f19011215614e575760008081fd5b614e5f613d2f565b8882013581526040614e72818401614aa0565b8a8301526060614e83818501614aa0565b8284015260809150614e96828501613e27565b9083015260a08381013589811115614eae5760008081fd5b614ebc8f8d83880101614d52565b838501525060c0840135915088821115614ed65760008081fd5b614ee48e8c84870101614d52565b9083015250845250918601918601614e29565b634e487b7160e01b600052603260045260246000fd5b600181811c90821680614f2157607f821691505b602082108103614f4157634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561081557610815614f47565b634e487b7160e01b600052601260045260246000fd5b60006001600160401b0380841680614fa057614fa0614f70565b92169190910692915050565b808202811582820484141761081557610815614f47565b80518252600060206001600160401b0381840151168185015260408084015160a06040870152614ff660a0870182613ff1565b90506060850151868203606088015261500f8282613ff1565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561506457835180516001600160a01b0316835286015186830152928501926001929092019190840190615032565b50979650505050505050565b6020815260006108126020830184614fc3565b6080815260006150966080830187614fc3565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b6000806000606084860312156150d457600080fd5b83516150df81613e19565b60208501519093506001600160401b038111156150fb57600080fd5b8401601f8101861361510c57600080fd5b805161511a613e7882613e32565b81815287602083850101111561512f57600080fd5b615140826020830160208601613fcd565b809450505050604084015190509250925092565b80356001600160e01b0381168114613e1457600080fd5b600082601f83011261517c57600080fd5b8135602061518c613e7883613dc5565b82815260069290921b840181019181810190868411156151ab57600080fd5b8286015b8481101561431c57604081890312156151c85760008081fd5b6151d0613d51565b6151d982613dfd565b81526151e6858301615154565b818601528352918301916040016151af565b600082601f83011261520957600080fd5b81356020615219613e7883613dc5565b82815260059290921b8401810191818101908684111561523857600080fd5b8286015b8481101561431c5780356001600160401b038082111561525c5760008081fd5b9088019060a0828b03601f19018113156152765760008081fd5b61527e613d0d565b615289888501613dfd565b81526040808501358481111561529f5760008081fd5b6152ad8e8b83890101613e59565b8a84015250606093506152c1848601613dfd565b9082015260806152d2858201613dfd565b9382019390935292013590820152835291830191830161523c565b600082601f8301126152fe57600080fd5b8135602061530e613e7883613dc5565b82815260069290921b8401810191818101908684111561532d57600080fd5b8286015b8481101561431c576040818903121561534a5760008081fd5b615352613d51565b813581528482013585820152835291830191604001615331565b6000602080838503121561537f57600080fd5b82356001600160401b038082111561539657600080fd5b90840190606082870312156153aa57600080fd5b6153b2613d73565b8235828111156153c157600080fd5b830160408189038113156153d457600080fd5b6153dc613d51565b8235858111156153eb57600080fd5b8301601f81018b136153fc57600080fd5b803561540a613e7882613dc5565b81815260069190911b8201890190898101908d83111561542957600080fd5b928a01925b828410156154795785848f0312156154465760008081fd5b61544e613d51565b843561545981613de8565b8152615466858d01615154565b818d0152825292850192908a019061542e565b84525050508287013591508482111561549157600080fd5b61549d8a83850161516b565b818801528352505082840135828111156154b657600080fd5b6154c2888286016151f8565b858301525060408301359350818411156154db57600080fd5b6154e7878585016152ed565b60408201529695505050505050565b600082825180855260208086019550808260051b84010181860160005b8481101561558757601f19868403018952815160a06001600160401b0380835116865286830151828888015261554b83880182613ff1565b60408581015184169089015260608086015190931692880192909252506080928301519290950191909152509783019790830190600101615513565b5090979650505050505050565b6001600160a01b0384168152600060206060818401526155b760608401866154f6565b83810360408581019190915285518083528387019284019060005b81811015614109578451805184528601518684015293850193918301916001016155d2565b805160408084528151848201819052600092602091908201906060870190855b8181101561564e57835180516001600160a01b031684528501516001600160e01b0316858401529284019291850191600101615617565b50508583015187820388850152805180835290840192506000918401905b8083101561506457835180516001600160401b031683528501516001600160e01b03168583015292840192600192909201919085019061566c565b60208152600061081260208301846155f7565b6000602082840312156156cc57600080fd5b8151613c0d81613e19565b60008083546156e581614f0d565b600182811680156156fd576001811461571257615741565b60ff1984168752821515830287019450615741565b8760005260208060002060005b858110156157385781548a82015290840190820161571f565b50505082870194505b50929695505050505050565b6000815461575a81614f0d565b8085526020600183811680156157775760018114615791576157bf565b60ff1985168884015283151560051b8801830195506157bf565b866000528260002060005b858110156157b75781548a820186015290830190840161579c565b890184019650505b505050505092915050565b6040815260006157dd6040830185613ff1565b8281036020840152614b7d818561574d565b6001600160401b0381811683821601908082111561580f5761580f614f47565b5092915050565b60408152600061582960408301856154f6565b8281036020840152614b7d81856155f7565b60006020828403121561584d57600080fd5b81356001600160401b0381111561586357600080fd5b613651848285016145ba565b601f821115610aaa576000816000526020600020601f850160051c810160208610156158985750805b601f850160051c820191505b818110156158b7578281556001016158a4565b505050505050565b81516001600160401b038111156158d8576158d8613ccf565b6158ec816158e68454614f0d565b8461586f565b602080601f83116001811461592157600084156159095750858301515b600019600386901b1c1916600185901b1785556158b7565b600085815260208120601f198616915b8281101561595057888601518255948401946001909101908401615931565b508582101561596e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60208152600082546001600160a01b038116602084015260ff8160a01c16151560408401526001600160401b038160a81c1660608401525060808083015261081260a083016001850161574d565b60006001600160401b03808416806159e6576159e6614f70565b92169190910492915050565b600060208284031215615a0457600080fd5b610812826141f8565b6000808335601e19843603018112615a2457600080fd5b8301803591506001600160401b03821115615a3e57600080fd5b60200191503681900382131561496657600080fd5b8082018082111561081557610815614f47565b60ff818116838216019081111561081557610815614f47565b8183823760009101908152919050565b828152604082602083013760600192915050565b6020810160068310615ab757615ab761414b565b91905290565b60ff818116838216029081169081811461580f5761580f614f47565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615b315784546001600160a01b031683526001948501949284019201615b0c565b50508481036060860152865180825290820192508187019060005b81811015615b715782516001600160a01b031685529383019391830191600101615b4c565b50505060ff851660808501525090505b9695505050505050565b60006001600160401b03808616835280851660208401525060606040830152614b7d6060830184613ff1565b8281526040602082015260006136516040830184613ff1565b6001600160401b03848116825283166020820152606081016136516040830184614161565b848152615c056020820185614161565b608060408201526000615c1b6080830185613ff1565b905082606083015295945050505050565b600060208284031215615c3e57600080fd5b8151613c0d81613de8565b6020815260008251610100806020850152615c68610120850183613ff1565b91506020850151615c8460408601826001600160401b03169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615cbe60a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615cdb8483613ff1565b935060c08701519150808685030160e0870152615cf88483613ff1565b935060e0870151915080868503018387015250615b818382613ff1565b6001600160a01b03831681526040602082015260006136516040830184613ff1565b600060208284031215615d4957600080fd5b5051919050565b600082825180855260208086019550808260051b84010181860160005b8481101561558757601f19868403018952815160a08151818652615d9382870182613ff1565b9150506001600160a01b03868301511686860152604063ffffffff8184015116818701525060608083015186830382880152615dcf8382613ff1565b6080948501519790940196909652505098840198925090830190600101615d6d565b6020815260006108126020830184615d50565b60008282518085526020808601955060208260051b8401016020860160005b8481101561558757601f19868403018952615e3f838351613ff1565b98840198925090830190600101615e23565b60008151808452602080850194506020840160005b83811015614b0657815163ffffffff1687529582019590820190600101615e66565b60608152600084518051606084015260208101516001600160401b0380821660808601528060408401511660a08601528060608401511660c08601528060808401511660e0860152505050602085015161014080610100850152615ef06101a0850183613ff1565b91506040870151605f198086850301610120870152615f0f8483613ff1565b935060608901519150615f2c838701836001600160a01b03169052565b608089015161016087015260a0890151925080868503016101808701525050615f558282615d50565b9150508281036020840152615f6a8186615e04565b90508281036040840152615b818185615e5156fea164736f6c6343000818000a", } var OffRampABI = OffRampMetaData.ABI @@ -2467,7 +2468,7 @@ func (OffRampSourceChainSelectorAdded) Topic() common.Hash { } func (OffRampStaticConfigSet) Topic() common.Hash { - return common.HexToHash("0x683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d8") + return common.HexToHash("0xb0fa1fb01508c5097c502ad056fd77018870c9be9a86d9e56b6b471862d7c5b7") } func (OffRampTransmitted) Topic() common.Hash { 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 e4df70b2452..f35104e20df 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 @@ -16,7 +16,7 @@ mock_v3_aggregator_contract: ../../../contracts/solc/v0.8.24/MockV3Aggregator/Mo multi_aggregate_rate_limiter: ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.abi ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.bin c3cac2010c2815b484055bf981363a2bd04e7fbe7bb502dc8fd29a16165d221c multi_ocr3_helper: ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.abi ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.bin a523e11ea4c069d7d61b309c156951cc6834aff0f352bd1ac37c3a838ff2588f nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin e6008490d916826cefd1903612db39621d51617300fc9bb42b68c6c117958198 -offramp: ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.abi ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.bin 7c65e586181c5099a6ecb5353f60043bb6add9ebad941ddf7ef9998c7ee008ea +offramp: ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.abi ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.bin 067fdfbf7cae1557fc03ca16d9c38737ee4595655792a1b8bc4846c45caa0c74 onramp: ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.abi ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.bin 2bf74188a997218502031f177cb2df505b272d66b25fd341a741289e77380c59 ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin 24b4415a883a470d65c484be0fa20714a46b1c9262db205f1c958017820307b2 registry_module_owner_custom: ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin 0fc277a0b512db4e20b5a32a775b94ed2c0d342d8237511de78c94f7dacad428 diff --git a/deployment/ccip/changeset/cs_deploy_chain.go b/deployment/ccip/changeset/cs_deploy_chain.go index de6e4b5f466..5acb8e15307 100644 --- a/deployment/ccip/changeset/cs_deploy_chain.go +++ b/deployment/ccip/changeset/cs_deploy_chain.go @@ -380,10 +380,11 @@ func deployChainContracts( chain.DeployerKey, chain.Client, offramp.OffRampStaticConfig{ - ChainSelector: chain.Selector, - RmnRemote: rmnProxyContract.Address(), - NonceManager: nmContract.Address(), - TokenAdminRegistry: tokenAdminReg.Address(), + ChainSelector: chain.Selector, + GasForCallExactCheck: 5_000, + RmnRemote: rmnProxyContract.Address(), + NonceManager: nmContract.Address(), + TokenAdminRegistry: tokenAdminReg.Address(), }, offramp.OffRampDynamicConfig{ FeeQuoter: feeQuoterContract.Address(), From 88a0338576dad34068f8ee278a5cf5ac0b8870ad Mon Sep 17 00:00:00 2001 From: Akhil Chainani Date: Tue, 10 Dec 2024 09:02:39 -0500 Subject: [PATCH 26/29] Deploy call proxy instead of using deployer executor keys (#15559) * Deploy call proxy instead of using deployer executor keys * inject call proxies in execution methods * skip call proxy when loading chain state * revert all changes * Revert "revert all changes" This reverts commit c17911eb1ff4382b3f80d0edb055d748096dc59f. * consolidate timelocks + callProxies in a single struct * add comment to tiemlock deploy function * update go.mod * go mod tidy * revert go.mod changes * go mod tidy * revert * go mod tidy * fix keystone test * fix ccip tests --- .../ccip/changeset/accept_ownership_test.go | 15 ++++--- .../changeset/cs_active_candidate_test.go | 25 ++++++++--- .../ccip/changeset/cs_add_chain_test.go | 40 +++++++++++------ .../ccip/changeset/cs_deploy_chain_test.go | 9 ++-- .../ccip/changeset/cs_update_rmn_config.go | 13 +++--- deployment/ccip/changeset/state.go | 1 + deployment/ccip/changeset/test_helpers.go | 24 ++++++----- deployment/common/changeset/internal/mcms.go | 43 +++++++++++++++++-- .../common/changeset/internal/mcms_test.go | 12 ++---- .../common/changeset/mcms_test_helpers.go | 14 ++++-- deployment/common/changeset/state.go | 18 +++++++- deployment/common/changeset/test_helpers.go | 12 +++--- .../transfer_to_mcms_with_timelock_test.go | 17 ++++---- deployment/common/types/types.go | 11 +++-- deployment/common/view/v1_0/mcms.go | 26 +++++++++-- .../changeset/accept_ownership_test.go | 17 ++++---- .../changeset/deploy_forwarder_test.go | 11 +++-- .../keystone/changeset/deploy_ocr3_test.go | 12 ++++-- deployment/keystone/changeset/helpers_test.go | 12 +++--- .../keystone/changeset/update_nodes_test.go | 10 +++-- integration-tests/go.mod | 2 +- .../testsetups/ccip/test_helpers.go | 19 ++++---- 22 files changed, 241 insertions(+), 122 deletions(-) diff --git a/deployment/ccip/changeset/accept_ownership_test.go b/deployment/ccip/changeset/accept_ownership_test.go index 796db6aed09..d3a641a2aaf 100644 --- a/deployment/ccip/changeset/accept_ownership_test.go +++ b/deployment/ccip/changeset/accept_ownership_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" - "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" "github.com/smartcontractkit/chainlink/deployment/environment/memory" @@ -29,9 +28,15 @@ func Test_NewAcceptOwnershipChangeset(t *testing.T) { source := allChains[0] dest := allChains[1] - timelocks := map[uint64]*gethwrappers.RBACTimelock{ - source: state.Chains[source].Timelock, - dest: state.Chains[dest].Timelock, + timelockContracts := map[uint64]*commonchangeset.TimelockExecutionContracts{ + source: &commonchangeset.TimelockExecutionContracts{ + Timelock: state.Chains[source].Timelock, + CallProxy: state.Chains[source].CallProxy, + }, + dest: &commonchangeset.TimelockExecutionContracts{ + Timelock: state.Chains[dest].Timelock, + CallProxy: state.Chains[dest].CallProxy, + }, } // at this point we have the initial deploys done, now we need to transfer ownership @@ -40,7 +45,7 @@ func Test_NewAcceptOwnershipChangeset(t *testing.T) { require.NoError(t, err) // compose the transfer ownership and accept ownership changesets - _, err = commonchangeset.ApplyChangesets(t, e.Env, timelocks, []commonchangeset.ChangesetApplication{ + _, err = commonchangeset.ApplyChangesets(t, e.Env, timelockContracts, []commonchangeset.ChangesetApplication{ // note this doesn't have proposals. { Changeset: commonchangeset.WrapChangeSet(commonchangeset.TransferToMCMSWithTimelock), diff --git a/deployment/ccip/changeset/cs_active_candidate_test.go b/deployment/ccip/changeset/cs_active_candidate_test.go index 0fb29242794..4c8706472fe 100644 --- a/deployment/ccip/changeset/cs_active_candidate_test.go +++ b/deployment/ccip/changeset/cs_active_candidate_test.go @@ -91,11 +91,15 @@ func TestActiveCandidate(t *testing.T) { ConfirmExecWithSeqNrsForAll(t, e, state, expectedSeqNumExec, startBlocks) // compose the transfer ownership and accept ownership changesets - timelocks := make(map[uint64]*gethwrappers.RBACTimelock) + timelockContracts := make(map[uint64]*commonchangeset.TimelockExecutionContracts) for _, chain := range allChains { - timelocks[chain] = state.Chains[chain].Timelock + timelockContracts[chain] = &commonchangeset.TimelockExecutionContracts{ + Timelock: state.Chains[chain].Timelock, + CallProxy: state.Chains[chain].CallProxy, + } } - _, err = commonchangeset.ApplyChangesets(t, e, timelocks, []commonchangeset.ChangesetApplication{ + + _, err = commonchangeset.ApplyChangesets(t, e, timelockContracts, []commonchangeset.ChangesetApplication{ // note this doesn't have proposals. { Changeset: commonchangeset.WrapChangeSet(commonchangeset.TransferToMCMSWithTimelock), @@ -177,7 +181,10 @@ func TestActiveCandidate(t *testing.T) { }}, "set new candidates on commit plugin", 0) require.NoError(t, err) setCommitCandidateSigned := commonchangeset.SignProposal(t, e, setCommitCandidateProposal) - commonchangeset.ExecuteProposal(t, e, setCommitCandidateSigned, state.Chains[tenv.HomeChainSel].Timelock, tenv.HomeChainSel) + commonchangeset.ExecuteProposal(t, e, setCommitCandidateSigned, &commonchangeset.TimelockExecutionContracts{ + Timelock: state.Chains[tenv.HomeChainSel].Timelock, + CallProxy: state.Chains[tenv.HomeChainSel].CallProxy, + }, tenv.HomeChainSel) // create the op for the commit plugin as well setExecCandidateOp, err := setCandidateOnExistingDon( @@ -195,7 +202,10 @@ func TestActiveCandidate(t *testing.T) { }}, "set new candidates on commit and exec plugins", 0) require.NoError(t, err) setExecCandidateSigned := commonchangeset.SignProposal(t, e, setExecCandidateProposal) - commonchangeset.ExecuteProposal(t, e, setExecCandidateSigned, state.Chains[tenv.HomeChainSel].Timelock, tenv.HomeChainSel) + commonchangeset.ExecuteProposal(t, e, setExecCandidateSigned, &commonchangeset.TimelockExecutionContracts{ + Timelock: state.Chains[tenv.HomeChainSel].Timelock, + CallProxy: state.Chains[tenv.HomeChainSel].CallProxy, + }, tenv.HomeChainSel) // check setup was successful by confirming number of nodes from cap reg donInfo, err = state.Chains[tenv.HomeChainSel].CapabilityRegistry.GetDON(nil, donID) @@ -222,7 +232,10 @@ func TestActiveCandidate(t *testing.T) { }}, "promote candidates and revoke actives", 0) require.NoError(t, err) promoteSigned := commonchangeset.SignProposal(t, e, promoteProposal) - commonchangeset.ExecuteProposal(t, e, promoteSigned, state.Chains[tenv.HomeChainSel].Timelock, tenv.HomeChainSel) + commonchangeset.ExecuteProposal(t, e, promoteSigned, &commonchangeset.TimelockExecutionContracts{ + Timelock: state.Chains[tenv.HomeChainSel].Timelock, + CallProxy: state.Chains[tenv.HomeChainSel].CallProxy, + }, tenv.HomeChainSel) // [NEW ACTIVE, NO CANDIDATE] done promoting // [NEW ACTIVE, NO CANDIDATE] check onchain state diff --git a/deployment/ccip/changeset/cs_add_chain_test.go b/deployment/ccip/changeset/cs_add_chain_test.go index 2873b3bf613..3a9425dd3a9 100644 --- a/deployment/ccip/changeset/cs_add_chain_test.go +++ b/deployment/ccip/changeset/cs_add_chain_test.go @@ -5,8 +5,6 @@ import ( "testing" "time" - "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" - "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" @@ -52,11 +50,10 @@ func TestAddChainInbound(t *testing.T) { require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses)) cfg := commontypes.MCMSWithTimelockConfig{ - Canceller: commonchangeset.SingleGroupMCMS(t), - Bypasser: commonchangeset.SingleGroupMCMS(t), - Proposer: commonchangeset.SingleGroupMCMS(t), - TimelockExecutors: e.Env.AllDeployerKeys(), - TimelockMinDelay: big.NewInt(0), + Canceller: commonchangeset.SingleGroupMCMS(t), + Bypasser: commonchangeset.SingleGroupMCMS(t), + Proposer: commonchangeset.SingleGroupMCMS(t), + TimelockMinDelay: big.NewInt(0), } e.Env, err = commonchangeset.ApplyChangesets(t, e.Env, nil, []commonchangeset.ChangesetApplication{ { @@ -158,10 +155,19 @@ func TestAddChainInbound(t *testing.T) { } // transfer ownership to timelock - _, err = commonchangeset.ApplyChangesets(t, e.Env, map[uint64]*gethwrappers.RBACTimelock{ - initialDeploy[0]: state.Chains[initialDeploy[0]].Timelock, - initialDeploy[1]: state.Chains[initialDeploy[1]].Timelock, - initialDeploy[2]: state.Chains[initialDeploy[2]].Timelock, + _, err = commonchangeset.ApplyChangesets(t, e.Env, map[uint64]*commonchangeset.TimelockExecutionContracts{ + initialDeploy[0]: &commonchangeset.TimelockExecutionContracts{ + Timelock: state.Chains[initialDeploy[0]].Timelock, + CallProxy: state.Chains[initialDeploy[0]].CallProxy, + }, + initialDeploy[1]: &commonchangeset.TimelockExecutionContracts{ + Timelock: state.Chains[initialDeploy[1]].Timelock, + CallProxy: state.Chains[initialDeploy[1]].CallProxy, + }, + initialDeploy[2]: &commonchangeset.TimelockExecutionContracts{ + Timelock: state.Chains[initialDeploy[2]].Timelock, + CallProxy: state.Chains[initialDeploy[2]].CallProxy, + }, }, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(commonchangeset.TransferToMCMSWithTimelock), @@ -191,9 +197,15 @@ func TestAddChainInbound(t *testing.T) { nodeIDs = append(nodeIDs, node.NodeID) } - _, err = commonchangeset.ApplyChangesets(t, e.Env, map[uint64]*gethwrappers.RBACTimelock{ - e.HomeChainSel: state.Chains[e.HomeChainSel].Timelock, - newChain: state.Chains[newChain].Timelock, + _, err = commonchangeset.ApplyChangesets(t, e.Env, map[uint64]*commonchangeset.TimelockExecutionContracts{ + e.HomeChainSel: &commonchangeset.TimelockExecutionContracts{ + Timelock: state.Chains[e.HomeChainSel].Timelock, + CallProxy: state.Chains[e.HomeChainSel].CallProxy, + }, + newChain: &commonchangeset.TimelockExecutionContracts{ + Timelock: state.Chains[newChain].Timelock, + CallProxy: state.Chains[newChain].CallProxy, + }, }, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(AddDonAndSetCandidateChangeset), diff --git a/deployment/ccip/changeset/cs_deploy_chain_test.go b/deployment/ccip/changeset/cs_deploy_chain_test.go index 234d73cc4b5..646575dcaa4 100644 --- a/deployment/ccip/changeset/cs_deploy_chain_test.go +++ b/deployment/ccip/changeset/cs_deploy_chain_test.go @@ -31,11 +31,10 @@ func TestDeployChainContractsChangeset(t *testing.T) { cfg := make(map[uint64]commontypes.MCMSWithTimelockConfig) for _, chain := range e.AllChainSelectors() { cfg[chain] = commontypes.MCMSWithTimelockConfig{ - Canceller: commonchangeset.SingleGroupMCMS(t), - Bypasser: commonchangeset.SingleGroupMCMS(t), - Proposer: commonchangeset.SingleGroupMCMS(t), - TimelockExecutors: e.AllDeployerKeys(), - TimelockMinDelay: big.NewInt(0), + Canceller: commonchangeset.SingleGroupMCMS(t), + Bypasser: commonchangeset.SingleGroupMCMS(t), + Proposer: commonchangeset.SingleGroupMCMS(t), + TimelockMinDelay: big.NewInt(0), } } e, err = commonchangeset.ApplyChangesets(t, e, nil, []commonchangeset.ChangesetApplication{ diff --git a/deployment/ccip/changeset/cs_update_rmn_config.go b/deployment/ccip/changeset/cs_update_rmn_config.go index 7e4d09af20f..b10991c977c 100644 --- a/deployment/ccip/changeset/cs_update_rmn_config.go +++ b/deployment/ccip/changeset/cs_update_rmn_config.go @@ -9,10 +9,10 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" - mcmsWrappers "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink/deployment" + commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_home" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_remote" @@ -274,10 +274,13 @@ func NewPromoteCandidateConfigChangeset(e deployment.Environment, config Promote }, nil } -func buildTimelockPerChain(e deployment.Environment, state CCIPOnChainState) map[uint64]*mcmsWrappers.RBACTimelock { - timelocksPerChain := make(map[uint64]*mcmsWrappers.RBACTimelock) +func buildTimelockPerChain(e deployment.Environment, state CCIPOnChainState) map[uint64]*commonchangeset.TimelockExecutionContracts { + timelocksPerChain := make(map[uint64]*commonchangeset.TimelockExecutionContracts) for _, chain := range e.Chains { - timelocksPerChain[chain.Selector] = state.Chains[chain.Selector].Timelock + timelocksPerChain[chain.Selector] = &commonchangeset.TimelockExecutionContracts{ + Timelock: state.Chains[chain.Selector].Timelock, + CallProxy: state.Chains[chain.Selector].CallProxy, + } } return timelocksPerChain } @@ -286,7 +289,7 @@ func buildTimelockAddressPerChain(e deployment.Environment, state CCIPOnChainSta timelocksPerChain := buildTimelockPerChain(e, state) timelockAddressPerChain := make(map[uint64]common.Address) for chain, timelock := range timelocksPerChain { - timelockAddressPerChain[chain] = timelock.Address() + timelockAddressPerChain[chain] = timelock.Timelock.Address() } return timelockAddressPerChain } diff --git a/deployment/ccip/changeset/state.go b/deployment/ccip/changeset/state.go index 22ae59fc360..122ce8ec13c 100644 --- a/deployment/ccip/changeset/state.go +++ b/deployment/ccip/changeset/state.go @@ -311,6 +311,7 @@ func LoadChainState(chain deployment.Chain, addresses map[string]deployment.Type for address, tvStr := range addresses { switch tvStr.String() { case deployment.NewTypeAndVersion(commontypes.RBACTimelock, deployment.Version1_0_0).String(), + deployment.NewTypeAndVersion(commontypes.CallProxy, deployment.Version1_0_0).String(), deployment.NewTypeAndVersion(commontypes.ProposerManyChainMultisig, deployment.Version1_0_0).String(), deployment.NewTypeAndVersion(commontypes.CancellerManyChainMultisig, deployment.Version1_0_0).String(), deployment.NewTypeAndVersion(commontypes.BypasserManyChainMultisig, deployment.Version1_0_0).String(), diff --git a/deployment/ccip/changeset/test_helpers.go b/deployment/ccip/changeset/test_helpers.go index 49edb275526..921a24741a1 100644 --- a/deployment/ccip/changeset/test_helpers.go +++ b/deployment/ccip/changeset/test_helpers.go @@ -18,7 +18,6 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/pkg/errors" - "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/chainlink-ccip/pluginconfig" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" @@ -279,11 +278,10 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, mcmsCfg := make(map[uint64]commontypes.MCMSWithTimelockConfig) for _, c := range e.Env.AllChainSelectors() { mcmsCfg[c] = commontypes.MCMSWithTimelockConfig{ - Canceller: commonchangeset.SingleGroupMCMS(t), - Bypasser: commonchangeset.SingleGroupMCMS(t), - Proposer: commonchangeset.SingleGroupMCMS(t), - TimelockExecutors: e.Env.AllDeployerKeys(), - TimelockMinDelay: big.NewInt(0), + Canceller: commonchangeset.SingleGroupMCMS(t), + Bypasser: commonchangeset.SingleGroupMCMS(t), + Proposer: commonchangeset.SingleGroupMCMS(t), + TimelockMinDelay: big.NewInt(0), } } var ( @@ -366,14 +364,17 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, } // Build the per chain config. chainConfigs := make(map[uint64]CCIPOCRParams) - timelocksPerChain := make(map[uint64]*gethwrappers.RBACTimelock) + timelockContractsPerChain := make(map[uint64]*commonchangeset.TimelockExecutionContracts) for _, chain := range allChains { - timelocksPerChain[chain] = state.Chains[chain].Timelock + timelockContractsPerChain[chain] = &commonchangeset.TimelockExecutionContracts{ + Timelock: state.Chains[chain].Timelock, + CallProxy: state.Chains[chain].CallProxy, + } tokenInfo := tokenConfig.GetTokenInfo(e.Env.Logger, state.Chains[chain].LinkToken, state.Chains[chain].Weth9) chainConfigs[chain] = DefaultOCRParams(e.FeedChainSel, tokenInfo, tokenDataProviders) } // Deploy second set of changesets to deploy and configure the CCIP contracts. - e.Env, err = commonchangeset.ApplyChangesets(t, e.Env, timelocksPerChain, []commonchangeset.ChangesetApplication{ + e.Env, err = commonchangeset.ApplyChangesets(t, e.Env, timelockContractsPerChain, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(ConfigureNewChains), Config: NewChainsConfig{ @@ -822,7 +823,10 @@ func ProcessChangeset(t *testing.T, e deployment.Environment, c deployment.Chang signed := commonchangeset.SignProposal(t, e, &prop) for _, sel := range chains.ToSlice() { - commonchangeset.ExecuteProposal(t, e, signed, state.Chains[sel].Timelock, sel) + commonchangeset.ExecuteProposal(t, e, signed, &commonchangeset.TimelockExecutionContracts{ + Timelock: state.Chains[sel].Timelock, + CallProxy: state.Chains[sel].CallProxy, + }, sel) } } } diff --git a/deployment/common/changeset/internal/mcms.go b/deployment/common/changeset/internal/mcms.go index 281f43924f4..baa82d77c8f 100644 --- a/deployment/common/changeset/internal/mcms.go +++ b/deployment/common/changeset/internal/mcms.go @@ -55,6 +55,7 @@ type MCMSWithTimelockDeploy struct { Bypasser *deployment.ContractDeploy[*owner_helpers.ManyChainMultiSig] Proposer *deployment.ContractDeploy[*owner_helpers.ManyChainMultiSig] Timelock *deployment.ContractDeploy[*owner_helpers.RBACTimelock] + CallProxy *deployment.ContractDeploy[*owner_helpers.CallProxy] } func DeployMCMSWithTimelockContractsBatch( @@ -106,10 +107,12 @@ func DeployMCMSWithTimelockContracts( // TODO: Could expose this as config? // Or keep this enforced to follow the same pattern? chain.DeployerKey.From, - []common.Address{proposer.Address}, // proposers - config.TimelockExecutors, //executors - []common.Address{canceller.Address}, // cancellers - []common.Address{bypasser.Address}, // bypassers + []common.Address{proposer.Address}, // proposers + // Executors field is empty here because we grant the executor role to the call proxy later + // and the call proxy cannot be deployed before the timelock. + []common.Address{}, + []common.Address{canceller.Address, proposer.Address, bypasser.Address}, // cancellers + []common.Address{bypasser.Address}, // bypassers ) return deployment.ContractDeploy[*owner_helpers.RBACTimelock]{ timelock, cc, tx2, deployment.NewTypeAndVersion(types.RBACTimelock, deployment.Version1_0_0), err2, @@ -119,6 +122,37 @@ func DeployMCMSWithTimelockContracts( lggr.Errorw("Failed to deploy timelock", "chain", chain.String(), "err", err) return nil, err } + + callProxy, err := deployment.DeployContract(lggr, chain, ab, + func(chain deployment.Chain) deployment.ContractDeploy[*owner_helpers.CallProxy] { + callProxy, tx2, cc, err2 := owner_helpers.DeployCallProxy( + chain.DeployerKey, + chain.Client, + timelock.Address, + ) + return deployment.ContractDeploy[*owner_helpers.CallProxy]{ + callProxy, cc, tx2, deployment.NewTypeAndVersion(types.CallProxy, deployment.Version1_0_0), err2, + } + }) + if err != nil { + lggr.Errorw("Failed to deploy call proxy", "chain", chain.String(), "err", err) + return nil, err + } + + grantRoleTx, err := timelock.Contract.GrantRole( + chain.DeployerKey, + v1_0.EXECUTOR_ROLE.ID, + callProxy.Address, + ) + if err != nil { + lggr.Errorw("Failed to grant timelock executor role", "chain", chain.String(), "err", err) + return nil, err + } + + if _, err := deployment.ConfirmIfNoError(chain, grantRoleTx, err); err != nil { + lggr.Errorw("Failed to grant timelock executor role", "chain", chain.String(), "err", err) + return nil, err + } // We grant the timelock the admin role on the MCMS contracts. tx, err := timelock.Contract.GrantRole(chain.DeployerKey, v1_0.ADMIN_ROLE.ID, timelock.Address) @@ -133,5 +167,6 @@ func DeployMCMSWithTimelockContracts( Bypasser: bypasser, Proposer: proposer, Timelock: timelock, + CallProxy: callProxy, }, nil } diff --git a/deployment/common/changeset/internal/mcms_test.go b/deployment/common/changeset/internal/mcms_test.go index 2269911f4cd..10fb1d980de 100644 --- a/deployment/common/changeset/internal/mcms_test.go +++ b/deployment/common/changeset/internal/mcms_test.go @@ -5,7 +5,6 @@ import ( "math/big" "testing" - "github.com/ethereum/go-ethereum/common" chainsel "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/require" @@ -37,18 +36,15 @@ func TestDeployMCMSWithTimelockContracts(t *testing.T) { _, err := internal.DeployMCMSWithTimelockContracts(lggr, chains[chainsel.TEST_90000001.Selector], ab, types.MCMSWithTimelockConfig{ - Canceller: changeset.SingleGroupMCMS(t), - Bypasser: changeset.SingleGroupMCMS(t), - Proposer: changeset.SingleGroupMCMS(t), - TimelockExecutors: []common.Address{ - chains[chainsel.TEST_90000001.Selector].DeployerKey.From, - }, + Canceller: changeset.SingleGroupMCMS(t), + Bypasser: changeset.SingleGroupMCMS(t), + Proposer: changeset.SingleGroupMCMS(t), TimelockMinDelay: big.NewInt(0), }) require.NoError(t, err) addresses, err := ab.AddressesForChain(chainsel.TEST_90000001.Selector) require.NoError(t, err) - require.Len(t, addresses, 4) + require.Len(t, addresses, 5) mcmsState, err := changeset.MaybeLoadMCMSWithTimelockState(chains[chainsel.TEST_90000001.Selector], addresses) require.NoError(t, err) v, err := mcmsState.GenerateMCMSWithTimelockView() diff --git a/deployment/common/changeset/mcms_test_helpers.go b/deployment/common/changeset/mcms_test_helpers.go index 3951149815c..ffa99114d74 100644 --- a/deployment/common/changeset/mcms_test_helpers.go +++ b/deployment/common/changeset/mcms_test_helpers.go @@ -25,6 +25,13 @@ var ( TestXXXMCMSSigner *ecdsa.PrivateKey ) +// TimelockExecutionContracts is a helper struct for executing timelock proposals. it contains +// the timelock and call proxy contracts. +type TimelockExecutionContracts struct { + Timelock *owner_helpers.RBACTimelock + CallProxy *owner_helpers.CallProxy +} + func init() { key, err := crypto.GenerateKey() if err != nil { @@ -65,7 +72,7 @@ func SignProposal(t *testing.T, env deployment.Environment, proposal *timelock.M } func ExecuteProposal(t *testing.T, env deployment.Environment, executor *mcms.Executor, - timelock *owner_helpers.RBACTimelock, sel uint64) { + timelockContracts *TimelockExecutionContracts, sel uint64) { t.Log("Executing proposal on chain", sel) // Set the root. tx, err2 := executor.SetRootOnChain(env.Chains[sel].Client, env.Chains[sel].DeployerKey, mcms.ChainIdentifier(sel)) @@ -85,7 +92,7 @@ func ExecuteProposal(t *testing.T, env deployment.Environment, executor *mcms.Ex block, err3 := env.Chains[sel].Confirm(opTx) require.NoError(t, err3) t.Log("executed", chainOp) - it, err3 := timelock.FilterCallScheduled(&bind.FilterOpts{ + it, err3 := timelockContracts.Timelock.FilterCallScheduled(&bind.FilterOpts{ Start: block, End: &block, Context: context.Background(), @@ -104,7 +111,8 @@ func ExecuteProposal(t *testing.T, env deployment.Environment, executor *mcms.Ex Value: it.Event.Value, }) } - tx, err := timelock.ExecuteBatch( + timelockExecutorProxy, err := owner_helpers.NewRBACTimelock(timelockContracts.CallProxy.Address(), env.Chains[sel].Client) + tx, err := timelockExecutorProxy.ExecuteBatch( env.Chains[sel].DeployerKey, calls, pred, salt) require.NoError(t, err) _, err = env.Chains[sel].Confirm(tx) diff --git a/deployment/common/changeset/state.go b/deployment/common/changeset/state.go index 0055c908f8d..a580c13b40b 100644 --- a/deployment/common/changeset/state.go +++ b/deployment/common/changeset/state.go @@ -23,6 +23,7 @@ type MCMSWithTimelockState struct { BypasserMcm *owner_helpers.ManyChainMultiSig ProposerMcm *owner_helpers.ManyChainMultiSig Timelock *owner_helpers.RBACTimelock + CallProxy *owner_helpers.CallProxy } // Validate checks that all fields are non-nil, ensuring it's ready @@ -40,6 +41,9 @@ func (state MCMSWithTimelockState) Validate() error { if state.BypasserMcm == nil { return errors.New("bypasser not found") } + if state.CallProxy == nil { + return errors.New("call proxy not found") + } return nil } @@ -51,6 +55,10 @@ func (state MCMSWithTimelockState) GenerateMCMSWithTimelockView() (v1_0.MCMSWith if err != nil { return v1_0.MCMSWithTimelockView{}, nil } + callProxyView, err := v1_0.GenerateCallProxyView(*state.CallProxy) + if err != nil { + return v1_0.MCMSWithTimelockView{}, nil + } bypasserView, err := v1_0.GenerateMCMSView(*state.BypasserMcm) if err != nil { return v1_0.MCMSWithTimelockView{}, nil @@ -68,6 +76,7 @@ func (state MCMSWithTimelockState) GenerateMCMSWithTimelockView() (v1_0.MCMSWith Bypasser: bypasserView, Proposer: proposerView, Canceller: cancellerView, + CallProxy: callProxyView, }, nil } @@ -82,6 +91,7 @@ func MaybeLoadMCMSWithTimelockState(chain deployment.Chain, addresses map[string state := MCMSWithTimelockState{} // We expect one of each contract on the chain. timelock := deployment.NewTypeAndVersion(types.RBACTimelock, deployment.Version1_0_0) + callProxy := deployment.NewTypeAndVersion(types.CallProxy, deployment.Version1_0_0) proposer := deployment.NewTypeAndVersion(types.ProposerManyChainMultisig, deployment.Version1_0_0) canceller := deployment.NewTypeAndVersion(types.CancellerManyChainMultisig, deployment.Version1_0_0) bypasser := deployment.NewTypeAndVersion(types.BypasserManyChainMultisig, deployment.Version1_0_0) @@ -89,7 +99,7 @@ func MaybeLoadMCMSWithTimelockState(chain deployment.Chain, addresses map[string // Ensure we either have the bundle or not. _, err := deployment.AddressesContainBundle(addresses, map[deployment.TypeAndVersion]struct{}{ - timelock: {}, proposer: {}, canceller: {}, bypasser: {}, + timelock: {}, proposer: {}, canceller: {}, bypasser: {}, callProxy: {}, }) if err != nil { return nil, fmt.Errorf("unable to check MCMS contracts on chain %s error: %w", chain.Name(), err) @@ -103,6 +113,12 @@ func MaybeLoadMCMSWithTimelockState(chain deployment.Chain, addresses map[string return nil, err } state.Timelock = tl + case callProxy: + cp, err := owner_helpers.NewCallProxy(common.HexToAddress(address), chain.Client) + if err != nil { + return nil, err + } + state.CallProxy = cp case proposer: mcms, err := owner_helpers.NewManyChainMultiSig(common.HexToAddress(address), chain.Client) if err != nil { diff --git a/deployment/common/changeset/test_helpers.go b/deployment/common/changeset/test_helpers.go index 2d5295282f5..8fce5ea79f2 100644 --- a/deployment/common/changeset/test_helpers.go +++ b/deployment/common/changeset/test_helpers.go @@ -5,7 +5,6 @@ import ( "testing" mapset "github.com/deckarep/golang-set/v2" - "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" @@ -33,7 +32,7 @@ func WrapChangeSet[C any](fn deployment.ChangeSet[C]) func(e deployment.Environm } // ApplyChangesets applies the changeset applications to the environment and returns the updated environment. -func ApplyChangesets(t *testing.T, e deployment.Environment, timelocksPerChain map[uint64]*gethwrappers.RBACTimelock, changesetApplications []ChangesetApplication) (deployment.Environment, error) { +func ApplyChangesets(t *testing.T, e deployment.Environment, timelockContractsPerChain map[uint64]*TimelockExecutionContracts, changesetApplications []ChangesetApplication) (deployment.Environment, error) { currentEnv := e for i, csa := range changesetApplications { out, err := csa.Changeset(currentEnv, csa.Config) @@ -75,11 +74,12 @@ func ApplyChangesets(t *testing.T, e deployment.Environment, timelocksPerChain m signed := SignProposal(t, e, &prop) for _, sel := range chains.ToSlice() { - timelock, ok := timelocksPerChain[sel] - if !ok || timelock == nil { - return deployment.Environment{}, fmt.Errorf("timelock not found for chain %d", sel) + timelockContracts, ok := timelockContractsPerChain[sel] + if !ok || timelockContracts == nil { + return deployment.Environment{}, fmt.Errorf("timelock contracts not found for chain %d", sel) } - ExecuteProposal(t, e, signed, timelock, sel) + + ExecuteProposal(t, e, signed, timelockContracts, sel) } } } diff --git a/deployment/common/changeset/transfer_to_mcms_with_timelock_test.go b/deployment/common/changeset/transfer_to_mcms_with_timelock_test.go index 6cdff286707..6c68924b35e 100644 --- a/deployment/common/changeset/transfer_to_mcms_with_timelock_test.go +++ b/deployment/common/changeset/transfer_to_mcms_with_timelock_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" - owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/stretchr/testify/require" "math/big" @@ -30,11 +29,10 @@ func TestTransferToMCMSWithTimelock(t *testing.T) { Changeset: WrapChangeSet(DeployMCMSWithTimelock), Config: map[uint64]types.MCMSWithTimelockConfig{ chain1: { - Canceller: SingleGroupMCMS(t), - Bypasser: SingleGroupMCMS(t), - Proposer: SingleGroupMCMS(t), - TimelockExecutors: e.AllDeployerKeys(), - TimelockMinDelay: big.NewInt(0), + Canceller: SingleGroupMCMS(t), + Bypasser: SingleGroupMCMS(t), + Proposer: SingleGroupMCMS(t), + TimelockMinDelay: big.NewInt(0), }, }, }, @@ -46,8 +44,11 @@ func TestTransferToMCMSWithTimelock(t *testing.T) { require.NoError(t, err) link, err := MaybeLoadLinkTokenState(e.Chains[chain1], addrs) require.NoError(t, err) - e, err = ApplyChangesets(t, e, map[uint64]*owner_helpers.RBACTimelock{ - chain1: state.Timelock, + e, err = ApplyChangesets(t, e, map[uint64]*TimelockExecutionContracts{ + chain1: { + Timelock: state.Timelock, + CallProxy: state.CallProxy, + }, }, []ChangesetApplication{ { Changeset: WrapChangeSet(TransferToMCMSWithTimelock), diff --git a/deployment/common/types/types.go b/deployment/common/types/types.go index 386ef8fbb36..0f04421af43 100644 --- a/deployment/common/types/types.go +++ b/deployment/common/types/types.go @@ -5,7 +5,6 @@ import ( "math/big" "time" - "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/ccip-owner-contracts/pkg/config" "github.com/smartcontractkit/chainlink/deployment" @@ -16,6 +15,7 @@ const ( CancellerManyChainMultisig deployment.ContractType = "CancellerManyChainMultiSig" ProposerManyChainMultisig deployment.ContractType = "ProposerManyChainMultiSig" RBACTimelock deployment.ContractType = "RBACTimelock" + CallProxy deployment.ContractType = "CallProxy" // LinkToken is the burn/mint link token. It should be used everywhere for // new deployments. Corresponds to // https://github.com/smartcontractkit/chainlink/blob/develop/core/gethwrappers/shared/generated/link_token/link_token.go#L34 @@ -29,11 +29,10 @@ const ( ) type MCMSWithTimelockConfig struct { - Canceller config.Config - Bypasser config.Config - Proposer config.Config - TimelockExecutors []common.Address - TimelockMinDelay *big.Int + Canceller config.Config + Bypasser config.Config + Proposer config.Config + TimelockMinDelay *big.Int } type OCRParameters struct { diff --git a/deployment/common/view/v1_0/mcms.go b/deployment/common/view/v1_0/mcms.go index 25ca614a553..bc971623545 100644 --- a/deployment/common/view/v1_0/mcms.go +++ b/deployment/common/view/v1_0/mcms.go @@ -107,11 +107,24 @@ func GenerateTimelockView(tl owner_helpers.RBACTimelock) (TimelockView, error) { }, nil } +type CallProxyView struct { + types.ContractMetaData +} + +func GenerateCallProxyView(cp owner_helpers.CallProxy) (CallProxyView, error) { + return CallProxyView{ + ContractMetaData: types.ContractMetaData{ + Address: cp.Address(), + }, + }, nil +} + type MCMSWithTimelockView struct { - Bypasser MCMSView `json:"bypasser"` - Canceller MCMSView `json:"canceller"` - Proposer MCMSView `json:"proposer"` - Timelock TimelockView `json:"timelock"` + Bypasser MCMSView `json:"bypasser"` + Canceller MCMSView `json:"canceller"` + Proposer MCMSView `json:"proposer"` + Timelock TimelockView `json:"timelock"` + CallProxy CallProxyView `json:"callProxy"` } func GenerateMCMSWithTimelockView( @@ -124,6 +137,10 @@ func GenerateMCMSWithTimelockView( if err != nil { return MCMSWithTimelockView{}, nil } + callProxyView, err := GenerateCallProxyView(owner_helpers.CallProxy{}) + if err != nil { + return MCMSWithTimelockView{}, nil + } bypasserView, err := GenerateMCMSView(bypasser) if err != nil { return MCMSWithTimelockView{}, nil @@ -142,5 +159,6 @@ func GenerateMCMSWithTimelockView( Bypasser: bypasserView, Proposer: proposerView, Canceller: cancellerView, + CallProxy: callProxyView, }, nil } diff --git a/deployment/keystone/changeset/accept_ownership_test.go b/deployment/keystone/changeset/accept_ownership_test.go index f205adda496..9ac0063143e 100644 --- a/deployment/keystone/changeset/accept_ownership_test.go +++ b/deployment/keystone/changeset/accept_ownership_test.go @@ -4,7 +4,6 @@ import ( "math/big" "testing" - owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" @@ -42,11 +41,10 @@ func TestAcceptAllOwnership(t *testing.T) { Changeset: commonchangeset.WrapChangeSet(commonchangeset.DeployMCMSWithTimelock), Config: map[uint64]types.MCMSWithTimelockConfig{ registrySel: { - Canceller: commonchangeset.SingleGroupMCMS(t), - Bypasser: commonchangeset.SingleGroupMCMS(t), - Proposer: commonchangeset.SingleGroupMCMS(t), - TimelockExecutors: env.AllDeployerKeys(), - TimelockMinDelay: big.NewInt(0), + Canceller: commonchangeset.SingleGroupMCMS(t), + Bypasser: commonchangeset.SingleGroupMCMS(t), + Proposer: commonchangeset.SingleGroupMCMS(t), + TimelockMinDelay: big.NewInt(0), }, }, }, @@ -57,8 +55,11 @@ func TestAcceptAllOwnership(t *testing.T) { timelock, err := commonchangeset.MaybeLoadMCMSWithTimelockState(env.Chains[registrySel], addrs) require.NoError(t, err) - _, err = commonchangeset.ApplyChangesets(t, env, map[uint64]*owner_helpers.RBACTimelock{ - registrySel: timelock.Timelock, + _, err = commonchangeset.ApplyChangesets(t, env, map[uint64]*commonchangeset.TimelockExecutionContracts{ + registrySel: &commonchangeset.TimelockExecutionContracts{ + Timelock: timelock.Timelock, + CallProxy: timelock.CallProxy, + }, }, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(changeset.AcceptAllOwnershipsProposal), diff --git a/deployment/keystone/changeset/deploy_forwarder_test.go b/deployment/keystone/changeset/deploy_forwarder_test.go index 32a53f1cf08..82454599226 100644 --- a/deployment/keystone/changeset/deploy_forwarder_test.go +++ b/deployment/keystone/changeset/deploy_forwarder_test.go @@ -8,7 +8,6 @@ import ( "github.com/stretchr/testify/require" - "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/deployment" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" @@ -117,12 +116,16 @@ func TestConfigureForwarders(t *testing.T) { require.Len(t, csOut.Proposals, nChains) require.Nil(t, csOut.AddressBook) - timelocks := make(map[uint64]*gethwrappers.RBACTimelock) + timelockContracts := make(map[uint64]*commonchangeset.TimelockExecutionContracts) for selector, contractSet := range te.ContractSets() { require.NotNil(t, contractSet.Timelock) - timelocks[selector] = contractSet.Timelock + require.NotNil(t, contractSet.CallProxy) + timelockContracts[selector] = &commonchangeset.TimelockExecutionContracts{ + Timelock: contractSet.Timelock, + CallProxy: contractSet.CallProxy, + } } - _, err = commonchangeset.ApplyChangesets(t, te.Env, timelocks, []commonchangeset.ChangesetApplication{ + _, err = commonchangeset.ApplyChangesets(t, te.Env, timelockContracts, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(changeset.ConfigureForwardContracts), Config: cfg, diff --git a/deployment/keystone/changeset/deploy_ocr3_test.go b/deployment/keystone/changeset/deploy_ocr3_test.go index ae00f19fc22..60abd702929 100644 --- a/deployment/keystone/changeset/deploy_ocr3_test.go +++ b/deployment/keystone/changeset/deploy_ocr3_test.go @@ -10,7 +10,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/chainlink-common/pkg/logger" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" @@ -119,13 +118,18 @@ func TestConfigureOCR3(t *testing.T) { t.Logf("got: %v", csOut.Proposals[0]) contracts := te.ContractSets()[te.RegistrySelector] - var timelocks = map[uint64]*gethwrappers.RBACTimelock{ - te.RegistrySelector: contracts.Timelock, + require.NoError(t, err) + var timelockContracts = map[uint64]*commonchangeset.TimelockExecutionContracts{ + te.RegistrySelector: { + Timelock: contracts.Timelock, + CallProxy: contracts.CallProxy, + }, } + // now apply the changeset such that the proposal is signed and execed w2 := &bytes.Buffer{} cfg.WriteGeneratedConfig = w2 - _, err = commonchangeset.ApplyChangesets(t, te.Env, timelocks, []commonchangeset.ChangesetApplication{ + _, err = commonchangeset.ApplyChangesets(t, te.Env, timelockContracts, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(changeset.ConfigureOCR3Contract), Config: cfg, diff --git a/deployment/keystone/changeset/helpers_test.go b/deployment/keystone/changeset/helpers_test.go index a4e98efd550..4e7553d0b8e 100644 --- a/deployment/keystone/changeset/helpers_test.go +++ b/deployment/keystone/changeset/helpers_test.go @@ -12,7 +12,6 @@ import ( "sort" "testing" - "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" @@ -260,11 +259,10 @@ func SetupTestEnv(t *testing.T, c TestConfig) TestEnv { for sel := range env.Chains { t.Logf("Enabling MCMS on chain %d", sel) timelockCfgs[sel] = commontypes.MCMSWithTimelockConfig{ - Canceller: commonchangeset.SingleGroupMCMS(t), - Bypasser: commonchangeset.SingleGroupMCMS(t), - Proposer: commonchangeset.SingleGroupMCMS(t), - TimelockExecutors: env.AllDeployerKeys(), - TimelockMinDelay: big.NewInt(0), + Canceller: commonchangeset.SingleGroupMCMS(t), + Bypasser: commonchangeset.SingleGroupMCMS(t), + Proposer: commonchangeset.SingleGroupMCMS(t), + TimelockMinDelay: big.NewInt(0), } } env, err = commonchangeset.ApplyChangesets(t, env, nil, []commonchangeset.ChangesetApplication{ @@ -286,7 +284,7 @@ func SetupTestEnv(t *testing.T, c TestConfig) TestEnv { require.NoError(t, mcms.Validate()) // transfer ownership of all contracts to the MCMS - env, err = commonchangeset.ApplyChangesets(t, env, map[uint64]*gethwrappers.RBACTimelock{sel: mcms.Timelock}, []commonchangeset.ChangesetApplication{ + env, err = commonchangeset.ApplyChangesets(t, env, map[uint64]*commonchangeset.TimelockExecutionContracts{sel: {Timelock: mcms.Timelock, CallProxy: mcms.CallProxy}}, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(kschangeset.AcceptAllOwnershipsProposal), Config: &kschangeset.AcceptAllOwnershipRequest{ diff --git a/deployment/keystone/changeset/update_nodes_test.go b/deployment/keystone/changeset/update_nodes_test.go index 10c08333d22..aebe10aa3d5 100644 --- a/deployment/keystone/changeset/update_nodes_test.go +++ b/deployment/keystone/changeset/update_nodes_test.go @@ -8,7 +8,6 @@ import ( "github.com/stretchr/testify/require" "golang.org/x/exp/maps" - "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" "github.com/smartcontractkit/chainlink/deployment/keystone/changeset" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" @@ -90,10 +89,13 @@ func TestUpdateNodes(t *testing.T) { // now apply the changeset such that the proposal is signed and execed contracts := te.ContractSets()[te.RegistrySelector] - timelocks := map[uint64]*gethwrappers.RBACTimelock{ - te.RegistrySelector: contracts.Timelock, + timelockContracts := map[uint64]*commonchangeset.TimelockExecutionContracts{ + te.RegistrySelector: { + Timelock: contracts.Timelock, + CallProxy: contracts.CallProxy, + }, } - _, err = commonchangeset.ApplyChangesets(t, te.Env, timelocks, []commonchangeset.ChangesetApplication{ + _, err = commonchangeset.ApplyChangesets(t, te.Env, timelockContracts, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(changeset.UpdateNodes), Config: &changeset.UpdateNodesRequest{ diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 58b2a6fa1c4..ae4b843ea1b 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -37,7 +37,6 @@ require ( github.com/segmentio/ksuid v1.0.4 github.com/shopspring/decimal v1.4.0 github.com/slack-go/slack v0.15.0 - github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 github.com/smartcontractkit/chain-selectors v1.0.34 github.com/smartcontractkit/chainlink-automation v0.8.1 github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e @@ -419,6 +418,7 @@ require ( github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect + github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 // indirect github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e // indirect github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db // indirect github.com/smartcontractkit/chainlink-feeds v0.1.1 // indirect diff --git a/integration-tests/testsetups/ccip/test_helpers.go b/integration-tests/testsetups/ccip/test_helpers.go index 3112d738869..f26a9d3c672 100644 --- a/integration-tests/testsetups/ccip/test_helpers.go +++ b/integration-tests/testsetups/ccip/test_helpers.go @@ -11,7 +11,6 @@ import ( "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" chainsel "github.com/smartcontractkit/chain-selectors" cciptypes "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" @@ -147,11 +146,10 @@ func NewLocalDevEnvironment( mcmsCfg := make(map[uint64]commontypes.MCMSWithTimelockConfig) for _, c := range env.AllChainSelectors() { mcmsCfg[c] = commontypes.MCMSWithTimelockConfig{ - Canceller: commonchangeset.SingleGroupMCMS(t), - Bypasser: commonchangeset.SingleGroupMCMS(t), - Proposer: commonchangeset.SingleGroupMCMS(t), - TimelockExecutors: env.AllDeployerKeys(), - TimelockMinDelay: big.NewInt(0), + Canceller: commonchangeset.SingleGroupMCMS(t), + Bypasser: commonchangeset.SingleGroupMCMS(t), + Proposer: commonchangeset.SingleGroupMCMS(t), + TimelockMinDelay: big.NewInt(0), } } // Need to deploy prerequisites first so that we can form the USDC config @@ -226,9 +224,12 @@ func NewLocalDevEnvironment( // Build the per chain config. tokenConfig := changeset.NewTestTokenConfig(state.Chains[feedSel].USDFeeds) chainConfigs := make(map[uint64]changeset.CCIPOCRParams) - timelocksPerChain := make(map[uint64]*gethwrappers.RBACTimelock) + timelockContractsPerChain := make(map[uint64]*commonchangeset.TimelockExecutionContracts) for _, chain := range allChains { - timelocksPerChain[chain] = state.Chains[chain].Timelock + timelockContractsPerChain[chain] = &commonchangeset.TimelockExecutionContracts{ + Timelock: state.Chains[chain].Timelock, + CallProxy: state.Chains[chain].CallProxy, + } tokenInfo := tokenConfig.GetTokenInfo(e.Logger, state.Chains[chain].LinkToken, state.Chains[chain].Weth9) ocrParams := changeset.DefaultOCRParams(feedSel, tokenInfo, tokenDataProviders) if tCfg.OCRConfigOverride != nil { @@ -238,7 +239,7 @@ func NewLocalDevEnvironment( } // Deploy second set of changesets to deploy and configure the CCIP contracts. - env, err = commonchangeset.ApplyChangesets(t, env, timelocksPerChain, []commonchangeset.ChangesetApplication{ + env, err = commonchangeset.ApplyChangesets(t, env, timelockContractsPerChain, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(changeset.ConfigureNewChains), Config: changeset.NewChainsConfig{ From cf10ccf6eec6cc7a64848c005d12c18335f2e272 Mon Sep 17 00:00:00 2001 From: Rafael Felix Correa Date: Tue, 10 Dec 2024 15:48:35 +0100 Subject: [PATCH 27/29] Handle non postfix path (#15518) Co-authored-by: HenryNguyen5 <6404866+HenryNguyen5@users.noreply.github.com> --- tools/bin/goreleaser_utils | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/bin/goreleaser_utils b/tools/bin/goreleaser_utils index 52e37cefd51..0bf745d5a58 100755 --- a/tools/bin/goreleaser_utils +++ b/tools/bin/goreleaser_utils @@ -27,8 +27,10 @@ before_hook() { # linux_arm64, rather than being suffixless on native platforms if [ "$GOARCH" = "arm64" ]; then if [ -d "$BIN_DIR/linux_arm64" ]; then + cp "$BIN_DIR/linux_arm64"/chainlink* "$PLUGIN_DIR" + elif [ -d "$BIN_DIR/linux_arm64_v8.0" ]; then cp "$BIN_DIR/linux_arm64_v8.0"/chainlink* "$PLUGIN_DIR" - else + else cp "$BIN_DIR"/chainlink* "$PLUGIN_DIR" fi # Call patchelf --set-interpreter on all plugins From 0e0d19e719a7e5905c52e28009ba4406409640ce Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Tue, 10 Dec 2024 16:06:18 +0100 Subject: [PATCH 28/29] Improve Flakeguard: Increased Test Runs, Improved Summaries, Fixes for Notifications, Parsing, and Logs (#15541) * Refactor flaky test detection reports * fix * fix * fail test * fix test * add test to fail * update pr report * fix * bump * pass test * Rename artifacts * fail test * remove test * bump flakeguard * update * bump * bump * bump flakeguard * bump flakeguard report runner * fail test to check flakeguard reports * Increase flakeguard nightly test runs from 15 to 50 * Add step to get url to failed tests artifact * bump timeout * bump flakeguard * to revert: disable slack notification * Add GITHUB_TOKEN secret * add missing secret * fix * temp: update nightly * Revert "temp: update nightly" This reverts commit 396793bb7576ff2401546c0d8a51c6ec9c578d36. * print out flakeguard summary file * bump * remove fail_test.go * Fix * Fix fromJSON * fix * Bump flakeguard * bump * bump * Run each test in flakeguard nightly 15 times * bump retention days for test results with logs --- .github/workflows/ci-core.yml | 2 + .github/workflows/flakeguard-nightly.yml | 2 + .github/workflows/flakeguard-on-demand.yml | 1 + .github/workflows/flakeguard.yml | 242 ++++++++++----------- 4 files changed, 122 insertions(+), 125 deletions(-) diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index c38ecd918ae..9134a8c9b56 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -466,6 +466,7 @@ jobs: extraArgs: '{ "skipped_tests": "TestChainComponents", "run_with_race": "true", "print_failed_tests": "true", "test_repeat_count": "3", "min_pass_ratio": "0.01" }' secrets: SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} trigger-flaky-test-detection-for-deployment-project: name: Flakeguard Deployment Project @@ -484,6 +485,7 @@ jobs: extraArgs: '{ "skipped_tests": "TestAddLane", "run_with_race": "true", "print_failed_tests": "true", "test_repeat_count": "3", "min_pass_ratio": "0.01" }' secrets: SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} clean: name: Clean Go Tidy & Generate diff --git a/.github/workflows/flakeguard-nightly.yml b/.github/workflows/flakeguard-nightly.yml index 37c00fa0a8f..178d43d809a 100644 --- a/.github/workflows/flakeguard-nightly.yml +++ b/.github/workflows/flakeguard-nightly.yml @@ -20,3 +20,5 @@ jobs: slackNotificationAfterTestsChannelId: 'C07TRF65CNS' #flaky-test-detector-notifications secrets: SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + diff --git a/.github/workflows/flakeguard-on-demand.yml b/.github/workflows/flakeguard-on-demand.yml index fe972894594..0ba84c5ab58 100644 --- a/.github/workflows/flakeguard-on-demand.yml +++ b/.github/workflows/flakeguard-on-demand.yml @@ -69,4 +69,5 @@ jobs: extraArgs: ${{ inputs.extraArgs }} secrets: SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/flakeguard.yml b/.github/workflows/flakeguard.yml index ecc56e2f291..4c1aa695c62 100644 --- a/.github/workflows/flakeguard.yml +++ b/.github/workflows/flakeguard.yml @@ -52,20 +52,21 @@ on: secrets: SLACK_BOT_TOKEN: required: false + GH_TOKEN: + required: true env: GIT_HEAD_REF: ${{ inputs.headRef || github.ref }} - SKIPPED_TESTS: ${{ fromJson(inputs.extraArgs)['skipped_tests'] || '' }} # Comma separated list of test names to skip running in the flaky detector. Related issue: TT-1823 - DEFAULT_MAX_RUNNER_COUNT: ${{ fromJson(inputs.extraArgs)['default_max_runner_count'] || '8' }} # The default maximum number of GitHub runners to use for parallel test execution. - ALL_TESTS_RUNNER_COUNT: ${{ fromJson(inputs.extraArgs)['all_tests_runner_count'] || '2' }} # The number of GitHub runners to use when running all tests `runAllTests=true`. - TEST_REPEAT_COUNT: ${{ fromJson(inputs.extraArgs)['test_repeat_count'] || '5' }} # The number of times each runner should run a test to detect flaky tests. - RUN_WITH_RACE: ${{ fromJson(inputs.extraArgs)['run_with_race'] || 'true' }} # Whether to run tests with -race flag. - RUN_WITH_SHUFFLE: ${{ fromJson(inputs.extraArgs)['run_with_shuffle'] || 'false' }} # Whether to run tests with -shuffle flag. - SHUFFLE_SEED: ${{ fromJson(inputs.extraArgs)['shuffle_seed'] || '999' }} # The seed to use when -shuffle flag is enabled. Requires RUN_WITH_SHUFFLE to be true. - ALL_TESTS_RUNNER: ${{ fromJson(inputs.extraArgs)['all_tests_runner'] || 'ubuntu22.04-32cores-128GB' }} # The runner to use for running all tests. + SKIPPED_TESTS: ${{ fromJSON(inputs.extraArgs)['skipped_tests'] || '' }} # Comma separated list of test names to skip running in the flaky detector. Related issue: TT-1823 + DEFAULT_MAX_RUNNER_COUNT: ${{ fromJSON(inputs.extraArgs)['default_max_runner_count'] || '8' }} # The default maximum number of GitHub runners to use for parallel test execution. + ALL_TESTS_RUNNER_COUNT: ${{ fromJSON(inputs.extraArgs)['all_tests_runner_count'] || '2' }} # The number of GitHub runners to use when running all tests `runAllTests=true`. + TEST_REPEAT_COUNT: ${{ fromJSON(inputs.extraArgs)['test_repeat_count'] || '5' }} # The number of times each runner should run a test to detect flaky tests. + RUN_WITH_RACE: ${{ fromJSON(inputs.extraArgs)['run_with_race'] || 'true' }} # Whether to run tests with -race flag. + RUN_WITH_SHUFFLE: ${{ fromJSON(inputs.extraArgs)['run_with_shuffle'] || 'false' }} # Whether to run tests with -shuffle flag. + SHUFFLE_SEED: ${{ fromJSON(inputs.extraArgs)['shuffle_seed'] || '999' }} # The seed to use when -shuffle flag is enabled. Requires RUN_WITH_SHUFFLE to be true. + ALL_TESTS_RUNNER: ${{ fromJSON(inputs.extraArgs)['all_tests_runner'] || 'ubuntu22.04-32cores-128GB' }} # The runner to use for running all tests. DEFAULT_RUNNER: 'ubuntu-latest' # The default runner to use for running tests. - UPLOAD_ALL_TEST_RESULTS: ${{ fromJson(inputs.extraArgs)['upload_all_test_results'] || 'false' }} # Whether to upload all test results as artifacts. - PRINT_FAILED_TESTS: ${{ fromJson(inputs.extraArgs)['print_failed_tests'] || 'false' }} # Whether to print failed tests in the GitHub console. + UPLOAD_ALL_TEST_RESULTS: ${{ fromJSON(inputs.extraArgs)['upload_all_test_results'] || 'false' }} # Whether to upload all test results as artifacts. jobs: @@ -101,7 +102,7 @@ jobs: - name: Install flakeguard shell: bash - run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@9e40f2765df01f20b3bf53f0fb3ead920e3a1f4a # flakguard@0.1.0 + run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@404e04e1e2e2dd5a384b09bd05b8d80409b6609a # flakguard@0.1.0 - name: Find new or updated test packages if: ${{ inputs.runAllTests == false }} @@ -196,11 +197,11 @@ jobs: needs: get-tests runs-on: ${{ matrix.runs_on }} if: ${{ needs.get-tests.outputs.matrix != '' && needs.get-tests.outputs.matrix != '[]' }} - timeout-minutes: 90 + timeout-minutes: 180 strategy: fail-fast: false matrix: - include: ${{ fromJson(needs.get-tests.outputs.matrix) }} + include: ${{ fromJSON(needs.get-tests.outputs.matrix) }} env: DB_URL: postgresql://postgres:postgres@localhost:5432/chainlink_test?sslmode=disable steps: @@ -260,11 +261,11 @@ jobs: - name: Install flakeguard shell: bash - run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@9e40f2765df01f20b3bf53f0fb3ead920e3a1f4a # flakguard@0.1.0 + run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@404e04e1e2e2dd5a384b09bd05b8d80409b6609a # flakguard@0.1.0 - name: Run tests with flakeguard shell: bash - run: flakeguard run --project-path=${{ inputs.projectPath }} --test-packages=${{ matrix.testPackages }} --run-count=${{ env.TEST_REPEAT_COUNT }} --max-pass-ratio=${{ inputs.maxPassRatio }} --race=${{ env.RUN_WITH_RACE }} --shuffle=${{ env.RUN_WITH_SHUFFLE }} --shuffle-seed=${{ env.SHUFFLE_SEED }} --skip-tests=${{ env.SKIPPED_TESTS }} --print-failed-tests=${{ env.PRINT_FAILED_TESTS }} --output-json=test-result.json + run: flakeguard run --project-path=${{ inputs.projectPath }} --test-packages=${{ matrix.testPackages }} --run-count=${{ env.TEST_REPEAT_COUNT }} --max-pass-ratio=${{ inputs.maxPassRatio }} --race=${{ env.RUN_WITH_RACE }} --shuffle=${{ env.RUN_WITH_SHUFFLE }} --shuffle-seed=${{ env.SHUFFLE_SEED }} --skip-tests=${{ env.SKIPPED_TESTS }} --output-json=test-result.json env: CL_DATABASE_URL: ${{ env.DB_URL }} @@ -280,9 +281,9 @@ jobs: needs: [get-tests, run-tests] if: always() name: Report - runs-on: ubuntu-latest + runs-on: ubuntu-24.04-8cores-32GB-ARM # Use a runner with more resources to avoid OOM errors when aggregating test results. outputs: - test_results: ${{ steps.set_test_results.outputs.results }} + test_results: ${{ steps.results.outputs.results }} steps: - name: Checkout repository uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 @@ -307,136 +308,127 @@ jobs: - name: Install flakeguard shell: bash - run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@9e40f2765df01f20b3bf53f0fb3ead920e3a1f4a # flakguard@0.1.0 + run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@404e04e1e2e2dd5a384b09bd05b8d80409b6609a # flakguard@0.1.0 - - name: Set combined test results - id: set_test_results + - name: Aggregate Flakeguard Results + id: results shell: bash run: | set -e # Exit immediately if a command exits with a non-zero status. - - if [ -d "ci_test_results" ]; then - cd ci_test_results - ls -R . - - # Fix flakeguard binary path - PATH=$PATH:$(go env GOPATH)/bin - export PATH - - # Use flakeguard to aggregate all test results - flakeguard aggregate-results --results-path . --output-results ../all_tests.json --project-path=${{ github.workspace }}/${{ inputs.projectPath }} --codeowners-path=${{ github.workspace }}/.github/CODEOWNERS - - # Count all tests - ALL_TESTS_COUNT=$(jq '.Results | length' ../all_tests.json) - echo "All tests count: $ALL_TESTS_COUNT" - echo "all_tests_count=$ALL_TESTS_COUNT" >> "$GITHUB_OUTPUT" - - # Use flakeguard to filter and output failed tests based on MaxPassRatio - flakeguard aggregate-results --filter-failed=true --max-pass-ratio=${{ inputs.maxPassRatio }} --results-path . --output-results ../failed_tests.json --output-logs ../failed_test_logs.json --project-path=${{ github.workspace }}/${{ inputs.projectPath }} --codeowners-path=${{ github.workspace }}/.github/CODEOWNERS - - # Count failed tests - if [ -f "../failed_tests.json" ]; then - FAILED_TESTS_COUNT=$(jq '.Results | length' ../failed_tests.json) - else - FAILED_TESTS_COUNT=0 - fi - echo "Failed tests count: $FAILED_TESTS_COUNT" - echo "failed_tests_count=$FAILED_TESTS_COUNT" >> "$GITHUB_OUTPUT" - - # Calculate failed ratio (failed / non-failed tests ratio in %) - if [ "$ALL_TESTS_COUNT" -gt 0 ]; then - NON_FAILED_COUNT=$((ALL_TESTS_COUNT - FAILED_TESTS_COUNT)) - - if [ "$NON_FAILED_COUNT" -gt 0 ]; then - FAILED_RATIO=$(awk "BEGIN {printf \"%.2f\", ($FAILED_TESTS_COUNT / $NON_FAILED_COUNT) * 100}") - else - FAILED_RATIO=0 - fi - else - NON_FAILED_COUNT=0 - FAILED_RATIO=0 - fi - echo "Failed tests ratio: $FAILED_RATIO%" - echo "failed_ratio=$FAILED_RATIO" >> "$GITHUB_OUTPUT" - else - echo "No test results directory found." - echo "all_tests_count=0" >> "$GITHUB_OUTPUT" - echo "failed_tests_count=0" >> "$GITHUB_OUTPUT" - echo "failed_ratio=0" >> "$GITHUB_OUTPUT" - fi - - - name: Tests Summary - if: ${{ fromJson(steps.set_test_results.outputs.all_tests_count) > 0 }} - run: | - FILE_SIZE=$(wc -c < all_tests.md) - echo "File size: $FILE_SIZE bytes" - SIZE_LIMIT=$((1024 * 1024)) - - if [ "$FILE_SIZE" -le "$SIZE_LIMIT" ]; then - cat all_tests.md >> $GITHUB_STEP_SUMMARY - else - echo "**We found flaky tests, so many flaky tests that the summary is too large for github actions step summaries!**" >> $GITHUB_STEP_SUMMARY - echo "**Please see logs, or the attached `all-summary.md` artifact**" >> $GITHUB_STEP_SUMMARY - cat all_tests.md - fi - - - name: Upload All Tests Summary as Artifact - if: ${{ fromJson(steps.set_test_results.outputs.all_tests_count) > 0 }} - uses: actions/upload-artifact@v4.4.3 - with: - path: all_tests.md - name: all-summary.md - retention-days: 90 + + # Create test results folder if it doesn't exist + mkdir -p ci_test_results + + # Fix flakeguard binary path + PATH=$PATH:$(go env GOPATH)/bin + export PATH + + # Aggregate Flakeguard test results + flakeguard aggregate-results \ + --results-path ./ci_test_results \ + --output-path ./flakeguard-report \ + --repo-path "${{ github.workspace }}" \ + --codeowners-path "${{ github.workspace }}/.github/CODEOWNERS" \ + --max-pass-ratio "${{ inputs.maxPassRatio }}" + + # Print out the summary file + echo -e "\nFlakeguard Summary:" + jq . ./flakeguard-report/all-test-summary.json + + # Read the summary from the generated report + summary=$(jq -c '.' ./flakeguard-report/all-test-summary.json) + echo "summary=$summary" >> $GITHUB_OUTPUT - name: Upload All Test Results as Artifact - if: ${{ fromJson(steps.set_test_results.outputs.all_tests_count) > 0 }} + if: ${{ fromJSON(steps.results.outputs.summary).total_tests > 0 }} uses: actions/upload-artifact@v4.4.3 with: - path: all_tests.json + path: ./flakeguard-report/all-test-results.json name: all-test-results.json retention-days: 90 - - name: Upload Failed Tests Summary as Artifact - if: ${{ fromJson(steps.set_test_results.outputs.all_tests_count) > 0 }} - uses: actions/upload-artifact@v4.4.3 - with: - path: failed_tests.md - name: failed-summary.md - retention-days: 90 - - name: Upload Failed Test Results as Artifact - if: ${{ fromJson(steps.set_test_results.outputs.failed_tests_count) > 0 }} + if: ${{ fromJSON(steps.results.outputs.summary).failed_runs > 0 }} uses: actions/upload-artifact@v4.4.3 with: - path: failed_tests.json + path: ./flakeguard-report/failed-test-results.json name: failed-test-results.json - retention-days: 90 - - - name: Upload Failed Test Logs as Artifact - if: ${{ fromJson(steps.set_test_results.outputs.failed_tests_count) > 0 }} - uses: actions/upload-artifact@v4.4.3 - with: - path: failed_test_logs.json - name: failed-test-logs.json - retention-days: 90 - - - name: Upload All Test Results as Artifact - if: ${{ fromJson(steps.set_test_results.outputs.all_tests_count) > 0 && env.UPLOAD_ALL_TEST_RESULTS == 'true' }} + retention-days: 90 + + - name: Upload Failed Test Results With Logs as Artifact + if: ${{ fromJSON(steps.results.outputs.summary).failed_runs > 0 }} uses: actions/upload-artifact@v4.4.3 with: - path: all_tests.json - name: all-test-results.json + path: ./flakeguard-report/failed-test-results-with-logs.json + name: failed-test-results-with-logs.json retention-days: 90 + - name: Generate Flakeguard Reports + shell: bash + env: + GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + run: | + set -e # Exit immediately if a command exits with a non-zero status. + + # Fix flakeguard binary path + PATH=$PATH:$(go env GOPATH)/bin + export PATH + + # Check if the event is a pull request + if [ "${{ github.event_name }}" = "pull_request" ]; then + flakeguard generate-report \ + --aggregated-results-path ./flakeguard-report/all-test-results.json \ + --summary-path ./flakeguard-report/all-test-summary.json \ + --output-path ./flakeguard-report \ + --github-repository "${{ github.repository }}" \ + --github-run-id "${{ github.run_id }}" \ + --failed-tests-artifact-name "failed-test-results-with-logs.json" \ + --generate-pr-comment \ + --base-branch "${{ github.event.pull_request.base.ref }}" \ + --current-branch "${{ github.head_ref }}" \ + --current-commit-sha "${{ github.event.pull_request.head.sha }}" \ + --repo-url "https://github.com/${{ github.repository }}" \ + --action-run-id "${{ github.run_id }}" \ + --max-pass-ratio "${{ inputs.maxPassRatio }}" + else + flakeguard generate-report \ + --aggregated-results-path ./flakeguard-report/all-test-results.json \ + --summary-path ./flakeguard-report/all-test-summary.json \ + --output-path ./flakeguard-report \ + --github-repository "${{ github.repository }}" \ + --github-run-id "${{ github.run_id }}" \ + --failed-tests-artifact-name "failed-test-results-with-logs.json" \ + --base-branch "${{ github.event.pull_request.base.ref }}" \ + --current-branch "${{ github.head_ref }}" \ + --current-commit-sha "${{ github.event.pull_request.head.sha }}" \ + --repo-url "https://github.com/${{ github.repository }}" \ + --action-run-id "${{ github.run_id }}" \ + --max-pass-ratio "${{ inputs.maxPassRatio }}" + fi + + - name: Add Github Summary + run: | + FILE_SIZE=$(wc -c < ./flakeguard-report/all-test-summary.md) + echo "File size: $FILE_SIZE bytes" + SIZE_LIMIT=$((1024 * 1024)) + + if [ "$FILE_SIZE" -le "$SIZE_LIMIT" ]; then + cat ./flakeguard-report/all-test-summary.md >> $GITHUB_STEP_SUMMARY + else + echo "**We found flaky tests, so many flaky tests that the summary is too large for github actions step summaries!**" >> $GITHUB_STEP_SUMMARY + echo "**Please see logs, or the attached `all-test-summary.md` artifact**" >> $GITHUB_STEP_SUMMARY + cat ./flakeguard-report/all-test-summary.md + fi + - name: Post comment on PR if flaky tests found - if: ${{ fromJson(steps.set_test_results.outputs.failed_tests_count) > 0 && github.event_name == 'pull_request' }} + if: ${{ fromJSON(steps.results.outputs.summary).flaky_tests > 0 && github.event_name == 'pull_request' }} uses: actions/github-script@v7 continue-on-error: true with: script: | const fs = require('fs'); const prNumber = context.payload.pull_request.number; - const commentBody = fs.readFileSync('all_tests.md', 'utf8'); + const commentBody = fs.readFileSync('./flakeguard-report/all-test-pr-comment.md', 'utf8'); await github.rest.issues.createComment({ owner: context.repo.owner, @@ -446,7 +438,7 @@ jobs: }); - name: Send Slack message for failed tests - if: ${{ inputs.slackNotificationAfterTestsChannelId != '' && fromJson(steps.set_test_results.outputs.failed_tests_count) > 0 }} + if: ${{ inputs.slackNotificationAfterTestsChannelId != '' && fromJSON(steps.results.outputs.summary).flaky_tests > 0 }} uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} @@ -477,11 +469,11 @@ jobs: "fields": [ { "type": "mrkdwn", - "text": "Total Failed Tests: ${{ steps.set_test_results.outputs.failed_tests_count }}" + "text": "Total Flaky Tests: ${{ fromJSON(steps.results.outputs.summary).flaky_tests }}" }, { "type": "mrkdwn", - "text": "Failed to Non-Failed Ratio: ${{ steps.set_test_results.outputs.failed_ratio }}%" + "text": "Flaky Tests Ratio: ${{ fromJSON(steps.results.outputs.summary).flaky_test_ratio }}" } ] }, @@ -499,7 +491,7 @@ jobs: - name: Send general Slack message uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 - if: ${{ inputs.slackNotificationAfterTestsChannelId != '' && fromJson(steps.set_test_results.outputs.failed_tests_count) == 0 && fromJson(steps.set_test_results.outputs.all_tests_count) > 0 }} + if: ${{ inputs.slackNotificationAfterTestsChannelId != '' && fromJSON(steps.results.outputs.summary).flaky_tests == 0 && fromJSON(steps.results.outputs.summary).total_tests > 0 }} id: slack env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} From 4eca0ec7a7fcf23fb31d0df1581cd7721deb7507 Mon Sep 17 00:00:00 2001 From: Makram Date: Tue, 10 Dec 2024 18:17:00 +0200 Subject: [PATCH 29/29] deployment/ccip/changeset: use singular GetChainConfig (#15601) * deployment/ccip/changeset: use singular GetChainConfig Use the singular GetChainConfig method on CCIPHome to get the chain config of a particular chain instead of GetAllChainConfigs. * more info in error --- deployment/ccip/changeset/cs_add_chain.go | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/deployment/ccip/changeset/cs_add_chain.go b/deployment/ccip/changeset/cs_add_chain.go index d589d16b779..b3d0df04c93 100644 --- a/deployment/ccip/changeset/cs_add_chain.go +++ b/deployment/ccip/changeset/cs_add_chain.go @@ -169,21 +169,14 @@ func (a AddDonAndSetCandidateChangesetConfig) Validate(e deployment.Environment, } // check that chain config is set up for the new chain - // TODO: feels like we should just have a getter for a particular chain, this pagination - // logic seems a bit out of place here. - allConfigs, err := state.Chains[a.HomeChainSelector].CCIPHome.GetAllChainConfigs(nil, big.NewInt(0), big.NewInt(100)) + chainConfig, err := state.Chains[a.HomeChainSelector].CCIPHome.GetChainConfig(nil, a.NewChainSelector) if err != nil { return nil, fmt.Errorf("get all chain configs: %w", err) } - var found bool - for _, chainConfig := range allConfigs { - if chainConfig.ChainSelector == a.NewChainSelector { - found = true - break - } - } - if !found { - return nil, fmt.Errorf("chain config not set for chain %d", a.NewChainSelector) + + // FChain should never be zero if a chain config is set in CCIPHome + if chainConfig.FChain == 0 { + return nil, fmt.Errorf("chain config not set up for new chain %d", a.NewChainSelector) } err = a.CCIPOCRParams.Validate()