diff --git a/.github/workflows/pipeline-daily.yml b/.github/workflows/pipeline-daily.yml index 6ffcb6f..0de546e 100644 --- a/.github/workflows/pipeline-daily.yml +++ b/.github/workflows/pipeline-daily.yml @@ -1,20 +1,28 @@ name: pipeline-daily -# Runs the onchain analytics pipeline daily at 01:00 UTC (1h after midnight -# to ensure yesterday's data is fully finalized on all chains), then refreshes -# the dbt models so dashboards show the latest data. +# Manual only. The daily cron trigger was removed deliberately. # -# Required secrets: -# ENVIO_API_TOKEN -- HyperSync API token -# GCP_SA_KEY -- GCP service account JSON key (BigQuery access) -# SLACK_WEBHOOK_URL -- Slack incoming webhook for alerts (optional) +# Scheduled ingestion stays off until the readiness remediation is complete. Until then this +# workflow runs only on an explicit manual dispatch, and only against a caller supplied dataset +# that is not the production dataset. The guard below enforces that at the workflow boundary, so +# a mistyped or forgotten input stops the run instead of writing to production. # -# Manual trigger: use workflow_dispatch to run on demand. +# Required secrets: +# ENVIO_API_TOKEN HyperSync API token +# GCP_SA_KEY GCP service account JSON key (BigQuery access) +# SLACK_WEBHOOK_URL Slack incoming webhook for alerts (optional) on: - schedule: - - cron: '0 1 * * *' # 01:00 UTC daily - workflow_dispatch: # Manual trigger from GitHub UI + workflow_dispatch: + inputs: + dataset_id: + description: 'Target BigQuery dataset. Must not be the production dataset.' + required: true + type: string + confirm: + description: 'Type RUN-AGAINST-SANDBOX to confirm the target is not production.' + required: true + type: string concurrency: group: pipeline-daily @@ -30,6 +38,24 @@ jobs: timeout-minutes: 30 steps: + - name: Refuse a production or unconfirmed target + working-directory: . + env: + DATASET_ID: ${{ inputs.dataset_id }} + CONFIRM: ${{ inputs.confirm }} + run: | + if [ "$CONFIRM" != "RUN-AGAINST-SANDBOX" ]; then + echo "Refused: confirmation phrase missing or wrong." + exit 1 + fi + case "$DATASET_ID" in + ""|BlockchainEvents|Staging|Semantic|Marts) + echo "Refused: '$DATASET_ID' is a production dataset or is empty." + exit 1 + ;; + esac + echo "Target dataset accepted: $DATASET_ID" + - uses: actions/checkout@v4 - uses: actions/setup-node@v4 @@ -48,6 +74,7 @@ jobs: - name: Run pipeline (daily) env: + DATASET_ID: ${{ inputs.dataset_id }} ENVIO_API_TOKEN: ${{ secrets.ENVIO_API_TOKEN }} SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} run: npx tsx src/index.ts daily diff --git a/.github/workflows/pipeline-pr.yml b/.github/workflows/pipeline-pr.yml new file mode 100644 index 0000000..e72f232 --- /dev/null +++ b/.github/workflows/pipeline-pr.yml @@ -0,0 +1,115 @@ +name: pipeline-pr + +# The pull-request gate for the ingestion pipeline. NO CREDENTIALS, BY DESIGN. +# +# Nothing in this workflow authenticates to anything. It uses no `secrets.*` value, invokes no +# cloud authentication action, and reaches no chain, so a fork pull request runs it in full and a +# compromised dependency has nothing to steal. That is a deliberate property and the reason the +# test harness is built the way it is: every edge the pipeline has is replaceable in process, so +# proving the code works needs no BigQuery and no RPC endpoint. +# +# WHAT IT DOES NOT DO, AND WHEN THAT CHANGES. It does not run the known-failures suite. That suite +# reproduces defects other phases own, so gating pull requests on it would make every pull request +# red for reasons its author cannot act on. `npm run verify:local` runs both and is the command +# that decides whether the candidate is releasable; enforcement of the full suite in CI is added +# by the phase that makes the last known failure green. + +on: + pull_request: + paths: + - 'projects/onchain-analytics/pipeline-v5/**' + - 'projects/onchain-analytics/gd_dbt/**' + - '.github/workflows/pipeline-pr.yml' + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: pipeline-pr-${{ github.ref }} + cancel-in-progress: true + +jobs: + pipeline: + name: Pipeline lint, typecheck and tests + runs-on: ubuntu-latest + timeout-minutes: 15 + defaults: + run: + working-directory: projects/onchain-analytics/pipeline-v5 + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: projects/onchain-analytics/pipeline-v5/package-lock.json + + # `ci`, not `install`. It fails when package.json and the lockfile disagree, which is the + # only way a dependency change can be noticed in review rather than in production. + - name: Install dependencies from the lockfile + run: npm ci + + - name: Lint + run: npm run lint + + - name: Strict typecheck + run: npm run typecheck + + - name: Unit and integration tests with coverage + run: npm run test:coverage + + - name: Upload coverage + if: always() + uses: actions/upload-artifact@v4 + with: + name: pipeline-coverage + path: projects/onchain-analytics/pipeline-v5/coverage + retention-days: 7 + + dbt: + name: dbt dependency resolution and parse + runs-on: ubuntu-latest + timeout-minutes: 15 + defaults: + run: + working-directory: projects/onchain-analytics/gd_dbt + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install dbt + run: pip install "dbt-bigquery==1.8.*" + + - name: Resolve packages + run: dbt deps + + # `parse` builds the manifest from the project alone. It compiles the graph, resolves every + # ref and source, and validates the YAML, all without a warehouse connection, which is what + # lets this job run with no credentials. A broken ref or a malformed schema file fails here. + - name: Parse the project + env: + # A profile must exist for the parse to resolve, and these values are never connected + # to. There is no key, so no authentication can occur even if something tried. + DBT_PROFILES_DIR: ${{ github.workspace }}/projects/onchain-analytics/gd_dbt/.ci + run: | + mkdir -p "$DBT_PROFILES_DIR" + cat > "$DBT_PROFILES_DIR/profiles.yml" <<'YAML' + gd_dbt: + target: parse_only + outputs: + parse_only: + type: bigquery + method: oauth + project: parse-only-no-such-project + dataset: parse_only + threads: 1 + location: US + YAML + dbt parse --no-partial-parse diff --git a/.github/workflows/pipeline-sandbox-integration.yml b/.github/workflows/pipeline-sandbox-integration.yml new file mode 100644 index 0000000..5cefd09 --- /dev/null +++ b/.github/workflows/pipeline-sandbox-integration.yml @@ -0,0 +1,142 @@ +name: pipeline-sandbox-integration + +# DEFINED AND DISABLED. Do not enable this workflow yet. +# +# This is the credentialled half of the test strategy: the integration checks that genuinely need +# a BigQuery sandbox, which the in-process simulator can only approximate. The definition lands +# before the identity does, so the shape is reviewable before anything can run with it. +# +# WHY IT CANNOT RUN YET, precisely. It needs a workload-identity provider and a service account +# that can write to a sandbox dataset and cannot touch `BlockchainEvents`. Neither exists: +# `iam.serviceAccounts.create` is denied to the current identity at project scope, and no +# previously disabled billable service may be activated to work around that. Creating the +# identity is an administrator action on the Google Cloud project. +# +# THREE THINGS KEEP IT OFF UNTIL THEN, so forgetting one is not enough to start it: +# 1. There is no `schedule` and no `pull_request` trigger. Manual dispatch only. +# 2. The first step refuses unless `confirm` is typed exactly, and refuses every production +# dataset name outright. +# 3. Every job is gated on `vars.SANDBOX_INTEGRATION_ENABLED == 'true'`, a repository variable +# that does not exist. Until someone creates it, dispatching this workflow does nothing. +# +# KEYLESS BY CONSTRUCTION. It authenticates through Workload Identity Federation, never a +# downloaded key. `GCP_SA_KEY` is deliberately absent from this file: a long-lived JSON key in a +# repository secret is the same class of standing credential this project is removing elsewhere. + +on: + workflow_dispatch: + inputs: + dataset_id: + description: 'Sandbox BigQuery dataset to create and drop. Must not be a production dataset.' + required: true + type: string + confirm: + description: 'Type RUN-AGAINST-SANDBOX to confirm the target is not production.' + required: true + type: string + +permissions: + contents: read + id-token: write + +concurrency: + group: pipeline-sandbox-integration + cancel-in-progress: false + +jobs: + guard: + name: Refuse unless explicitly enabled and confirmed + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: This workflow is disabled + if: vars.SANDBOX_INTEGRATION_ENABLED != 'true' + run: | + echo "Refused: SANDBOX_INTEGRATION_ENABLED is not set to 'true'." + echo "This workflow is defined but disabled until its service account exists." + exit 1 + + - name: Refuse a production or unconfirmed target + env: + DATASET_ID: ${{ inputs.dataset_id }} + CONFIRM: ${{ inputs.confirm }} + run: | + if [ "$CONFIRM" != "RUN-AGAINST-SANDBOX" ]; then + echo "Refused: confirmation phrase missing or wrong." + exit 1 + fi + case "$DATASET_ID" in + ""|BlockchainEvents|Staging|Semantic|Marts|dev_sandbox) + echo "Refused: '$DATASET_ID' is a production or in-use dataset, or is empty." + exit 1 + ;; + esac + echo "Target dataset accepted: $DATASET_ID" + + integration: + name: Sandbox integration tests + needs: guard + if: vars.SANDBOX_INTEGRATION_ENABLED == 'true' + runs-on: ubuntu-latest + timeout-minutes: 30 + environment: sandbox + defaults: + run: + working-directory: projects/onchain-analytics/pipeline-v5 + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: projects/onchain-analytics/pipeline-v5/package-lock.json + + - name: Install dependencies from the lockfile + run: npm ci + + # Keyless. The provider and service account are supplied as repository variables, not + # secrets, because neither is a credential. + - name: Authenticate to GCP through Workload Identity Federation + uses: google-github-actions/auth@v2 + with: + workload_identity_provider: ${{ vars.GCP_WORKLOAD_IDENTITY_PROVIDER }} + service_account: ${{ vars.GCP_SANDBOX_SERVICE_ACCOUNT }} + + - name: Sandbox integration tests + env: + DATASET_ID: ${{ inputs.dataset_id }} + STAGING_DATASET_ID: ${{ inputs.dataset_id }}_staging + GCP_PROJECT_ID: ${{ vars.GCP_PROJECT_ID }} + ENVIO_API_TOKEN: ${{ secrets.ENVIO_API_TOKEN }} + # The name the pipeline actually reads. This previously set BQ_MAX_BYTES_BILLED, which + # nothing in the codebase looks at, so the cap it claimed to apply was never applied. + # 10 GiB per job. + MAX_BYTES_BILLED_PER_JOB: '10737418240' + run: npm run test:integration + + # The two-process write-safety check. It cannot run in the credential-free suite: it needs + # a real table for two separate processes to contend over, which is the only way to + # demonstrate that one of them is excluded. Everything else about the write path is + # covered in-process, and in-process cannot answer this question. + - name: Write-safety gate, two concurrent processes against a real sandbox + env: + GCP_PROJECT_ID: ${{ vars.GCP_PROJECT_ID }} + ENVIO_API_TOKEN: ${{ secrets.ENVIO_API_TOKEN }} + MAX_BYTES_BILLED_PER_JOB: '10737418240' + run: npm run gate:write-safety + + # Runs even when the tests fail, because a sandbox left behind is a defect this project has + # already produced twice: two undocumented datasets exist in the project today, one of them + # recorded as deleted in a maintenance note and still present. + - name: Drop the sandbox dataset + if: always() + env: + DATASET_ID: ${{ inputs.dataset_id }} + GCP_PROJECT_ID: ${{ vars.GCP_PROJECT_ID }} + run: | + echo "Cleanup for $GCP_PROJECT_ID:$DATASET_ID is supplied by the sandbox manager in" + echo "pipeline-v5/src/sandbox.ts, which checks the purpose label before deleting" + echo "anything and proves absence with a listing afterwards." + exit 1 diff --git a/.gitignore b/.gitignore index bd03876..c798b81 100644 --- a/.gitignore +++ b/.gitignore @@ -153,3 +153,8 @@ queries/dune/sybil-monitor/ # one checkout. Giving the mess one address is what actually contains it. _scratch/ **/_scratch/ + +# Test coverage output (added 2026-09-28 with the pipeline test harness). +# Generated by `npm run test:coverage`; the PR workflow uploads it as an artifact instead. +coverage/ +**/coverage/ diff --git a/.shipgate-allow b/.shipgate-allow index d8f8c7b..8ed9fa6 100644 --- a/.shipgate-allow +++ b/.shipgate-allow @@ -21,6 +21,28 @@ queries/dune/reserve-analysis/lp-v3-positions.sql :: content:address-list :: Uni # --- dbt seeds: address + number pairs, but the number is not a balance ------- projects/onchain-analytics/gd_dbt/seeds/contract_deployments.csv :: content:holder-table :: contract address paired with its deployment BLOCK, not a holder balance projects/onchain-analytics/gd_dbt/seeds/tokens.csv :: content:holder-table :: token contract address paired with its DECIMALS, not a holder balance +# event_surface.csv is the event ABI catalogue: one row per (contract, era, event). +# Checked 2026-09-28 before waiving, not assumed. All 347 distinct addresses in the +# file are contract addresses already present in contract_deployments.csv above, +# including the 11 that appear outside the two address columns (all in abi_source, +# all of the form bytecode_equality_with_celo_0x..., naming a registry contract). +# Its only numeric columns are chain_id, era_index, indexed_positions and the two +# era block bounds. No balance column and no wallet address exists in it. +# Receipt: specs/_scratch/coord-unit-01/out/01-event-surface-address-provenance.json +projects/onchain-analytics/gd_dbt/seeds/event_surface.csv :: content:holder-table :: contract address paired with its era BLOCK BOUNDS, not a holder balance +# era_intervals.csv and era_boundary_evidence.csv are the era validity-interval table +# and the evidence behind it: which implementation was live between which blocks, and +# how that was established. Checked 2026-09-28 before waiving, not assumed. +# era_intervals.csv 262 rows, 278 distinct addresses, ALL already present in +# contract_deployments.csv above. Numeric columns are chain_id, +# valid_from_block, valid_to_block, era_index. +# era_boundary_evidence.csv 41 rows, 44 distinct addresses, ALL already present above. +# Numeric columns are block numbers plus COUNTS of verification +# checkpoints, events and chunks. +# Neither file has an amount column, a balance, or a wallet address. +# Receipt: specs/_scratch/coord-unit-02-gate/verify-new-seeds.mjs +projects/onchain-analytics/gd_dbt/seeds/era_intervals.csv :: content:holder-table :: contract address paired with its era BLOCK BOUNDS, not a holder balance +projects/onchain-analytics/gd_dbt/seeds/era_boundary_evidence.csv :: content:holder-table :: contract address paired with block numbers and verification COUNTS, not a holder balance # --- reader-facing docs that trip a filename or attribution rule ------------- projects/goodwidget-components/spec.md :: name:spec.md :: real component specification, reader-facing product doc, not a pipeline artifact diff --git a/projects/onchain-analytics/docs/release-scope.md b/projects/onchain-analytics/docs/release-scope.md new file mode 100644 index 0000000..4cf2d96 --- /dev/null +++ b/projects/onchain-analytics/docs/release-scope.md @@ -0,0 +1,80 @@ +# Release scope: which chains this system covers + +**This release covers Celo, XDC and Ethereum. Fuse is out.** + +That one sentence is the whole decision. The rest of this page explains what it means for the +data you can query, and how the codebase enforces it so the statement cannot drift out of date +without something failing. + +| Chain | In the release | Ingested in this release | Note | +| - | - | - | - | +| Celo | Yes | Yes | Primary chain for claims | +| XDC | Yes | Yes | Holds the existing invites and claims dataset | +| Ethereum | Yes | No | Declared, deliberately not ingested here. Reserve paused since 2023-12-17, and no model reads an Ethereum contract today | +| **Fuse** | **No, dropped 2026-09-28** | No | See below | +| Base | No | No | Never assessed. Recorded as a decision not to look, rather than as a finding that there is nothing there | +| Gnosis | No | No | Same as Base | + +"In the release" and "ingested" are different questions and this table keeps them apart. A chain +can be declared in scope and still not be captured yet; Ethereum is exactly that case. + +## Why Fuse was dropped, 2026-09-28 + +Fuse data is disproportionately expensive to obtain, and the cost was holding up everything else. +Specifically: + +- There is no HyperSync index for Fuse, so it is the only chain that needs a raw RPC adapter. +- The one archive-capable Fuse endpoint this project could find is rate limited to roughly 54 + reads per hour, and both enumerating readers cap at 20,000 logs per response. +- Fuse prunes its transaction index, so a receipt lookup cannot establish a contract's creation + block there the way it can elsewhere. +- Finality cannot be read from any Fuse endpoint, so every Fuse row would have to carry a weaker + assurance than the same row on any other chain. + +None of that is a statement about whether Fuse matters. It is a statement about what it costs to +serve it to the same standard as the rest, and the decision was to ship the rest first. + +**Fuse can be added back as its own piece of work.** Nothing has been thrown away: Fuse history is +permanently readable from the chain itself, and the inventory this project already measured is +still in the repository (see the next section). Bringing it back means building the RPC reader and +re-running ingestion, not rediscovering what is there. + +## What "dropped" means for data that is already recorded + +**The Fuse inventory stays in the repository. It is a record, not a re-admission.** + +The reference seeds still carry every Fuse row this project measured: 1 chain row, 96 contract +deployment rows and 616 event surface rows. They are kept for three reasons: + +1. They cost real measurement, and deleting them means paying for it twice. +2. The event surface rows are bound to the deployment rows by a foreign key that the test suite + checks. Deleting the deployment rows would orphan 616 surface rows and turn a passing test into + 616 failures, which is a worse outcome than describing the situation accurately. +3. A deleted row says nothing. A retained row that is declared out of the release says exactly + what happened and when. + +Retaining the rows does **not** put Fuse back in the release. The pipeline refuses to build +capture targets for a chain outside the release scope, the planner reports such a chain as +unsupported and exits nonzero, and no model above the raw layer may consume an era on a chain that +is not in release. Those three refusals are what make the table at the top of this page true in +the running system and not only on this page. + +## How this is enforced + +The declaration lives in code, next to the loader that reads the reference seeds: +`pipeline-v5/src/control-plane/releaseScope.ts`, in `RELEASE_SCOPE_FREEZE`. + +- `releaseChains` is the list in the table above. Every other part of the system reads the chain + list from there rather than keeping a copy, so changing it changes the whole system at once. +- `chainsDropped` records a chain that was deliberately removed, with the date and the reason. + That field is what separates "we decided to drop this" from "nobody ever decided about this". + A chain that is in neither list still fails the build, which is the case worth catching: a chain + arriving in a seed that no one has made a decision about. +- A retained row on a dropped chain may not declare itself in release. That combination is + refused, so the inventory cannot quietly become a re-admission through a seed edit. + +## Changing it + +Scope is frozen. Changing which chains are in the release is a deliberate act, not a seed edit: +amend `RELEASE_SCOPE_FREEZE`, amend this page, and re-derive anything that was built on the old +scope. The checks above exist so that doing it by accident is not possible. diff --git a/projects/onchain-analytics/gd_dbt/dbt_project.yml b/projects/onchain-analytics/gd_dbt/dbt_project.yml index 791156a..bc018c9 100644 --- a/projects/onchain-analytics/gd_dbt/dbt_project.yml +++ b/projects/onchain-analytics/gd_dbt/dbt_project.yml @@ -39,6 +39,17 @@ seeds: valid_to_block: INT64 creation_block: INT64 is_live: BOOLEAN + event_surface: + +column_types: + chain_id: INT64 + era_index: INT64 + era_bound_from_block: INT64 + era_bound_to_block: INT64 + anonymous: BOOLEAN + era_bound: BOOLEAN + indexed_positions: STRING + param_types: STRING + param_names: STRING # Default materialization per layer. # "view" = BigQuery view (no data stored, always fresh) diff --git a/projects/onchain-analytics/gd_dbt/models/overview.md b/projects/onchain-analytics/gd_dbt/models/overview.md index 22b9a28..6477474 100644 --- a/projects/onchain-analytics/gd_dbt/models/overview.md +++ b/projects/onchain-analytics/gd_dbt/models/overview.md @@ -40,6 +40,17 @@ Marts (tables — dashboard-ready) └── invite_funnel_snapshot ``` +**Reference seeds** sit beside this flow rather than in it. They describe the contracts the pipeline reads, and every layer above raw may join to them: + +| Seed | What it answers | +| - | - | +| `chains` | Which networks exist, and which are active | +| `contract_deployments` | Which implementation was behind each proxy at which block, and whether the row is inside the release | +| `event_surface` | Which events each contract era can emit, keyed by the `topic0` the chain actually writes | +| `era_intervals` | Each era as a validity interval, with its confidence grade and a receipt you can open | +| `era_boundary_evidence` | The measurement behind each graded era, so any grade can be re-derived rather than trusted | +| `tokens` | Token decimals per chain. **GD is 18 decimals on Celo and XDC and 2 on Fuse and Ethereum**, which is why a figure must never be scaled by a constant | + ## Key Domains ### UBI Claims @@ -50,10 +61,19 @@ Tracks the full invite lifecycle: signup → claiming activity → eligibility ## Networks -GoodDollar operates across three blockchains: -- **XDC** — Primary network (majority of activity) -- **CELO** — Secondary network -- **Ethereum/Fuse** — Legacy network (minimal current activity) +**This release covers Celo, XDC and Ethereum. Fuse is out, dropped 2026-09-28.** + +- **XDC** - in the release and ingested. Majority of current activity. +- **CELO** - in the release and ingested. +- **Ethereum** - in the release, deliberately not ingested here. No model reads an Ethereum + contract today. +- **Fuse** - dropped from the release. Its reference-seed rows are retained as a record of what + was measured, so you will still see Fuse rows in the `chains`, `contract_deployments`, + `event_surface` and `tokens` seeds. **No model above the raw layer reads them.** If a number on + this site looks like it should include Fuse, it does not. + +Full record, including why Fuse was dropped and what it would take to bring it back: +`docs/release-scope.md` in the repository. ## How to Use This Site @@ -103,6 +123,26 @@ GoodDollar operates across three blockchains: > programme over-reported 1,223 bounties and 1,834,500 GD against a true 939 and 1,408,500 GD. > Any figure quoted from this warehouse before that date should be re-derived. +### Contract Eras and Confidence + +- **Contract era**: The period during which one implementation sat behind a proxy address. Most GoodDollar addresses are proxies whose logic has changed, so a rule written against "the Identity contract" is silently wrong for part of history unless it names the era. Eras are stored as **half-open intervals** `[valid_from_block, valid_to_block)` in `era_intervals`; a live era carries the INT64 sentinel `9223372036854775807` as its upper bound. +- **ABI union**: The set of every event definition a proxy has ever had, decoded by `topic0` with no block dimension. This is the industry default and for almost every event it is provably safe, because different parameter types produce different `topic0` values and cannot collide. **Unions are built newest-implementation-first**, which matters: a `topic0` is computed from the signature *excluding* `indexed` flags, so two implementations that only changed which parameters are indexed share one `topic0`, and a decoder that tries the older one first decodes a newer log into the wrong columns without raising an error. +- **Decode ambiguity**: A `(chain, address, topic0)` key carrying more than one physical layout — the case the union cannot resolve on its own. Computed from the seed with no chain calls. **Two exist across all chains, and none inside the chains this release ingests.** A third one fails the build rather than decoding silently. +- **Undecodable log**: A captured log whose `topic0` matches no event in that address's surface. It is indistinguishable from an absent log in every model downstream, so it is counted and reported beside block coverage rather than inferred from it. + +**Confidence grade** (`era_intervals.confidence_grade`) answers *how wrong could this interval be*. It **never** decides whether you may use the data — it propagates alongside it, so a figure can always state what backs it. + +| Grade | What stands behind the interval | +| - | - | +| `corroborated` | Two independent instruments agree: the contract's own implementation slot read either side of the boundary, **and** a second reader that re-read every upgrade event | +| `slot_bisected` | The contract's own state binds the interval, from one voice | +| `announced` | An on-chain record bounds it — an upgrade log or the contract's creation — and no state read confirms it | +| `inferred` | A single unchallenged source, with no independent check available at all | + +> **A low grade is not a data defect.** No era in this system reaches a "fully proven" state, and that is a property of Ethereum rather than a gap in this work: EIP-1967 says a proxy *should* emit an upgrade event, not that it *must*, and OpenZeppelin's own implementation has a path that changes the code pointer while emitting nothing. Roughly 95 percent of questions asked of this warehouse concern the last twelve months, where the grades are strongest, and the raw logs are permanently re-readable, so deep history may sit at `inferred` indefinitely by design. + +> **What the interval tests do not tell you.** `era_intervals` is checked for overlaps, gaps, and that exactly one row covers any queried block. Those catch a broken interval chain. **They cannot detect weak evidence** — a perfectly shaped chain can still rest on a single unchallenged source. That is what the grade is for. + ### Important Distinctions - **Transaction** vs **Event** vs **Transfer**: One blockchain transaction (`tx_hash`) can emit multiple contract events and include token transfers. These produce different counts. diff --git a/projects/onchain-analytics/gd_dbt/seeds/_seeds.yml b/projects/onchain-analytics/gd_dbt/seeds/_seeds.yml index 039fcd8..091c990 100644 --- a/projects/onchain-analytics/gd_dbt/seeds/_seeds.yml +++ b/projects/onchain-analytics/gd_dbt/seeds/_seeds.yml @@ -161,6 +161,49 @@ seeds: description: "How this row was established, as a single provenance string for the whole generation." - name: notes description: "Free text. Anything a reader would otherwise get wrong." + - name: boundary_completeness + tests: + - not_null + - accepted_values: + values: ['complete', 'plain_contract', 'raw_only_unproven'] + description: > + How well the era's own boundaries are evidenced. **Reads `raw_only_unproven` on every + row, and that is a measurement rather than a backlog.** Reaching `complete` required + every slot-writing path to obligatorily emit its upgrade event, and EIP-1967 says + upgrade events SHOULD be emitted, not MUST -- OpenZeppelin's own reference + implementation writes the slot before emitting on the rollback branch. Zero of the 41 + assessed eras could reach it, and the remaining eras were never assessed. + + + **This column does not gate anything.** It used to forbid every decoder and every + user-facing model over every era, which was all of them. A bar that cannot tell a + well-understood contract from an unknown one moves no decision, so the refusal was + removed and the discrimination moved to `era_intervals.confidence_grade`, which + propagates instead. + - name: boundary_evidence_manifest_hash + description: > + SHA256 of the boundary-evidence manifest backing this era, `0x`-prefixed. Set on the 41 + eras a manifest covers and empty elsewhere -- an era with no manifest declares nothing + rather than declaring an absence as though it had been measured. The manifest content + itself ships in `era_boundary_evidence`. + - name: boundary_checked_through_block + description: "Highest block the boundary scan actually read. Empty where no manifest exists." + - name: frozen_safe_head + description: > + The head the boundary scan was frozen against, so a later reader can tell what "through + head" meant at the time rather than assuming it meant now. + - name: release_scope + tests: + - not_null + - accepted_values: + values: ['in_release', 'out_of_release', 'scope_pending'] + description: > + Whether this row is inside the frozen release. **Every row states one**, which is the + point: `scope_pending` exists so an undecided contract is RECORDED as undecided rather + than resolved by whichever way the seed happens to fall, and a column that is simply + absent lets "nobody has decided yet" read as "everything is in". The 96 Fuse rows read + `out_of_release`: they are retained as a record of what was measured, and a retained row + is not a re-admission. See `docs/release-scope.md`. tests: - dbt_utils.unique_combination_of_columns: combination_of_columns: @@ -168,6 +211,293 @@ seeds: - proxy_address - valid_from_block + - name: era_intervals + description: > + **What this is:** Each contract era as a validity interval, with the confidence grade and the + receipt behind it. 262 rows, one per deployed era on a release chain -- 206 on Celo and XDC, + 56 on Ethereum, which is declared in the release and deliberately not ingested yet. + + + **Why it exists separately from `contract_deployments`:** "Which ABI was in force at block N" + is an as-of temporal join, which is a solved modelling problem. Shaping an era as what it is + -- a Type-2 validity interval -- puts the rigour where it belongs and makes the question + answerable by a join rather than by a convention everyone has to remember. + + + **Intervals are HALF-OPEN, `[valid_from_block, valid_to_block)`.** A live era carries the + INT64 sentinel 9223372036854775807 as its upper bound. Reading them as closed makes every + contiguous pair look like an overlap and returns two rows at every boundary. + + + **`confidence_grade` answers "how wrong could this be", never "may I proceed".** It + propagates to whatever reads the era and gates nothing. A low grade on deep history is not a + data defect: about 95 percent of questions asked of this system concern the last twelve + months, the raw logs are permanently re-readable, and deep history may sit at `inferred` + indefinitely by design. See the Business Glossary in `models/overview.md` for what each grade + means and which evidence produces it. + + + **Three tests hold the shape:** no overlapping intervals per contract, no gaps from + deployment to head, and exactly one row covering any queried block. They detect overlaps, + gaps and multi-coverage. **They do not detect weak evidence** -- that is what the grade is + for, and saying so is the difference between a test suite and a reassurance. + config: + tags: ['seed', 'reference'] + columns: + - name: chain + tests: + - not_null + - accepted_values: + values: ['CELO', 'XDC', 'ETHEREUM'] + description: "Uppercase chain name. Release chains only; Fuse is out of the release." + - name: chain_id + tests: [not_null] + description: "EVM chain id." + - name: proxy_address + tests: [not_null] + description: "The stable address a reader queries. Lowercase, 20 bytes." + - name: valid_from_block + tests: [not_null] + description: "First block of the interval, inclusive." + - name: valid_to_block + tests: [not_null] + description: "Upper bound, EXCLUSIVE. 9223372036854775807 means open ended." + - name: implementation + tests: [not_null] + description: "Implementation address behind the proxy for this interval." + - name: abi_id + tests: [not_null] + description: > + Identifies the ABI in force. The implementation's `runtime_code_hash` where it is held, + otherwise `impl:
`. Two eras sharing an `abi_id` are decodable by the same ABI. + - name: confidence_grade + tests: + - not_null + - accepted_values: + values: ['corroborated', 'slot_bisected', 'announced', 'inferred'] + description: > + How much independent agreement stands behind this interval. `corroborated` two + independent voices agree; `slot_bisected` the contract's own state binds it, from one + voice; `announced` an on-chain record bounds it and no state read binds it; `inferred` a + single unchallenged source with no independent check available. Assigned by a published + rule, never by hand. + - name: evidence_receipt_uri + tests: [not_null] + description: > + Where to open the evidence behind the grade, as a repository path with a row key. Points + at `era_boundary_evidence` for the 15 manifest-backed eras and at `contract_deployments` + otherwise. **It resolves inside this repository on purpose:** a receipt nobody else can + open is not a receipt, it is an assertion. + - name: contract_name + tests: [not_null] + description: "Logical contract name, for readability. A label, never evidence." + - name: era_index + tests: [not_null] + description: "1-based era number within the contract." + - name: is_live + tests: [not_null] + description: "Whether this is the era currently behind the proxy." + tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: + - chain_id + - proxy_address + - era_index + + - name: era_boundary_evidence + description: > + **What this is:** The boundary-evidence measurement behind every graded era, flattened to one + row per era. 41 rows over 6 contracts -- 15 on release chains, 26 on Fuse, retained as a + record of what was measured. + + + **Why it exists:** `era_intervals.evidence_receipt_uri` has to point somewhere an outside + reader can actually open. This is that somewhere. Every field the grading rule reads is here, + so any grade in `era_intervals` can be re-derived from first principles by someone holding + only this repository. + + + **Read `obligatorily_emits` first.** It is `false` on every row, and it is the reason no era + can be `complete`: every proxy here reaches `_setImplementation` through a path that writes + the implementation slot without emitting an upgrade event. It is carried precisely because it + does NOT discriminate between eras -- hiding it would make the grades look arbitrary. + + + **One caveat that must not be lost.** The upstream scan's own "two or more sources agreed" + label is misleading on Celo and XDC: its two sources were two query shapes against ONE index + URL, not two hosts. Log-source count is therefore never treated as corroboration. The + genuinely independent second voices are the EIP-1967 slot read and the transaction-receipt + replay, and only those are used. + config: + tags: ['seed', 'reference'] + columns: + - name: chain + tests: [not_null] + description: "Uppercase chain name. Includes FUSE, which is out of the release but measured." + - name: chain_id + tests: [not_null] + - name: proxy_address + tests: [not_null] + - name: era_index + tests: [not_null] + - name: implementation_address + description: "Implementation this era binds to." + - name: opening_both_measured + description: > + Whether the EIP-1967 slot was read on BOTH sides of this era's opening block. `true` is + what a bisection means; empty means no transition was recorded for the block at all. + - name: opening_address_agrees + description: "Whether the slot reading agrees with the announcing event's implementation." + - name: slot_agreeing + description: > + How many independent readers agreed on the head slot value. A reading is admissible at + two or more; one reader is one voice and cannot corroborate itself. + - name: slot_error_count + description: > + Errors encountered while reading the slot, counted SEPARATELY from the result. An absence + is a measurement only when this is zero. A non-zero count beside a positive answer that + two readers agree on does not void the answer, and is carried so a reader can weigh it. + - name: cross_check_blocked + description: > + `true` where no historical state read is obtainable at any level of patience -- Fuse has + at most one archive-capable endpoint. This is what separates `announced` from `inferred`. + - name: claimed_events + description: "Upgrade events the scan found for this contract." + - name: independently_confirmed_events + description: > + How many of those a second independent reader re-read. Used ALL-OR-NOTHING: a count is a + contract-level number and cannot be attributed to one era, so a partial count buys + nothing rather than being rounded up. + - name: obligatorily_emits + description: "See the note above. False everywhere; carried for the reader, never used to grade." + - name: source_manifest + tests: [not_null] + description: "The manifest file this row was flattened from." + - name: manifest_sha256 + tests: [not_null] + description: "SHA256 of that manifest, so the promotion is verifiable rather than trusted." + tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: + - chain_id + - proxy_address + - era_index + + - name: event_surface + description: > + **What this is:** Every event every contract era can emit, keyed by the selector the chain + actually puts in `topic0`. 2,824 rows, 301 distinct selectors, one row per event per era. + + + **Why it exists:** Ingestion binds on `topic0` and never on an event name, and decoding needs + the parameter types and the indexed positions for the exact era the log was emitted in. This + seed is that mapping. Without it a decoder has to carry hardcoded selectors, which is how the + two defects below reached production. + + + **The two traps this shape exists to prevent, both of which already happened here.** A type + change alters the selector: A decoder written for `ReserveRatioUpdated(bytes32,uint256)` + against a deployed `(bytes32,uint32)` finds zero events forever and raises nothing. Indexed + flags do NOT alter the selector: A wrong-but-plausible interface returns exactly the expected + row count while writing business fields into the wrong columns. So `param_types` and + `indexed_positions` are recorded per parameter, from the same verified source the selector + was computed from. + + + **Every selector here was computed, not recalled.** Each was produced by hashing a signature + rebuilt from the verified interface's own parameter types, tuples included, and then checked + a second time by an independent reader: 2,823 of 2,823 selectors recomputed identically, with + zero mismatches, and 301 signatures map to 301 selectors as a bijection must. + + + **This is the callable surface, not a record of what fired.** An event listed here may never + have been emitted. One case is already known: A transfer fee event exists on the token and + has been measured as never charged. + + + **One row carries no selector and that is correct.** It is an anonymous event, which by + definition puts no signature hash in `topic0`. It cannot be matched by selector and is + recorded rather than filled in. + config: + tags: ['seed', 'reference'] + columns: + - name: chain + tests: + - not_null + - accepted_values: + values: ['CELO', 'XDC', 'FUSE', 'ETHEREUM'] + - name: chain_id + tests: [not_null] + - name: contract_name + tests: [not_null] + description: "Logical contract name. A label, never a binding key." + - name: proxy_address + tests: [not_null] + description: > + The address the log is emitted from. Lowercase. Joins to + `contract_deployments.proxy_address`, but NOT on its own: the binding key is the triple + (chain, proxy_address, era_index) and it is enforced by the singular test + `assert_event_surface_binds_to_a_real_era`. A `relationships` test on this column alone + used to stand here; it was removed because it constrains nothing about the era. Measured + on this seed: an era_index corrupted to one past that contract's real maximum passes it + on 2,824 of 2,824 rows. + - name: era_index + tests: [not_null] + description: > + Which era of that contract this row describes. Joins to + `contract_deployments.era_index` as part of the composite key above. Era resolution is + mandatory rather than cosmetic: two (chain, address, topic0) keys in this seed change + their indexed layout across their own eras, so the same selector decodes differently + depending on the era, and a lookup that cannot fail returns a confident wrong answer. + - name: implementation_address + description: "The implementation whose verified interface this row was read from." + - name: event_name + tests: [not_null] + description: > + The name in the interface. Informational only. The token declares two different events + both named `Transfer`, a 3-argument and a 4-argument form, with different selectors. + Binding on this column would fuse them. + - name: event_signature + tests: [not_null] + description: "Canonical signature, the exact string that was hashed to produce `topic0`." + - name: topic0 + description: "Keccak hash of `event_signature`, lowercase. NULL only for the single anonymous event. **This is the only sound binding key.**" + - name: anonymous + description: "True for an anonymous event, which emits no selector at all." + - name: indexed_positions + description: > + Space-separated 0-based parameter positions that are indexed, and therefore arrive in + `topic1` through `topic3` rather than in the data blob. Empty means every parameter is in + the data section. Getting this wrong does not change the row count, only which column the + value lands in. + - name: param_types + description: "Space-separated ABI types in declaration order." + - name: param_names + description: "Space-separated parameter names in declaration order." + - name: era_bound + description: > + True when this event is NOT present in every era of its contract, so a decoder must check + the era before expecting it. 59 combinations are removed from one era and restored in a + later one; a first-and-last era comparison renders those as continuously present. + - name: era_bound_from_block + description: "First block this event can be emitted at, for era-bound rows." + - name: era_bound_to_block + description: "Exclusive upper bound for era-bound rows." + - name: abi_source + description: "Where the verified interface came from." + - name: source + tests: [not_null] + description: "How this row was established." + - name: notes + description: "Free text." + tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: + - chain + - proxy_address + - era_index + - event_signature + - name: chains description: > **What this is:** One row per blockchain the system covers. diff --git a/projects/onchain-analytics/gd_dbt/seeds/contract_deployments.csv b/projects/onchain-analytics/gd_dbt/seeds/contract_deployments.csv index cae7c06..c11e3f1 100644 --- a/projects/onchain-analytics/gd_dbt/seeds/contract_deployments.csv +++ b/projects/onchain-analytics/gd_dbt/seeds/contract_deployments.csv @@ -1,363 +1,363 @@ -chain,chain_id,contract_name,category,provenance,proxy_address,implementation_address,implementation_name,era_index,era_count,valid_from_block,valid_to_block,is_live,creation_block,creation_method,era_method,era_evidence,era_announcement_event,abi_source,runtime_code_hash,semantics_note,source,notes -CELO,42220,AdminWallet,gooddollar_owned,published,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,0xbfb5052aee113fc160c18ae85c9831dcd2b2fdc0,AdminWallet,1,5,18002976,21368263,false,18002976,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0xc67787fd2231f7326a2527db40332b920f33840fe942296e17be56f6125ac589,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,AdminWallet,gooddollar_owned,published,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,0x24614ad257f4d09fccaec024c65c40c060e73e9d,AdminWallet,2,5,21368263,21369184,false,18002976,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xe21dd06280946f5040f63cbfa0ea2b2e35e000ae528828935dbbaed0244177d7,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,AdminWallet,gooddollar_owned,published,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,0xae2cd2a9513215961d344a2581dcab678598eedf,AdminWallet,3,5,21369184,28227319,false,18002976,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xae2e0d5cd6fc590c4b6ce659efebd29bb417c359076b8ecd7ec4adf389379c00,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,AdminWallet,gooddollar_owned,published,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,0x703856db9a5432964f081ff4dc46480738fae7bd,AdminWallet,4,5,28227319,50872873,false,18002976,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xf15f2e31e0c7251bd3babc7f23dccff946ca6582daa5f0eee7e19d3424823619,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,AdminWallet,gooddollar_owned,published,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,0xfef0ef0916c5c7745b201dc9e2d04483b1eb36f1,AdminWallet,5,5,50872873,9223372036854775807,true,18002976,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x28708bf9f584205831cdf5ff571feb8c3fe60d1759a4edc4953eb2ffe8b88430,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Avatar,gooddollar_owned,published+registry,0x495d133b938596c9984d462f007b676bdc57ecec,0x495d133b938596c9984d462f007b676bdc57ecec,Avatar,1,1,17237959,9223372036854775807,true,17237959,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x8a27316984da83331e574723efd0810faf4d7065f3037b8778d9c572ea49c6d8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,BulkWhitelist,gooddollar_owned,published,0x30afd0534daa29135308d048103b40dc1ba4518d,0x30afd0534daa29135308d048103b40dc1ba4518d,BulkWhitelist,1,1,26952390,9223372036854775807,true,26952390,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x60344a20cbd88bedbfd88cec885b62ad50c025de6de11abf30abf652d86ebbc4,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,BuyGDFactory,gooddollar_owned,published,0x00e533b7d6255d05b7f15034b1c989c21f51b91c,0x00e533b7d6255d05b7f15034b1c989c21f51b91c,BuyGDCloneFactory,1,1,21006324,9223372036854775807,true,21006324,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x047ee7c00427bb66d4412b5748c158d3a8e3330166dd6e5a849ec2e4d9fc728c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,BuyGDFactoryV2,gooddollar_owned,published,0x1f60c4c7037c6766924a43666b781ed1479587a2,0x1f60c4c7037c6766924a43666b781ed1479587a2,BuyGDCloneFactory,1,1,22909812,9223372036854775807,true,22909812,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xb0deea380b10aaab11e12102a20b31fa11fd7ddfbed72761ad30cd6933e143b9,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,BUYGDFactoryV3,gooddollar_owned,published,0xb1c87d3270d4a23bc1fcca8be53af11e4773d89d,0xb1c87d3270d4a23bc1fcca8be53af11e4773d89d,BuyGDCloneFactory,1,1,72905831,9223372036854775807,true,72905831,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x2c25daa8960a888e9b92aa463cfe8770a5b7afcf0d7359dcd1bf3b344c8be1a8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,CeloDistributionHelper,gooddollar_owned,published,0x6b845effaf36c374e8e7cf543efa680f2f71f098,0x6db04d771e2ba750effbbad59dcca20381efb1c5,CeloDistributionHelper,1,1,31415781,9223372036854775807,true,31415781,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0xa1a06f022a982744ad4a646f9ced63087f65f2b7d4e29c4e92345f2714abb030,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,CommunitySafe,gooddollar_owned_safe,published,0x437c699887779d0a95ad6349cfde7dfa716c005d,0x437c699887779d0a95ad6349cfde7dfa716c005d,GnosisSafeProxy,1,1,18862438,9223372036854775807,true,18862438,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,Controller,gooddollar_owned,published+registry,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,Controller,1,1,17237959,9223372036854775807,true,17237959,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x1cce4814ac502cec7e982e73d29bdc95e9094476ba971b6777f8abd4a415fc26,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,CUSD,third_party_token,published,0x765de816845861e75a25fca122bb6898b8b1282a,0x0000000000000000000000000000000000000000,uninitialised,1,9,2957,2961,false,2957,explorer_index_and_state_read_agree,bisection_and_announcement_union,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,CUSD,third_party_token,published,0x765de816845861e75a25fca122bb6898b8b1282a,0xaa933baf03cfc55b8e4e0d7de479bcc12f189352,unknown,2,9,2961,3629000,false,2957,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,none,0xa23ae32221bdebb534ab6da55a2b31ca5cc931aa8b6def9bb5f8401e139d51d2,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,CUSD,third_party_token,published,0x765de816845861e75a25fca122bb6898b8b1282a,0x7e327831c644f2b1fef642079f116181bc471cb3,unknown,3,9,3629000,5822108,false,2957,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,none,0xfd545fc18c7a1a554e36aeb4392a9d532ba2911131296f6a5d1d5a478ffbe4e1,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,CUSD,third_party_token,published,0x765de816845861e75a25fca122bb6898b8b1282a,0x2c4c1f3e06d494bcc03e93b373637cc4333cbd7d,unknown,4,9,5822108,9105530,false,2957,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,none,0xe4c43237f59abc7e640bd1a1e60fe5d81b77b5522ad3459aede9f1e17c3d0b46,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,CUSD,third_party_token,published,0x765de816845861e75a25fca122bb6898b8b1282a,0x18e6bfdc909063f7445e410a5495264619495bcb,StableToken,5,9,9105530,18635694,false,2957,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,etherscan_v2_verified_source,0x040dda9403fdb8661a907d59b7aa0b98d8d163e35647e41c4e697d669036367b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,CUSD,third_party_token,published,0x765de816845861e75a25fca122bb6898b8b1282a,0x7ae2f384fe14ead85779f9224558862d6d3e4f28,StableToken,6,9,18635694,23065563,false,2957,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,etherscan_v2_verified_source,0xd73ed2d40adbb84367cd834fa834bb09eb4f67e668215e8895635930c8d7b714,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,CUSD,third_party_token,published,0x765de816845861e75a25fca122bb6898b8b1282a,0x434563b0604be100f04b7ae485bcafe3c9d8850e,StableTokenV2,7,9,23065563,60666007,false,2957,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,etherscan_v2_verified_source,0x659d421716b8eac9026199a99ab15d277dc163a46f48ac5ebf9e1462a6d85170,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,CUSD,third_party_token,published,0x765de816845861e75a25fca122bb6898b8b1282a,0x4b9b0e94197b7b2b11d311239e1420106ce7a2a2,StableTokenV3,8,9,60666007,60745284,false,2957,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,etherscan_v2_verified_source,0x43c6a9f2bbd66e2a2cff43250a380b0fbbf4880e865b163303a849bf45a71ca8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,CUSD,third_party_token,published,0x765de816845861e75a25fca122bb6898b8b1282a,0x815795c30d0758a297b08cd4e0643620c974c318,StableTokenV3,9,9,60745284,9223372036854775807,true,2957,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,etherscan_v2_verified_source,0xd5be5b27724e5f68e90b0765f4a2bc883b6847812356d4ef33ac38ed277a30cf,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,DAOCreator,gooddollar_owned,published,0x76e76e10ac308a1d54a00f9df27edce4801f288b,,unknown,1,0,,,false,,"not applicable, no code is deployed at this address",no_code_deployed,none,none,none,,no_code_at_pinned_block: A published artifact or the registry names this address and nothing is deployed there,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,read at block 78286906 -CELO,42220,Faucet,gooddollar_owned,published,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,Faucet,1,10,18003061,18481054,false,18003061,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x60adef4e58f448da1c484b8f64b875688ea6b17e6cf34531bc9530985d05be5e,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Faucet,gooddollar_owned,published,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,0x91b6eed85458239f281f5ad46c8defd60ddef8b2,Faucet,2,10,18481054,18866025,false,18003061,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xbdc69d3696a4a6de3cdd277f5b71e67bad0f19f0a433f3e6a4d4235257c28f7c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Faucet,gooddollar_owned,published,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,0xac92cea7b8936e769b00117e7428f7499c93f9db,Faucet,3,10,18866025,20299862,false,18003061,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x1e06dc2d8337ea3aaa409d7742b21d35a686da7e31b7211ecd338bfea40aac9d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Faucet,gooddollar_owned,published,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,0x0cb76de990330b36b72c9b604a71d24eaa45ebf4,Faucet,4,10,20299862,39388555,false,18003061,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xa342d94b354aa61ba8221b004ade990d040fb7de31385ca82ff9b0a65c649286,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Faucet,gooddollar_owned,published,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,0x783548481a6ca92b6589365161b31e3ed64d0c3c,Faucet,5,10,39388555,40258358,false,18003061,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xebabf487538a31aba764a34ab1ed1570d6795310a94f6d3d4309abc5b2f975dc,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Faucet,gooddollar_owned,published,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,0xf224d5166fb194d8404a4a2d1d9fbb41866625ad,Faucet,6,10,40258358,49737165,false,18003061,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xe5aa4f18fa67a7c1ac33d6277d9216f7adbec3f5cf027a50534f7ab929fadbdf,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Faucet,gooddollar_owned,published,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,Faucet,7,10,49737165,49740289,false,18003061,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x68755099f25764af194ff16c1f4a6fd14bdd4bd89a1c3f6832649a36508e6533,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Faucet,gooddollar_owned,published,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,Faucet,8,10,49740289,59605758,false,18003061,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xe8429a22753ce3f82c856a7f5dee88264782d956d615db983d0cd5ec8e9fb325,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Faucet,gooddollar_owned,published,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,0x41ef166fb7d022ce9a90b47581f323d19fafbddd,unknown,9,10,59605758,59606288,false,18003061,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),none,0x368dbfc1d9f8d5f05945e140ed7b50750b906c2373068f38cc9e892ab0b66163,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Faucet,gooddollar_owned,published,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,0x08fdf766694c353401350c225caeb9c631dc3288,Faucet,10,10,59606288,9223372036854775807,true,18003061,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x60946ac381f89c0e81d17e75a66b09f5eb90e0846cbc50fba2e642a50f5373cc,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,FeeFormula,gooddollar_owned,published,0x1151867da39003695eed28fafa871079c91884c9,0x1151867da39003695eed28fafa871079c91884c9,FeeFormula,1,1,17237953,9223372036854775807,true,17237953,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xb10599b90c45878333139dfa098974b8df30eba5596654ef05c46daa2a6f0847,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,GoodDollar,gooddollar_owned,published+registry,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,0x0000000000000000000000000000000000000000,uninitialised,1,8,17237955,17237956,false,17237955,explorer_index_and_state_read_agree,bisection_and_announcement_union,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,GoodDollar,gooddollar_owned,published+registry,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,0xca903643aa81a2d67863079548f6b53a6dae43d7,SuperGoodDollar,2,8,17237956,17238214,false,17237955,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,etherscan_v2_verified_source,0x6d4edf2a14e946bc4bc85ccd999d505d35a8c0a901030d95d96cf42312f36d85,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,GoodDollar,gooddollar_owned,published+registry,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,SuperGoodDollar,3,8,17238214,17260434,false,17237955,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xf6dcc0590e58b7501bb8701ad1ad658cf2b7de8ec3a8faa9b6d4f2fba8764fa2,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,GoodDollar,gooddollar_owned,published+registry,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,SuperGoodDollar,4,8,17260434,17271388,false,17237955,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x083fbabd4a581ff5a538068453614131f51ee536a0bce7bcc5aa716a55d7aa8d,carried_from_seed: TransferFee event added. MEASURED as never fired to date so Transfer.value remains the whole story. Recheck if it ever fires.,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,GoodDollar,gooddollar_owned,published+registry,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,SuperGoodDollar,5,8,17271388,21746648,false,17237955,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x934f7100a5cf339f677c3822c76029b38a9e97438635450c878f8c4d58f4909a,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,GoodDollar,gooddollar_owned,published+registry,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,0xac862af0a463a5faebbe959e3483b41400f5bb38,SuperGoodDollar,6,8,21746648,22596133,false,17237955,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xbff04a2102f39ae6f66ae309cb4591635ca34f2459429261134e25411faf01fb,carried_from_seed: Superfluid NFT agreement model. TokenUpgraded and TokenDowngraded removed. ConstantInflowNFTCreated and ConstantOutflowNFTCreated added. Eleven functions swapped including downgrade getUnderlyingToken selfMint selfBurn.,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,GoodDollar,gooddollar_owned,published+registry,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,SuperGoodDollar,7,8,22596133,77207809,false,17237955,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xa2d98dc81d3ca3bab7e5cdbe11a4860fbefde5b50a0c910c52a2504b146e2db5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,GoodDollar,gooddollar_owned,published+registry,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,SuperGoodDollar,8,8,77207809,9223372036854775807,true,17237955,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x4650c5f121ca37da373278cb05efc0857704454f4a1afec72b6bc4058bd409d6,carried_from_seed: BlockedUpdated event added and IS IN USE. 15 addresses blocked in one tx at block 77233730 including a Uniswap V3 pool. A blocked address cannot move the token so a quiet address may be prohibited rather than inactive.,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,GoodDollarMintBurnWrapper,gooddollar_owned,published+registry,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,0xb0b86dd967655728218b7b87b10051a60758af82,MintBurnWrapper,1,6,13037458,13254104,false,13037458,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0xc8359e84630f5907348cea1136429f5b91a3d0f687b57f20835a1146881f80e2,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,GoodDollarMintBurnWrapper,gooddollar_owned,published+registry,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,0x413e395b10be6f39f2aa0d80eec48edb88738ac4,GoodDollarMintBurnWrapper,2,6,13254104,13660450,false,13037458,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x35f1a1bc56ad9ca11379afa307e637159af9caba0eafea55d97486882a3e4a33,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,GoodDollarMintBurnWrapper,gooddollar_owned,published+registry,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,GoodDollarMintBurnWrapper,3,6,13660450,15806090,false,13037458,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xdfcf646513c464e512d4c0cac0bf69f5ecd5db669a5cba84244159daaba61c82,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,GoodDollarMintBurnWrapper,gooddollar_owned,published+registry,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,0x0a36091884b8d7808d5fdb47cbdead457ea9803e,GoodDollarMintBurnWrapper,4,6,15806090,17228965,false,13037458,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x6a9b48197ba0fb19f74cf5467b1207f689120d97702df03bd2d90c90efff6100,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,GoodDollarMintBurnWrapper,gooddollar_owned,published+registry,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,0xb3109ca8c7bf74fc5d28285ecf7fe498c21a0698,GoodDollarMintBurnWrapper,5,6,17228965,17239796,false,13037458,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x54ef0f8fab68d40828eeeabb66ea0f3d714be1a52894f55431d1c5c76be88d0c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,GoodDollarMintBurnWrapper,gooddollar_owned,published+registry,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,0x098148534ac15a44cff52387ba81ed929589ecaf,GoodDollarMintBurnWrapper,6,6,17239796,9223372036854775807,true,13037458,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x976528b459f21a7bd143cf3b456517b0a452da77a06e6749356da66a98548dfd,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,GReputation,gooddollar_owned,published+registry,0xa9000aa66903b5e26f88fa8462739cdcf7956ea6,0x4be0c7f9c468b174dfeba304d8bd6af000948a79,GReputation,1,1,17237958,9223372036854775807,true,17237958,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x47c7e53ea14ed9e7757ba2640dfbdcb6ddf21ef2bc9578d9d2c4e92e53ebeea0,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,GuardiansSafe,gooddollar_owned_safe,published,0xa2521e8f5a990903fdd8afa6570c52526e7e0d5e,0xa2521e8f5a990903fdd8afa6570c52526e7e0d5e,GnosisSafeProxy,1,1,16375699,9223372036854775807,true,16375699,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,GuardiansSafeOld,gooddollar_owned,published,0xc9d09ba972b4eb6bb7347f2229fb6d50434ffca6,0xc9d09ba972b4eb6bb7347f2229fb6d50434ffca6,GnosisSafeProxy,1,1,12956494,9223372036854775807,true,12956494,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,Identity,gooddollar_owned,published+registry,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,IdentityV2,1,5,17237952,18314662,false,17237952,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x8a3716a5117789bfbb058b671557334c9f95d40631126f92b67f977ba7e44fe7,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Identity,gooddollar_owned,published+registry,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,0x7d3033247d4a57b8193b6d9193fd56b45c3f794f,IdentityV2,2,5,18314662,19163670,false,17237952,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x68684e4903b9e207776736097e4c0bc1be9043a4e83a8b1553a9327b0cc42142,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Identity,gooddollar_owned,published+registry,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,0x3df6ea625866df8d0a61408a122c484b98f3184c,IdentityV2,3,5,19163670,50351048,false,17237952,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x622b7abbc47d60c8a7493bde94d8e9164b244c4631dd33ed79590c739cdb0ced,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Identity,gooddollar_owned,published+registry,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,0x1eeeb5ba9a9f8b84e52612884a4c18c78cc7413e,IdentityV3,4,5,50351048,61416834,false,17237952,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x4bd0225a727e3608ce47277a685849547c779c35785388dffcb68a1064f49f23,carried_from_seed: IdentityV3. Event set identical to V2.,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Identity,gooddollar_owned,published+registry,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,0x0ecc03f4e3fa94fa6e2098428a3ad393b65933c9,IdentityV4,5,5,61416834,9223372036854775807,true,17237952,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x0a43a8aa37ea56339ba7f8b8083eb95f17e582d1ccfb2c9f37b8436b195085ad,carried_from_seed: IdentityV4. Whitelist expiry moves from one global authenticationPeriod to a PER WALLET reverifyDaysOptions[authCount] schedule. Boundary comparison flips from <= to <. addBlacklisted now emits WhitelistedRemoved before BlacklistAdded in the same tx. authenticationPeriod() stops being stored and returns the last option. AccountConnected and AccountDisconnected events added.,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Invites,gooddollar_owned,published,0x36829d1cda92fff5782d5d48991620664fc857d3,0xdbc8860618482f703a4047340b8639b1452f96ec,InvitesV2,1,8,18003063,18795892,false,18003063,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0xe65975cf95e2a884b17fff033799e3ea2f0a852c8b8ea018906dd136b66e639e,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Invites,gooddollar_owned,published,0x36829d1cda92fff5782d5d48991620664fc857d3,0x61760d949357066ae29c469b70a91934273e4ef3,InvitesV2,2,8,18795892,20211506,false,18003063,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xb9b02551b4d049d0c13cfca61238ea61363f54e1d129dbbad9ed95646aca23cc,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Invites,gooddollar_owned,published,0x36829d1cda92fff5782d5d48991620664fc857d3,0x142e6d0afdd09c8629970b5fb0cf9798a3d21f89,InvitesV2,3,8,20211506,20645578,false,18003063,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xe469498ecb04290fffe5eab6e1f064e4974fea90b4a6f63e1c7d14106793c001,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Invites,gooddollar_owned,published,0x36829d1cda92fff5782d5d48991620664fc857d3,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,InvitesV2,4,8,20645578,24428495,false,18003063,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xb104188d6bf90a6f72c1278594cf06f53ea827a7fe85d91e1dc4167706903edd,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Invites,gooddollar_owned,published,0x36829d1cda92fff5782d5d48991620664fc857d3,0xd2e26679b4d21cb501ebbc99744c29ed061a6b8c,InvitesV2,5,8,24428495,24518263,false,18003063,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x2009538d39810ef0f0f43438fa262223bcb744fd3e722af01c898afadb3e15a6,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Invites,gooddollar_owned,published,0x36829d1cda92fff5782d5d48991620664fc857d3,0x87c222b6212b8352c48b7047e5c97c8797535a09,InvitesV2,6,8,24518263,24600260,false,18003063,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x1b8340f46186440723c9966efc1401b06da022e2ea896256168da6be8f783f84,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Invites,gooddollar_owned,published,0x36829d1cda92fff5782d5d48991620664fc857d3,0xf2196f8c2ba0674a8b00369cd65fab3f54b080a0,InvitesV2,7,8,24600260,61165821,false,18003063,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x02225e275e9e2e265175be1ac585904205a1a49612c41c23b6a15238c05bdf0d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,Invites,gooddollar_owned,published,0x36829d1cda92fff5782d5d48991620664fc857d3,0x4072cb2d7e95def1559f6f72491039fe0534fa37,InvitesV2,8,8,61165821,9223372036854775807,true,18003063,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xea995ee585fba0d4d31a119bcc206c76b7af8a7155b7c2ee1ca071e111b77ed5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,MentoBroker,third_party_mento,published,0x88de45906d4f5a57315c133620cfa484cb297541,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,Broker,1,2,31415857,61416834,false,31415857,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x58558a86a3aced5b23ae279244bd285f68c9d6d0a20cf283b7a40a0784697831,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,MentoBroker,third_party_mento,published,0x88de45906d4f5a57315c133620cfa484cb297541,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,Broker,2,2,61416834,9223372036854775807,true,31415857,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x2e63673ca3232bd818d12804ade7e1d688b7c11da7812d0237a3564e99cd0fb7,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,MentoExchangeProvider,third_party_mento,published,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,0xd9ce916d711977d5b27697a13964556b4fb8af1d,GoodDollarExchangeProvider,1,2,31415857,61416834,false,31415857,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x65d8c817bac8f41eb34548c15ad6ae5e744da2bd5373916df3b8e63f1fecd916,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,MentoExchangeProvider,third_party_mento,published,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,0xe930cde20f60d0a4fc9487874861ae259f5bed48,GoodDollarExchangeProvider,2,2,61416834,9223372036854775807,true,31415857,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x5ed71ccf7c4789f438827e074bc8bba84c7fc2c615495b12a2f9c51398a8b0d5,carried_from_seed: ExchangeUpdated event added. Not currently consumed.,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,MentoExpansionController,third_party_mento,published,0x5557e9def86ad6564462741a7a3f3679c1223f5d,0x7288d592e1b9013c668801f722be650993d2925a,GoodDollarExpansionController,1,1,31415857,9223372036854775807,true,31415857,explorer_creation_tx_plus_receipt_single_endpoint,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x9da4f4203282696d49deb0c241e49e0ff09f8b6da2d463f69f3fc98e66899a74,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,MentoProxyAdmin,third_party_mento,published,0x8471406c3bff67cc6538481c8550364bda6ca691,0x8471406c3bff67cc6538481c8550364bda6ca691,ProxyAdmin,1,1,31415855,9223372036854775807,true,31415855,explorer_creation_tx_plus_receipt_two_endpoints_agreeing,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xdd44d5a52707f76ac1bb4147820056bd47ca2c90f79d82fdaeb19b7d180179b4,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,MentoReserve,third_party_mento,published,0x94a3240f484a04f5e3d524f528d02694c109463b,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,Reserve,1,1,31415856,9223372036854775807,true,31415856,explorer_creation_tx_plus_receipt_single_endpoint,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0xe5750e9acc0322eae552526478b90a1a762ea401bf9094ff36daa6d0e4669020,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,MentoUpgradeHelper,third_party_mento,published,0xc413cc6c58f0c290e89ddaec83c2590017985eb7,0xc413cc6c58f0c290e89ddaec83c2590017985eb7,ProtocolUpgradeV4Mento,1,1,31415775,9223372036854775807,true,31415775,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xec07536d5a957fe23c6401f1d120012f7eec8637486054801d7915f025b2063b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x0000000000000000000000000000000000000000,uninitialised,1,7,21473545,21473546,false,21473545,explorer_index_and_state_read_agree,bisection_and_announcement_union,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0xd0a3fad8d7887f8264414ddd3290ed1782fb4658,MessagePassingBridge,2,7,21473546,23063176,false,21473545,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x3cf5b0c8c76f42b66f9fdea7cc3fa15f701f158458a5d0ed4e5a7966e5cbb891,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x691de730d97d545c141d13ed5e9c12b7cb384a73,MessagePassingBridge,3,7,23063176,31525116,false,21473545,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x61ac5f3f5751317589d19866c83ec842c45e2e38869f22973b935ed691ac8f88,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x2537f22e7b2d5d14e7f571fa67fcd846d73317f6,MessagePassingBridge,4,7,31525116,50351048,false,21473545,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xf73e0601329e2c0be422f8110b8d9e72950ec58d1a23d0aebf931dc07aa742f9,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x7bdaf2fb332761b2a6a565a43ccb0acfc36d2c3d,MessagePassingBridge,5,7,50351048,52958251,false,21473545,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x1624abfee3f1e647d995471b9cd0434db19d19df21e57b80046ae86f52c9df34,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0xf3eab7018d74e7df95a5d8dc70987c0539bdf48f,MessagePassingBridge,6,7,52958251,61416834,false,21473545,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x7fd33bb337b7565f86a2f7099feb87a2b4f446b94151b7c68b4091eadfb0b369,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x3edd30a1cd94dd6d3329b5ebaff5aa4e0a4e4a55,MessagePassingBridge,7,7,61416834,9223372036854775807,true,21473545,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x29296c3a605737b0ad6dcd4b9040193cc76a01bf8488220f789e13219be9a5a5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,MultichainRouter,third_party_infrastructure,published,0xf27ee99622c3c9b264583dacb2cce056e194494f,0xf27ee99622c3c9b264583dacb2cce056e194494f,AnyswapV3Router,1,1,10155435,9223372036854775807,true,10155435,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xcd92052cccde60e3a65926c5a58ebf8ba7ddd85e99f8bd7af270fdec0a409495,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,NameService,gooddollar_owned,published,0x0f5db7a64a6a64052693676ca898ec7f7a94ff4e,0xed9c5987e7109bb43a8a1a40a726b275e4eb4ace,NameService,1,1,17237962,9223372036854775807,true,17237962,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x0b90907ca330b6cb3ee57cdba11984e10cd8e5e5f004a3284c246ff6ea90ceab,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,OneTimePayments,gooddollar_owned,published,0xb27d247f5c2a61d2cb6b6e67fee51d839447e97d,0xb27d247f5c2a61d2cb6b6e67fee51d839447e97d,OneTimePayments,1,1,18105474,9223372036854775807,true,18105474,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xc7ffb78edacaf8c162f803f1d06d60a0f7959fef40e59c642134256cbe714fac,carried_from_seed: Not a proxy. EIP-1967 slot empty across all history. Single immutable era.,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,PoolGdCeloV2,third_party_dex_pool,discovered,0x25878951ae130014e827e6f54fd3b4cca057a7e8,0x25878951ae130014e827e6f54fd3b4cca057a7e8,UniswapV2Pair,1,1,17713819,9223372036854775807,true,17713819,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xe0ce44f796f8c819bdba6334eb56f0ab6be2936af74486a2c2ccae17e0d17b1f,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,PoolGdCeloV3Hi,third_party_dex_pool,discovered,0xcb037f27eb3952222810966e28e0ceb650c65cd9,0xcb037f27eb3952222810966e28e0ceb650c65cd9,UniswapV3Pool,1,1,20750772,9223372036854775807,true,20750772,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xb444db86df9a51d5ea46b9174dbbf339e48710745d888234840a9ce5679968ed,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,PoolGdCeloV3Mid,third_party_dex_pool,discovered,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,UniswapV3Pool,1,1,40596860,9223372036854775807,true,40596860,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x84fe2b52e16ffad7d7e40b57117e8ee7ab3c7e4c3edb2acfc9a7dee556f25a47,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,PoolGdMcusdV2,third_party_dex_pool,discovered,0x07f86b39728be613062bc7413fc2ca7293eef022,0x07f86b39728be613062bc7413fc2ca7293eef022,UniswapV2Pair,1,1,17714580,9223372036854775807,true,17714580,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xe0ce44f796f8c819bdba6334eb56f0ab6be2936af74486a2c2ccae17e0d17b1f,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,PoolGdUsdgloV3Hi,third_party_dex_pool,discovered,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,UniswapV3Pool,1,1,31680016,9223372036854775807,true,31680016,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xced8cb884f76be736e2ac90f1bcc4eaadac233235a7da8dd813d9adbfeffbcce,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,PoolGdUsdgloV3Hi2,third_party_dex_pool,discovered,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,UniswapV3Pool,1,1,21818995,9223372036854775807,true,21818995,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x81108761c6a03889b76abe78e2a059fa23bcdd3a028668984e17f95a5651e2f1,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,PoolGdUsdgloV3Low,third_party_dex_pool,discovered,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,UniswapV3Pool,1,1,21108554,9223372036854775807,true,21108554,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x4571767e06d5040fa5e97ac1a4d2552c38d18a335a34e1f9315558f06a3bae3d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,PoolGdUsdmV3,third_party_dex_pool,discovered,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,UniswapV3Pool,1,1,19916922,9223372036854775807,true,19916922,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x98890919ba4af6d5acadd5f3bf6b6387333d595bf974ef93adfd993d79acf92c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,ProxyFactory,gooddollar_owned,published,0xd86cd6bb3c2a576b2c2cef4e047b1a7adc5be62d,0xd86cd6bb3c2a576b2c2cef4e047b1a7adc5be62d,ProxyFactory1967,1,1,17237868,9223372036854775807,true,17237868,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x7f63d978bb61348d9321e9e9a382a2f88679edb38c483385333d4dbb0760fea9,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,StaticOracle,third_party_infrastructure,published,0x00851a91a3c4e9a4c1b48df827bacc1f884bde28,0x00851a91a3c4e9a4c1b48df827bacc1f884bde28,StaticOracle,1,1,20262304,9223372036854775807,true,20262304,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x86143ea0f1beb35753eec610670dc4ca6a7dc9924fba2f76851456201041c5e5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x25cc912cc038f1791734f39ceb4d8bffb32c7c61,ConstantFlowAgreementV1,1,16,16393492,18349124,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,contract_creation,none,etherscan_v2_verified_source,0x75e9777e4dc04eb4239f29c5d7f293dc476140250658aa342ae46dc5943dcaba,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0xe40983c2476032a0915600b9472b3141aa5b5ba9,ConstantFlowAgreementV1,2,16,18349124,19952321,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x7d085cb6ac5adcabb2282b7790fd4b6ce42dba3bf82c7984db6c9a8ea98e611f,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x5f001c3915084186b9109fb9dc1e978c98f854b0,ConstantFlowAgreementV1,3,16,19952321,20091409,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xfd8e2cc384599300dce3e61069f0d2ce1313164acf549816f25fb59f548f543d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x9f9eed9bbc38e9e0514fd9dfcc0bca9869a9c534,ConstantFlowAgreementV1,4,16,20091409,21146434,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x2ef2c7bfba9b8dca88af2515f2a4aa08cde06f64b0af0a15c90068db7f8c6d1c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x4247ba6c3658fa5c0f523bacea8d0b97af1a175e,ConstantFlowAgreementV1,5,16,21146434,23701580,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x1c984c77810263353e0e29c4f8d46f24622b7bb0ed55499cc51aeae7c834554c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0xdf3f4b9e4e67a21c868d043a92ae921ff0ebadbb,ConstantFlowAgreementV1,6,16,23701580,24738429,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xbd691ecb50633ce343c9f1cd04c7789a1cbb1e075621e3209809c1482b3e78f3,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0xe3f6ec0676b9ce5d759580e1d526dee31678c283,ConstantFlowAgreementV1,7,16,24738429,26706819,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x85d3c06af86a7ad69fb86b1dc069dcacff6cba81fdcce7fa857eae31d3fc31dc,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x247f65bd849d686147330978aa7521457c5a83bf,ConstantFlowAgreementV1,8,16,26706819,27058151,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x20b540bd27dd1019829f59165480a11522745d5fb13a6815102e65452d36236f,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x81398af97997f3973416d312939f790636719195,ConstantFlowAgreementV1,9,16,27058151,28853698,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x942776f307798a9174da8bc44d2dc4f24469b24ce6d3974e35f4280a7e88f846,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0xf10e526e33f3f377e5b11d62e091fe3f4162a3d0,ConstantFlowAgreementV1,10,16,28853698,29627986,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",blockscout_verified_source,0x0b9f6edffde404761e0993c5b1712631e782dd372af34820a9ea0dd95aed21ca,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x75e58f16f95ac530789d22e55713c9f8dc22444c,ConstantFlowAgreementV1,11,16,29627986,33928238,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xd4b756d9a39c0ac5df7daeda534d2ab144410bab2a665553566f0f2b7f9246fe,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x511cba3de92db7891967e21dbd7c4571531ab84b,ConstantFlowAgreementV1,12,16,33928238,39643668,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xb4e15d60d54a173a5cfe3820cb03c0f7ecb514f015a7ab934c6b76ab6849aeac,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0xd571f5ec96a5b362d10615ff999f06fac4c9e141,ConstantFlowAgreementV1,13,16,39643668,52777129,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xacf7e26bc301a35fe1ba129370a5af1d3e8555c6610bc768c8f7183e3f18903a,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x57897b796ece6633fc7c0c6490b4eb84d58509e5,ConstantFlowAgreementV1,14,16,52777129,61309260,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xcc3e5b55fc44f61f11120b6ad3973f97782035b82eb55455a2589a2a37a4c623,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x7e115385bdbd12fb943a099320c41224b4fa96f4,ConstantFlowAgreementV1,15,16,61309260,74797088,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x938d286c9bc510c3815ee4df6bc0c94e47770008998c9c0c05f8f35c6ca0d4c1,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x88bb53dea50691cc41094cde84f88d6afb8ca499,ConstantFlowAgreementV1,16,16,74797088,9223372036854775807,true,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xfb234d8843f0d85344c9a28a31c61b75c71866116caed48021c0419b16be14ca,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0x7ffce315b2014546ba461d54eded7aac70df4f53,GeneralDistributionAgreementV1,1,14,23675300,23701580,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,contract_creation,none,etherscan_v2_verified_source,0xb786d4ce6758e6e6e6c95c8f4dd32c3f605575b77a97d676cc77e0a357557ae6,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0x554a8acef6c689a74b25b1c41f58fa2e678162b5,GeneralDistributionAgreementV1,2,14,23701580,24738429,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x339ef1ccdc96ea6e5f945d0869f69e68d704e5aee4a3f0fb47e920233f2e58e2,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0xc70ce47df817f25bfbb4fb66fd42326ad306f27d,GeneralDistributionAgreementV1,3,14,24738429,26706819,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x2f10ed30f32aac01825d800417aa9a035350611a8846ab187ad2f5683030b04b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0xab1286ab62d0dffd994f4b2d72b24eaa9e295562,GeneralDistributionAgreementV1,4,14,26706819,27058151,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x467730c607a2af26278920b99602bba2ae00fa99735aa8b92b7c31d4aeb1e01d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0xe72830e7ebbff8ce0866059de83cacd4263acd08,GeneralDistributionAgreementV1,5,14,27058151,27279493,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x78428255afad1008379da37854d51a8c6be3020f156dcc65a2f150180332cb71,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0xb75bd19c682e62e6a0c35399bb3a2538fcc9cef6,GeneralDistributionAgreementV1,6,14,27279493,28853698,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x51a1f5d9659cf4db2e53be47120a0b772ad7156ff8cb7e2383659deeb66e9deb,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0x6fc99f5591b51583ba15a8c2572408257a1d2797,unknown,7,14,28853698,29627986,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,"CodeUpdated(bytes32,address)",none,0x4f906e557ab9ee6a7b78ddfc34f24a3ac478263d6a6ee139c0a45c028dd762a4,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0xa0844efaf9a6803e9fa379ee59d44d3ef581ea3f,GeneralDistributionAgreementV1,8,14,29627986,33928238,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x3a8c483a4085356d3be9ba5fa9861d796479f2b012f1e6a6b4d59f1c20741303,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0xc8f6f1720e6266445b3b53b9b9870b25ade5154e,GeneralDistributionAgreementV1,9,14,33928238,39643668,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x6d6bcbc09347c139ac7030309ad6974266386ded295636658d837996e388cb56,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0x96c3c2d23d143301cf363a02cb7fe3596d2834d7,GeneralDistributionAgreementV1,10,14,39643668,44995009,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x2327ceb8850a68dabe52cebd96a38eb4f32cdec27395a3b52877751c3c2468d8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0x4c78cad0cc7152fa8f64ce5298a2d5216c7e4d81,GeneralDistributionAgreementV1,11,14,44995009,52777129,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xead9a7e206538e62c0f6e4dd33621dc98ba53e3352e3214034d618bc44478abe,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0xa347bdc5965323f92ccd950a8b7012c0e438e178,GeneralDistributionAgreementV1,12,14,52777129,61309260,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x5a8b677cd86a18a93c7ae21271fd141fa249950147262c7da8088b683e28d3a0,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0x20dd21b94b88cbeee338c7ffd6124f716c0b54b2,GeneralDistributionAgreementV1,13,14,61309260,74797088,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xabe37902c5582ed6ca1fa60c4c6e6956d4abaa1c701b43c219536457fa63c893,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0x0fcddf2d5023219145e902cb3b0c44159ab59d61,GeneralDistributionAgreementV1,14,14,74797088,9223372036854775807,true,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x1638d7614afb64812742f4e5df6511885567ff68515e7e74a16416107afa670e,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x0000000000000000000000000000000000000000,uninitialised,1,20,16393469,16393473,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0xf37a766fb6684fa86842f88380e786c2bd32ba4c,Superfluid,2,20,16393473,18349124,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,etherscan_v2_verified_source,0x191b0b9c7e52f28242fb40f248e987dc8aa98ee003548293837c02ac582c0fa7,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x109412e3c84f0539b43d39db691b08c90f58dc7c,Superfluid,3,20,18349124,19952321,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xbad743f142e85dab71de287f4efced306d2dd49c2522aa8e5937581d1fa2caea,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x15f0ca26781c3852f8166ed2ebce5d18265cceb7,Superfluid,4,20,19952321,20091409,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x79c0bf6cc0a97404a1ba4f04a21491ed3dd432ffd8c792578680a79363aa9030,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0xe01f8743677da897f4e7de9073b57bf034fc2433,Superfluid,5,20,20091409,21146434,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xbe25805f704e9912841503d6f91e3570d8bf75dea127874a0afb35a0c0c566d0,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0xb8f12031d79615f3faf6ec5f9795057e55e3069a,Superfluid,6,20,21146434,23701580,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xd402dc49770a98fa224b4f55fc6d7d6a937655d3c788084771133ebbaea954f5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x143ea239159155b408e71cdbe836e8cfd6766732,Superfluid,7,20,23701580,24738429,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x7c07df056c3c6dab1e3fe96a6d7d8453b594969f72fa151a5c8b47063613532f,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0xddc77ec35a571c98c7465b51f152e4888835bee6,Superfluid,8,20,24738429,26706819,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x57164c7f8472925746087e8db09c807893b00780c5a1c92c8faf1743b48977f8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0xcf3f4fa77f4427f6a1c1a96556194b40fc9dbf02,Superfluid,9,20,26706819,27058151,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x2878db05fa2818412b3dc91044e48209e42aed3f5912e5153ef076c953099914,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x78743a68d52c9d6ccf3ff4558f3af510592e3c2d,Superfluid,10,20,27058151,27279493,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x29b712122f26431d8f811f6b06e233dadd2e5efd3d1d73e693753da543178401,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x862f59081fc7907f940be4227b9f485d700e6cdd,Superfluid,11,20,27279493,28853698,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xbdd0248aee9f9d9cd42b1ec49b695e18234162ea5f5fd7f3bf3f2a1db1ea1d4c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0xae50ba6b0f7412dfd2061bfcd15c2d63f36af143,unknown,12,20,28853698,29627986,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",none,0x5e9cb99ff4ba661eb86d8c7a44f90f36a2ad1fbeabd1769133e6d34c726fd95a,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0xf26967f92151487f8c6642199c3441b02398d19e,Superfluid,13,20,29627986,33928238,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xd725780f0e452fc2e98ba0b229c1854c34e9882a5550c03501406c8fcc98f3d0,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x9a19773ebe33c5917012c2bb982bc683d91ec600,Superfluid,14,20,33928238,39643668,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x49e13d9d72661dfdb490a8a67c32fef72a7b212bdaaabf0c9cc231818377de45,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x97620d4d7950223963f00db25f12b4ac1d4eed99,Superfluid,15,20,39643668,44995009,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x271879ac911f8440a875974a04b54db30b8a5f63898975a041489de41f36554c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x3b526b50709a5551030673be284bc9c1e38351ac,Superfluid,16,20,44995009,52777129,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x6f43af90345b70565298e49768034ab0ff782c995fd5fdb26c0871f6ded40fe1,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x8e03f0edb581e8b6aad80eece89b3028388f4b53,Superfluid,17,20,52777129,61309260,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x5f3453e79f1aaac3f7dfe0c14452701fd8f3501ec000334f70bc80f9e9dcbf7b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0xf17e88391b68c2a5972131f5044fd6ace665f221,Superfluid,18,20,61309260,74797088,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x19a7ec64380e14852eee8d4a0f7bdb4a15c98dd9e8359f42a0cc2316415b759e,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0xc899724f32859e8169e607a23448e4b487b4dc04,Superfluid,19,20,74797088,76632579,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x61f96160837a684e3c8b66ebac18d6c0517947e8d3789d8833f567592d3ea40d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x724676722b69b8b0e5fcf030de796047e771e5f9,unknown,20,20,76632579,9223372036854775807,true,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",none,0xdb6e855c140ab4a6e967d9ddb3d022b5fb39cf6956ff6677bbddf9f7ef334e70,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0x7dc6b57adae1aaa94e01a3049cd42b8adce5090c,InstantDistributionAgreementV1,1,14,16393503,18349124,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,contract_creation,none,etherscan_v2_verified_source,0x7423f597fdcfb7c349e024be728df2d0c05e3337e615808c64b8c0994ff66a5c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0xd399e2fb5f4cf3722a11f65b88fab6b2b8621005,InstantDistributionAgreementV1,2,14,18349124,19952321,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x131499da5b515b0f696d9e320b87b3258838287f30bcde867d1648ba1bd83471,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0x507c3a7c6ccc253884a2e3a3ee2a211cc7e796a6,InstantDistributionAgreementV1,3,14,19952321,20091409,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x0103da8886a08479c1249b11691d702669168e2f64f65595db70270ee66859f0,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0x2622bfc83f429bf313341857850a1dde09685855,InstantDistributionAgreementV1,4,14,20091409,21146434,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x005ec5ffe135e03f2feacd794c02fe50aabc4dd3c572eb0dcc023023bb2a215f,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0xd48317ccdac2ca3fd5e3c58c32da3a7c517937b6,InstantDistributionAgreementV1,5,14,21146434,23701580,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x0799b7eb67f8bf5f1db451db0b501b02796bedddfe80efa2a991ff28f1a4df4c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0xfb2b126660be2fdeba254b1f6e4348644e8482e7,InstantDistributionAgreementV1,6,14,23701580,24738429,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xfafd5fc7ae369d3fce5cc48edaa0de12d57761ce316328b0228d358d69b9ee65,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0x2e4861b1f56a67473b7bf0dd1ef85e9e9fa5ad75,InstantDistributionAgreementV1,7,14,24738429,26706819,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x3f185f2c62fd18472510fbb526fc17a7bf9b0da44f028195dacb1f1ad6b85e2c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0x0de6448cc883168076f7b10449bc7024d42f7910,InstantDistributionAgreementV1,8,14,26706819,28853698,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xd1000660be8820603092f51c3c5435be3cc133c9f7a2e47a745fd159d4d45bc4,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0x466be9ef50dec3c22eaa4f070e9c9ceaaccd1e75,unknown,9,14,28853698,29627986,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",none,0xb86b086999fdf33a2056b5fb2d92686006ff58f9d59216ad9ceea32e456af822,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0xb84c98d9b51d0e32114c60c500e17ea79dfd0daf,InstantDistributionAgreementV1,10,14,29627986,33928238,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x5144e6bd0aff5ec0dc215c75db7a2e5a6ea9539e21f10ac47bce49108c1f1798,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0xd59ba9a84fa02e3687bb0694e459b3c1d76586f9,InstantDistributionAgreementV1,11,14,33928238,39643668,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x4c0dce8901dea2158d8f1edcc42bc70261cce1f74e58f4f0ef5ca644a44427b6,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0xf0ec6a8842ca72aec8a4d4573e731242389e18a8,InstantDistributionAgreementV1,12,14,39643668,52777129,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x3b0de12889b24499a458af0c481b84c9a572276f46a6faf92f7a5e9de2107226,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0x1d38a1f81216b73c05a10eac5e84f566d4d9d8da,InstantDistributionAgreementV1,13,14,52777129,61309260,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xfb7ddd181f516de9d0f9448a3aa6faab8aaba0d4296d4df8793f1f09a9fb9d8f,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0x295cef78e76564b124b948a05dbd6522c3ec76b1,InstantDistributionAgreementV1,14,14,61309260,9223372036854775807,true,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x062b6f052bfc1eeb46d77828aecf61f2c118d08d8dbdd4bd6672e42f1fed0fbb,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,SwapHelper,gooddollar_owned,published,0xe45cab86609a16dfadec112fdd61e4ea80edaa8d,0xe45cab86609a16dfadec112fdd61e4ea80edaa8d,DexSwapHelper,1,1,18468536,9223372036854775807,true,18468536,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x15ae5796a74f46cfb3b34a673823263ac0cbd3eb5bdb803a393516d0bc446375,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,UBIScheme,gooddollar_owned,published+registry,0x43d72ff17701b2da814620735c39c620ce0ea4a1,0xedbe438cd865992fdb72dd252e6055a71b02be72,UBIScheme,1,4,18006679,19276072,false,18006679,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x0e581bfc2fe31489ffb4c73916e5eb871089492aab7d977d80cd563d3011e236,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,UBIScheme,gooddollar_owned,published+registry,0x43d72ff17701b2da814620735c39c620ce0ea4a1,0x854f84ef0d9abc1e0afb4e96c962d5456b62214e,UBISchemeV2,2,4,19276072,23063176,false,18006679,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xa218cc030a5bf302bd79f7c0814e7d03ba74606098b00733d9751be6af84dbb8,carried_from_seed: ActivatedUser InactiveUserFished and TotalFished REMOVED. They exist ONLY in blocks 18006679 to 19276071. Contract renamed UBIScheme to UBISchemeV2.,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,UBIScheme,gooddollar_owned,published+registry,0x43d72ff17701b2da814620735c39c620ce0ea4a1,0xe8fcbac4bd18f80301450e428518e9dedc183a26,UBISchemeV2,3,4,23063176,50351048,false,18006679,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x3588b09013666a632da7bb2559251b2efb62086be858ddaf9a604eb4340542c4,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,UBIScheme,gooddollar_owned,published+registry,0x43d72ff17701b2da814620735c39c620ce0ea4a1,0x43f0eb66ea3c2d9552241525aa1af6607227dfbf,UBISchemeV2,4,4,50351048,9223372036854775807,true,18006679,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xdb2d70994b744a419372a0526da1e3bbe069a59e7569a9f3c0965d85d1b60ecd,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -CELO,42220,UniswapQouter,third_party_infrastructure,published,0x82825d0554fa07f7fc52ab63c961f330fdefa8e8,0x82825d0554fa07f7fc52ab63c961f330fdefa8e8,QuoterV2,1,1,13916379,9223372036854775807,true,13916379,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x557b5bc80c7000c05bac66693aff2264927a0a22ea1f80d590449b52d515aa34,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,UniswapV2Factory,third_party_dex_factory,discovered,0x62d5b84be28a183abb507e125b384122d2c25fae,0x62d5b84be28a183abb507e125b384122d2c25fae,UniswapV2Factory,1,1,5272596,9223372036854775807,true,5272596,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xdac4452e3e8e28193a714ff79e8268661235b1f73a3ccf61d85470d3ce89ed3b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,UniswapV3Factory,third_party_dex_factory,discovered,0xafe208a311b21f13ef87e33a90049fc17a7acdec,0xafe208a311b21f13ef87e33a90049fc17a7acdec,UniswapV3Factory,1,1,13916355,9223372036854775807,true,13916355,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x5960f2f785dd273f0eeb9624f32a9f93bd1560dc1335171d22411d48296d79b3,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,UniswapV3FactorySecond,third_party_dex_factory,discovered,0x67fea58d5a5a4162ced847e13c2c81c73bf8aec4,0x67fea58d5a5a4162ced847e13c2c81c73bf8aec4,UniswapV3Factory,1,1,25639915,9223372036854775807,true,25639915,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xa99af02b020bfe03b92021add28ab8707c33a0d1887e01e67da39c5531fb9e85,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,UniswapV3Router,third_party_infrastructure,published,0x5615cdab10dc425a742d643d949a7f474c01abc4,0x5615cdab10dc425a742d643d949a7f474c01abc4,SwapRouter02,1,1,13916381,9223372036854775807,true,13916381,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xec8b1d6527bdadca0f0158435b41f0a9518215005a39b1f286d6a3628b7f806c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -CELO,42220,UniswapV4PoolManager,third_party_dex_singleton,discovered,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,PoolManager,1,1,43985163,9223372036854775807,true,43985163,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x3ed9587168a0fe70acc18971f52cba06f18bcd4b4b5ba2f0590b8c17b1c0cdca,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906 -ETHEREUM,1,AaveStakingFactory,third_party_infrastructure,published,0xf4411c22766947db2da39ad534a040b770b51153,0xf4411c22766947db2da39ad534a040b770b51153,AaveStakingFactory,1,1,14338311,9223372036854775807,true,14338311,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xe5c076c8e4675670baa06fb5f76fee3dc8ef6f48b7c7df96efe4790d773e1771,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,AnyGoodDollar,gooddollar_owned,published,0xd17652350cfd2a37ba2f947c910987a3b1a1c60d,0xd17652350cfd2a37ba2f947c910987a3b1a1c60d,AnyswapV6ERC20,1,1,14809447,9223372036854775807,true,14809447,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x48c30df8d84160f9085fffbc3ff8a72e42be14aca8ad94626249d836a1392565,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,Avatar,gooddollar_owned,published+registry,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,Avatar,1,1,10561463,9223372036854775807,true,10561463,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x8a27316984da83331e574723efd0810faf4d7065f3037b8778d9c572ea49c6d8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,BancorFormula,third_party_infrastructure,published+registry,0xa049894d5dcad406b7c827d6dc6a0b58ca4ae73a,0xa049894d5dcad406b7c827d6dc6a0b58ca4ae73a,BancorFormula,1,1,10566777,9223372036854775807,true,10566777,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xd17f840b97128d5f5ecc258913b071648460f9c11298c00d21cb478907f2ac03,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,cDAI,third_party_token,published+registry,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,CErc20Delegator,1,1,8983575,9223372036854775807,true,8983575,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x3f1d4a4e2a03855c7ee8f6f2477c1245752a5ca3ef28d59e8fd509efe59ef877,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,COMP,third_party_token,published+registry,0xc00e94cb662c3520282e6f5717214004a7f26888,0xc00e94cb662c3520282e6f5717214004a7f26888,Comp,1,1,9601359,9223372036854775807,true,9601359,explorer_index_and_state_read_agree,slots_unreadable,contract_creation,none,etherscan_v2_verified_source,0x9398f9b1f117941e8e25a4aff4d11754f48933cc3c08101975e3306e98d88c2a,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,proxy classification unresolved. slots re-read at block 26041882 -ETHEREUM,1,CompoundStakingFactory,third_party_infrastructure,published,0x78cc5ab2f0990b5fe58f95baebf8f37879534aeb,0x78cc5ab2f0990b5fe58f95baebf8f37879534aeb,CompoundStakingFactory,1,1,14338308,9223372036854775807,true,14338308,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x883ade859bcf2356e3b7cd3523018b571087dced077a1ed4ac45a4c96d8d3980,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,CompoundVotingMachine,gooddollar_owned,published,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,0x92af163505c05d63a4f7478c01b9af9be369c143,CompoundVotingMachine,1,2,14380642,22165594,false,14380642,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x6eaae71845e0c65ee44592019c400d81c9ebca6b3a544cdc10368c6af43f4216,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,CompoundVotingMachine,gooddollar_owned,published,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,0x807d0066d60a0a8312b6d191f60a6938a527e971,CompoundVotingMachine,2,2,22165594,9223372036854775807,true,14380642,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x0d5e8f324a69af2b72f2d9e3266036966ba2bcfd2d594f82c28b0ab275d6d5ed,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,Contribution,gooddollar_owned,published+registry,0x8eec64bb6807c0178f96277cce6a334b4e565e5c,0x8eec64bb6807c0178f96277cce6a334b4e565e5c,ContributionCalculation,1,1,10569456,9223372036854775807,true,10569456,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x8afd3472b2ba7c9664301e1db0e1a4ff03e1d4abf7037870060aec9479e95d88,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,Controller,gooddollar_owned,published+registry,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,Controller,1,1,10561463,9223372036854775807,true,10561463,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x1cce4814ac502cec7e982e73d29bdc95e9094476ba971b6777f8abd4a415fc26,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,DAI,third_party_token,published+registry,0x6b175474e89094c44da98b954eedeac495271d0f,0x6b175474e89094c44da98b954eedeac495271d0f,Dai,1,1,8928158,9223372036854775807,true,8928158,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x4e36f96ee1667a663dfaac57c4d185a0e369a3a217e0079d49620f34f85d1ac7,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,DAI_ETH_ORACLE,third_party_infrastructure,registry,0x773616e4d11a78f511299002da57a0a94577f1f4,0x773616e4d11a78f511299002da57a0a94577f1f4,EACAggregatorProxy,1,1,10606425,9223372036854775807,true,10606425,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x4b79b5c8aee6da0f7b393e8b53e6265ef7320a1d16184c65bd3841b5aa3d700d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,DistributionHelper,gooddollar_owned,published+registry,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,0x42cda1bd60cc66ab2e2411e8c93db436c8a27060,DistributionHelper,1,5,16167621,17661435,false,16167621,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x15354959eb9bdda169ce6b338a64f4949ca5fd2fc4fa790fc506f7b62f221520,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,DistributionHelper,gooddollar_owned,published+registry,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,0x16171d113d9592b77cec52b8cc4bdd6f5810daef,DistributionHelper,2,5,17661435,18190480,false,16167621,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xf80378215ded3a92155f1331c852040bbabb670f2aa13da253d5af430ab7082d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,DistributionHelper,gooddollar_owned,published+registry,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,DistributionHelper,3,5,18190480,18719715,false,16167621,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xb95001d06c848c5680808debf2aba0ed20f162ec873722d17784acf0aeb7acdc,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,DistributionHelper,gooddollar_owned,published+registry,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,0xa339b7f4e95a93d2c6569cb139ad034c3b9caa77,DistributionHelper,4,5,18719715,22165594,false,16167621,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x6b215c6b5d9777cc6f1f5f2130a9b2c9fe16e933e18b076243e9181c446921f1,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,DistributionHelper,gooddollar_owned,published+registry,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,0xae2cd2a9513215961d344a2581dcab678598eedf,DistributionHelper,5,5,22165594,9223372036854775807,true,16167621,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xc3767b93a60456d6aa441ce3d8b319a5e479d9bde160f4dc87bedfc70558f73f,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,ETH_USD_ORACLE,third_party_infrastructure,registry,0x5f4ec3df9cbd43714fe2740f5e3616155c5b8419,0x5f4ec3df9cbd43714fe2740f5e3616155c5b8419,EACAggregatorProxy,1,1,10606501,9223372036854775807,true,10606501,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x4b79b5c8aee6da0f7b393e8b53e6265ef7320a1d16184c65bd3841b5aa3d700d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,ExchangeHelper,gooddollar_owned,published+registry,0x98fa532dd5c3a6b66fbf370813803192de4e0abd,0xbebbd9538d594619d36d48666e12d8c9f8372736,ExchangeHelper,1,2,14296277,22165594,false,14296277,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x26322c949531dde942496f5930d4820de88a98c486980fc5f4f43cbe5ea5a594,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,ExchangeHelper,gooddollar_owned,published+registry,0x98fa532dd5c3a6b66fbf370813803192de4e0abd,0x24614ad257f4d09fccaec024c65c40c060e73e9d,ExchangeHelper,2,2,22165594,9223372036854775807,true,14296277,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xcbdb11d6fd35031a639ffb1834cbce6879073b685912f740dd2a9b4ada1dd2b8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,ForeignBridge,gooddollar_owned,published+registry,0xd5d11ee582c8931f336fbcd135e98cee4db8ccb0,0xd5d11ee582c8931f336fbcd135e98cee4db8ccb0,EternalStorageProxy,1,1,11238178,9223372036854775807,true,11238178,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x2d05a6bd0ad793d9459975bf7760dcbfefa24baf8c7f70efa4aab6b52db668bb,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,GAS_PRICE_ORACLE,third_party_infrastructure,registry,0x169e633a2d1e6c10dd91238ba11c4a708dfef37c,0x169e633a2d1e6c10dd91238ba11c4a708dfef37c,EACAggregatorProxy,1,1,10606498,9223372036854775807,true,10606498,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x4b79b5c8aee6da0f7b393e8b53e6265ef7320a1d16184c65bd3841b5aa3d700d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,GoodDollar,gooddollar_owned,published+registry,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,GoodDollar,1,1,10561463,9223372036854775807,true,10561463,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x554945bfa422af5800554ef7b37f229465f13208db908d482249f1dd9803a3c0,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,GoodFundManager,gooddollar_owned,published+registry,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,0x4a10354b8e1928c38cc6a738cd2748fa1c818cea,GoodFundManager,1,4,14338654,16240765,false,14338654,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0xbb78513636d0bcb8076eb8dded78b38961998755abb5d65b2b29b04109c8135b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,GoodFundManager,gooddollar_owned,published+registry,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,0x53b3c6b18a03a9a0c3487cf1230eea1eb9a38a0a,GoodFundManager,2,4,16240765,18190480,false,14338654,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x3069da8e333310c4eee88b81b810e14ededc06f5904a64dd8198129ae82eb4d4,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,GoodFundManager,gooddollar_owned,published+registry,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,0x4a37a8d7cdb43d89b4dbd7ecfaeaf9bd39e24929,GoodFundManager,3,4,18190480,22165594,false,14338654,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x1603edb57ff936d52c7ff4f3696a591f39bf8b46b8e93cf5591de63473bf48ba,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,GoodFundManager,gooddollar_owned,published+registry,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,0xaacbaab8571cbeceb46ba85b5981efdb8928545e,GoodFundManager,4,4,22165594,9223372036854775807,true,14338654,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x80dcb898400e373e62b938941ea18dba14b621a35ec858897bdee60bb21a5b64,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,GoodMarketMaker,gooddollar_owned,published+registry,0xdac6a0c973ba7cf3526de456affa43ab421f659f,0xb3ff03c8a42506ba58b1127cd4b5928c7ed70a03,GoodMarketMaker,1,2,14296152,22165594,false,14296152,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x3ed7a72aaa5e00bea85f4c5a6b7cefc973c2e1e7a42754ed1812b5fa735ed268,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,GoodMarketMaker,gooddollar_owned,published+registry,0xdac6a0c973ba7cf3526de456affa43ab421f659f,0x8520633e40574e9550f6a0436b0f8d56f3b99bd0,GoodMarketMaker,2,2,22165594,9223372036854775807,true,14296152,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xfdd8235cfa88eea23f3dba545fdf43e6c4cf831b3dea3e2331c60606eaf380d1,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,GoodReserveCDai,gooddollar_owned,published+registry,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,0x865193da25c4fe135421fca78d2bd061b6efd744,GoodReserveCDai,1,4,14296271,16174339,false,14296271,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0xb04200c786691948f77f0a7be422af88e22b5a424ee637df3f722a6e45a9de10,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. slots re-read at block 26041882 -ETHEREUM,1,GoodReserveCDai,gooddollar_owned,published+registry,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,0x6e1c3f516ffd14852f9b25f21af13b6ce98dace5,GoodReserveCDai,2,4,16174339,18190480,false,14296271,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xa6ee500bfe454a9e75a1741294ee0b7729c3f510b5022de40246caa38c53a2cc,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. slots re-read at block 26041882 -ETHEREUM,1,GoodReserveCDai,gooddollar_owned,published+registry,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,0x2793a5887f53b025f49f7a9249d66f4671bce29b,GoodReserveCDai,3,4,18190480,22165594,false,14296271,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x2befbf5a304c75892209914c0a756d8c1c8bf82dd6508e3656eba753d100ad1f,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. slots re-read at block 26041882 -ETHEREUM,1,GoodReserveCDai,gooddollar_owned,published+registry,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,0x18bcdf79a724648bf34eb06701be81bd072a2384,GoodReserveCDai,4,4,22165594,9223372036854775807,true,14296271,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x43410466ac894d865cff8f6bbeaf0ede8804ae379f6260a2cd7c8ea0ac9ddc05,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. slots re-read at block 26041882 -ETHEREUM,1,GReputation,gooddollar_owned,published+registry,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,0x0a5dcf330ba39434dbda59b982a3dd09759cc788,GReputation,1,3,14344739,14352686,false,14344739,etherscan_v2_getcontractcreation,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x824339abb39e2b39cb85a8e45048c2eb366c9110a4918c2ea2d1f102f0354367,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,GReputation,gooddollar_owned,published+registry,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,0x438eb12a081041b525731c34086de3ed31658dee,GReputation,2,3,14352686,16885600,false,14344739,etherscan_v2_getcontractcreation,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x40781353ff48e1d9fe0feada2bf9c447956538f67d1b9a2f0d72d7c1fe8cc7be,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,GReputation,gooddollar_owned,published+registry,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,0x634e25b6ffde325d5beb8c6c2d8af6d543b6ff7f,GReputation,3,3,16885600,9223372036854775807,true,14344739,etherscan_v2_getcontractcreation,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x0b6ff946fd1ad1ebc33dd134a57713419b8ac0fdecbd56db74ffcf6266909cc5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,GuardiansSafe,gooddollar_owned_safe,published,0xe0c5daa7cc6f88d29505f702a53bb5e67600e7ec,0xe0c5daa7cc6f88d29505f702a53bb5e67600e7ec,GnosisSafeProxy,1,1,16060725,9223372036854775807,true,16060725,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,Identity,gooddollar_owned,published+registry,0x76e76e10ac308a1d54a00f9df27edce4801f288b,0x76e76e10ac308a1d54a00f9df27edce4801f288b,Identity,1,1,10561341,9223372036854775807,true,10561341,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x83c740a8ac588a566556553a334afdfded5add581f27efc0215d3ccfd842eaad,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x0000000000000000000000000000000000000000,uninitialised,1,5,18162554,18162562,false,18162554,etherscan_v2_getcontractcreation,bisection_and_announcement_union,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0xf19fb90fa4ddb67c330b41ad4d64ef75b9d8cd33,MessagePassingBridge,2,5,18162562,22165594,false,18162554,etherscan_v2_getcontractcreation,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x2e5d3e54855f5864dc7e6abf562989a74a3fc1e020b976c592a79a7b2da9c408,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x618fae127b803eabf72f9e86a88a7505eebf218a,MessagePassingBridge,3,5,22165594,23940256,false,18162554,etherscan_v2_getcontractcreation,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xf89052533300161b0a7d20c5eb600d0850f5c95fb48f1e2727825b231cd1b0aa,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x12ab702f015d3302f3cc0c4aba0626a127d06a07,MessagePassingBridge,4,5,23940256,24641278,false,18162554,etherscan_v2_getcontractcreation,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xd28a518f866e7d53b195a37a71eb04cc68fee21d7cb991427934b6f9d53e1fc2,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x3a2d0a9ef558b42af5ff8d27fe438b466fa7692f,MessagePassingBridge,5,5,24641278,9223372036854775807,true,18162554,etherscan_v2_getcontractcreation,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x104d6ab3b6a95b2ebf4cfb4a6cb485f5e4b5ef02c3d119c07e43322bbd5daacf,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,MultichainRouter,third_party_infrastructure,published,0x765277eebeca2e31912c9946eae1021199b39c61,0x765277eebeca2e31912c9946eae1021199b39c61,AnyswapV4Router,1,1,12242619,9223372036854775807,true,12242619,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xf8548d4270316b12fe3628b1d57ba1d79cd8a97861793af639eb0ee1ba330356,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,NameService,gooddollar_owned,published,0xec6dce387b1616a0c44ff2e4fa9e90e53cf14eb0,0xeb151e175d3d53032c2c185052e48c8c2d5c245d,NameService,1,1,14295851,9223372036854775807,true,14295851,etherscan_v2_getcontractcreation,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0xce45d07e83296b1ea2bdaf7be5635193dda560b978c1afe17b4e87667f2b507a,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,ProtocolUpgradeRecover,gooddollar_owned,published,0x6f1b4dfdd7156fc5752541ef35edf57b48e74475,,unknown,1,0,,,false,,"not applicable, no code is deployed at this address",no_code_deployed,none,none,none,,no_code_at_pinned_block: A published artifact or the registry names this address and nothing is deployed there,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,read at block 26041882 -ETHEREUM,1,ProxyAdmin,gooddollar_owned,published,0xa2db14c68ab35e620fea5bf07d65e9bff84c994c,0xa2db14c68ab35e620fea5bf07d65e9bff84c994c,ProxyAdmin,1,1,11512052,9223372036854775807,true,11512052,etherscan_v2_getcontractcreation,slots_unreadable,contract_creation,none,etherscan_v2_verified_source,0x2b57f0728a5ffe03a475faab83005c468d0f669c0a473f87425e3edb6101ec8a,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,proxy classification unresolved. slots re-read at block 26041882 -ETHEREUM,1,ProxyFactory,gooddollar_owned,published,0xda85fced9bd193526b7667f2ad1fd4a0f900d3a7,0xda85fced9bd193526b7667f2ad1fd4a0f900d3a7,ProxyFactory1967,1,1,14294877,9223372036854775807,true,14294877,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x1a30c8ca34283aa6a8722d626c290a575108a1e4d7d018db6faf46c77e1f19a3,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,StakersDistribution,gooddollar_owned,published+registry,0x5766cf4b2fdb09d986eb1783d276013c224e28c8,0x5f78ed3a4fdde9e9d91d3707a847fb4ad820ce26,StakersDistribution,1,2,14338550,22165594,false,14338550,etherscan_v2_getcontractcreation,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x23c18a3cc25e04ccd645243059a51da30d3ed25a321c6997f8db86ef90573106,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,StakersDistribution,gooddollar_owned,published+registry,0x5766cf4b2fdb09d986eb1783d276013c224e28c8,0x92c69a12c2ffc54afcfa320be7305ffd0f5782e0,StakersDistribution,2,2,22165594,9223372036854775807,true,14338550,etherscan_v2_getcontractcreation,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xdb6b68ed9eb7db3045bc8fdf06a2da5d34164ff07e810f4e5c270cbdd24d479b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -ETHEREUM,1,StakingContracts,gooddollar_owned,published,0xd33ba17c8a644c585089145e86e282fada6f3bfd,0xd33ba17c8a644c585089145e86e282fada6f3bfd,GoodCompoundStaking,1,1,13701103,9223372036854775807,true,13701103,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x80648f5b74b165322f61c0e45e315077d1eb8776607f893ce654bbc483382c54,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,StakingContractsV2,gooddollar_owned,published,0x02416eb83cff1f19163f21010149c3867f3261e1,0x02416eb83cff1f19163f21010149c3867f3261e1,GoodCompoundStakingV2,1,1,14132483,9223372036854775807,true,14132483,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x19d236ce0180396e675601e31fe953bba57e046cfcfee783c621862b4696e065,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,StakingContractsV2,gooddollar_owned,published,0xf4c34bed7dd779485692bb1857acf9c561b45010,0xf4c34bed7dd779485692bb1857acf9c561b45010,GoodAaveStakingV2,1,1,14132483,9223372036854775807,true,14132483,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x6d7aa6e4422780f33acf8093fdbe3669832ad519486c8396b7320ba429c62497,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,StakingContractsV3,gooddollar_owned,published,0x3ff2d8eb2573819a9ef7167d2ba6fd6d31b17f4f,0x3ff2d8eb2573819a9ef7167d2ba6fd6d31b17f4f,GoodAaveStakingV2,1,1,14338483,9223372036854775807,true,14338483,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xcce057daa357d310d82f1bba3c24f93cb7c7b0d8d00d185c1c8395abbbaf036b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,StakingContractsV3,gooddollar_owned,published,0x7b7246c78e2f900d17646ff0cb2ec47d6ba10754,0x7b7246c78e2f900d17646ff0cb2ec47d6ba10754,GoodCompoundStakingV2,1,1,14338454,9223372036854775807,true,14338454,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x581fa12f95a355336e4fff7a6b5a324f6f93c8c1de4c4e0a3d839c3d8219db04,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -ETHEREUM,1,UBI_RECIPIENT,gooddollar_owned,registry,0xd253a5203817225e9768c05e5996d642fb96ba86,,unknown,1,0,,,false,,"not applicable, no code is deployed at this address",no_code_deployed,none,none,none,,no_code_at_pinned_block: A published artifact or the registry names this address and nothing is deployed there,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,read at block 26041882 -ETHEREUM,1,UNISWAP_ROUTER,gooddollar_owned,registry,0x7a250d5630b4cf539739df2c5dacb4c659f2488d,0x7a250d5630b4cf539739df2c5dacb4c659f2488d,UniswapV2Router02,1,1,10207858,9223372036854775807,true,10207858,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xa324bc7db3d091b6f1a2d526e48a9c7039e03b3cc35f7d44b15ac7a1544c11d2,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882 -FUSE,122,AdminWallet,gooddollar_owned,published,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,0x832548c789ea71cae69f562476e9978d77e36c70,AdminWallet,1,6,18838651,22038689,false,18838651,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x66b4691f8dbbbeca25c2d211e9956b11f70436b977606825e22ad57175b4ee1a,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,AdminWallet,gooddollar_owned,published,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,0xeed7ecf710aa2cf1c15dcdba29de8655a384e299,AdminWalletFuse,2,6,22038689,25360323,false,18838651,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xa64b2065c3bdea43c0c94eef6982542b4546f32b6e6dea99c2d86643d9a2c6a9,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,AdminWallet,gooddollar_owned,published,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,0xdd107728aa2445166942837a7338c157065bd8c8,unknown,3,6,25360323,25360565,false,18838651,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0xd5b671d4e75d1403bdf6c0aa6dcfba8c5373ac9b165ef9ec4aa7c1bd16c640d0,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,AdminWallet,gooddollar_owned,published,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,0x44035ca8d61472adbfb9dc6a7fdcc6af9d1f7f0a,unknown,4,6,25360565,25361140,false,18838651,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0xe65c8d986b9ae0135ea86a802c94ae2cf27da0ddaffae8ba2256d4194ed8fda1,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,AdminWallet,gooddollar_owned,published,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,0xa9133a3d11bc39eb4d65e6de44fe9ceac3c71f54,AdminWalletFuse,5,6,25361140,38833573,false,18838651,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xf1d2b5dd090e70e6c85fa5b55ff2df42f4c12e54e6b7368ae08768d2f9c52120,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,AdminWallet,gooddollar_owned,published,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,0x7ac74c2c00b1e403a2d9972b8fdb237ebeffb901,AdminWalletFuse,6,6,38833573,9223372036854775807,true,18838651,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x0e5dcba485a857f32569ff106b8bbd663daa48097d326d5f7684bf37693f93df,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0x7ac74c2c00b1e403a2d9972b8fdb237ebeffb901 -FUSE,122,AdminWalletOld,gooddollar_owned,published,0x9f75dacb77419b87f568d417ebc84346e134144e,0x9f75dacb77419b87f568d417ebc84346e134144e,AdminWallet,1,1,6246332,9223372036854775807,true,6246332,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x6b4b178e5e2f68c4ec1500db73eb9c44faf11b3f88fc30937180ff7d1f771062,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239453 -FUSE,122,Avatar,gooddollar_owned,published+registry,0xf96dadc6d71113f6500e97590760c924da1ef70e,0xf96dadc6d71113f6500e97590760c924da1ef70e,Avatar,1,1,6246330,9223372036854775807,true,6246330,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x8a27316984da83331e574723efd0810faf4d7065f3037b8778d9c572ea49c6d8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239459 -FUSE,122,BulkWhitelist,gooddollar_owned,published,0x3b0f4974eb53fe7ca16ac311ebf1cd183d7d63cd,0x3b0f4974eb53fe7ca16ac311ebf1cd183d7d63cd,BulkWhitelist,1,1,30846522,9223372036854775807,true,30846522,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x60344a20cbd88bedbfd88cec885b62ad50c025de6de11abf30abf652d86ebbc4,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239453 -FUSE,122,ClaimersDistribution,gooddollar_owned,published+registry,0x1ae4929090258a9d5000d98cfb8a27174d345834,0x264adea794247a7e4dc216c7ca2f1429e3af54a9,ClaimersDistribution,1,1,15740398,9223372036854775807,true,15740398,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xa768b8e29028527a8ad81974daa5507bd4ec7e38f2aba2981664a518953fb852,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0x264adea794247a7e4dc216c7ca2f1429e3af54a9 -FUSE,122,CommunitySafe,gooddollar_owned_safe,published,0x5eb5f5fe13d1d5e6440dbd5913412299bc5b5564,0x5eb5f5fe13d1d5e6440dbd5913412299bc5b5564,GnosisSafeProxy,1,1,15067222,9223372036854775807,true,15067222,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239453 -FUSE,122,CompoundVotingMachine,gooddollar_owned,published,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,CompoundVotingMachine,1,2,15740389,34980099,false,15740389,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x2e33bb42b9056732aba2fdd606e3427c3b67c927947fd39a8b11c7ce0d8b4ea7,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,CompoundVotingMachine,gooddollar_owned,published,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,0x9373046bbc6d381129b49ac3334881390df1cb13,CompoundVotingMachine,2,2,34980099,9223372036854775807,true,15740389,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x348bfbd3bd8c8386b1b1bd205380278b7efb71070ceb110cc8dafffb5a0748e9,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0x9373046bbc6d381129b49ac3334881390df1cb13 -FUSE,122,Controller,gooddollar_owned,published+registry,0xbce053b99e22158f8b62f4dbfbede1f936b2d4e4,0xbce053b99e22158f8b62f4dbfbede1f936b2d4e4,Controller,1,1,6246330,9223372036854775807,true,6246330,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x1cce4814ac502cec7e982e73d29bdc95e9094476ba971b6777f8abd4a415fc26,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239459 -FUSE,122,FirstClaimPool,gooddollar_owned,published,0x18bcdf79a724648bf34eb06701be81bd072a2384,,unknown,1,0,,,false,,"not applicable, no code is deployed at this address",no_code_deployed,none,none,none,,no_code_at_pinned_block: A published artifact or the registry names this address and nothing is deployed there,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,read at block 44228002 -FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,uninitialised,1,12,9287140,18632009,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0x7a73f1fa2d9d24b6e8b02aae83eb348d51440623,FuseFaucet,2,12,18632009,18632133,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xa550b4543e2d05be80f569cbc0da17bb404d897f4609b7bf14c33aa0c2774bdc,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0xbded8cf5629732956d58d85b6cc619d83778a226,FuseFaucet,3,12,18632133,18632465,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xba02cd4c27b29b745d4a2ba2436a2ce5b17105fff5ca296a9758e2ca9a58ad34,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0xc9f33d360ed722fb8f26209b402b58494ef8f54b,unknown,4,12,18632465,18632495,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0x39a2ce0c262ea1305f3d2262e66a7818ee30e6d2d15bfadcd988c6b6c09bda9f,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0xc0753ae7d5e010083035090b405110ed8323d07e,FuseFaucet,5,12,18632495,18839080,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x72d4da8afd26f9a92ad5d8d4b9f266b8dfb96dd1489ef6a097fc9fb97b8558c4,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0x6c8efc4ab75b834ee9e7f2d9fa96b09724fbf4d3,FuseFaucet,6,12,18839080,18845979,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x49d2add807ef458e4f02bc0e8c8582a11b0daec746d2a66055e71f7001c6bdd1,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0x06b5b324baa4e7d1c9a8137f0e82ebb780b3570e,FuseFaucet,7,12,18845979,22038735,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xc94d58b41bcdb02ddc252624b2acc79db4ddb6eeced07ca4a01dd2d9ba65ba87,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0x6ba541e6f4e7df758b98d0117c6ccd353eccc728,FuseFaucetV2,8,12,22038735,22880830,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xcf67b2cd16ce05fc9a29179de4b0268c573abbcfc925548b92f0f9e3d7a1b570,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0xa528531d648cfb3cda91cda71c7ec6a172bcbd04,FuseFaucetV2,9,12,22880830,24304872,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x1bb2ff96e0e4302438331fbceae937a1f6291f4bf69cc490dbb2a4b87e51aaa7,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0x2e4fdb111b46a15987c275d8472d51bfb16597c5,FuseFaucetV2,10,12,24304872,38606265,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x12eaef1325c901bfe07bffcc431c027734f0a56617d3b0fcaff3e4668c232dad,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0x49ddbcc575c0a813a453fe4466e5a08449bd533d,FuseFaucetV2,11,12,38606265,38607227,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x194cf0e8579c60f4ba5c61e5eda5f1dc0c21e169f446a35c8d082d7c6e78d2e5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0x6b7405c75d461237fc89dac475dcbfbe1459f10f,FuseFaucetV2,12,12,38607227,9223372036854775807,true,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x93ae3699136504d4e9a3598e91dd3e7b0a849299e9015f5787214959e897df4b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0x6b7405c75d461237fc89dac475dcbfbe1459f10f -FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0xa199f0c353e25adf022378b0c208d600f39a6505,uninitialised,1,16,8815068,8824926,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0x9f9ff3720dba5f0e67e28ecfba5e433b0d271204,FuseStakingV3,2,16,8824926,9471687,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xd4c46219d523a73f3cb19758721142cce51552ac0ba44d5cb62b758f185a2f2a,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0x7fca2b3e1047291f65c2c914083d970c027f4290,FuseStakingV3,3,16,9471687,11531487,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xa676484e5aee5866227ccf5d6002f08449eb8fcc942ccd328008d8c68e4919c8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0x1e3a43799b4e68c7d872ebece91a6389c0d8844c,FuseStakingV3,4,16,11531487,11614374,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xb7b3c3278570684855b5b3f65dde9c00fbb99d30704702133296f919aa3149d0,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0x8141208203c298f07ddcd794b14722e69aa42549,FuseStakingV3,5,16,11614374,11850342,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x49998619549fd712f25d82ef5ccf804c2625b6eeaa49ba51c9f4a1e7e01b8516,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0xfda6a8aee1a909e1cc7da28b34f61b32e4e9a74a,FuseStakingV3,6,16,11850342,11868104,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x9f5cab50812967e338ad9b7ffbcc4a5bf1c079523dca773b39f7bba3c88e23c2,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0xd980a608abd9566c87bb4e60302259858766b996,FuseStakingV3,7,16,11868104,11868821,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x33617b9c20ab11715c1c20bc5e003962eaa505d2efc02786284c7c169cef2cd5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0x53f650758deff504f4e5a327f11f44275a710aa9,FuseStakingV3,8,16,11868821,11869054,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x44f7c970e0af4baafbecaf6da425541b537113e37a46484bcbc40c04a57db7b7,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0xbd1f52ab9f30483796d33fa7a4e7371b043dbbe6,unknown,9,16,11869054,11869227,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0x5850debc7391a2be27ce29315d9ce94d81da3050a01314ea9e5c4a53c0152642,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0x2560f53027fd1800174f842f071abd52521f0807,FuseStakingV3,10,16,11869227,15989875,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x16efe88328a1b5f228c9940964e941179d0d13099492ef5b8a448c68edaaf54b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0xf2c42adcc899871f1a8aa1a313702b4e7ebff9f5,FuseStakingV3,11,16,15989875,18632672,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x3f65eda9b2f53a0a631162bc7f21f9b69535f9899677e71cf1a7ccf127d4f028,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0x2e15da5e7b0c9861272912454f2382949beca07c,FuseStakingV3,12,16,18632672,18633445,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xbacf533d1ebe195b54f0f6de8109fe90d4927097656c39b7108625d7b7ca9899,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0xb51ed83bd8329ab1712a4698864e6d2871c38fc7,FuseStakingV3,13,16,18633445,20715888,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xaf26d0e166dda1de9e5e962c47a23e4f191a347dd2438fed2b5da341d5889012,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0x720d18ebeac3326098b96201ffe32b580508d018,FuseStakingV3,14,16,20715888,24976379,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x5c196350dbe9eb2637e70a35cc66037e56863c9f97156a0a692265f80dfaeb2e,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0xe2491656c5657b87b09e5adea27bd637a8953395,FuseStakingV3,15,16,24976379,27047375,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x3119ba292007d0b3d540a4d4e064aef8af1ca2456668bf92957250afa3c56e82,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0x7c723bbeb808b74fb63fc1cb09ffa43d66a96390,unknown,16,16,27047375,9223372036854775807,true,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0xba742d73273e51079257a3e68f403e661e886ea6e32afb7dbfe9a2282b0a6953,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0x7c723bbeb808b74fb63fc1cb09ffa43d66a96390 -FUSE,122,GDAO_STAKING,gooddollar_owned,registry,0x280226a143b7dfdf84645006e32f899b531c2f98,0x280226a143b7dfdf84645006e32f899b531c2f98,unknown,1,1,15747396,9223372036854775807,true,15747396,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,none,0x5e11c717620e654220b2a30bb69874f18bbbc438cfbebbc60ff05a9c33803614,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239453 -FUSE,122,GoodDollar,gooddollar_owned,published+registry,0x495d133b938596c9984d462f007b676bdc57ecec,0x495d133b938596c9984d462f007b676bdc57ecec,GoodDollar,1,1,6246330,9223372036854775807,true,6246330,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x554945bfa422af5800554ef7b37f229465f13208db908d482249f1dd9803a3c0,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239453 -FUSE,122,GoodDollarMintBurnWrapper,gooddollar_owned,published+registry,0x031b2b7c7854dd8ee9c4a644d7e54ad17f56e3cb,0x716031ae7db1a5c07b24ed3b651d5f57945e1ac3,GoodDollarMintBurnWrapper,1,1,22035558,9223372036854775807,true,22035558,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xa2822dc882ca15bfae3ad35a44bd5129746267dec37a19844bb2f59675aec288,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0x716031ae7db1a5c07b24ed3b651d5f57945e1ac3 -FUSE,122,GovernanceStaking,gooddollar_owned,published,0xfaf457fb4a978be059506f6cd41f9b30fca753b0,0xfaf457fb4a978be059506f6cd41f9b30fca753b0,GovernanceStaking,1,1,14149736,9223372036854775807,true,14149736,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x2d112154566a9ba4f271ef486aa2f5dd6843e134d03e7aa456359d12325f849d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239459 -FUSE,122,GovernanceStakingV2,gooddollar_owned,published+registry,0xb7c3e738224625289c573c54d402e9be46205546,0xb7c3e738224625289c573c54d402e9be46205546,GovernanceStaking,1,1,15956809,9223372036854775807,true,15956809,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x813356a3f27cf275db45b87b8823a3d9fb90534dbf0749962fd57c95fca57e61,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239459 -FUSE,122,GReputation,gooddollar_owned,published+registry,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,0xdeef7c187a9e254ded7b503ac5703adc7b3b15e6,GReputation,1,3,15740330,15890735,false,15740330,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xbc782ccf8b3bd3538e5e81fb0cd55832a712f5bc83dd0693b7e7e4bf7ec5657d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,GReputation,gooddollar_owned,published+registry,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,0x418accc2e62cc3745d67ef6b779c441ff223fc27,GReputation,2,3,15890735,22365120,false,15740330,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x0d4bf8c2025617b7d7d51131e6c74eb95e48f4dfa9f6b58688badd38c1c12bc8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,GReputation,gooddollar_owned,published+registry,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,0x2845b2ff94d01355bdf5bab2333a5c173a803c3d,GReputation,3,3,22365120,9223372036854775807,true,15740330,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xbe55b28d2684d22fe78fad3d4b2357fef68796bc17eecc548e673d8b91798a8e,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0x2845b2ff94d01355bdf5bab2333a5c173a803c3d -FUSE,122,GuardiansSafe,gooddollar_owned_safe,published,0x5878123fe880881f1ecc92d5fd31e5d3f5fba2e9,0x5878123fe880881f1ecc92d5fd31e5d3f5fba2e9,GnosisSafeProxy,1,1,20403981,9223372036854775807,true,20403981,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239453 -FUSE,122,HomeBridge,gooddollar_owned,published+registry,0xd39021db018e2caeadb4b2e6717d31550e7918d0,0xd39021db018e2caeadb4b2e6717d31550e7918d0,EternalStorageProxy,1,1,8028888,9223372036854775807,true,8028888,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x2d05a6bd0ad793d9459975bf7760dcbfefa24baf8c7f70efa4aab6b52db668bb,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239459 -FUSE,122,Identity,gooddollar_owned,published+registry,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,0xf36b3394235965aa0605fb09eb319eb3586c9ed1,IdentityV2,1,4,22022901,22365120,false,22022901,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x4f2dde9da36f569ba703900471653202ceb84560492a6843cbae6909a9e0dfe9,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,Identity,gooddollar_owned,published+registry,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,0xc1956c99fd3209e30c0746dfd4d4f11d03cc0e9a,IdentityV2,2,4,22365120,38729068,false,22022901,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x004e7e548478ce0b95023a5c5c1f6b47db746932cb69b4ea1d8fc0d8fce9c843,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,Identity,gooddollar_owned,published+registry,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,0x4111a54797e11043def22c4a0240e1605fd7b719,IdentityV3,3,4,38729068,40887165,false,22022901,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x5055517bed3931aaf7fdba386b96fd4047da82a04291aa8c3fae3ee9a3811a27,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,Identity,gooddollar_owned,published+registry,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d,IdentityV4,4,4,40887165,9223372036854775807,true,22022901,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xb88131c06ca0eacac2f89760bcdfb43e25c34ce0a0a80b5a7d6f0cb66995e93c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d -FUSE,122,IdentityOld,gooddollar_owned,published,0xfa8d865a962ca8456df331d78806152d3ac5b84f,0xfa8d865a962ca8456df331d78806152d3ac5b84f,Identity,1,1,6246324,9223372036854775807,true,6246324,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x83c740a8ac588a566556553a334afdfded5add581f27efc0215d3ccfd842eaad,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239459 -FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,uninitialised,1,13,8853311,9117508,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0x0e9c269afd9ee20a349507c61092f58a636a1ed3,InvitesV1,2,13,9117508,11656836,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xfbeb86b2899df3187344633457846e24a96059037e85ae12ee4e86d19d3e4344,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0x0c8e02371de8c6ec3a261bd24a419beb19171558,InvitesV1,3,13,11656836,14140137,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x9f67a124f4c0343d454188abf9e0f52e163413efd83de49e16ac58ced2205115,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0x1394a4658f88e40a6f7673136f533157dfb6ba20,InvitesV1,4,13,14140137,14208467,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x621d961ddc680d661939a30bed3d20b84d95b555dc153930c7770c6775278f74,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0xdd45a44f2e11fb95d1be4ac41501ca0b8cd60de7,InvitesV1,5,13,14208467,16820893,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x6c2bbf91f0f6e7c0370a02ac530857699d87c4ab4981bf910c2b09d5c3c1c8d7,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0xd97ecd0487293e0e2b0b52f37eeb2951d69d43f0,InvitesV1,6,13,16820893,16821011,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x6aebe73bfaff44b2528c9143aa08ed9e1e1e4e221283b2ee227b06912150f1ab,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0x3ac09cfaa27c830693c55d5454ca39ced7b9cf3a,InvitesV1,7,13,16821011,22038741,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x5bb2bc7ec822c0ef08bb205d62c6d58f1dd3bc0456401ddca6bb10a299d350ea,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0x4461384c11a73948ab62fd489478f7bbc3166528,InvitesFuseV2,8,13,22038741,22592960,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x7f8487911e5572fc99bad7bb765a3407aff0745246d320a31e8b5618966e3e04,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0xc5a2c8c6dbac1f1c934f9651733758ff3ba06345,InvitesFuseV2,9,13,22592960,22810725,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xbecdca30eb58e2a3bc2719c1829409b4fff6044fa88d5bab869382dac185ac73,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0x618dc4c8f5aa433b6c8e03da1e69d299c6c49ef6,InvitesFuseV2,10,13,22810725,24219845,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x5297a1637435daa8cf4a158b7563506883c6ddffb65ffac0460c3e2df124da05,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0x4072cb2d7e95def1559f6f72491039fe0534fa37,InvitesFuseV2,11,13,24219845,25470784,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x6b19fd3a33c6bbe6439c35d77bdb8c10a43bf746b45f034d4241d22f8f4c0453,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0xef577898972e72c7bc03791d22f79c0056917517,unknown,12,13,25470784,25470814,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0x4d6d28c57b14136bfc1ee4e0eedcb8767c6d91b05fa14abad67006c0fac6722f,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0x502aa6663621759d299f15bd967d53431daa9503,InvitesFuseV2,13,13,25470814,9223372036854775807,true,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xddbdc81478111ab6a561e0e747fc450e1d33930594566ffd7f3526168c74b222,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0x502aa6663621759d299f15bd967d53431daa9503 -FUSE,122,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,uninitialised,1,6,25464921,25464924,false,25464921,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0xd3b5bfdacb042a89bbabad2376aa1a923b365a14,MessagePassingBridge,2,6,25464924,34980099,false,25464921,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x708c90e202c4b8508c0c7ade2ea51ebfc5ec98b2f7ff38060bb2490c8823124e,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0xfcd61ccb982ce77192e3d18a5ae3326dce0b6874,MessagePassingBridge,3,6,34980099,38729068,false,25464921,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xf68c6a526808dc147f00d3f891c6f32a37abeaeb4332cc83fde6ba1fd6e0e240,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x6f252280eb53df085ead27bbe55d615741a8268d,MessagePassingBridge,4,6,38729068,39455704,false,25464921,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x5046d22320e05430d464b6c2f01533594448d625c0c6554a3f5529895c582d49,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0xfb62aa509a7b260b6697b671c969a184d6c39e90,MessagePassingBridge,5,6,39455704,40887165,false,25464921,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xbe09161676ba22506d184c3b979a289bec312079fc94c338763b5431a0def5bd,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0xcac4215c57ef199210e759af92bcad012f61e7a1,MessagePassingBridge,6,6,40887165,9223372036854775807,true,25464921,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x186ca006b94443015386d2fb2eccec5b0932885d174449a97dd1b54900041b3b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0xcac4215c57ef199210e759af92bcad012f61e7a1 -FUSE,122,MultichainRouter,third_party_infrastructure,published,0x735abe48e8782948a37c7765ecb76b98cde97b0f,0x735abe48e8782948a37c7765ecb76b98cde97b0f,AnyswapV6Router,1,1,21863761,9223372036854775807,true,21863761,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0xc309902226a63a7279065be321792f1669adb7b0c96a2909e587aafcb59715ee,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239453 -FUSE,122,NameService,gooddollar_owned,published,0xec6dce387b1616a0c44ff2e4fa9e90e53cf14eb0,0xba3f1ba4eb215204385107e76c11894b876ecf40,NameService,1,1,15740314,9223372036854775807,true,15740314,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x14430756d9064b0f9d3f50f024ec5de5fcef5dcaa35d6c79da463848fb687aa3,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0xba3f1ba4eb215204385107e76c11894b876ecf40 -FUSE,122,OneTimePayments,gooddollar_owned,published,0xd9aa86e0ddb932bd78ab8c71c1b98f83cf610bd4,0xd9aa86e0ddb932bd78ab8c71c1b98f83cf610bd4,OneTimePayments,1,1,6248705,9223372036854775807,true,6248705,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0xe7a0e7797844d5adccfdac8ad5cec77c4c9484ada37964b99178f29a4265132d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239459 -FUSE,122,ProtocolUpgradeFuseRecover,gooddollar_owned,published,0xbe43ecb37af7f7c4a8606e672c504be55fc6226b,,unknown,1,0,,,false,,"not applicable, no code is deployed at this address",no_code_deployed,none,none,none,,no_code_at_pinned_block: A published artifact or the registry names this address and nothing is deployed there,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,read at block 44228002 -FUSE,122,ProxyAdmin,gooddollar_owned,published,0x57179b2a8eb019157b0c3e761cdb26c82c982a3b,0x57179b2a8eb019157b0c3e761cdb26c82c982a3b,ProxyAdmin,1,1,8815067,9223372036854775807,true,8815067,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x2b57f0728a5ffe03a475faab83005c468d0f669c0a473f87425e3edb6101ec8a,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239453 -FUSE,122,ProxyFactory,gooddollar_owned,published,0xda85fced9bd193526b7667f2ad1fd4a0f900d3a7,0xda85fced9bd193526b7667f2ad1fd4a0f900d3a7,ProxyFactory1967,1,1,15740066,9223372036854775807,true,15740066,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x1a30c8ca34283aa6a8722d626c290a575108a1e4d7d018db6faf46c77e1f19a3,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239459 -FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0xfaa48a6b603985a507f18ad7f453f784f1faa025,UBIScheme,1,13,15747401,15748014,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x26e78908c4cd0f264d2e1d3b0dbf5a7bd6e299f0dd31bc7a9dd1c9e67a81af16,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0xf288e44c7e5baa05b2de9d916e53b67c183e46e0,UBIScheme,2,13,15748014,15750751,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xf628c8c1cf0d0d53ec9c88e85dfb422ffc89839541a89fac1efe9c0f2ae3dd37,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0x0d7014649e6f5979d2a09a3d3ad2d3ae3eefb42e,unknown,3,13,15750751,15750869,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0x670e3daf264fd6c903e42b79bf8ccc5e76dcf5dc5513430d325dc3d43edb9c1c,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0x8294378a45b52389d45b623d0191f7285f4f047f,unknown,4,13,15750869,15750920,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0x3129f20edac3fba2d1542b9dac36cff87ee84fbea1be91bccd2b57d2228469d9,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0xa99ba154223052b8c5fd92b3f5df9eb08b72d5fc,unknown,5,13,15750920,15750929,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0x3bf18751bd05d7d99b711df861d2e6d3b5c2906bf8a92a9421bb58b30438007e,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0x8294378a45b52389d45b623d0191f7285f4f047f,unknown,6,13,15750929,15751049,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0x3129f20edac3fba2d1542b9dac36cff87ee84fbea1be91bccd2b57d2228469d9,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0x76eb96616514adac35152155bbc614272f0601b3,UBIScheme,7,13,15751049,17896941,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x678b37494b483f090daecee4968024b0b4f3f6db76535944386d9888832377d0,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0x11f077ae87952948de96b975a805ebaa20eada12,unknown,8,13,17896941,17913778,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0xadd201c864e8059b8c41a9ad02cc803533813245ef715215bf5f9334da97391f,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0x306cd90bfefb7e409f089a1bde1aa77bbc4cb660,UBIScheme,9,13,17913778,17913899,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x1639c60ee4892fbabcfd640f63fb854c7888f340eb2ef9d2b3dcd2996dae01a5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0xb22764dce0960b61c5a8d688f075857632917a93,UBIScheme,10,13,17913899,17927761,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x75360d28f3bde7f7e61b820000583ffeacfa138af7360b858b4d4ad0c61f069e,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0xbb6dff610ecbea25a6c57b086ef92c6724306a76,UBIScheme,11,13,17927761,25635053,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xa2242ec4a9520cb7f7a978505ed5821044cc7a5cfbcee7138618130510da306d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0x1c90f733e1724bd1db47f84cde4f9e83087cfb6d,UBIScheme,12,13,25635053,38729068,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xff3d518029b7db924159838cb0e890a960865d2861529e2208f87efdcc373d98,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,UBISchemeV2,13,13,38729068,9223372036854775807,true,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x409fd8ecff99ab5fb8082d4f683259854d7ee0af6b66ce8c5dab16ecd3a2f47b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961 -XDC,50,AdminWallet,gooddollar_owned,published,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,0xa7f4717bf6e7d27d7c855d5f4a869e96bd16d873,AdminWallet,1,2,95144743,95866130,false,95144743,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x9e231a1f32074c2535d1793d1a863dbe4ddb5438f6f6ef526fd87ab683dff181,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,AdminWallet,gooddollar_owned,published,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,0x68dbe795ee2219437299bb23d70311e3b7c69f9a,AdminWallet,2,2,95866130,9223372036854775807,true,95144743,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xb18bdf42222c3100c99f40bbb2fe56734e863977f1beebe0527148d2b44b70b5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,Avatar,gooddollar_owned,published+registry,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,Avatar,1,1,95143598,9223372036854775807,true,95143598,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x8a27316984da83331e574723efd0810faf4d7065f3037b8778d9c572ea49c6d8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851 -XDC,50,BulkWhitelist,gooddollar_owned,published,0xe8861a20452db53df685f1d9e6b7017de3db0e46,0xe8861a20452db53df685f1d9e6b7017de3db0e46,BulkWhitelist,1,1,97033779,9223372036854775807,true,97033779,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x554fc53842f02a76351be11bad71cbd6ff31cbd4a8b4c0513f068e12527fb720,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851 -XDC,50,Controller,gooddollar_owned,published+registry,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,Controller,1,1,95143598,9223372036854775807,true,95143598,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x1cce4814ac502cec7e982e73d29bdc95e9094476ba971b6777f8abd4a415fc26,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851 -XDC,50,CUSD,third_party_token,published,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,FiatTokenV2_2,1,1,92678020,9223372036854775807,true,92678020,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x231f4b29fe5be8f3ae57a88ce9c67fed31128c6588cd35e4da397f04f6cbc1c3,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,zeppelinos pre 1967 slot -XDC,50,DAOCreator,gooddollar_owned,published,0xa2b9993d198904e4bdce48379fdff65405607f42,,unknown,1,0,,,false,,"not applicable, no code is deployed at this address",no_code_deployed,none,none,none,,no_code_at_pinned_block: A published artifact or the registry names this address and nothing is deployed there,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,read at block 107576851 -XDC,50,DistributionHelper,gooddollar_owned,published+registry,0xb8a0d4b97327a0b6dd0705dc290ae26aa38a7d2b,0x971fdacd201cdaa741db06d580eb634b02307926,GenericDistributionHelper,1,1,100111925,9223372036854775807,true,100111925,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x409c0dc6ff42f770c99147d26af9e12a6f90e807bf198937bfe5a59f0179116c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,Faucet,gooddollar_owned,published,0x7344da1be296f03fbb8082adac5696058b5a9bd9,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,Faucet,1,3,95144750,95325786,false,95144750,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x3072e58a72b2536637e3827c180dc2763faaeb267035deec1436b343afedb4c6,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,Faucet,gooddollar_owned,published,0x7344da1be296f03fbb8082adac5696058b5a9bd9,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,Faucet,2,3,95325786,95327264,false,95144750,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x68755099f25764af194ff16c1f4a6fd14bdd4bd89a1c3f6832649a36508e6533,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,Faucet,gooddollar_owned,published,0x7344da1be296f03fbb8082adac5696058b5a9bd9,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,Faucet,3,3,95327264,9223372036854775807,true,95144750,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xe8429a22753ce3f82c856a7f5dee88264782d956d615db983d0cd5ec8e9fb325,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,FeeFormula,gooddollar_owned,published,0xf4e9af892a09f04b7408266777198206e7f80d46,0xf4e9af892a09f04b7408266777198206e7f80d46,FeeFormula,1,1,95143060,9223372036854775807,true,95143060,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xb10599b90c45878333139dfa098974b8df30eba5596654ef05c46daa2a6f0847,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851 -XDC,50,GoodDollar,gooddollar_owned,published+registry,0xec2136843a983885aebf2feb3931f73a8ebee50c,0x0000000000000000000000000000000000000000,uninitialised,1,3,95143070,95143245,false,95143070,explorer_index_and_state_read_agree,bisection_and_announcement_union,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,GoodDollar,gooddollar_owned,published+registry,0xec2136843a983885aebf2feb3931f73a8ebee50c,0x6936441113610483cc5b6a7adec4b45303b297a9,SuperGoodDollar,2,3,95143245,107529281,false,95143070,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,etherscan_v2_verified_source,0xf1ef96de94aefc5848537637a56767402734cf35f4763e1f4e326c3e56ee457a,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,GoodDollar,gooddollar_owned,published+registry,0xec2136843a983885aebf2feb3931f73a8ebee50c,0x1db2f592014a9394604bf6381f025754579547ec,SuperGoodDollar,3,3,107529281,9223372036854775807,true,95143070,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x2157adffb2622cfac69e299e2de636551391eddba892b5dd0c1b9f6469bb38f5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,GuardiansSafe,gooddollar_owned_safe,published,0xe0c5daa7cc6f88d29505f702a53bb5e67600e7ec,0xe0c5daa7cc6f88d29505f702a53bb5e67600e7ec,GnosisSafeProxy,1,1,95134102,9223372036854775807,true,95134102,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851 -XDC,50,Identity,gooddollar_owned,published+registry,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,IdentityV3,1,2,95143058,100340676,false,95143058,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x01ec062dc685b7aec5b7e7574302648c016d25423b86a8a999cbf05ee6ed3a85,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,Identity,gooddollar_owned,published+registry,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,0x28830934ad2146e7a273fd394f706571c2d09373,IdentityV4,2,2,100340676,9223372036854775807,true,95143058,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x307c50e010de98eed4870743567fd1ad954811f59b99752b709dc18bbf868eab,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,Invites,gooddollar_owned,published,0x6bd698566632bf2e81e2278f1656cb24aaf06d2e,0xb22bb27d920a4efdafaa03a51e8a4c41e4cc4217,InvitesV2,1,2,95144756,100123036,false,95144756,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x5da156e5a7ff212885d03e8f52531c50f273d7b9410a07177379859562a5acc5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,Invites,gooddollar_owned,published,0x6bd698566632bf2e81e2278f1656cb24aaf06d2e,0x783548481a6ca92b6589365161b31e3ed64d0c3c,InvitesV2,2,2,100123036,9223372036854775807,true,95144756,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x9c0c0028170b3295f0555171e63b4150b56b7ec427b9f26eb0c21a8dd7662df5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,MentoBroker,third_party_mento,published,0x88de45906d4f5a57315c133620cfa484cb297541,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,Broker,1,2,100091095,100340676,false,100091095,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),bytecode_equality_with_celo_0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,0x58558a86a3aced5b23ae279244bd285f68c9d6d0a20cf283b7a40a0784697831,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"eip1967 implementation slot. bisection says 0xc22505d3a6ae087c0bd4715a56c38b7a029477b2, announcement says 0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2" -XDC,50,MentoBroker,third_party_mento,published,0x88de45906d4f5a57315c133620cfa484cb297541,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,Broker,2,2,100340676,9223372036854775807,true,100091095,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x2e63673ca3232bd818d12804ade7e1d688b7c11da7812d0237a3564e99cd0fb7,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,MentoExchangeProvider,third_party_mento,published,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,0xd9ce916d711977d5b27697a13964556b4fb8af1d,GoodDollarExchangeProvider,1,2,100091095,100340676,false,100091095,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x65d8c817bac8f41eb34548c15ad6ae5e744da2bd5373916df3b8e63f1fecd916,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"eip1967 implementation slot. bisection says 0xd9ce916d711977d5b27697a13964556b4fb8af1d, announcement says 0x66375ec587d8482d77cf7529a8479c3fa85c850f" -XDC,50,MentoExchangeProvider,third_party_mento,published,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,0xe930cde20f60d0a4fc9487874861ae259f5bed48,GoodDollarExchangeProvider,2,2,100340676,9223372036854775807,true,100091095,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x5ed71ccf7c4789f438827e074bc8bba84c7fc2c615495b12a2f9c51398a8b0d5,carried_from_seed: ExchangeUpdated event added. Not currently consumed.,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,MentoExpansionController,third_party_mento,published,0x5557e9def86ad6564462741a7a3f3679c1223f5d,0x7288d592e1b9013c668801f722be650993d2925a,GoodDollarExpansionController,1,1,100091095,9223372036854775807,true,100091095,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x9da4f4203282696d49deb0c241e49e0ff09f8b6da2d463f69f3fc98e66899a74,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,MentoProxyAdmin,third_party_mento,published,0x8471406c3bff67cc6538481c8550364bda6ca691,0x8471406c3bff67cc6538481c8550364bda6ca691,ProxyAdmin,1,1,98383258,9223372036854775807,true,98383258,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xdd44d5a52707f76ac1bb4147820056bd47ca2c90f79d82fdaeb19b7d180179b4,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851 -XDC,50,MentoReserve,third_party_mento,published,0x94a3240f484a04f5e3d524f528d02694c109463b,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,Reserve,1,2,100091095,100340676,false,100091095,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0xe5750e9acc0322eae552526478b90a1a762ea401bf9094ff36daa6d0e4669020,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,MentoReserve,third_party_mento,published,0x94a3240f484a04f5e3d524f528d02694c109463b,0xbdaa65e8175875340365d76a660bb2a7a4efe909,Reserve,2,2,100340676,9223372036854775807,true,100091095,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xe5750e9acc0322eae552526478b90a1a762ea401bf9094ff36daa6d0e4669020,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x0000000000000000000000000000000000000000,uninitialised,1,4,95254417,95254421,false,95254417,explorer_index_and_state_read_agree,bisection_and_announcement_union,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0xa7bfc0d36300b5978cfa18301446cad3e855ae06,MessagePassingBridge,2,4,95254421,96841591,false,95254417,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x039a036cd2a30cc1536d5b5a368c77e7bd870ae3d59c0b699dd5b51439b17838,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0xe4cfa18a3d0a7d77faa42961ee943c9221d61937,MessagePassingBridge,3,4,96841591,100340676,false,95254417,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xa5b7233c025a48d44655a945ead941546d2a69fad9cc2dec4c1a1ef033498a08,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x00f7f61080ef40d3832c8c06e8a2af757839e1f7,MessagePassingBridge,4,4,100340676,9223372036854775807,true,95254417,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xbacb5fa708349d8fba6d008557d8ed01abb888eb445b8d4bd1b2cceaef833d62,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,NameService,gooddollar_owned,published,0x1e5154bf5e31ff56051bbd45958b879fb7a290fe,0x653c67be5b3739708e84b61641253822405d78d8,NameService,1,1,95143608,9223372036854775807,true,95143608,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0xaa0ffd7041640c8b913e2b76301b0ffa064ee7a84aad1d43b631dac209b7f747,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,ProxyFactory,gooddollar_owned,published,0x5be34022c26fa03a8d6926314a42414c7ca2df51,0x5be34022c26fa03a8d6926314a42414c7ca2df51,ProxyFactory1967,1,1,95142721,9223372036854775807,true,95142721,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,bytecode_equality_with_celo_0xd86cd6bb3c2a576b2c2cef4e047b1a7adc5be62d,0x7f63d978bb61348d9321e9e9a382a2f88679edb38c483385333d4dbb0760fea9,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851 -XDC,50,StaticOracle,third_party_infrastructure,published,0x725244458f011551dde1104c9728746eebea19f9,0x725244458f011551dde1104c9728746eebea19f9,StaticOracle,1,1,93357551,9223372036854775807,true,93357551,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x511ddd7509fe316b6a954e51453cbfa51e42e7ab82becf2360066ddf1b2084fb,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851 -XDC,50,UBIScheme,gooddollar_owned,published+registry,0x22867567e2d80f2049200e25c6f31cb6ec2f0faf,0xea12bb3917cf6ae2fde97ce4756177703426d41f,UBISchemeV2,1,1,95249624,9223372036854775807,true,95249624,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x1a2a42df99ac104b92c4f611df6d9d8e136aecf0875ac9be4dd49ab1be300c5c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot -XDC,50,UniswapV3Router,third_party_infrastructure,published,0x3b9edecc4286ba33ea6e27119c2a4db99829839d,0x3b9edecc4286ba33ea6e27119c2a4db99829839d,SwapRouter02,1,1,59782347,9223372036854775807,true,59782347,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xec362365703d4ab51bd8adfb8f580413cba66e152720928a7c975d5197f2d07a,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851 -XDC,50,UniswapV3RouterOfficial,third_party_infrastructure,published,0xaa52bb8110fe38d0d2d2af0b85c3a3ee622ca455,0xaa52bb8110fe38d0d2d2af0b85c3a3ee622ca455,SwapRouter02,1,1,87230719,9223372036854775807,true,87230719,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x5a20e5e77f75c2bc855c4e93352437bfc53301ea95935350f2f4799e898ddd48,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851 -XDC,50,WXDC,third_party_token,published,0x951857744785e80e2de051c32ee7b25f9c458c42,0x951857744785e80e2de051c32ee7b25f9c458c42,WXDC,1,1,42776215,9223372036854775807,true,42776215,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x4e0fcac36e857c9408b310cc1b8dfe2c3e8aff8c199ea1df31c4ebdaccdcc57e,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851 -CELO,42220,UpdateReserveRatio,unclassified_pending_ownership_test,discovered,0x1f3d49414e4b7b32a5e23fbca71778df760d97a3,0x1f3d49414e4b7b32a5e23fbca71778df760d97a3,UpdateReserveRatio,1,1,61141715,9223372036854775807,true,61141715,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x83c1d603e8c3ed0dbd3a813582014dc03b823fa18aa71c5fa7786f5640837fff,ownership_unestablished: The verified source name references the GoodDollar reserve and the same creator deployed it on both GoodDollar chains but neither fact is a control relationship. What would settle it is reading whether the protocol Controller or Avatar ever granted this address a role or whether it appears as a caller in a reserve parameter change.,measured_2026_09_24_state_reads_at_a_pinned_block_two_endpoints_agreeing,omission found by factory enumeration and added 2026-09-24. NOT a proxy: EIP-1967 implementation beacon and admin slots and the older OpenZeppelin and EIP-1822 slots and storage slots 0 1 and 2 are ALL zero at the creation block at eight interior probes and at the pin with two agreeing endpoints on every read. Verified source names it UpdateReserveRatio and the index reports Proxy=0. ABI declares ZERO events so it contributes no event_surface row. Creation tx creator is 0x5128e3c1f8846724cc1007af9b4189713922e4bb on BOTH chains which is neither of the ProxyFactory addresses the earlier passes named. Identical runtime bytecode on both chains. slots read at block 78397063 -XDC,50,UpdateReserveRatio,unclassified_pending_ownership_test,discovered,0x2431f53afda24130722dbeb9f9b1b0b8d2fbb197,0x2431f53afda24130722dbeb9f9b1b0b8d2fbb197,UpdateReserveRatio,1,1,100111919,9223372036854775807,true,100111919,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x83c1d603e8c3ed0dbd3a813582014dc03b823fa18aa71c5fa7786f5640837fff,ownership_unestablished: The verified source name references the GoodDollar reserve and the same creator deployed it on both GoodDollar chains but neither fact is a control relationship. What would settle it is reading whether the protocol Controller or Avatar ever granted this address a role or whether it appears as a caller in a reserve parameter change.,measured_2026_09_24_state_reads_at_a_pinned_block_two_endpoints_agreeing,omission found by factory enumeration and added 2026-09-24. NOT a proxy: EIP-1967 implementation beacon and admin slots and the older OpenZeppelin and EIP-1822 slots and storage slots 0 1 and 2 are ALL zero at the creation block at eight interior probes and at the pin with two agreeing endpoints on every read. Verified source names it UpdateReserveRatio and the index reports Proxy=0. ABI declares ZERO events so it contributes no event_surface row. Creation tx creator is 0x5128e3c1f8846724cc1007af9b4189713922e4bb on BOTH chains which is neither of the ProxyFactory addresses the earlier passes named. Identical runtime bytecode on both chains. slots read at block 107626168 +chain,chain_id,contract_name,category,provenance,proxy_address,implementation_address,implementation_name,era_index,era_count,valid_from_block,valid_to_block,is_live,creation_block,creation_method,era_method,era_evidence,era_announcement_event,abi_source,runtime_code_hash,semantics_note,source,notes,boundary_completeness,boundary_evidence_manifest_hash,boundary_checked_through_block,frozen_safe_head,release_scope +CELO,42220,AdminWallet,gooddollar_owned,published,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,0xbfb5052aee113fc160c18ae85c9831dcd2b2fdc0,AdminWallet,1,5,18002976,21368263,false,18002976,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0xc67787fd2231f7326a2527db40332b920f33840fe942296e17be56f6125ac589,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,AdminWallet,gooddollar_owned,published,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,0x24614ad257f4d09fccaec024c65c40c060e73e9d,AdminWallet,2,5,21368263,21369184,false,18002976,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xe21dd06280946f5040f63cbfa0ea2b2e35e000ae528828935dbbaed0244177d7,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,AdminWallet,gooddollar_owned,published,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,0xae2cd2a9513215961d344a2581dcab678598eedf,AdminWallet,3,5,21369184,28227319,false,18002976,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xae2e0d5cd6fc590c4b6ce659efebd29bb417c359076b8ecd7ec4adf389379c00,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,AdminWallet,gooddollar_owned,published,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,0x703856db9a5432964f081ff4dc46480738fae7bd,AdminWallet,4,5,28227319,50872873,false,18002976,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xf15f2e31e0c7251bd3babc7f23dccff946ca6582daa5f0eee7e19d3424823619,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,AdminWallet,gooddollar_owned,published,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,0xfef0ef0916c5c7745b201dc9e2d04483b1eb36f1,AdminWallet,5,5,50872873,9223372036854775807,true,18002976,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x28708bf9f584205831cdf5ff571feb8c3fe60d1759a4edc4953eb2ffe8b88430,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,Avatar,gooddollar_owned,published+registry,0x495d133b938596c9984d462f007b676bdc57ecec,0x495d133b938596c9984d462f007b676bdc57ecec,Avatar,1,1,17237959,9223372036854775807,true,17237959,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x8a27316984da83331e574723efd0810faf4d7065f3037b8778d9c572ea49c6d8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,BulkWhitelist,gooddollar_owned,published,0x30afd0534daa29135308d048103b40dc1ba4518d,0x30afd0534daa29135308d048103b40dc1ba4518d,BulkWhitelist,1,1,26952390,9223372036854775807,true,26952390,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x60344a20cbd88bedbfd88cec885b62ad50c025de6de11abf30abf652d86ebbc4,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,BuyGDFactory,gooddollar_owned,published,0x00e533b7d6255d05b7f15034b1c989c21f51b91c,0x00e533b7d6255d05b7f15034b1c989c21f51b91c,BuyGDCloneFactory,1,1,21006324,9223372036854775807,true,21006324,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x047ee7c00427bb66d4412b5748c158d3a8e3330166dd6e5a849ec2e4d9fc728c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,BuyGDFactoryV2,gooddollar_owned,published,0x1f60c4c7037c6766924a43666b781ed1479587a2,0x1f60c4c7037c6766924a43666b781ed1479587a2,BuyGDCloneFactory,1,1,22909812,9223372036854775807,true,22909812,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xb0deea380b10aaab11e12102a20b31fa11fd7ddfbed72761ad30cd6933e143b9,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,BUYGDFactoryV3,gooddollar_owned,published,0xb1c87d3270d4a23bc1fcca8be53af11e4773d89d,0xb1c87d3270d4a23bc1fcca8be53af11e4773d89d,BuyGDCloneFactory,1,1,72905831,9223372036854775807,true,72905831,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x2c25daa8960a888e9b92aa463cfe8770a5b7afcf0d7359dcd1bf3b344c8be1a8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,CeloDistributionHelper,gooddollar_owned,published,0x6b845effaf36c374e8e7cf543efa680f2f71f098,0x6db04d771e2ba750effbbad59dcca20381efb1c5,CeloDistributionHelper,1,1,31415781,9223372036854775807,true,31415781,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0xa1a06f022a982744ad4a646f9ced63087f65f2b7d4e29c4e92345f2714abb030,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,CommunitySafe,gooddollar_owned_safe,published,0x437c699887779d0a95ad6349cfde7dfa716c005d,0x437c699887779d0a95ad6349cfde7dfa716c005d,GnosisSafeProxy,1,1,18862438,9223372036854775807,true,18862438,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,Controller,gooddollar_owned,published+registry,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,Controller,1,1,17237959,9223372036854775807,true,17237959,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x1cce4814ac502cec7e982e73d29bdc95e9094476ba971b6777f8abd4a415fc26,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,CUSD,third_party_token,published,0x765de816845861e75a25fca122bb6898b8b1282a,0x0000000000000000000000000000000000000000,uninitialised,1,9,2957,2961,false,2957,explorer_index_and_state_read_agree,bisection_and_announcement_union,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,CUSD,third_party_token,published,0x765de816845861e75a25fca122bb6898b8b1282a,0xaa933baf03cfc55b8e4e0d7de479bcc12f189352,unknown,2,9,2961,3629000,false,2957,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,none,0xa23ae32221bdebb534ab6da55a2b31ca5cc931aa8b6def9bb5f8401e139d51d2,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,CUSD,third_party_token,published,0x765de816845861e75a25fca122bb6898b8b1282a,0x7e327831c644f2b1fef642079f116181bc471cb3,unknown,3,9,3629000,5822108,false,2957,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,none,0xfd545fc18c7a1a554e36aeb4392a9d532ba2911131296f6a5d1d5a478ffbe4e1,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,CUSD,third_party_token,published,0x765de816845861e75a25fca122bb6898b8b1282a,0x2c4c1f3e06d494bcc03e93b373637cc4333cbd7d,unknown,4,9,5822108,9105530,false,2957,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,none,0xe4c43237f59abc7e640bd1a1e60fe5d81b77b5522ad3459aede9f1e17c3d0b46,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,CUSD,third_party_token,published,0x765de816845861e75a25fca122bb6898b8b1282a,0x18e6bfdc909063f7445e410a5495264619495bcb,StableToken,5,9,9105530,18635694,false,2957,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,etherscan_v2_verified_source,0x040dda9403fdb8661a907d59b7aa0b98d8d163e35647e41c4e697d669036367b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,CUSD,third_party_token,published,0x765de816845861e75a25fca122bb6898b8b1282a,0x7ae2f384fe14ead85779f9224558862d6d3e4f28,StableToken,6,9,18635694,23065563,false,2957,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,etherscan_v2_verified_source,0xd73ed2d40adbb84367cd834fa834bb09eb4f67e668215e8895635930c8d7b714,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,CUSD,third_party_token,published,0x765de816845861e75a25fca122bb6898b8b1282a,0x434563b0604be100f04b7ae485bcafe3c9d8850e,StableTokenV2,7,9,23065563,60666007,false,2957,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,etherscan_v2_verified_source,0x659d421716b8eac9026199a99ab15d277dc163a46f48ac5ebf9e1462a6d85170,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,CUSD,third_party_token,published,0x765de816845861e75a25fca122bb6898b8b1282a,0x4b9b0e94197b7b2b11d311239e1420106ce7a2a2,StableTokenV3,8,9,60666007,60745284,false,2957,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,etherscan_v2_verified_source,0x43c6a9f2bbd66e2a2cff43250a380b0fbbf4880e865b163303a849bf45a71ca8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,CUSD,third_party_token,published,0x765de816845861e75a25fca122bb6898b8b1282a,0x815795c30d0758a297b08cd4e0643620c974c318,StableTokenV3,9,9,60745284,9223372036854775807,true,2957,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,etherscan_v2_verified_source,0xd5be5b27724e5f68e90b0765f4a2bc883b6847812356d4ef33ac38ed277a30cf,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,DAOCreator,gooddollar_owned,published,0x76e76e10ac308a1d54a00f9df27edce4801f288b,,unknown,1,0,,,false,,"not applicable, no code is deployed at this address",no_code_deployed,none,none,none,,no_code_at_pinned_block: A published artifact or the registry names this address and nothing is deployed there,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,Faucet,gooddollar_owned,published,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,Faucet,1,10,18003061,18481054,false,18003061,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x60adef4e58f448da1c484b8f64b875688ea6b17e6cf34531bc9530985d05be5e,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,Faucet,gooddollar_owned,published,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,0x91b6eed85458239f281f5ad46c8defd60ddef8b2,Faucet,2,10,18481054,18866025,false,18003061,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xbdc69d3696a4a6de3cdd277f5b71e67bad0f19f0a433f3e6a4d4235257c28f7c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,Faucet,gooddollar_owned,published,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,0xac92cea7b8936e769b00117e7428f7499c93f9db,Faucet,3,10,18866025,20299862,false,18003061,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x1e06dc2d8337ea3aaa409d7742b21d35a686da7e31b7211ecd338bfea40aac9d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,Faucet,gooddollar_owned,published,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,0x0cb76de990330b36b72c9b604a71d24eaa45ebf4,Faucet,4,10,20299862,39388555,false,18003061,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xa342d94b354aa61ba8221b004ade990d040fb7de31385ca82ff9b0a65c649286,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,Faucet,gooddollar_owned,published,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,0x783548481a6ca92b6589365161b31e3ed64d0c3c,Faucet,5,10,39388555,40258358,false,18003061,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xebabf487538a31aba764a34ab1ed1570d6795310a94f6d3d4309abc5b2f975dc,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,Faucet,gooddollar_owned,published,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,0xf224d5166fb194d8404a4a2d1d9fbb41866625ad,Faucet,6,10,40258358,49737165,false,18003061,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xe5aa4f18fa67a7c1ac33d6277d9216f7adbec3f5cf027a50534f7ab929fadbdf,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,Faucet,gooddollar_owned,published,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,Faucet,7,10,49737165,49740289,false,18003061,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x68755099f25764af194ff16c1f4a6fd14bdd4bd89a1c3f6832649a36508e6533,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,Faucet,gooddollar_owned,published,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,Faucet,8,10,49740289,59605758,false,18003061,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xe8429a22753ce3f82c856a7f5dee88264782d956d615db983d0cd5ec8e9fb325,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,Faucet,gooddollar_owned,published,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,0x41ef166fb7d022ce9a90b47581f323d19fafbddd,unknown,9,10,59605758,59606288,false,18003061,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),none,0x368dbfc1d9f8d5f05945e140ed7b50750b906c2373068f38cc9e892ab0b66163,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,Faucet,gooddollar_owned,published,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,0x08fdf766694c353401350c225caeb9c631dc3288,Faucet,10,10,59606288,9223372036854775807,true,18003061,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x60946ac381f89c0e81d17e75a66b09f5eb90e0846cbc50fba2e642a50f5373cc,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,FeeFormula,gooddollar_owned,published,0x1151867da39003695eed28fafa871079c91884c9,0x1151867da39003695eed28fafa871079c91884c9,FeeFormula,1,1,17237953,9223372036854775807,true,17237953,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xb10599b90c45878333139dfa098974b8df30eba5596654ef05c46daa2a6f0847,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,GoodDollar,gooddollar_owned,published+registry,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,0x0000000000000000000000000000000000000000,uninitialised,1,8,17237955,17237956,false,17237955,explorer_index_and_state_read_agree,bisection_and_announcement_union,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,GoodDollar,gooddollar_owned,published+registry,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,0xca903643aa81a2d67863079548f6b53a6dae43d7,SuperGoodDollar,2,8,17237956,17238214,false,17237955,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,etherscan_v2_verified_source,0x6d4edf2a14e946bc4bc85ccd999d505d35a8c0a901030d95d96cf42312f36d85,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,GoodDollar,gooddollar_owned,published+registry,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,SuperGoodDollar,3,8,17238214,17260434,false,17237955,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xf6dcc0590e58b7501bb8701ad1ad658cf2b7de8ec3a8faa9b6d4f2fba8764fa2,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,GoodDollar,gooddollar_owned,published+registry,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,SuperGoodDollar,4,8,17260434,17271388,false,17237955,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x083fbabd4a581ff5a538068453614131f51ee536a0bce7bcc5aa716a55d7aa8d,carried_from_seed: TransferFee event added. MEASURED as never fired to date so Transfer.value remains the whole story. Recheck if it ever fires.,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,GoodDollar,gooddollar_owned,published+registry,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,SuperGoodDollar,5,8,17271388,21746648,false,17237955,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x934f7100a5cf339f677c3822c76029b38a9e97438635450c878f8c4d58f4909a,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,GoodDollar,gooddollar_owned,published+registry,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,0xac862af0a463a5faebbe959e3483b41400f5bb38,SuperGoodDollar,6,8,21746648,22596133,false,17237955,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xbff04a2102f39ae6f66ae309cb4591635ca34f2459429261134e25411faf01fb,carried_from_seed: Superfluid NFT agreement model. TokenUpgraded and TokenDowngraded removed. ConstantInflowNFTCreated and ConstantOutflowNFTCreated added. Eleven functions swapped including downgrade getUnderlyingToken selfMint selfBurn.,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,GoodDollar,gooddollar_owned,published+registry,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,SuperGoodDollar,7,8,22596133,77207809,false,17237955,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xa2d98dc81d3ca3bab7e5cdbe11a4860fbefde5b50a0c910c52a2504b146e2db5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,GoodDollar,gooddollar_owned,published+registry,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,SuperGoodDollar,8,8,77207809,9223372036854775807,true,17237955,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x4650c5f121ca37da373278cb05efc0857704454f4a1afec72b6bc4058bd409d6,carried_from_seed: BlockedUpdated event added and IS IN USE. 15 addresses blocked in one tx at block 77233730 including a Uniswap V3 pool. A blocked address cannot move the token so a quiet address may be prohibited rather than inactive.,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,GoodDollarMintBurnWrapper,gooddollar_owned,published+registry,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,0xb0b86dd967655728218b7b87b10051a60758af82,MintBurnWrapper,1,6,13037458,13254104,false,13037458,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0xc8359e84630f5907348cea1136429f5b91a3d0f687b57f20835a1146881f80e2,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,GoodDollarMintBurnWrapper,gooddollar_owned,published+registry,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,0x413e395b10be6f39f2aa0d80eec48edb88738ac4,GoodDollarMintBurnWrapper,2,6,13254104,13660450,false,13037458,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x35f1a1bc56ad9ca11379afa307e637159af9caba0eafea55d97486882a3e4a33,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,GoodDollarMintBurnWrapper,gooddollar_owned,published+registry,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,GoodDollarMintBurnWrapper,3,6,13660450,15806090,false,13037458,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xdfcf646513c464e512d4c0cac0bf69f5ecd5db669a5cba84244159daaba61c82,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,GoodDollarMintBurnWrapper,gooddollar_owned,published+registry,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,0x0a36091884b8d7808d5fdb47cbdead457ea9803e,GoodDollarMintBurnWrapper,4,6,15806090,17228965,false,13037458,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x6a9b48197ba0fb19f74cf5467b1207f689120d97702df03bd2d90c90efff6100,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,GoodDollarMintBurnWrapper,gooddollar_owned,published+registry,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,0xb3109ca8c7bf74fc5d28285ecf7fe498c21a0698,GoodDollarMintBurnWrapper,5,6,17228965,17239796,false,13037458,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x54ef0f8fab68d40828eeeabb66ea0f3d714be1a52894f55431d1c5c76be88d0c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,GoodDollarMintBurnWrapper,gooddollar_owned,published+registry,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,0x098148534ac15a44cff52387ba81ed929589ecaf,GoodDollarMintBurnWrapper,6,6,17239796,9223372036854775807,true,13037458,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x976528b459f21a7bd143cf3b456517b0a452da77a06e6749356da66a98548dfd,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,GReputation,gooddollar_owned,published+registry,0xa9000aa66903b5e26f88fa8462739cdcf7956ea6,0x4be0c7f9c468b174dfeba304d8bd6af000948a79,GReputation,1,1,17237958,9223372036854775807,true,17237958,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x47c7e53ea14ed9e7757ba2640dfbdcb6ddf21ef2bc9578d9d2c4e92e53ebeea0,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,GuardiansSafe,gooddollar_owned_safe,published,0xa2521e8f5a990903fdd8afa6570c52526e7e0d5e,0xa2521e8f5a990903fdd8afa6570c52526e7e0d5e,GnosisSafeProxy,1,1,16375699,9223372036854775807,true,16375699,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,GuardiansSafeOld,gooddollar_owned,published,0xc9d09ba972b4eb6bb7347f2229fb6d50434ffca6,0xc9d09ba972b4eb6bb7347f2229fb6d50434ffca6,GnosisSafeProxy,1,1,12956494,9223372036854775807,true,12956494,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,Identity,gooddollar_owned,published+registry,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,IdentityV2,1,5,17237952,18314662,false,17237952,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x8a3716a5117789bfbb058b671557334c9f95d40631126f92b67f977ba7e44fe7,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,Identity,gooddollar_owned,published+registry,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,0x7d3033247d4a57b8193b6d9193fd56b45c3f794f,IdentityV2,2,5,18314662,19163670,false,17237952,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x68684e4903b9e207776736097e4c0bc1be9043a4e83a8b1553a9327b0cc42142,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,Identity,gooddollar_owned,published+registry,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,0x3df6ea625866df8d0a61408a122c484b98f3184c,IdentityV2,3,5,19163670,50351048,false,17237952,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x622b7abbc47d60c8a7493bde94d8e9164b244c4631dd33ed79590c739cdb0ced,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,Identity,gooddollar_owned,published+registry,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,0x1eeeb5ba9a9f8b84e52612884a4c18c78cc7413e,IdentityV3,4,5,50351048,61416834,false,17237952,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x4bd0225a727e3608ce47277a685849547c779c35785388dffcb68a1064f49f23,carried_from_seed: IdentityV3. Event set identical to V2.,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,Identity,gooddollar_owned,published+registry,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,0x0ecc03f4e3fa94fa6e2098428a3ad393b65933c9,IdentityV4,5,5,61416834,9223372036854775807,true,17237952,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x0a43a8aa37ea56339ba7f8b8083eb95f17e582d1ccfb2c9f37b8436b195085ad,carried_from_seed: IdentityV4. Whitelist expiry moves from one global authenticationPeriod to a PER WALLET reverifyDaysOptions[authCount] schedule. Boundary comparison flips from <= to <. addBlacklisted now emits WhitelistedRemoved before BlacklistAdded in the same tx. authenticationPeriod() stops being stored and returns the last option. AccountConnected and AccountDisconnected events added.,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,Invites,gooddollar_owned,published,0x36829d1cda92fff5782d5d48991620664fc857d3,0xdbc8860618482f703a4047340b8639b1452f96ec,InvitesV2,1,8,18003063,18795892,false,18003063,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0xe65975cf95e2a884b17fff033799e3ea2f0a852c8b8ea018906dd136b66e639e,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xd69865ff84b5d38adb4dc6c0978fa46abde037b35cdb492734d29a55a7728cae,78286906,78698174,in_release +CELO,42220,Invites,gooddollar_owned,published,0x36829d1cda92fff5782d5d48991620664fc857d3,0x61760d949357066ae29c469b70a91934273e4ef3,InvitesV2,2,8,18795892,20211506,false,18003063,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xb9b02551b4d049d0c13cfca61238ea61363f54e1d129dbbad9ed95646aca23cc,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xd69865ff84b5d38adb4dc6c0978fa46abde037b35cdb492734d29a55a7728cae,78286906,78698174,in_release +CELO,42220,Invites,gooddollar_owned,published,0x36829d1cda92fff5782d5d48991620664fc857d3,0x142e6d0afdd09c8629970b5fb0cf9798a3d21f89,InvitesV2,3,8,20211506,20645578,false,18003063,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xe469498ecb04290fffe5eab6e1f064e4974fea90b4a6f63e1c7d14106793c001,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xd69865ff84b5d38adb4dc6c0978fa46abde037b35cdb492734d29a55a7728cae,78286906,78698174,in_release +CELO,42220,Invites,gooddollar_owned,published,0x36829d1cda92fff5782d5d48991620664fc857d3,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,InvitesV2,4,8,20645578,24428495,false,18003063,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xb104188d6bf90a6f72c1278594cf06f53ea827a7fe85d91e1dc4167706903edd,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xd69865ff84b5d38adb4dc6c0978fa46abde037b35cdb492734d29a55a7728cae,78286906,78698174,in_release +CELO,42220,Invites,gooddollar_owned,published,0x36829d1cda92fff5782d5d48991620664fc857d3,0xd2e26679b4d21cb501ebbc99744c29ed061a6b8c,InvitesV2,5,8,24428495,24518263,false,18003063,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x2009538d39810ef0f0f43438fa262223bcb744fd3e722af01c898afadb3e15a6,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xd69865ff84b5d38adb4dc6c0978fa46abde037b35cdb492734d29a55a7728cae,78286906,78698174,in_release +CELO,42220,Invites,gooddollar_owned,published,0x36829d1cda92fff5782d5d48991620664fc857d3,0x87c222b6212b8352c48b7047e5c97c8797535a09,InvitesV2,6,8,24518263,24600260,false,18003063,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x1b8340f46186440723c9966efc1401b06da022e2ea896256168da6be8f783f84,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xd69865ff84b5d38adb4dc6c0978fa46abde037b35cdb492734d29a55a7728cae,78286906,78698174,in_release +CELO,42220,Invites,gooddollar_owned,published,0x36829d1cda92fff5782d5d48991620664fc857d3,0xf2196f8c2ba0674a8b00369cd65fab3f54b080a0,InvitesV2,7,8,24600260,61165821,false,18003063,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x02225e275e9e2e265175be1ac585904205a1a49612c41c23b6a15238c05bdf0d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xd69865ff84b5d38adb4dc6c0978fa46abde037b35cdb492734d29a55a7728cae,78286906,78698174,in_release +CELO,42220,Invites,gooddollar_owned,published,0x36829d1cda92fff5782d5d48991620664fc857d3,0x4072cb2d7e95def1559f6f72491039fe0534fa37,InvitesV2,8,8,61165821,9223372036854775807,true,18003063,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xea995ee585fba0d4d31a119bcc206c76b7af8a7155b7c2ee1ca071e111b77ed5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xd69865ff84b5d38adb4dc6c0978fa46abde037b35cdb492734d29a55a7728cae,78286906,78698174,in_release +CELO,42220,MentoBroker,third_party_mento,published,0x88de45906d4f5a57315c133620cfa484cb297541,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,Broker,1,2,31415857,61416834,false,31415857,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x58558a86a3aced5b23ae279244bd285f68c9d6d0a20cf283b7a40a0784697831,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,MentoBroker,third_party_mento,published,0x88de45906d4f5a57315c133620cfa484cb297541,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,Broker,2,2,61416834,9223372036854775807,true,31415857,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x2e63673ca3232bd818d12804ade7e1d688b7c11da7812d0237a3564e99cd0fb7,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,MentoExchangeProvider,third_party_mento,published,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,0xd9ce916d711977d5b27697a13964556b4fb8af1d,GoodDollarExchangeProvider,1,2,31415857,61416834,false,31415857,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x65d8c817bac8f41eb34548c15ad6ae5e744da2bd5373916df3b8e63f1fecd916,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,MentoExchangeProvider,third_party_mento,published,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,0xe930cde20f60d0a4fc9487874861ae259f5bed48,GoodDollarExchangeProvider,2,2,61416834,9223372036854775807,true,31415857,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x5ed71ccf7c4789f438827e074bc8bba84c7fc2c615495b12a2f9c51398a8b0d5,carried_from_seed: ExchangeUpdated event added. Not currently consumed.,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,MentoExpansionController,third_party_mento,published,0x5557e9def86ad6564462741a7a3f3679c1223f5d,0x7288d592e1b9013c668801f722be650993d2925a,GoodDollarExpansionController,1,1,31415857,9223372036854775807,true,31415857,explorer_creation_tx_plus_receipt_single_endpoint,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x9da4f4203282696d49deb0c241e49e0ff09f8b6da2d463f69f3fc98e66899a74,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,MentoProxyAdmin,third_party_mento,published,0x8471406c3bff67cc6538481c8550364bda6ca691,0x8471406c3bff67cc6538481c8550364bda6ca691,ProxyAdmin,1,1,31415855,9223372036854775807,true,31415855,explorer_creation_tx_plus_receipt_two_endpoints_agreeing,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xdd44d5a52707f76ac1bb4147820056bd47ca2c90f79d82fdaeb19b7d180179b4,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,MentoReserve,third_party_mento,published,0x94a3240f484a04f5e3d524f528d02694c109463b,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,Reserve,1,1,31415856,9223372036854775807,true,31415856,explorer_creation_tx_plus_receipt_single_endpoint,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0xe5750e9acc0322eae552526478b90a1a762ea401bf9094ff36daa6d0e4669020,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,MentoUpgradeHelper,third_party_mento,published,0xc413cc6c58f0c290e89ddaec83c2590017985eb7,0xc413cc6c58f0c290e89ddaec83c2590017985eb7,ProtocolUpgradeV4Mento,1,1,31415775,9223372036854775807,true,31415775,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xec07536d5a957fe23c6401f1d120012f7eec8637486054801d7915f025b2063b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x0000000000000000000000000000000000000000,uninitialised,1,7,21473545,21473546,false,21473545,explorer_index_and_state_read_agree,bisection_and_announcement_union,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0xd0a3fad8d7887f8264414ddd3290ed1782fb4658,MessagePassingBridge,2,7,21473546,23063176,false,21473545,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x3cf5b0c8c76f42b66f9fdea7cc3fa15f701f158458a5d0ed4e5a7966e5cbb891,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x691de730d97d545c141d13ed5e9c12b7cb384a73,MessagePassingBridge,3,7,23063176,31525116,false,21473545,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x61ac5f3f5751317589d19866c83ec842c45e2e38869f22973b935ed691ac8f88,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x2537f22e7b2d5d14e7f571fa67fcd846d73317f6,MessagePassingBridge,4,7,31525116,50351048,false,21473545,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xf73e0601329e2c0be422f8110b8d9e72950ec58d1a23d0aebf931dc07aa742f9,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x7bdaf2fb332761b2a6a565a43ccb0acfc36d2c3d,MessagePassingBridge,5,7,50351048,52958251,false,21473545,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x1624abfee3f1e647d995471b9cd0434db19d19df21e57b80046ae86f52c9df34,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0xf3eab7018d74e7df95a5d8dc70987c0539bdf48f,MessagePassingBridge,6,7,52958251,61416834,false,21473545,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x7fd33bb337b7565f86a2f7099feb87a2b4f446b94151b7c68b4091eadfb0b369,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x3edd30a1cd94dd6d3329b5ebaff5aa4e0a4e4a55,MessagePassingBridge,7,7,61416834,9223372036854775807,true,21473545,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x29296c3a605737b0ad6dcd4b9040193cc76a01bf8488220f789e13219be9a5a5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,MultichainRouter,third_party_infrastructure,published,0xf27ee99622c3c9b264583dacb2cce056e194494f,0xf27ee99622c3c9b264583dacb2cce056e194494f,AnyswapV3Router,1,1,10155435,9223372036854775807,true,10155435,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xcd92052cccde60e3a65926c5a58ebf8ba7ddd85e99f8bd7af270fdec0a409495,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,NameService,gooddollar_owned,published,0x0f5db7a64a6a64052693676ca898ec7f7a94ff4e,0xed9c5987e7109bb43a8a1a40a726b275e4eb4ace,NameService,1,1,17237962,9223372036854775807,true,17237962,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x0b90907ca330b6cb3ee57cdba11984e10cd8e5e5f004a3284c246ff6ea90ceab,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,OneTimePayments,gooddollar_owned,published,0xb27d247f5c2a61d2cb6b6e67fee51d839447e97d,0xb27d247f5c2a61d2cb6b6e67fee51d839447e97d,OneTimePayments,1,1,18105474,9223372036854775807,true,18105474,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xc7ffb78edacaf8c162f803f1d06d60a0f7959fef40e59c642134256cbe714fac,carried_from_seed: Not a proxy. EIP-1967 slot empty across all history. Single immutable era.,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,PoolGdCeloV2,third_party_dex_pool,discovered,0x25878951ae130014e827e6f54fd3b4cca057a7e8,0x25878951ae130014e827e6f54fd3b4cca057a7e8,UniswapV2Pair,1,1,17713819,9223372036854775807,true,17713819,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xe0ce44f796f8c819bdba6334eb56f0ab6be2936af74486a2c2ccae17e0d17b1f,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,PoolGdCeloV3Hi,third_party_dex_pool,discovered,0xcb037f27eb3952222810966e28e0ceb650c65cd9,0xcb037f27eb3952222810966e28e0ceb650c65cd9,UniswapV3Pool,1,1,20750772,9223372036854775807,true,20750772,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xb444db86df9a51d5ea46b9174dbbf339e48710745d888234840a9ce5679968ed,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,PoolGdCeloV3Mid,third_party_dex_pool,discovered,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,UniswapV3Pool,1,1,40596860,9223372036854775807,true,40596860,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x84fe2b52e16ffad7d7e40b57117e8ee7ab3c7e4c3edb2acfc9a7dee556f25a47,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,PoolGdMcusdV2,third_party_dex_pool,discovered,0x07f86b39728be613062bc7413fc2ca7293eef022,0x07f86b39728be613062bc7413fc2ca7293eef022,UniswapV2Pair,1,1,17714580,9223372036854775807,true,17714580,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xe0ce44f796f8c819bdba6334eb56f0ab6be2936af74486a2c2ccae17e0d17b1f,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,PoolGdUsdgloV3Hi,third_party_dex_pool,discovered,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,UniswapV3Pool,1,1,31680016,9223372036854775807,true,31680016,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xced8cb884f76be736e2ac90f1bcc4eaadac233235a7da8dd813d9adbfeffbcce,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,PoolGdUsdgloV3Hi2,third_party_dex_pool,discovered,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,UniswapV3Pool,1,1,21818995,9223372036854775807,true,21818995,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x81108761c6a03889b76abe78e2a059fa23bcdd3a028668984e17f95a5651e2f1,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,PoolGdUsdgloV3Low,third_party_dex_pool,discovered,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,UniswapV3Pool,1,1,21108554,9223372036854775807,true,21108554,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x4571767e06d5040fa5e97ac1a4d2552c38d18a335a34e1f9315558f06a3bae3d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,PoolGdUsdmV3,third_party_dex_pool,discovered,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,UniswapV3Pool,1,1,19916922,9223372036854775807,true,19916922,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x98890919ba4af6d5acadd5f3bf6b6387333d595bf974ef93adfd993d79acf92c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,ProxyFactory,gooddollar_owned,published,0xd86cd6bb3c2a576b2c2cef4e047b1a7adc5be62d,0xd86cd6bb3c2a576b2c2cef4e047b1a7adc5be62d,ProxyFactory1967,1,1,17237868,9223372036854775807,true,17237868,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x7f63d978bb61348d9321e9e9a382a2f88679edb38c483385333d4dbb0760fea9,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,StaticOracle,third_party_infrastructure,published,0x00851a91a3c4e9a4c1b48df827bacc1f884bde28,0x00851a91a3c4e9a4c1b48df827bacc1f884bde28,StaticOracle,1,1,20262304,9223372036854775807,true,20262304,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x86143ea0f1beb35753eec610670dc4ca6a7dc9924fba2f76851456201041c5e5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x25cc912cc038f1791734f39ceb4d8bffb32c7c61,ConstantFlowAgreementV1,1,16,16393492,18349124,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,contract_creation,none,etherscan_v2_verified_source,0x75e9777e4dc04eb4239f29c5d7f293dc476140250658aa342ae46dc5943dcaba,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0xe40983c2476032a0915600b9472b3141aa5b5ba9,ConstantFlowAgreementV1,2,16,18349124,19952321,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x7d085cb6ac5adcabb2282b7790fd4b6ce42dba3bf82c7984db6c9a8ea98e611f,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x5f001c3915084186b9109fb9dc1e978c98f854b0,ConstantFlowAgreementV1,3,16,19952321,20091409,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xfd8e2cc384599300dce3e61069f0d2ce1313164acf549816f25fb59f548f543d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x9f9eed9bbc38e9e0514fd9dfcc0bca9869a9c534,ConstantFlowAgreementV1,4,16,20091409,21146434,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x2ef2c7bfba9b8dca88af2515f2a4aa08cde06f64b0af0a15c90068db7f8c6d1c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x4247ba6c3658fa5c0f523bacea8d0b97af1a175e,ConstantFlowAgreementV1,5,16,21146434,23701580,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x1c984c77810263353e0e29c4f8d46f24622b7bb0ed55499cc51aeae7c834554c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0xdf3f4b9e4e67a21c868d043a92ae921ff0ebadbb,ConstantFlowAgreementV1,6,16,23701580,24738429,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xbd691ecb50633ce343c9f1cd04c7789a1cbb1e075621e3209809c1482b3e78f3,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0xe3f6ec0676b9ce5d759580e1d526dee31678c283,ConstantFlowAgreementV1,7,16,24738429,26706819,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x85d3c06af86a7ad69fb86b1dc069dcacff6cba81fdcce7fa857eae31d3fc31dc,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x247f65bd849d686147330978aa7521457c5a83bf,ConstantFlowAgreementV1,8,16,26706819,27058151,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x20b540bd27dd1019829f59165480a11522745d5fb13a6815102e65452d36236f,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x81398af97997f3973416d312939f790636719195,ConstantFlowAgreementV1,9,16,27058151,28853698,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x942776f307798a9174da8bc44d2dc4f24469b24ce6d3974e35f4280a7e88f846,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0xf10e526e33f3f377e5b11d62e091fe3f4162a3d0,ConstantFlowAgreementV1,10,16,28853698,29627986,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",blockscout_verified_source,0x0b9f6edffde404761e0993c5b1712631e782dd372af34820a9ea0dd95aed21ca,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x75e58f16f95ac530789d22e55713c9f8dc22444c,ConstantFlowAgreementV1,11,16,29627986,33928238,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xd4b756d9a39c0ac5df7daeda534d2ab144410bab2a665553566f0f2b7f9246fe,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x511cba3de92db7891967e21dbd7c4571531ab84b,ConstantFlowAgreementV1,12,16,33928238,39643668,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xb4e15d60d54a173a5cfe3820cb03c0f7ecb514f015a7ab934c6b76ab6849aeac,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0xd571f5ec96a5b362d10615ff999f06fac4c9e141,ConstantFlowAgreementV1,13,16,39643668,52777129,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xacf7e26bc301a35fe1ba129370a5af1d3e8555c6610bc768c8f7183e3f18903a,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x57897b796ece6633fc7c0c6490b4eb84d58509e5,ConstantFlowAgreementV1,14,16,52777129,61309260,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xcc3e5b55fc44f61f11120b6ad3973f97782035b82eb55455a2589a2a37a4c623,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x7e115385bdbd12fb943a099320c41224b4fa96f4,ConstantFlowAgreementV1,15,16,61309260,74797088,false,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x938d286c9bc510c3815ee4df6bc0c94e47770008998c9c0c05f8f35c6ca0d4c1,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidCFAv1,third_party_superfluid,discovered,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,0x88bb53dea50691cc41094cde84f88d6afb8ca499,ConstantFlowAgreementV1,16,16,74797088,9223372036854775807,true,16393492,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xfb234d8843f0d85344c9a28a31c61b75c71866116caed48021c0419b16be14ca,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0x7ffce315b2014546ba461d54eded7aac70df4f53,GeneralDistributionAgreementV1,1,14,23675300,23701580,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,contract_creation,none,etherscan_v2_verified_source,0xb786d4ce6758e6e6e6c95c8f4dd32c3f605575b77a97d676cc77e0a357557ae6,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0x554a8acef6c689a74b25b1c41f58fa2e678162b5,GeneralDistributionAgreementV1,2,14,23701580,24738429,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x339ef1ccdc96ea6e5f945d0869f69e68d704e5aee4a3f0fb47e920233f2e58e2,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0xc70ce47df817f25bfbb4fb66fd42326ad306f27d,GeneralDistributionAgreementV1,3,14,24738429,26706819,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x2f10ed30f32aac01825d800417aa9a035350611a8846ab187ad2f5683030b04b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0xab1286ab62d0dffd994f4b2d72b24eaa9e295562,GeneralDistributionAgreementV1,4,14,26706819,27058151,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x467730c607a2af26278920b99602bba2ae00fa99735aa8b92b7c31d4aeb1e01d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0xe72830e7ebbff8ce0866059de83cacd4263acd08,GeneralDistributionAgreementV1,5,14,27058151,27279493,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x78428255afad1008379da37854d51a8c6be3020f156dcc65a2f150180332cb71,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0xb75bd19c682e62e6a0c35399bb3a2538fcc9cef6,GeneralDistributionAgreementV1,6,14,27279493,28853698,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x51a1f5d9659cf4db2e53be47120a0b772ad7156ff8cb7e2383659deeb66e9deb,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0x6fc99f5591b51583ba15a8c2572408257a1d2797,unknown,7,14,28853698,29627986,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,"CodeUpdated(bytes32,address)",none,0x4f906e557ab9ee6a7b78ddfc34f24a3ac478263d6a6ee139c0a45c028dd762a4,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0xa0844efaf9a6803e9fa379ee59d44d3ef581ea3f,GeneralDistributionAgreementV1,8,14,29627986,33928238,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x3a8c483a4085356d3be9ba5fa9861d796479f2b012f1e6a6b4d59f1c20741303,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0xc8f6f1720e6266445b3b53b9b9870b25ade5154e,GeneralDistributionAgreementV1,9,14,33928238,39643668,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x6d6bcbc09347c139ac7030309ad6974266386ded295636658d837996e388cb56,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0x96c3c2d23d143301cf363a02cb7fe3596d2834d7,GeneralDistributionAgreementV1,10,14,39643668,44995009,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x2327ceb8850a68dabe52cebd96a38eb4f32cdec27395a3b52877751c3c2468d8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0x4c78cad0cc7152fa8f64ce5298a2d5216c7e4d81,GeneralDistributionAgreementV1,11,14,44995009,52777129,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xead9a7e206538e62c0f6e4dd33621dc98ba53e3352e3214034d618bc44478abe,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0xa347bdc5965323f92ccd950a8b7012c0e438e178,GeneralDistributionAgreementV1,12,14,52777129,61309260,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x5a8b677cd86a18a93c7ae21271fd141fa249950147262c7da8088b683e28d3a0,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0x20dd21b94b88cbeee338c7ffd6124f716c0b54b2,GeneralDistributionAgreementV1,13,14,61309260,74797088,false,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xabe37902c5582ed6ca1fa60c4c6e6956d4abaa1c701b43c219536457fa63c893,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidGDAv1,third_party_superfluid,discovered,0x308b7405272d11494716e30c6e972dbf6fb89555,0x0fcddf2d5023219145e902cb3b0c44159ab59d61,GeneralDistributionAgreementV1,14,14,74797088,9223372036854775807,true,23675300,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x1638d7614afb64812742f4e5df6511885567ff68515e7e74a16416107afa670e,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x0000000000000000000000000000000000000000,uninitialised,1,20,16393469,16393473,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0xf37a766fb6684fa86842f88380e786c2bd32ba4c,Superfluid,2,20,16393473,18349124,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,etherscan_v2_verified_source,0x191b0b9c7e52f28242fb40f248e987dc8aa98ee003548293837c02ac582c0fa7,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x109412e3c84f0539b43d39db691b08c90f58dc7c,Superfluid,3,20,18349124,19952321,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xbad743f142e85dab71de287f4efced306d2dd49c2522aa8e5937581d1fa2caea,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x15f0ca26781c3852f8166ed2ebce5d18265cceb7,Superfluid,4,20,19952321,20091409,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x79c0bf6cc0a97404a1ba4f04a21491ed3dd432ffd8c792578680a79363aa9030,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0xe01f8743677da897f4e7de9073b57bf034fc2433,Superfluid,5,20,20091409,21146434,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xbe25805f704e9912841503d6f91e3570d8bf75dea127874a0afb35a0c0c566d0,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0xb8f12031d79615f3faf6ec5f9795057e55e3069a,Superfluid,6,20,21146434,23701580,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xd402dc49770a98fa224b4f55fc6d7d6a937655d3c788084771133ebbaea954f5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x143ea239159155b408e71cdbe836e8cfd6766732,Superfluid,7,20,23701580,24738429,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x7c07df056c3c6dab1e3fe96a6d7d8453b594969f72fa151a5c8b47063613532f,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0xddc77ec35a571c98c7465b51f152e4888835bee6,Superfluid,8,20,24738429,26706819,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x57164c7f8472925746087e8db09c807893b00780c5a1c92c8faf1743b48977f8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0xcf3f4fa77f4427f6a1c1a96556194b40fc9dbf02,Superfluid,9,20,26706819,27058151,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x2878db05fa2818412b3dc91044e48209e42aed3f5912e5153ef076c953099914,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x78743a68d52c9d6ccf3ff4558f3af510592e3c2d,Superfluid,10,20,27058151,27279493,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x29b712122f26431d8f811f6b06e233dadd2e5efd3d1d73e693753da543178401,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x862f59081fc7907f940be4227b9f485d700e6cdd,Superfluid,11,20,27279493,28853698,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xbdd0248aee9f9d9cd42b1ec49b695e18234162ea5f5fd7f3bf3f2a1db1ea1d4c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0xae50ba6b0f7412dfd2061bfcd15c2d63f36af143,unknown,12,20,28853698,29627986,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",none,0x5e9cb99ff4ba661eb86d8c7a44f90f36a2ad1fbeabd1769133e6d34c726fd95a,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0xf26967f92151487f8c6642199c3441b02398d19e,Superfluid,13,20,29627986,33928238,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xd725780f0e452fc2e98ba0b229c1854c34e9882a5550c03501406c8fcc98f3d0,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x9a19773ebe33c5917012c2bb982bc683d91ec600,Superfluid,14,20,33928238,39643668,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x49e13d9d72661dfdb490a8a67c32fef72a7b212bdaaabf0c9cc231818377de45,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x97620d4d7950223963f00db25f12b4ac1d4eed99,Superfluid,15,20,39643668,44995009,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x271879ac911f8440a875974a04b54db30b8a5f63898975a041489de41f36554c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x3b526b50709a5551030673be284bc9c1e38351ac,Superfluid,16,20,44995009,52777129,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x6f43af90345b70565298e49768034ab0ff782c995fd5fdb26c0871f6ded40fe1,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x8e03f0edb581e8b6aad80eece89b3028388f4b53,Superfluid,17,20,52777129,61309260,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x5f3453e79f1aaac3f7dfe0c14452701fd8f3501ec000334f70bc80f9e9dcbf7b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0xf17e88391b68c2a5972131f5044fd6ace665f221,Superfluid,18,20,61309260,74797088,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x19a7ec64380e14852eee8d4a0f7bdb4a15c98dd9e8359f42a0cc2316415b759e,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0xc899724f32859e8169e607a23448e4b487b4dc04,Superfluid,19,20,74797088,76632579,false,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x61f96160837a684e3c8b66ebac18d6c0517947e8d3789d8833f567592d3ea40d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidHost,third_party_superfluid,discovered,0xa4ff07cf81c02cfd356184879d953970ca957585,0x724676722b69b8b0e5fcf030de796047e771e5f9,unknown,20,20,76632579,9223372036854775807,true,16393469,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",none,0xdb6e855c140ab4a6e967d9ddb3d022b5fb39cf6956ff6677bbddf9f7ef334e70,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0x7dc6b57adae1aaa94e01a3049cd42b8adce5090c,InstantDistributionAgreementV1,1,14,16393503,18349124,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,contract_creation,none,etherscan_v2_verified_source,0x7423f597fdcfb7c349e024be728df2d0c05e3337e615808c64b8c0994ff66a5c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0xd399e2fb5f4cf3722a11f65b88fab6b2b8621005,InstantDistributionAgreementV1,2,14,18349124,19952321,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x131499da5b515b0f696d9e320b87b3258838287f30bcde867d1648ba1bd83471,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0x507c3a7c6ccc253884a2e3a3ee2a211cc7e796a6,InstantDistributionAgreementV1,3,14,19952321,20091409,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x0103da8886a08479c1249b11691d702669168e2f64f65595db70270ee66859f0,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0x2622bfc83f429bf313341857850a1dde09685855,InstantDistributionAgreementV1,4,14,20091409,21146434,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x005ec5ffe135e03f2feacd794c02fe50aabc4dd3c572eb0dcc023023bb2a215f,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0xd48317ccdac2ca3fd5e3c58c32da3a7c517937b6,InstantDistributionAgreementV1,5,14,21146434,23701580,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x0799b7eb67f8bf5f1db451db0b501b02796bedddfe80efa2a991ff28f1a4df4c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0xfb2b126660be2fdeba254b1f6e4348644e8482e7,InstantDistributionAgreementV1,6,14,23701580,24738429,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xfafd5fc7ae369d3fce5cc48edaa0de12d57761ce316328b0228d358d69b9ee65,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0x2e4861b1f56a67473b7bf0dd1ef85e9e9fa5ad75,InstantDistributionAgreementV1,7,14,24738429,26706819,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x3f185f2c62fd18472510fbb526fc17a7bf9b0da44f028195dacb1f1ad6b85e2c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0x0de6448cc883168076f7b10449bc7024d42f7910,InstantDistributionAgreementV1,8,14,26706819,28853698,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xd1000660be8820603092f51c3c5435be3cc133c9f7a2e47a745fd159d4d45bc4,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0x466be9ef50dec3c22eaa4f070e9c9ceaaccd1e75,unknown,9,14,28853698,29627986,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",none,0xb86b086999fdf33a2056b5fb2d92686006ff58f9d59216ad9ceea32e456af822,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0xb84c98d9b51d0e32114c60c500e17ea79dfd0daf,InstantDistributionAgreementV1,10,14,29627986,33928238,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x5144e6bd0aff5ec0dc215c75db7a2e5a6ea9539e21f10ac47bce49108c1f1798,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0xd59ba9a84fa02e3687bb0694e459b3c1d76586f9,InstantDistributionAgreementV1,11,14,33928238,39643668,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x4c0dce8901dea2158d8f1edcc42bc70261cce1f74e58f4f0ef5ca644a44427b6,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0xf0ec6a8842ca72aec8a4d4573e731242389e18a8,InstantDistributionAgreementV1,12,14,39643668,52777129,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x3b0de12889b24499a458af0c481b84c9a572276f46a6faf92f7a5e9de2107226,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0x1d38a1f81216b73c05a10eac5e84f566d4d9d8da,InstantDistributionAgreementV1,13,14,52777129,61309260,false,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0xfb7ddd181f516de9d0f9448a3aa6faab8aaba0d4296d4df8793f1f09a9fb9d8f,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SuperfluidIDAv1,third_party_superfluid,discovered,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,0x295cef78e76564b124b948a05dbd6522c3ec76b1,InstantDistributionAgreementV1,14,14,61309260,9223372036854775807,true,16393503,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x062b6f052bfc1eeb46d77828aecf61f2c118d08d8dbdd4bd6672e42f1fed0fbb,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +CELO,42220,SwapHelper,gooddollar_owned,published,0xe45cab86609a16dfadec112fdd61e4ea80edaa8d,0xe45cab86609a16dfadec112fdd61e4ea80edaa8d,DexSwapHelper,1,1,18468536,9223372036854775807,true,18468536,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x15ae5796a74f46cfb3b34a673823263ac0cbd3eb5bdb803a393516d0bc446375,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,UBIScheme,gooddollar_owned,published+registry,0x43d72ff17701b2da814620735c39c620ce0ea4a1,0xedbe438cd865992fdb72dd252e6055a71b02be72,UBIScheme,1,4,18006679,19276072,false,18006679,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x0e581bfc2fe31489ffb4c73916e5eb871089492aab7d977d80cd563d3011e236,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0x23ed554b63b086930ca3ea996cb5c1a705d4433ad29f650f1b69fb4fa8f0248e,78286906,78698174,in_release +CELO,42220,UBIScheme,gooddollar_owned,published+registry,0x43d72ff17701b2da814620735c39c620ce0ea4a1,0x854f84ef0d9abc1e0afb4e96c962d5456b62214e,UBISchemeV2,2,4,19276072,23063176,false,18006679,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xa218cc030a5bf302bd79f7c0814e7d03ba74606098b00733d9751be6af84dbb8,carried_from_seed: ActivatedUser InactiveUserFished and TotalFished REMOVED. They exist ONLY in blocks 18006679 to 19276071. Contract renamed UBIScheme to UBISchemeV2.,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0x23ed554b63b086930ca3ea996cb5c1a705d4433ad29f650f1b69fb4fa8f0248e,78286906,78698174,in_release +CELO,42220,UBIScheme,gooddollar_owned,published+registry,0x43d72ff17701b2da814620735c39c620ce0ea4a1,0xe8fcbac4bd18f80301450e428518e9dedc183a26,UBISchemeV2,3,4,23063176,50351048,false,18006679,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x3588b09013666a632da7bb2559251b2efb62086be858ddaf9a604eb4340542c4,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0x23ed554b63b086930ca3ea996cb5c1a705d4433ad29f650f1b69fb4fa8f0248e,78286906,78698174,in_release +CELO,42220,UBIScheme,gooddollar_owned,published+registry,0x43d72ff17701b2da814620735c39c620ce0ea4a1,0x43f0eb66ea3c2d9552241525aa1af6607227dfbf,UBISchemeV2,4,4,50351048,9223372036854775807,true,18006679,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xdb2d70994b744a419372a0526da1e3bbe069a59e7569a9f3c0965d85d1b60ecd,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0x23ed554b63b086930ca3ea996cb5c1a705d4433ad29f650f1b69fb4fa8f0248e,78286906,78698174,in_release +CELO,42220,UniswapQouter,third_party_infrastructure,published,0x82825d0554fa07f7fc52ab63c961f330fdefa8e8,0x82825d0554fa07f7fc52ab63c961f330fdefa8e8,QuoterV2,1,1,13916379,9223372036854775807,true,13916379,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x557b5bc80c7000c05bac66693aff2264927a0a22ea1f80d590449b52d515aa34,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,UniswapV2Factory,third_party_dex_factory,discovered,0x62d5b84be28a183abb507e125b384122d2c25fae,0x62d5b84be28a183abb507e125b384122d2c25fae,UniswapV2Factory,1,1,5272596,9223372036854775807,true,5272596,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xdac4452e3e8e28193a714ff79e8268661235b1f73a3ccf61d85470d3ce89ed3b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,UniswapV3Factory,third_party_dex_factory,discovered,0xafe208a311b21f13ef87e33a90049fc17a7acdec,0xafe208a311b21f13ef87e33a90049fc17a7acdec,UniswapV3Factory,1,1,13916355,9223372036854775807,true,13916355,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x5960f2f785dd273f0eeb9624f32a9f93bd1560dc1335171d22411d48296d79b3,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,UniswapV3FactorySecond,third_party_dex_factory,discovered,0x67fea58d5a5a4162ced847e13c2c81c73bf8aec4,0x67fea58d5a5a4162ced847e13c2c81c73bf8aec4,UniswapV3Factory,1,1,25639915,9223372036854775807,true,25639915,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xa99af02b020bfe03b92021add28ab8707c33a0d1887e01e67da39c5531fb9e85,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,UniswapV3Router,third_party_infrastructure,published,0x5615cdab10dc425a742d643d949a7f474c01abc4,0x5615cdab10dc425a742d643d949a7f474c01abc4,SwapRouter02,1,1,13916381,9223372036854775807,true,13916381,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xec8b1d6527bdadca0f0158435b41f0a9518215005a39b1f286d6a3628b7f806c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +CELO,42220,UniswapV4PoolManager,third_party_dex_singleton,discovered,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,PoolManager,1,1,43985163,9223372036854775807,true,43985163,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x3ed9587168a0fe70acc18971f52cba06f18bcd4b4b5ba2f0590b8c17b1c0cdca,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 78286906,raw_only_unproven,,,,in_release +ETHEREUM,1,AaveStakingFactory,third_party_infrastructure,published,0xf4411c22766947db2da39ad534a040b770b51153,0xf4411c22766947db2da39ad534a040b770b51153,AaveStakingFactory,1,1,14338311,9223372036854775807,true,14338311,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xe5c076c8e4675670baa06fb5f76fee3dc8ef6f48b7c7df96efe4790d773e1771,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,AnyGoodDollar,gooddollar_owned,published,0xd17652350cfd2a37ba2f947c910987a3b1a1c60d,0xd17652350cfd2a37ba2f947c910987a3b1a1c60d,AnyswapV6ERC20,1,1,14809447,9223372036854775807,true,14809447,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x48c30df8d84160f9085fffbc3ff8a72e42be14aca8ad94626249d836a1392565,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,Avatar,gooddollar_owned,published+registry,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,Avatar,1,1,10561463,9223372036854775807,true,10561463,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x8a27316984da83331e574723efd0810faf4d7065f3037b8778d9c572ea49c6d8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,BancorFormula,third_party_infrastructure,published+registry,0xa049894d5dcad406b7c827d6dc6a0b58ca4ae73a,0xa049894d5dcad406b7c827d6dc6a0b58ca4ae73a,BancorFormula,1,1,10566777,9223372036854775807,true,10566777,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xd17f840b97128d5f5ecc258913b071648460f9c11298c00d21cb478907f2ac03,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,cDAI,third_party_token,published+registry,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,CErc20Delegator,1,1,8983575,9223372036854775807,true,8983575,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x3f1d4a4e2a03855c7ee8f6f2477c1245752a5ca3ef28d59e8fd509efe59ef877,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,COMP,third_party_token,published+registry,0xc00e94cb662c3520282e6f5717214004a7f26888,0xc00e94cb662c3520282e6f5717214004a7f26888,Comp,1,1,9601359,9223372036854775807,true,9601359,explorer_index_and_state_read_agree,slots_unreadable,contract_creation,none,etherscan_v2_verified_source,0x9398f9b1f117941e8e25a4aff4d11754f48933cc3c08101975e3306e98d88c2a,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,proxy classification unresolved. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,CompoundStakingFactory,third_party_infrastructure,published,0x78cc5ab2f0990b5fe58f95baebf8f37879534aeb,0x78cc5ab2f0990b5fe58f95baebf8f37879534aeb,CompoundStakingFactory,1,1,14338308,9223372036854775807,true,14338308,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x883ade859bcf2356e3b7cd3523018b571087dced077a1ed4ac45a4c96d8d3980,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,CompoundVotingMachine,gooddollar_owned,published,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,0x92af163505c05d63a4f7478c01b9af9be369c143,CompoundVotingMachine,1,2,14380642,22165594,false,14380642,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x6eaae71845e0c65ee44592019c400d81c9ebca6b3a544cdc10368c6af43f4216,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,CompoundVotingMachine,gooddollar_owned,published,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,0x807d0066d60a0a8312b6d191f60a6938a527e971,CompoundVotingMachine,2,2,22165594,9223372036854775807,true,14380642,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x0d5e8f324a69af2b72f2d9e3266036966ba2bcfd2d594f82c28b0ab275d6d5ed,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,Contribution,gooddollar_owned,published+registry,0x8eec64bb6807c0178f96277cce6a334b4e565e5c,0x8eec64bb6807c0178f96277cce6a334b4e565e5c,ContributionCalculation,1,1,10569456,9223372036854775807,true,10569456,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x8afd3472b2ba7c9664301e1db0e1a4ff03e1d4abf7037870060aec9479e95d88,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,Controller,gooddollar_owned,published+registry,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,Controller,1,1,10561463,9223372036854775807,true,10561463,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x1cce4814ac502cec7e982e73d29bdc95e9094476ba971b6777f8abd4a415fc26,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,DAI,third_party_token,published+registry,0x6b175474e89094c44da98b954eedeac495271d0f,0x6b175474e89094c44da98b954eedeac495271d0f,Dai,1,1,8928158,9223372036854775807,true,8928158,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x4e36f96ee1667a663dfaac57c4d185a0e369a3a217e0079d49620f34f85d1ac7,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,DAI_ETH_ORACLE,third_party_infrastructure,registry,0x773616e4d11a78f511299002da57a0a94577f1f4,0x773616e4d11a78f511299002da57a0a94577f1f4,EACAggregatorProxy,1,1,10606425,9223372036854775807,true,10606425,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x4b79b5c8aee6da0f7b393e8b53e6265ef7320a1d16184c65bd3841b5aa3d700d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,DistributionHelper,gooddollar_owned,published+registry,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,0x42cda1bd60cc66ab2e2411e8c93db436c8a27060,DistributionHelper,1,5,16167621,17661435,false,16167621,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x15354959eb9bdda169ce6b338a64f4949ca5fd2fc4fa790fc506f7b62f221520,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,DistributionHelper,gooddollar_owned,published+registry,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,0x16171d113d9592b77cec52b8cc4bdd6f5810daef,DistributionHelper,2,5,17661435,18190480,false,16167621,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xf80378215ded3a92155f1331c852040bbabb670f2aa13da253d5af430ab7082d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,DistributionHelper,gooddollar_owned,published+registry,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,DistributionHelper,3,5,18190480,18719715,false,16167621,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xb95001d06c848c5680808debf2aba0ed20f162ec873722d17784acf0aeb7acdc,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,DistributionHelper,gooddollar_owned,published+registry,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,0xa339b7f4e95a93d2c6569cb139ad034c3b9caa77,DistributionHelper,4,5,18719715,22165594,false,16167621,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x6b215c6b5d9777cc6f1f5f2130a9b2c9fe16e933e18b076243e9181c446921f1,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,DistributionHelper,gooddollar_owned,published+registry,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,0xae2cd2a9513215961d344a2581dcab678598eedf,DistributionHelper,5,5,22165594,9223372036854775807,true,16167621,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xc3767b93a60456d6aa441ce3d8b319a5e479d9bde160f4dc87bedfc70558f73f,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,ETH_USD_ORACLE,third_party_infrastructure,registry,0x5f4ec3df9cbd43714fe2740f5e3616155c5b8419,0x5f4ec3df9cbd43714fe2740f5e3616155c5b8419,EACAggregatorProxy,1,1,10606501,9223372036854775807,true,10606501,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x4b79b5c8aee6da0f7b393e8b53e6265ef7320a1d16184c65bd3841b5aa3d700d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,ExchangeHelper,gooddollar_owned,published+registry,0x98fa532dd5c3a6b66fbf370813803192de4e0abd,0xbebbd9538d594619d36d48666e12d8c9f8372736,ExchangeHelper,1,2,14296277,22165594,false,14296277,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x26322c949531dde942496f5930d4820de88a98c486980fc5f4f43cbe5ea5a594,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,ExchangeHelper,gooddollar_owned,published+registry,0x98fa532dd5c3a6b66fbf370813803192de4e0abd,0x24614ad257f4d09fccaec024c65c40c060e73e9d,ExchangeHelper,2,2,22165594,9223372036854775807,true,14296277,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xcbdb11d6fd35031a639ffb1834cbce6879073b685912f740dd2a9b4ada1dd2b8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,ForeignBridge,gooddollar_owned,published+registry,0xd5d11ee582c8931f336fbcd135e98cee4db8ccb0,0xd5d11ee582c8931f336fbcd135e98cee4db8ccb0,EternalStorageProxy,1,1,11238178,9223372036854775807,true,11238178,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x2d05a6bd0ad793d9459975bf7760dcbfefa24baf8c7f70efa4aab6b52db668bb,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,GAS_PRICE_ORACLE,third_party_infrastructure,registry,0x169e633a2d1e6c10dd91238ba11c4a708dfef37c,0x169e633a2d1e6c10dd91238ba11c4a708dfef37c,EACAggregatorProxy,1,1,10606498,9223372036854775807,true,10606498,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x4b79b5c8aee6da0f7b393e8b53e6265ef7320a1d16184c65bd3841b5aa3d700d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,GoodDollar,gooddollar_owned,published+registry,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,GoodDollar,1,1,10561463,9223372036854775807,true,10561463,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x554945bfa422af5800554ef7b37f229465f13208db908d482249f1dd9803a3c0,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,GoodFundManager,gooddollar_owned,published+registry,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,0x4a10354b8e1928c38cc6a738cd2748fa1c818cea,GoodFundManager,1,4,14338654,16240765,false,14338654,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0xbb78513636d0bcb8076eb8dded78b38961998755abb5d65b2b29b04109c8135b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,GoodFundManager,gooddollar_owned,published+registry,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,0x53b3c6b18a03a9a0c3487cf1230eea1eb9a38a0a,GoodFundManager,2,4,16240765,18190480,false,14338654,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x3069da8e333310c4eee88b81b810e14ededc06f5904a64dd8198129ae82eb4d4,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,GoodFundManager,gooddollar_owned,published+registry,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,0x4a37a8d7cdb43d89b4dbd7ecfaeaf9bd39e24929,GoodFundManager,3,4,18190480,22165594,false,14338654,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x1603edb57ff936d52c7ff4f3696a591f39bf8b46b8e93cf5591de63473bf48ba,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,GoodFundManager,gooddollar_owned,published+registry,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,0xaacbaab8571cbeceb46ba85b5981efdb8928545e,GoodFundManager,4,4,22165594,9223372036854775807,true,14338654,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x80dcb898400e373e62b938941ea18dba14b621a35ec858897bdee60bb21a5b64,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,GoodMarketMaker,gooddollar_owned,published+registry,0xdac6a0c973ba7cf3526de456affa43ab421f659f,0xb3ff03c8a42506ba58b1127cd4b5928c7ed70a03,GoodMarketMaker,1,2,14296152,22165594,false,14296152,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x3ed7a72aaa5e00bea85f4c5a6b7cefc973c2e1e7a42754ed1812b5fa735ed268,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,GoodMarketMaker,gooddollar_owned,published+registry,0xdac6a0c973ba7cf3526de456affa43ab421f659f,0x8520633e40574e9550f6a0436b0f8d56f3b99bd0,GoodMarketMaker,2,2,22165594,9223372036854775807,true,14296152,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xfdd8235cfa88eea23f3dba545fdf43e6c4cf831b3dea3e2331c60606eaf380d1,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,GoodReserveCDai,gooddollar_owned,published+registry,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,0x865193da25c4fe135421fca78d2bd061b6efd744,GoodReserveCDai,1,4,14296271,16174339,false,14296271,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0xb04200c786691948f77f0a7be422af88e22b5a424ee637df3f722a6e45a9de10,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,GoodReserveCDai,gooddollar_owned,published+registry,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,0x6e1c3f516ffd14852f9b25f21af13b6ce98dace5,GoodReserveCDai,2,4,16174339,18190480,false,14296271,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xa6ee500bfe454a9e75a1741294ee0b7729c3f510b5022de40246caa38c53a2cc,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,GoodReserveCDai,gooddollar_owned,published+registry,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,0x2793a5887f53b025f49f7a9249d66f4671bce29b,GoodReserveCDai,3,4,18190480,22165594,false,14296271,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x2befbf5a304c75892209914c0a756d8c1c8bf82dd6508e3656eba753d100ad1f,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,GoodReserveCDai,gooddollar_owned,published+registry,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,0x18bcdf79a724648bf34eb06701be81bd072a2384,GoodReserveCDai,4,4,22165594,9223372036854775807,true,14296271,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x43410466ac894d865cff8f6bbeaf0ede8804ae379f6260a2cd7c8ea0ac9ddc05,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,GReputation,gooddollar_owned,published+registry,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,0x0a5dcf330ba39434dbda59b982a3dd09759cc788,GReputation,1,3,14344739,14352686,false,14344739,etherscan_v2_getcontractcreation,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x824339abb39e2b39cb85a8e45048c2eb366c9110a4918c2ea2d1f102f0354367,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,GReputation,gooddollar_owned,published+registry,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,0x438eb12a081041b525731c34086de3ed31658dee,GReputation,2,3,14352686,16885600,false,14344739,etherscan_v2_getcontractcreation,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x40781353ff48e1d9fe0feada2bf9c447956538f67d1b9a2f0d72d7c1fe8cc7be,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,GReputation,gooddollar_owned,published+registry,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,0x634e25b6ffde325d5beb8c6c2d8af6d543b6ff7f,GReputation,3,3,16885600,9223372036854775807,true,14344739,etherscan_v2_getcontractcreation,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x0b6ff946fd1ad1ebc33dd134a57713419b8ac0fdecbd56db74ffcf6266909cc5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,GuardiansSafe,gooddollar_owned_safe,published,0xe0c5daa7cc6f88d29505f702a53bb5e67600e7ec,0xe0c5daa7cc6f88d29505f702a53bb5e67600e7ec,GnosisSafeProxy,1,1,16060725,9223372036854775807,true,16060725,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,Identity,gooddollar_owned,published+registry,0x76e76e10ac308a1d54a00f9df27edce4801f288b,0x76e76e10ac308a1d54a00f9df27edce4801f288b,Identity,1,1,10561341,9223372036854775807,true,10561341,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x83c740a8ac588a566556553a334afdfded5add581f27efc0215d3ccfd842eaad,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x0000000000000000000000000000000000000000,uninitialised,1,5,18162554,18162562,false,18162554,etherscan_v2_getcontractcreation,bisection_and_announcement_union,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0xf19fb90fa4ddb67c330b41ad4d64ef75b9d8cd33,MessagePassingBridge,2,5,18162562,22165594,false,18162554,etherscan_v2_getcontractcreation,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x2e5d3e54855f5864dc7e6abf562989a74a3fc1e020b976c592a79a7b2da9c408,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x618fae127b803eabf72f9e86a88a7505eebf218a,MessagePassingBridge,3,5,22165594,23940256,false,18162554,etherscan_v2_getcontractcreation,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xf89052533300161b0a7d20c5eb600d0850f5c95fb48f1e2727825b231cd1b0aa,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x12ab702f015d3302f3cc0c4aba0626a127d06a07,MessagePassingBridge,4,5,23940256,24641278,false,18162554,etherscan_v2_getcontractcreation,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xd28a518f866e7d53b195a37a71eb04cc68fee21d7cb991427934b6f9d53e1fc2,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x3a2d0a9ef558b42af5ff8d27fe438b466fa7692f,MessagePassingBridge,5,5,24641278,9223372036854775807,true,18162554,etherscan_v2_getcontractcreation,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x104d6ab3b6a95b2ebf4cfb4a6cb485f5e4b5ef02c3d119c07e43322bbd5daacf,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,MultichainRouter,third_party_infrastructure,published,0x765277eebeca2e31912c9946eae1021199b39c61,0x765277eebeca2e31912c9946eae1021199b39c61,AnyswapV4Router,1,1,12242619,9223372036854775807,true,12242619,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xf8548d4270316b12fe3628b1d57ba1d79cd8a97861793af639eb0ee1ba330356,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,NameService,gooddollar_owned,published,0xec6dce387b1616a0c44ff2e4fa9e90e53cf14eb0,0xeb151e175d3d53032c2c185052e48c8c2d5c245d,NameService,1,1,14295851,9223372036854775807,true,14295851,etherscan_v2_getcontractcreation,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0xce45d07e83296b1ea2bdaf7be5635193dda560b978c1afe17b4e87667f2b507a,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,ProtocolUpgradeRecover,gooddollar_owned,published,0x6f1b4dfdd7156fc5752541ef35edf57b48e74475,,unknown,1,0,,,false,,"not applicable, no code is deployed at this address",no_code_deployed,none,none,none,,no_code_at_pinned_block: A published artifact or the registry names this address and nothing is deployed there,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,ProxyAdmin,gooddollar_owned,published,0xa2db14c68ab35e620fea5bf07d65e9bff84c994c,0xa2db14c68ab35e620fea5bf07d65e9bff84c994c,ProxyAdmin,1,1,11512052,9223372036854775807,true,11512052,etherscan_v2_getcontractcreation,slots_unreadable,contract_creation,none,etherscan_v2_verified_source,0x2b57f0728a5ffe03a475faab83005c468d0f669c0a473f87425e3edb6101ec8a,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,proxy classification unresolved. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,ProxyFactory,gooddollar_owned,published,0xda85fced9bd193526b7667f2ad1fd4a0f900d3a7,0xda85fced9bd193526b7667f2ad1fd4a0f900d3a7,ProxyFactory1967,1,1,14294877,9223372036854775807,true,14294877,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x1a30c8ca34283aa6a8722d626c290a575108a1e4d7d018db6faf46c77e1f19a3,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,StakersDistribution,gooddollar_owned,published+registry,0x5766cf4b2fdb09d986eb1783d276013c224e28c8,0x5f78ed3a4fdde9e9d91d3707a847fb4ad820ce26,StakersDistribution,1,2,14338550,22165594,false,14338550,etherscan_v2_getcontractcreation,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x23c18a3cc25e04ccd645243059a51da30d3ed25a321c6997f8db86ef90573106,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,StakersDistribution,gooddollar_owned,published+registry,0x5766cf4b2fdb09d986eb1783d276013c224e28c8,0x92c69a12c2ffc54afcfa320be7305ffd0f5782e0,StakersDistribution,2,2,22165594,9223372036854775807,true,14338550,etherscan_v2_getcontractcreation,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xdb6b68ed9eb7db3045bc8fdf06a2da5d34164ff07e810f4e5c270cbdd24d479b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +ETHEREUM,1,StakingContracts,gooddollar_owned,published,0xd33ba17c8a644c585089145e86e282fada6f3bfd,0xd33ba17c8a644c585089145e86e282fada6f3bfd,GoodCompoundStaking,1,1,13701103,9223372036854775807,true,13701103,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x80648f5b74b165322f61c0e45e315077d1eb8776607f893ce654bbc483382c54,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,StakingContractsV2,gooddollar_owned,published,0x02416eb83cff1f19163f21010149c3867f3261e1,0x02416eb83cff1f19163f21010149c3867f3261e1,GoodCompoundStakingV2,1,1,14132483,9223372036854775807,true,14132483,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x19d236ce0180396e675601e31fe953bba57e046cfcfee783c621862b4696e065,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,StakingContractsV2,gooddollar_owned,published,0xf4c34bed7dd779485692bb1857acf9c561b45010,0xf4c34bed7dd779485692bb1857acf9c561b45010,GoodAaveStakingV2,1,1,14132483,9223372036854775807,true,14132483,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x6d7aa6e4422780f33acf8093fdbe3669832ad519486c8396b7320ba429c62497,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,StakingContractsV3,gooddollar_owned,published,0x3ff2d8eb2573819a9ef7167d2ba6fd6d31b17f4f,0x3ff2d8eb2573819a9ef7167d2ba6fd6d31b17f4f,GoodAaveStakingV2,1,1,14338483,9223372036854775807,true,14338483,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xcce057daa357d310d82f1bba3c24f93cb7c7b0d8d00d185c1c8395abbbaf036b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,StakingContractsV3,gooddollar_owned,published,0x7b7246c78e2f900d17646ff0cb2ec47d6ba10754,0x7b7246c78e2f900d17646ff0cb2ec47d6ba10754,GoodCompoundStakingV2,1,1,14338454,9223372036854775807,true,14338454,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x581fa12f95a355336e4fff7a6b5a324f6f93c8c1de4c4e0a3d839c3d8219db04,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,UBI_RECIPIENT,gooddollar_owned,registry,0xd253a5203817225e9768c05e5996d642fb96ba86,,unknown,1,0,,,false,,"not applicable, no code is deployed at this address",no_code_deployed,none,none,none,,no_code_at_pinned_block: A published artifact or the registry names this address and nothing is deployed there,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,read at block 26041882,raw_only_unproven,,,,in_release +ETHEREUM,1,UNISWAP_ROUTER,gooddollar_owned,registry,0x7a250d5630b4cf539739df2c5dacb4c659f2488d,0x7a250d5630b4cf539739df2c5dacb4c659f2488d,UniswapV2Router02,1,1,10207858,9223372036854775807,true,10207858,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xa324bc7db3d091b6f1a2d526e48a9c7039e03b3cc35f7d44b15ac7a1544c11d2,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 26041882,raw_only_unproven,,,,in_release +FUSE,122,AdminWallet,gooddollar_owned,published,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,0x832548c789ea71cae69f562476e9978d77e36c70,AdminWallet,1,6,18838651,22038689,false,18838651,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x66b4691f8dbbbeca25c2d211e9956b11f70436b977606825e22ad57175b4ee1a,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,AdminWallet,gooddollar_owned,published,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,0xeed7ecf710aa2cf1c15dcdba29de8655a384e299,AdminWalletFuse,2,6,22038689,25360323,false,18838651,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xa64b2065c3bdea43c0c94eef6982542b4546f32b6e6dea99c2d86643d9a2c6a9,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,AdminWallet,gooddollar_owned,published,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,0xdd107728aa2445166942837a7338c157065bd8c8,unknown,3,6,25360323,25360565,false,18838651,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0xd5b671d4e75d1403bdf6c0aa6dcfba8c5373ac9b165ef9ec4aa7c1bd16c640d0,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,AdminWallet,gooddollar_owned,published,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,0x44035ca8d61472adbfb9dc6a7fdcc6af9d1f7f0a,unknown,4,6,25360565,25361140,false,18838651,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0xe65c8d986b9ae0135ea86a802c94ae2cf27da0ddaffae8ba2256d4194ed8fda1,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,AdminWallet,gooddollar_owned,published,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,0xa9133a3d11bc39eb4d65e6de44fe9ceac3c71f54,AdminWalletFuse,5,6,25361140,38833573,false,18838651,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xf1d2b5dd090e70e6c85fa5b55ff2df42f4c12e54e6b7368ae08768d2f9c52120,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,AdminWallet,gooddollar_owned,published,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,0x7ac74c2c00b1e403a2d9972b8fdb237ebeffb901,AdminWalletFuse,6,6,38833573,9223372036854775807,true,18838651,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x0e5dcba485a857f32569ff106b8bbd663daa48097d326d5f7684bf37693f93df,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0x7ac74c2c00b1e403a2d9972b8fdb237ebeffb901,raw_only_unproven,,,,out_of_release +FUSE,122,AdminWalletOld,gooddollar_owned,published,0x9f75dacb77419b87f568d417ebc84346e134144e,0x9f75dacb77419b87f568d417ebc84346e134144e,AdminWallet,1,1,6246332,9223372036854775807,true,6246332,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x6b4b178e5e2f68c4ec1500db73eb9c44faf11b3f88fc30937180ff7d1f771062,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239453,raw_only_unproven,,,,out_of_release +FUSE,122,Avatar,gooddollar_owned,published+registry,0xf96dadc6d71113f6500e97590760c924da1ef70e,0xf96dadc6d71113f6500e97590760c924da1ef70e,Avatar,1,1,6246330,9223372036854775807,true,6246330,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x8a27316984da83331e574723efd0810faf4d7065f3037b8778d9c572ea49c6d8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239459,raw_only_unproven,,,,out_of_release +FUSE,122,BulkWhitelist,gooddollar_owned,published,0x3b0f4974eb53fe7ca16ac311ebf1cd183d7d63cd,0x3b0f4974eb53fe7ca16ac311ebf1cd183d7d63cd,BulkWhitelist,1,1,30846522,9223372036854775807,true,30846522,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x60344a20cbd88bedbfd88cec885b62ad50c025de6de11abf30abf652d86ebbc4,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239453,raw_only_unproven,,,,out_of_release +FUSE,122,ClaimersDistribution,gooddollar_owned,published+registry,0x1ae4929090258a9d5000d98cfb8a27174d345834,0x264adea794247a7e4dc216c7ca2f1429e3af54a9,ClaimersDistribution,1,1,15740398,9223372036854775807,true,15740398,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xa768b8e29028527a8ad81974daa5507bd4ec7e38f2aba2981664a518953fb852,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0x264adea794247a7e4dc216c7ca2f1429e3af54a9,raw_only_unproven,,,,out_of_release +FUSE,122,CommunitySafe,gooddollar_owned_safe,published,0x5eb5f5fe13d1d5e6440dbd5913412299bc5b5564,0x5eb5f5fe13d1d5e6440dbd5913412299bc5b5564,GnosisSafeProxy,1,1,15067222,9223372036854775807,true,15067222,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239453,raw_only_unproven,,,,out_of_release +FUSE,122,CompoundVotingMachine,gooddollar_owned,published,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,CompoundVotingMachine,1,2,15740389,34980099,false,15740389,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x2e33bb42b9056732aba2fdd606e3427c3b67c927947fd39a8b11c7ce0d8b4ea7,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,CompoundVotingMachine,gooddollar_owned,published,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,0x9373046bbc6d381129b49ac3334881390df1cb13,CompoundVotingMachine,2,2,34980099,9223372036854775807,true,15740389,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x348bfbd3bd8c8386b1b1bd205380278b7efb71070ceb110cc8dafffb5a0748e9,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0x9373046bbc6d381129b49ac3334881390df1cb13,raw_only_unproven,,,,out_of_release +FUSE,122,Controller,gooddollar_owned,published+registry,0xbce053b99e22158f8b62f4dbfbede1f936b2d4e4,0xbce053b99e22158f8b62f4dbfbede1f936b2d4e4,Controller,1,1,6246330,9223372036854775807,true,6246330,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x1cce4814ac502cec7e982e73d29bdc95e9094476ba971b6777f8abd4a415fc26,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239459,raw_only_unproven,,,,out_of_release +FUSE,122,FirstClaimPool,gooddollar_owned,published,0x18bcdf79a724648bf34eb06701be81bd072a2384,,unknown,1,0,,,false,,"not applicable, no code is deployed at this address",no_code_deployed,none,none,none,,no_code_at_pinned_block: A published artifact or the registry names this address and nothing is deployed there,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,read at block 44228002,raw_only_unproven,,,,out_of_release +FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,uninitialised,1,12,9287140,18632009,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0x7a73f1fa2d9d24b6e8b02aae83eb348d51440623,FuseFaucet,2,12,18632009,18632133,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xa550b4543e2d05be80f569cbc0da17bb404d897f4609b7bf14c33aa0c2774bdc,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0xbded8cf5629732956d58d85b6cc619d83778a226,FuseFaucet,3,12,18632133,18632465,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xba02cd4c27b29b745d4a2ba2436a2ce5b17105fff5ca296a9758e2ca9a58ad34,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0xc9f33d360ed722fb8f26209b402b58494ef8f54b,unknown,4,12,18632465,18632495,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0x39a2ce0c262ea1305f3d2262e66a7818ee30e6d2d15bfadcd988c6b6c09bda9f,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0xc0753ae7d5e010083035090b405110ed8323d07e,FuseFaucet,5,12,18632495,18839080,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x72d4da8afd26f9a92ad5d8d4b9f266b8dfb96dd1489ef6a097fc9fb97b8558c4,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0x6c8efc4ab75b834ee9e7f2d9fa96b09724fbf4d3,FuseFaucet,6,12,18839080,18845979,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x49d2add807ef458e4f02bc0e8c8582a11b0daec746d2a66055e71f7001c6bdd1,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0x06b5b324baa4e7d1c9a8137f0e82ebb780b3570e,FuseFaucet,7,12,18845979,22038735,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xc94d58b41bcdb02ddc252624b2acc79db4ddb6eeced07ca4a01dd2d9ba65ba87,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0x6ba541e6f4e7df758b98d0117c6ccd353eccc728,FuseFaucetV2,8,12,22038735,22880830,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xcf67b2cd16ce05fc9a29179de4b0268c573abbcfc925548b92f0f9e3d7a1b570,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0xa528531d648cfb3cda91cda71c7ec6a172bcbd04,FuseFaucetV2,9,12,22880830,24304872,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x1bb2ff96e0e4302438331fbceae937a1f6291f4bf69cc490dbb2a4b87e51aaa7,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0x2e4fdb111b46a15987c275d8472d51bfb16597c5,FuseFaucetV2,10,12,24304872,38606265,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x12eaef1325c901bfe07bffcc431c027734f0a56617d3b0fcaff3e4668c232dad,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0x49ddbcc575c0a813a453fe4466e5a08449bd533d,FuseFaucetV2,11,12,38606265,38607227,false,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x194cf0e8579c60f4ba5c61e5eda5f1dc0c21e169f446a35c8d082d7c6e78d2e5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseFaucet,gooddollar_owned,published,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,0x6b7405c75d461237fc89dac475dcbfbe1459f10f,FuseFaucetV2,12,12,38607227,9223372036854775807,true,9287140,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x93ae3699136504d4e9a3598e91dd3e7b0a849299e9015f5787214959e897df4b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0x6b7405c75d461237fc89dac475dcbfbe1459f10f,raw_only_unproven,,,,out_of_release +FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0xa199f0c353e25adf022378b0c208d600f39a6505,uninitialised,1,16,8815068,8824926,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0x9f9ff3720dba5f0e67e28ecfba5e433b0d271204,FuseStakingV3,2,16,8824926,9471687,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xd4c46219d523a73f3cb19758721142cce51552ac0ba44d5cb62b758f185a2f2a,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0x7fca2b3e1047291f65c2c914083d970c027f4290,FuseStakingV3,3,16,9471687,11531487,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xa676484e5aee5866227ccf5d6002f08449eb8fcc942ccd328008d8c68e4919c8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0x1e3a43799b4e68c7d872ebece91a6389c0d8844c,FuseStakingV3,4,16,11531487,11614374,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xb7b3c3278570684855b5b3f65dde9c00fbb99d30704702133296f919aa3149d0,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0x8141208203c298f07ddcd794b14722e69aa42549,FuseStakingV3,5,16,11614374,11850342,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x49998619549fd712f25d82ef5ccf804c2625b6eeaa49ba51c9f4a1e7e01b8516,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0xfda6a8aee1a909e1cc7da28b34f61b32e4e9a74a,FuseStakingV3,6,16,11850342,11868104,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x9f5cab50812967e338ad9b7ffbcc4a5bf1c079523dca773b39f7bba3c88e23c2,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0xd980a608abd9566c87bb4e60302259858766b996,FuseStakingV3,7,16,11868104,11868821,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x33617b9c20ab11715c1c20bc5e003962eaa505d2efc02786284c7c169cef2cd5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0x53f650758deff504f4e5a327f11f44275a710aa9,FuseStakingV3,8,16,11868821,11869054,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x44f7c970e0af4baafbecaf6da425541b537113e37a46484bcbc40c04a57db7b7,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0xbd1f52ab9f30483796d33fa7a4e7371b043dbbe6,unknown,9,16,11869054,11869227,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0x5850debc7391a2be27ce29315d9ce94d81da3050a01314ea9e5c4a53c0152642,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0x2560f53027fd1800174f842f071abd52521f0807,FuseStakingV3,10,16,11869227,15989875,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x16efe88328a1b5f228c9940964e941179d0d13099492ef5b8a448c68edaaf54b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0xf2c42adcc899871f1a8aa1a313702b4e7ebff9f5,FuseStakingV3,11,16,15989875,18632672,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x3f65eda9b2f53a0a631162bc7f21f9b69535f9899677e71cf1a7ccf127d4f028,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0x2e15da5e7b0c9861272912454f2382949beca07c,FuseStakingV3,12,16,18632672,18633445,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xbacf533d1ebe195b54f0f6de8109fe90d4927097656c39b7108625d7b7ca9899,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0xb51ed83bd8329ab1712a4698864e6d2871c38fc7,FuseStakingV3,13,16,18633445,20715888,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xaf26d0e166dda1de9e5e962c47a23e4f191a347dd2438fed2b5da341d5889012,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0x720d18ebeac3326098b96201ffe32b580508d018,FuseStakingV3,14,16,20715888,24976379,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x5c196350dbe9eb2637e70a35cc66037e56863c9f97156a0a692265f80dfaeb2e,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0xe2491656c5657b87b09e5adea27bd637a8953395,FuseStakingV3,15,16,24976379,27047375,false,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x3119ba292007d0b3d540a4d4e064aef8af1ca2456668bf92957250afa3c56e82,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,FuseStaking,gooddollar_owned,published,0xa199f0c353e25adf022378b0c208d600f39a6505,0x7c723bbeb808b74fb63fc1cb09ffa43d66a96390,unknown,16,16,27047375,9223372036854775807,true,8815068,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0xba742d73273e51079257a3e68f403e661e886ea6e32afb7dbfe9a2282b0a6953,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0x7c723bbeb808b74fb63fc1cb09ffa43d66a96390,raw_only_unproven,,,,out_of_release +FUSE,122,GDAO_STAKING,gooddollar_owned,registry,0x280226a143b7dfdf84645006e32f899b531c2f98,0x280226a143b7dfdf84645006e32f899b531c2f98,unknown,1,1,15747396,9223372036854775807,true,15747396,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,none,0x5e11c717620e654220b2a30bb69874f18bbbc438cfbebbc60ff05a9c33803614,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239453,raw_only_unproven,,,,out_of_release +FUSE,122,GoodDollar,gooddollar_owned,published+registry,0x495d133b938596c9984d462f007b676bdc57ecec,0x495d133b938596c9984d462f007b676bdc57ecec,GoodDollar,1,1,6246330,9223372036854775807,true,6246330,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x554945bfa422af5800554ef7b37f229465f13208db908d482249f1dd9803a3c0,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239453,raw_only_unproven,,,,out_of_release +FUSE,122,GoodDollarMintBurnWrapper,gooddollar_owned,published+registry,0x031b2b7c7854dd8ee9c4a644d7e54ad17f56e3cb,0x716031ae7db1a5c07b24ed3b651d5f57945e1ac3,GoodDollarMintBurnWrapper,1,1,22035558,9223372036854775807,true,22035558,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xa2822dc882ca15bfae3ad35a44bd5129746267dec37a19844bb2f59675aec288,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0x716031ae7db1a5c07b24ed3b651d5f57945e1ac3,raw_only_unproven,,,,out_of_release +FUSE,122,GovernanceStaking,gooddollar_owned,published,0xfaf457fb4a978be059506f6cd41f9b30fca753b0,0xfaf457fb4a978be059506f6cd41f9b30fca753b0,GovernanceStaking,1,1,14149736,9223372036854775807,true,14149736,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x2d112154566a9ba4f271ef486aa2f5dd6843e134d03e7aa456359d12325f849d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239459,raw_only_unproven,,,,out_of_release +FUSE,122,GovernanceStakingV2,gooddollar_owned,published+registry,0xb7c3e738224625289c573c54d402e9be46205546,0xb7c3e738224625289c573c54d402e9be46205546,GovernanceStaking,1,1,15956809,9223372036854775807,true,15956809,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x813356a3f27cf275db45b87b8823a3d9fb90534dbf0749962fd57c95fca57e61,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239459,raw_only_unproven,,,,out_of_release +FUSE,122,GReputation,gooddollar_owned,published+registry,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,0xdeef7c187a9e254ded7b503ac5703adc7b3b15e6,GReputation,1,3,15740330,15890735,false,15740330,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xbc782ccf8b3bd3538e5e81fb0cd55832a712f5bc83dd0693b7e7e4bf7ec5657d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,GReputation,gooddollar_owned,published+registry,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,0x418accc2e62cc3745d67ef6b779c441ff223fc27,GReputation,2,3,15890735,22365120,false,15740330,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x0d4bf8c2025617b7d7d51131e6c74eb95e48f4dfa9f6b58688badd38c1c12bc8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,GReputation,gooddollar_owned,published+registry,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,0x2845b2ff94d01355bdf5bab2333a5c173a803c3d,GReputation,3,3,22365120,9223372036854775807,true,15740330,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xbe55b28d2684d22fe78fad3d4b2357fef68796bc17eecc548e673d8b91798a8e,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0x2845b2ff94d01355bdf5bab2333a5c173a803c3d,raw_only_unproven,,,,out_of_release +FUSE,122,GuardiansSafe,gooddollar_owned_safe,published,0x5878123fe880881f1ecc92d5fd31e5d3f5fba2e9,0x5878123fe880881f1ecc92d5fd31e5d3f5fba2e9,GnosisSafeProxy,1,1,20403981,9223372036854775807,true,20403981,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239453,raw_only_unproven,,,,out_of_release +FUSE,122,HomeBridge,gooddollar_owned,published+registry,0xd39021db018e2caeadb4b2e6717d31550e7918d0,0xd39021db018e2caeadb4b2e6717d31550e7918d0,EternalStorageProxy,1,1,8028888,9223372036854775807,true,8028888,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x2d05a6bd0ad793d9459975bf7760dcbfefa24baf8c7f70efa4aab6b52db668bb,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239459,raw_only_unproven,,,,out_of_release +FUSE,122,Identity,gooddollar_owned,published+registry,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,0xf36b3394235965aa0605fb09eb319eb3586c9ed1,IdentityV2,1,4,22022901,22365120,false,22022901,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x4f2dde9da36f569ba703900471653202ceb84560492a6843cbae6909a9e0dfe9,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,Identity,gooddollar_owned,published+registry,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,0xc1956c99fd3209e30c0746dfd4d4f11d03cc0e9a,IdentityV2,2,4,22365120,38729068,false,22022901,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x004e7e548478ce0b95023a5c5c1f6b47db746932cb69b4ea1d8fc0d8fce9c843,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,Identity,gooddollar_owned,published+registry,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,0x4111a54797e11043def22c4a0240e1605fd7b719,IdentityV3,3,4,38729068,40887165,false,22022901,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x5055517bed3931aaf7fdba386b96fd4047da82a04291aa8c3fae3ee9a3811a27,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,Identity,gooddollar_owned,published+registry,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d,IdentityV4,4,4,40887165,9223372036854775807,true,22022901,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xb88131c06ca0eacac2f89760bcdfb43e25c34ce0a0a80b5a7d6f0cb66995e93c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d,raw_only_unproven,,,,out_of_release +FUSE,122,IdentityOld,gooddollar_owned,published,0xfa8d865a962ca8456df331d78806152d3ac5b84f,0xfa8d865a962ca8456df331d78806152d3ac5b84f,Identity,1,1,6246324,9223372036854775807,true,6246324,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x83c740a8ac588a566556553a334afdfded5add581f27efc0215d3ccfd842eaad,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239459,raw_only_unproven,,,,out_of_release +FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,uninitialised,1,13,8853311,9117508,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xe2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a,44232298,44310564,out_of_release +FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0x0e9c269afd9ee20a349507c61092f58a636a1ed3,InvitesV1,2,13,9117508,11656836,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xfbeb86b2899df3187344633457846e24a96059037e85ae12ee4e86d19d3e4344,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xe2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a,44232298,44310564,out_of_release +FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0x0c8e02371de8c6ec3a261bd24a419beb19171558,InvitesV1,3,13,11656836,14140137,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x9f67a124f4c0343d454188abf9e0f52e163413efd83de49e16ac58ced2205115,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xe2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a,44232298,44310564,out_of_release +FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0x1394a4658f88e40a6f7673136f533157dfb6ba20,InvitesV1,4,13,14140137,14208467,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x621d961ddc680d661939a30bed3d20b84d95b555dc153930c7770c6775278f74,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xe2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a,44232298,44310564,out_of_release +FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0xdd45a44f2e11fb95d1be4ac41501ca0b8cd60de7,InvitesV1,5,13,14208467,16820893,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x6c2bbf91f0f6e7c0370a02ac530857699d87c4ab4981bf910c2b09d5c3c1c8d7,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xe2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a,44232298,44310564,out_of_release +FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0xd97ecd0487293e0e2b0b52f37eeb2951d69d43f0,InvitesV1,6,13,16820893,16821011,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x6aebe73bfaff44b2528c9143aa08ed9e1e1e4e221283b2ee227b06912150f1ab,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xe2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a,44232298,44310564,out_of_release +FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0x3ac09cfaa27c830693c55d5454ca39ced7b9cf3a,InvitesV1,7,13,16821011,22038741,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x5bb2bc7ec822c0ef08bb205d62c6d58f1dd3bc0456401ddca6bb10a299d350ea,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xe2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a,44232298,44310564,out_of_release +FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0x4461384c11a73948ab62fd489478f7bbc3166528,InvitesFuseV2,8,13,22038741,22592960,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x7f8487911e5572fc99bad7bb765a3407aff0745246d320a31e8b5618966e3e04,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xe2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a,44232298,44310564,out_of_release +FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0xc5a2c8c6dbac1f1c934f9651733758ff3ba06345,InvitesFuseV2,9,13,22592960,22810725,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xbecdca30eb58e2a3bc2719c1829409b4fff6044fa88d5bab869382dac185ac73,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xe2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a,44232298,44310564,out_of_release +FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0x618dc4c8f5aa433b6c8e03da1e69d299c6c49ef6,InvitesFuseV2,10,13,22810725,24219845,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x5297a1637435daa8cf4a158b7563506883c6ddffb65ffac0460c3e2df124da05,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xe2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a,44232298,44310564,out_of_release +FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0x4072cb2d7e95def1559f6f72491039fe0534fa37,InvitesFuseV2,11,13,24219845,25470784,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x6b19fd3a33c6bbe6439c35d77bdb8c10a43bf746b45f034d4241d22f8f4c0453,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xe2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a,44232298,44310564,out_of_release +FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0xef577898972e72c7bc03791d22f79c0056917517,unknown,12,13,25470784,25470814,false,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0x4d6d28c57b14136bfc1ee4e0eedcb8767c6d91b05fa14abad67006c0fac6722f,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xe2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a,44232298,44310564,out_of_release +FUSE,122,Invites,gooddollar_owned,published,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,0x502aa6663621759d299f15bd967d53431daa9503,InvitesFuseV2,13,13,25470814,9223372036854775807,true,8853311,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xddbdc81478111ab6a561e0e747fc450e1d33930594566ffd7f3526168c74b222,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0x502aa6663621759d299f15bd967d53431daa9503,raw_only_unproven,0xe2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a,44232298,44310564,out_of_release +FUSE,122,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,uninitialised,1,6,25464921,25464924,false,25464921,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0xd3b5bfdacb042a89bbabad2376aa1a923b365a14,MessagePassingBridge,2,6,25464924,34980099,false,25464921,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x708c90e202c4b8508c0c7ade2ea51ebfc5ec98b2f7ff38060bb2490c8823124e,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0xfcd61ccb982ce77192e3d18a5ae3326dce0b6874,MessagePassingBridge,3,6,34980099,38729068,false,25464921,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xf68c6a526808dc147f00d3f891c6f32a37abeaeb4332cc83fde6ba1fd6e0e240,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x6f252280eb53df085ead27bbe55d615741a8268d,MessagePassingBridge,4,6,38729068,39455704,false,25464921,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x5046d22320e05430d464b6c2f01533594448d625c0c6554a3f5529895c582d49,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0xfb62aa509a7b260b6697b671c969a184d6c39e90,MessagePassingBridge,5,6,39455704,40887165,false,25464921,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xbe09161676ba22506d184c3b979a289bec312079fc94c338763b5431a0def5bd,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,out_of_release +FUSE,122,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0xcac4215c57ef199210e759af92bcad012f61e7a1,MessagePassingBridge,6,6,40887165,9223372036854775807,true,25464921,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x186ca006b94443015386d2fb2eccec5b0932885d174449a97dd1b54900041b3b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0xcac4215c57ef199210e759af92bcad012f61e7a1,raw_only_unproven,,,,out_of_release +FUSE,122,MultichainRouter,third_party_infrastructure,published,0x735abe48e8782948a37c7765ecb76b98cde97b0f,0x735abe48e8782948a37c7765ecb76b98cde97b0f,AnyswapV6Router,1,1,21863761,9223372036854775807,true,21863761,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0xc309902226a63a7279065be321792f1669adb7b0c96a2909e587aafcb59715ee,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239453,raw_only_unproven,,,,out_of_release +FUSE,122,NameService,gooddollar_owned,published,0xec6dce387b1616a0c44ff2e4fa9e90e53cf14eb0,0xba3f1ba4eb215204385107e76c11894b876ecf40,NameService,1,1,15740314,9223372036854775807,true,15740314,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x14430756d9064b0f9d3f50f024ec5de5fcef5dcaa35d6c79da463848fb687aa3,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0xba3f1ba4eb215204385107e76c11894b876ecf40,raw_only_unproven,,,,out_of_release +FUSE,122,OneTimePayments,gooddollar_owned,published,0xd9aa86e0ddb932bd78ab8c71c1b98f83cf610bd4,0xd9aa86e0ddb932bd78ab8c71c1b98f83cf610bd4,OneTimePayments,1,1,6248705,9223372036854775807,true,6248705,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0xe7a0e7797844d5adccfdac8ad5cec77c4c9484ada37964b99178f29a4265132d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239459,raw_only_unproven,,,,out_of_release +FUSE,122,ProtocolUpgradeFuseRecover,gooddollar_owned,published,0xbe43ecb37af7f7c4a8606e672c504be55fc6226b,,unknown,1,0,,,false,,"not applicable, no code is deployed at this address",no_code_deployed,none,none,none,,no_code_at_pinned_block: A published artifact or the registry names this address and nothing is deployed there,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,read at block 44228002,raw_only_unproven,,,,out_of_release +FUSE,122,ProxyAdmin,gooddollar_owned,published,0x57179b2a8eb019157b0c3e761cdb26c82c982a3b,0x57179b2a8eb019157b0c3e761cdb26c82c982a3b,ProxyAdmin,1,1,8815067,9223372036854775807,true,8815067,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x2b57f0728a5ffe03a475faab83005c468d0f669c0a473f87425e3edb6101ec8a,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239453,raw_only_unproven,,,,out_of_release +FUSE,122,ProxyFactory,gooddollar_owned,published,0xda85fced9bd193526b7667f2ad1fd4a0f900d3a7,0xda85fced9bd193526b7667f2ad1fd4a0f900d3a7,ProxyFactory1967,1,1,15740066,9223372036854775807,true,15740066,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,single_era_no_proxy_slot,contract_creation,none,blockscout_verified_source,0x1a30c8ca34283aa6a8722d626c290a575108a1e4d7d018db6faf46c77e1f19a3,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 44239459,raw_only_unproven,,,,out_of_release +FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0xfaa48a6b603985a507f18ad7f453f784f1faa025,UBIScheme,1,13,15747401,15748014,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x26e78908c4cd0f264d2e1d3b0dbf5a7bd6e299f0dd31bc7a9dd1c9e67a81af16,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0x96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f,44232298,44310564,out_of_release +FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0xf288e44c7e5baa05b2de9d916e53b67c183e46e0,UBIScheme,2,13,15748014,15750751,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xf628c8c1cf0d0d53ec9c88e85dfb422ffc89839541a89fac1efe9c0f2ae3dd37,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0x96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f,44232298,44310564,out_of_release +FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0x0d7014649e6f5979d2a09a3d3ad2d3ae3eefb42e,unknown,3,13,15750751,15750869,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0x670e3daf264fd6c903e42b79bf8ccc5e76dcf5dc5513430d325dc3d43edb9c1c,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0x96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f,44232298,44310564,out_of_release +FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0x8294378a45b52389d45b623d0191f7285f4f047f,unknown,4,13,15750869,15750920,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0x3129f20edac3fba2d1542b9dac36cff87ee84fbea1be91bccd2b57d2228469d9,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0x96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f,44232298,44310564,out_of_release +FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0xa99ba154223052b8c5fd92b3f5df9eb08b72d5fc,unknown,5,13,15750920,15750929,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0x3bf18751bd05d7d99b711df861d2e6d3b5c2906bf8a92a9421bb58b30438007e,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0x96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f,44232298,44310564,out_of_release +FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0x8294378a45b52389d45b623d0191f7285f4f047f,unknown,6,13,15750929,15751049,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0x3129f20edac3fba2d1542b9dac36cff87ee84fbea1be91bccd2b57d2228469d9,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0x96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f,44232298,44310564,out_of_release +FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0x76eb96616514adac35152155bbc614272f0601b3,UBIScheme,7,13,15751049,17896941,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x678b37494b483f090daecee4968024b0b4f3f6db76535944386d9888832377d0,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0x96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f,44232298,44310564,out_of_release +FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0x11f077ae87952948de96b975a805ebaa20eada12,unknown,8,13,17896941,17913778,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),none,0xadd201c864e8059b8c41a9ad02cc803533813245ef715215bf5f9334da97391f,"no_verified_abi: The event surface for this era is UNKNOWN, which is not the same as empty",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0x96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f,44232298,44310564,out_of_release +FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0x306cd90bfefb7e409f089a1bde1aa77bbc4cb660,UBIScheme,9,13,17913778,17913899,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x1639c60ee4892fbabcfd640f63fb854c7888f340eb2ef9d2b3dcd2996dae01a5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0x96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f,44232298,44310564,out_of_release +FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0xb22764dce0960b61c5a8d688f075857632917a93,UBIScheme,10,13,17913899,17927761,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x75360d28f3bde7f7e61b820000583ffeacfa138af7360b858b4d4ad0c61f069e,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0x96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f,44232298,44310564,out_of_release +FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0xbb6dff610ecbea25a6c57b086ef92c6724306a76,UBIScheme,11,13,17927761,25635053,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xa2242ec4a9520cb7f7a978505ed5821044cc7a5cfbcee7138618130510da306d,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0x96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f,44232298,44310564,out_of_release +FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0x1c90f733e1724bd1db47f84cde4f9e83087cfb6d,UBIScheme,12,13,25635053,38729068,false,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0xff3d518029b7db924159838cb0e890a960865d2861529e2208f87efdcc373d98,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0x96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f,44232298,44310564,out_of_release +FUSE,122,UBIScheme,gooddollar_owned,published+registry,0xd253a5203817225e9768c05e5996d642fb96ba86,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,UBISchemeV2,13,13,38729068,9223372036854775807,true,15747401,blockscout_creation_tx_block_confirmed_by_reading_the_block_on_two_or_more_nodes,announcement_logs_only,announcement_log_only,Upgraded(address),blockscout_verified_source,0x409fd8ecff99ab5fb8082d4f683259854d7ee0af6b66ce8c5dab16ecd3a2f47b,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot. confirmed: The slot at the rolling pin holds 0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,raw_only_unproven,0x96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f,44232298,44310564,out_of_release +XDC,50,AdminWallet,gooddollar_owned,published,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,0xa7f4717bf6e7d27d7c855d5f4a869e96bd16d873,AdminWallet,1,2,95144743,95866130,false,95144743,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x9e231a1f32074c2535d1793d1a863dbe4ddb5438f6f6ef526fd87ab683dff181,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +XDC,50,AdminWallet,gooddollar_owned,published,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,0x68dbe795ee2219437299bb23d70311e3b7c69f9a,AdminWallet,2,2,95866130,9223372036854775807,true,95144743,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xb18bdf42222c3100c99f40bbb2fe56734e863977f1beebe0527148d2b44b70b5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +XDC,50,Avatar,gooddollar_owned,published+registry,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,Avatar,1,1,95143598,9223372036854775807,true,95143598,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x8a27316984da83331e574723efd0810faf4d7065f3037b8778d9c572ea49c6d8,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851,raw_only_unproven,,,,in_release +XDC,50,BulkWhitelist,gooddollar_owned,published,0xe8861a20452db53df685f1d9e6b7017de3db0e46,0xe8861a20452db53df685f1d9e6b7017de3db0e46,BulkWhitelist,1,1,97033779,9223372036854775807,true,97033779,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x554fc53842f02a76351be11bad71cbd6ff31cbd4a8b4c0513f068e12527fb720,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851,raw_only_unproven,,,,in_release +XDC,50,Controller,gooddollar_owned,published+registry,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,Controller,1,1,95143598,9223372036854775807,true,95143598,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x1cce4814ac502cec7e982e73d29bdc95e9094476ba971b6777f8abd4a415fc26,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851,raw_only_unproven,,,,in_release +XDC,50,CUSD,third_party_token,published,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,FiatTokenV2_2,1,1,92678020,9223372036854775807,true,92678020,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x231f4b29fe5be8f3ae57a88ce9c67fed31128c6588cd35e4da397f04f6cbc1c3,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,zeppelinos pre 1967 slot,raw_only_unproven,,,,in_release +XDC,50,DAOCreator,gooddollar_owned,published,0xa2b9993d198904e4bdce48379fdff65405607f42,,unknown,1,0,,,false,,"not applicable, no code is deployed at this address",no_code_deployed,none,none,none,,no_code_at_pinned_block: A published artifact or the registry names this address and nothing is deployed there,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,read at block 107576851,raw_only_unproven,,,,in_release +XDC,50,DistributionHelper,gooddollar_owned,published+registry,0xb8a0d4b97327a0b6dd0705dc290ae26aa38a7d2b,0x971fdacd201cdaa741db06d580eb634b02307926,GenericDistributionHelper,1,1,100111925,9223372036854775807,true,100111925,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x409c0dc6ff42f770c99147d26af9e12a6f90e807bf198937bfe5a59f0179116c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +XDC,50,Faucet,gooddollar_owned,published,0x7344da1be296f03fbb8082adac5696058b5a9bd9,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,Faucet,1,3,95144750,95325786,false,95144750,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x3072e58a72b2536637e3827c180dc2763faaeb267035deec1436b343afedb4c6,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +XDC,50,Faucet,gooddollar_owned,published,0x7344da1be296f03fbb8082adac5696058b5a9bd9,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,Faucet,2,3,95325786,95327264,false,95144750,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x68755099f25764af194ff16c1f4a6fd14bdd4bd89a1c3f6832649a36508e6533,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +XDC,50,Faucet,gooddollar_owned,published,0x7344da1be296f03fbb8082adac5696058b5a9bd9,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,Faucet,3,3,95327264,9223372036854775807,true,95144750,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xe8429a22753ce3f82c856a7f5dee88264782d956d615db983d0cd5ec8e9fb325,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +XDC,50,FeeFormula,gooddollar_owned,published,0xf4e9af892a09f04b7408266777198206e7f80d46,0xf4e9af892a09f04b7408266777198206e7f80d46,FeeFormula,1,1,95143060,9223372036854775807,true,95143060,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xb10599b90c45878333139dfa098974b8df30eba5596654ef05c46daa2a6f0847,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851,raw_only_unproven,,,,in_release +XDC,50,GoodDollar,gooddollar_owned,published+registry,0xec2136843a983885aebf2feb3931f73a8ebee50c,0x0000000000000000000000000000000000000000,uninitialised,1,3,95143070,95143245,false,95143070,explorer_index_and_state_read_agree,bisection_and_announcement_union,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +XDC,50,GoodDollar,gooddollar_owned,published+registry,0xec2136843a983885aebf2feb3931f73a8ebee50c,0x6936441113610483cc5b6a7adec4b45303b297a9,SuperGoodDollar,2,3,95143245,107529281,false,95143070,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_only,none,etherscan_v2_verified_source,0xf1ef96de94aefc5848537637a56767402734cf35f4763e1f4e326c3e56ee457a,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +XDC,50,GoodDollar,gooddollar_owned,published+registry,0xec2136843a983885aebf2feb3931f73a8ebee50c,0x1db2f592014a9394604bf6381f025754579547ec,SuperGoodDollar,3,3,107529281,9223372036854775807,true,95143070,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,"CodeUpdated(bytes32,address)",etherscan_v2_verified_source,0x2157adffb2622cfac69e299e2de636551391eddba892b5dd0c1b9f6469bb38f5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +XDC,50,GuardiansSafe,gooddollar_owned_safe,published,0xe0c5daa7cc6f88d29505f702a53bb5e67600e7ec,0xe0c5daa7cc6f88d29505f702a53bb5e67600e7ec,GnosisSafeProxy,1,1,95134102,9223372036854775807,true,95134102,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851,raw_only_unproven,,,,in_release +XDC,50,Identity,gooddollar_owned,published+registry,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,IdentityV3,1,2,95143058,100340676,false,95143058,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x01ec062dc685b7aec5b7e7574302648c016d25423b86a8a999cbf05ee6ed3a85,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +XDC,50,Identity,gooddollar_owned,published+registry,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,0x28830934ad2146e7a273fd394f706571c2d09373,IdentityV4,2,2,100340676,9223372036854775807,true,95143058,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x307c50e010de98eed4870743567fd1ad954811f59b99752b709dc18bbf868eab,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +XDC,50,Invites,gooddollar_owned,published,0x6bd698566632bf2e81e2278f1656cb24aaf06d2e,0xb22bb27d920a4efdafaa03a51e8a4c41e4cc4217,InvitesV2,1,2,95144756,100123036,false,95144756,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x5da156e5a7ff212885d03e8f52531c50f273d7b9410a07177379859562a5acc5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xcb8df3ee7a647f0ab6e6b6709fa25bfb73a39545a82ef803c3c1ae212488fd44,107576851,107765548,in_release +XDC,50,Invites,gooddollar_owned,published,0x6bd698566632bf2e81e2278f1656cb24aaf06d2e,0x783548481a6ca92b6589365161b31e3ed64d0c3c,InvitesV2,2,2,100123036,9223372036854775807,true,95144756,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x9c0c0028170b3295f0555171e63b4150b56b7ec427b9f26eb0c21a8dd7662df5,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0xcb8df3ee7a647f0ab6e6b6709fa25bfb73a39545a82ef803c3c1ae212488fd44,107576851,107765548,in_release +XDC,50,MentoBroker,third_party_mento,published,0x88de45906d4f5a57315c133620cfa484cb297541,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,Broker,1,2,100091095,100340676,false,100091095,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),bytecode_equality_with_celo_0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,0x58558a86a3aced5b23ae279244bd285f68c9d6d0a20cf283b7a40a0784697831,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"eip1967 implementation slot. bisection says 0xc22505d3a6ae087c0bd4715a56c38b7a029477b2, announcement says 0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2",raw_only_unproven,,,,in_release +XDC,50,MentoBroker,third_party_mento,published,0x88de45906d4f5a57315c133620cfa484cb297541,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,Broker,2,2,100340676,9223372036854775807,true,100091095,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x2e63673ca3232bd818d12804ade7e1d688b7c11da7812d0237a3564e99cd0fb7,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +XDC,50,MentoExchangeProvider,third_party_mento,published,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,0xd9ce916d711977d5b27697a13964556b4fb8af1d,GoodDollarExchangeProvider,1,2,100091095,100340676,false,100091095,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x65d8c817bac8f41eb34548c15ad6ae5e744da2bd5373916df3b8e63f1fecd916,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"eip1967 implementation slot. bisection says 0xd9ce916d711977d5b27697a13964556b4fb8af1d, announcement says 0x66375ec587d8482d77cf7529a8479c3fa85c850f",raw_only_unproven,,,,in_release +XDC,50,MentoExchangeProvider,third_party_mento,published,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,0xe930cde20f60d0a4fc9487874861ae259f5bed48,GoodDollarExchangeProvider,2,2,100340676,9223372036854775807,true,100091095,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x5ed71ccf7c4789f438827e074bc8bba84c7fc2c615495b12a2f9c51398a8b0d5,carried_from_seed: ExchangeUpdated event added. Not currently consumed.,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +XDC,50,MentoExpansionController,third_party_mento,published,0x5557e9def86ad6564462741a7a3f3679c1223f5d,0x7288d592e1b9013c668801f722be650993d2925a,GoodDollarExpansionController,1,1,100091095,9223372036854775807,true,100091095,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x9da4f4203282696d49deb0c241e49e0ff09f8b6da2d463f69f3fc98e66899a74,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +XDC,50,MentoProxyAdmin,third_party_mento,published,0x8471406c3bff67cc6538481c8550364bda6ca691,0x8471406c3bff67cc6538481c8550364bda6ca691,ProxyAdmin,1,1,98383258,9223372036854775807,true,98383258,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xdd44d5a52707f76ac1bb4147820056bd47ca2c90f79d82fdaeb19b7d180179b4,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851,raw_only_unproven,,,,in_release +XDC,50,MentoReserve,third_party_mento,published,0x94a3240f484a04f5e3d524f528d02694c109463b,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,Reserve,1,2,100091095,100340676,false,100091095,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0xe5750e9acc0322eae552526478b90a1a762ea401bf9094ff36daa6d0e4669020,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +XDC,50,MentoReserve,third_party_mento,published,0x94a3240f484a04f5e3d524f528d02694c109463b,0xbdaa65e8175875340365d76a660bb2a7a4efe909,Reserve,2,2,100340676,9223372036854775807,true,100091095,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xe5750e9acc0322eae552526478b90a1a762ea401bf9094ff36daa6d0e4669020,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +XDC,50,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x0000000000000000000000000000000000000000,uninitialised,1,4,95254417,95254421,false,95254417,explorer_index_and_state_read_agree,bisection_and_announcement_union,contract_creation,none,none,,"proxy_deployed_without_an_implementation: The implementation slot read zero from the creation block until the next boundary, so only the events of the proxy contract itself can occur in this window",measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +XDC,50,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0xa7bfc0d36300b5978cfa18301446cad3e855ae06,MessagePassingBridge,2,4,95254421,96841591,false,95254417,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0x039a036cd2a30cc1536d5b5a368c77e7bd870ae3d59c0b699dd5b51439b17838,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +XDC,50,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0xe4cfa18a3d0a7d77faa42961ee943c9221d61937,MessagePassingBridge,3,4,96841591,100340676,false,95254417,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xa5b7233c025a48d44655a945ead941546d2a69fad9cc2dec4c1a1ef033498a08,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +XDC,50,MpbBridge,gooddollar_owned,published+registry,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,0x00f7f61080ef40d3832c8c06e8a2af757839e1f7,MessagePassingBridge,4,4,100340676,9223372036854775807,true,95254417,explorer_index_and_state_read_agree,bisection_and_announcement_union,slot_bisection_and_announcement_log,Upgraded(address),etherscan_v2_verified_source,0xbacb5fa708349d8fba6d008557d8ed01abb888eb445b8d4bd1b2cceaef833d62,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +XDC,50,NameService,gooddollar_owned,published,0x1e5154bf5e31ff56051bbd45958b879fb7a290fe,0x653c67be5b3739708e84b61641253822405d78d8,NameService,1,1,95143608,9223372036854775807,true,95143608,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0xaa0ffd7041640c8b913e2b76301b0ffa064ee7a84aad1d43b631dac209b7f747,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,,,,in_release +XDC,50,ProxyFactory,gooddollar_owned,published,0x5be34022c26fa03a8d6926314a42414c7ca2df51,0x5be34022c26fa03a8d6926314a42414c7ca2df51,ProxyFactory1967,1,1,95142721,9223372036854775807,true,95142721,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,bytecode_equality_with_celo_0xd86cd6bb3c2a576b2c2cef4e047b1a7adc5be62d,0x7f63d978bb61348d9321e9e9a382a2f88679edb38c483385333d4dbb0760fea9,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851,raw_only_unproven,,,,in_release +XDC,50,StaticOracle,third_party_infrastructure,published,0x725244458f011551dde1104c9728746eebea19f9,0x725244458f011551dde1104c9728746eebea19f9,StaticOracle,1,1,93357551,9223372036854775807,true,93357551,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x511ddd7509fe316b6a954e51453cbfa51e42e7ab82becf2360066ddf1b2084fb,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851,raw_only_unproven,,,,in_release +XDC,50,UBIScheme,gooddollar_owned,published+registry,0x22867567e2d80f2049200e25c6f31cb6ec2f0faf,0xea12bb3917cf6ae2fde97ce4756177703426d41f,UBISchemeV2,1,1,95249624,9223372036854775807,true,95249624,explorer_index_and_state_read_agree,bisection_and_announcement_union,announcement_log_only,Upgraded(address),etherscan_v2_verified_source,0x1a2a42df99ac104b92c4f611df6d9d8e136aecf0875ac9be4dd49ab1be300c5c,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,eip1967 implementation slot,raw_only_unproven,0x4e36ea80731be01541942643f5bc624b1c233c5d429980b8e4ac76517a822c79,107576851,107765548,in_release +XDC,50,UniswapV3Router,third_party_infrastructure,published,0x3b9edecc4286ba33ea6e27119c2a4db99829839d,0x3b9edecc4286ba33ea6e27119c2a4db99829839d,SwapRouter02,1,1,59782347,9223372036854775807,true,59782347,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0xec362365703d4ab51bd8adfb8f580413cba66e152720928a7c975d5197f2d07a,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851,raw_only_unproven,,,,in_release +XDC,50,UniswapV3RouterOfficial,third_party_infrastructure,published,0xaa52bb8110fe38d0d2d2af0b85c3a3ee622ca455,0xaa52bb8110fe38d0d2d2af0b85c3a3ee622ca455,SwapRouter02,1,1,87230719,9223372036854775807,true,87230719,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x5a20e5e77f75c2bc855c4e93352437bfc53301ea95935350f2f4799e898ddd48,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851,raw_only_unproven,,,,in_release +XDC,50,WXDC,third_party_token,published,0x951857744785e80e2de051c32ee7b25f9c458c42,0x951857744785e80e2de051c32ee7b25f9c458c42,WXDC,1,1,42776215,9223372036854775807,true,42776215,explorer_index_and_state_read_agree,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x4e0fcac36e857c9408b310cc1b8dfe2c3e8aff8c199ea1df31c4ebdaccdcc57e,abi_identical_bodies_unreviewed,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,plain contract. slots re-read at block 107576851,raw_only_unproven,,,,in_release +CELO,42220,UpdateReserveRatio,unclassified_pending_ownership_test,discovered,0x1f3d49414e4b7b32a5e23fbca71778df760d97a3,0x1f3d49414e4b7b32a5e23fbca71778df760d97a3,UpdateReserveRatio,1,1,61141715,9223372036854775807,true,61141715,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x83c1d603e8c3ed0dbd3a813582014dc03b823fa18aa71c5fa7786f5640837fff,ownership_unestablished: The verified source name references the GoodDollar reserve and the same creator deployed it on both GoodDollar chains but neither fact is a control relationship. What would settle it is reading whether the protocol Controller or Avatar ever granted this address a role or whether it appears as a caller in a reserve parameter change.,measured_2026_09_24_state_reads_at_a_pinned_block_two_endpoints_agreeing,omission found by factory enumeration and added 2026-09-24. NOT a proxy: EIP-1967 implementation beacon and admin slots and the older OpenZeppelin and EIP-1822 slots and storage slots 0 1 and 2 are ALL zero at the creation block at eight interior probes and at the pin with two agreeing endpoints on every read. Verified source names it UpdateReserveRatio and the index reports Proxy=0. ABI declares ZERO events so it contributes no event_surface row. Creation tx creator is 0x5128e3c1f8846724cc1007af9b4189713922e4bb on BOTH chains which is neither of the ProxyFactory addresses the earlier passes named. Identical runtime bytecode on both chains. slots read at block 78397063,raw_only_unproven,,,,in_release +XDC,50,UpdateReserveRatio,unclassified_pending_ownership_test,discovered,0x2431f53afda24130722dbeb9f9b1b0b8d2fbb197,0x2431f53afda24130722dbeb9f9b1b0b8d2fbb197,UpdateReserveRatio,1,1,100111919,9223372036854775807,true,100111919,etherscan_v2_getcontractcreation,single_era_no_proxy_slot,contract_creation,none,etherscan_v2_verified_source,0x83c1d603e8c3ed0dbd3a813582014dc03b823fa18aa71c5fa7786f5640837fff,ownership_unestablished: The verified source name references the GoodDollar reserve and the same creator deployed it on both GoodDollar chains but neither fact is a control relationship. What would settle it is reading whether the protocol Controller or Avatar ever granted this address a role or whether it appears as a caller in a reserve parameter change.,measured_2026_09_24_state_reads_at_a_pinned_block_two_endpoints_agreeing,omission found by factory enumeration and added 2026-09-24. NOT a proxy: EIP-1967 implementation beacon and admin slots and the older OpenZeppelin and EIP-1822 slots and storage slots 0 1 and 2 are ALL zero at the creation block at eight interior probes and at the pin with two agreeing endpoints on every read. Verified source names it UpdateReserveRatio and the index reports Proxy=0. ABI declares ZERO events so it contributes no event_surface row. Creation tx creator is 0x5128e3c1f8846724cc1007af9b4189713922e4bb on BOTH chains which is neither of the ProxyFactory addresses the earlier passes named. Identical runtime bytecode on both chains. slots read at block 107626168,raw_only_unproven,,,,in_release diff --git a/projects/onchain-analytics/gd_dbt/seeds/era_boundary_evidence.csv b/projects/onchain-analytics/gd_dbt/seeds/era_boundary_evidence.csv new file mode 100644 index 0000000..e048b41 --- /dev/null +++ b/projects/onchain-analytics/gd_dbt/seeds/era_boundary_evidence.csv @@ -0,0 +1,42 @@ +chain,chain_id,proxy_address,era_index,implementation_address,valid_from_block,valid_to_block,open_ended,opening_transition_kind,opening_event_implementation,opening_both_measured,opening_address_agrees,opening_order_agrees,slot_outcome,slot_address,slot_agreeing,slot_error_count,cross_check_blocked,check_points_total,check_points_measured,check_points_disagreeing,claimed_events,independently_confirmed_events,baseline_skipped_chunks,tail_complete,tail_skipped_chunks,tail_error_chunks,obligatorily_emits,frozen_safe_head,boundary_checked_through_block,source_manifest,manifest_sha256 +XDC,50,0x22867567e2d80f2049200e25c6f31cb6ec2f0faf,1,0xea12bb3917cf6ae2fde97ce4756177703426d41f,95249624,9223372036854775807,true,creation_initialisation,0xea12bb3917cf6ae2fde97ce4756177703426d41f,true,true,true,answer,0xea12bb3917cf6ae2fde97ce4756177703426d41f,2,0,false,3,3,0,1,1,0,true,0,0,false,107765548,107576851,XDC-UBIScheme-0x22867567e2d80f2049200e25c6f31cb6ec2f0faf.json,4e36ea80731be01541942643f5bc624b1c233c5d429980b8e4ac76517a822c79 +XDC,50,0x6bd698566632bf2e81e2278f1656cb24aaf06d2e,1,0xb22bb27d920a4efdafaa03a51e8a4c41e4cc4217,95144756,100123036,false,creation_initialisation,0xb22bb27d920a4efdafaa03a51e8a4c41e4cc4217,true,true,true,answer,0x783548481a6ca92b6589365161b31e3ed64d0c3c,2,0,false,5,5,0,2,2,0,true,0,0,false,107765548,107576851,XDC-Invites-0x6bd698566632bf2e81e2278f1656cb24aaf06d2e.json,cb8df3ee7a647f0ab6e6b6709fa25bfb73a39545a82ef803c3c1ae212488fd44 +XDC,50,0x6bd698566632bf2e81e2278f1656cb24aaf06d2e,2,0x783548481a6ca92b6589365161b31e3ed64d0c3c,100123036,9223372036854775807,true,interior_boundary,0x783548481a6ca92b6589365161b31e3ed64d0c3c,true,true,true,answer,0x783548481a6ca92b6589365161b31e3ed64d0c3c,2,0,false,5,5,0,2,2,0,true,0,0,false,107765548,107576851,XDC-Invites-0x6bd698566632bf2e81e2278f1656cb24aaf06d2e.json,cb8df3ee7a647f0ab6e6b6709fa25bfb73a39545a82ef803c3c1ae212488fd44 +FUSE,122,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,1,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,8853311,9117508,false,,,,,,answer,0x502aa6663621759d299f15bd967d53431daa9503,3,0,true,0,0,0,12,0,0,true,0,0,false,44310564,44232298,FUSE-Invites-0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0.json,e2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a +FUSE,122,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,2,0x0e9c269afd9ee20a349507c61092f58a636a1ed3,9117508,11656836,false,interior_boundary,0x0e9c269afd9ee20a349507c61092f58a636a1ed3,false,,,answer,0x502aa6663621759d299f15bd967d53431daa9503,3,0,true,0,0,0,12,0,0,true,0,0,false,44310564,44232298,FUSE-Invites-0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0.json,e2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a +FUSE,122,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,3,0x0c8e02371de8c6ec3a261bd24a419beb19171558,11656836,14140137,false,interior_boundary,0x0c8e02371de8c6ec3a261bd24a419beb19171558,false,,,answer,0x502aa6663621759d299f15bd967d53431daa9503,3,0,true,0,0,0,12,0,0,true,0,0,false,44310564,44232298,FUSE-Invites-0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0.json,e2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a +FUSE,122,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,4,0x1394a4658f88e40a6f7673136f533157dfb6ba20,14140137,14208467,false,interior_boundary,0x1394a4658f88e40a6f7673136f533157dfb6ba20,false,,,answer,0x502aa6663621759d299f15bd967d53431daa9503,3,0,true,0,0,0,12,0,0,true,0,0,false,44310564,44232298,FUSE-Invites-0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0.json,e2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a +FUSE,122,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,5,0xdd45a44f2e11fb95d1be4ac41501ca0b8cd60de7,14208467,16820893,false,interior_boundary,0xdd45a44f2e11fb95d1be4ac41501ca0b8cd60de7,false,,,answer,0x502aa6663621759d299f15bd967d53431daa9503,3,0,true,0,0,0,12,0,0,true,0,0,false,44310564,44232298,FUSE-Invites-0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0.json,e2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a +FUSE,122,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,6,0xd97ecd0487293e0e2b0b52f37eeb2951d69d43f0,16820893,16821011,false,interior_boundary,0xd97ecd0487293e0e2b0b52f37eeb2951d69d43f0,false,,,answer,0x502aa6663621759d299f15bd967d53431daa9503,3,0,true,0,0,0,12,0,0,true,0,0,false,44310564,44232298,FUSE-Invites-0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0.json,e2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a +FUSE,122,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,7,0x3ac09cfaa27c830693c55d5454ca39ced7b9cf3a,16821011,22038741,false,interior_boundary,0x3ac09cfaa27c830693c55d5454ca39ced7b9cf3a,false,,,answer,0x502aa6663621759d299f15bd967d53431daa9503,3,0,true,0,0,0,12,0,0,true,0,0,false,44310564,44232298,FUSE-Invites-0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0.json,e2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a +FUSE,122,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,8,0x4461384c11a73948ab62fd489478f7bbc3166528,22038741,22592960,false,interior_boundary,0x4461384c11a73948ab62fd489478f7bbc3166528,false,,,answer,0x502aa6663621759d299f15bd967d53431daa9503,3,0,true,0,0,0,12,0,0,true,0,0,false,44310564,44232298,FUSE-Invites-0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0.json,e2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a +FUSE,122,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,9,0xc5a2c8c6dbac1f1c934f9651733758ff3ba06345,22592960,22810725,false,interior_boundary,0xc5a2c8c6dbac1f1c934f9651733758ff3ba06345,false,,,answer,0x502aa6663621759d299f15bd967d53431daa9503,3,0,true,0,0,0,12,0,0,true,0,0,false,44310564,44232298,FUSE-Invites-0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0.json,e2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a +FUSE,122,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,10,0x618dc4c8f5aa433b6c8e03da1e69d299c6c49ef6,22810725,24219845,false,interior_boundary,0x618dc4c8f5aa433b6c8e03da1e69d299c6c49ef6,false,,,answer,0x502aa6663621759d299f15bd967d53431daa9503,3,0,true,0,0,0,12,0,0,true,0,0,false,44310564,44232298,FUSE-Invites-0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0.json,e2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a +FUSE,122,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,11,0x4072cb2d7e95def1559f6f72491039fe0534fa37,24219845,25470784,false,interior_boundary,0x4072cb2d7e95def1559f6f72491039fe0534fa37,false,,,answer,0x502aa6663621759d299f15bd967d53431daa9503,3,0,true,0,0,0,12,0,0,true,0,0,false,44310564,44232298,FUSE-Invites-0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0.json,e2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a +FUSE,122,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,12,0xef577898972e72c7bc03791d22f79c0056917517,25470784,25470814,false,interior_boundary,0xef577898972e72c7bc03791d22f79c0056917517,false,,,answer,0x502aa6663621759d299f15bd967d53431daa9503,3,0,true,0,0,0,12,0,0,true,0,0,false,44310564,44232298,FUSE-Invites-0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0.json,e2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a +FUSE,122,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,13,0x502aa6663621759d299f15bd967d53431daa9503,25470814,9223372036854775807,true,interior_boundary,0x502aa6663621759d299f15bd967d53431daa9503,false,,,answer,0x502aa6663621759d299f15bd967d53431daa9503,3,0,true,0,0,0,12,0,0,true,0,0,false,44310564,44232298,FUSE-Invites-0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0.json,e2fd5fe30d305dfc7c2648e6dcefc037e15442ebca5e724e5116309f916b304a +FUSE,122,0xd253a5203817225e9768c05e5996d642fb96ba86,1,0xfaa48a6b603985a507f18ad7f453f784f1faa025,15747401,15748014,false,creation_initialisation,0xfaa48a6b603985a507f18ad7f453f784f1faa025,false,,,answer,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,3,0,true,0,0,0,13,0,0,true,0,0,false,44310564,44232298,FUSE-UBIScheme-0xd253a5203817225e9768c05e5996d642fb96ba86.json,96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f +FUSE,122,0xd253a5203817225e9768c05e5996d642fb96ba86,2,0xf288e44c7e5baa05b2de9d916e53b67c183e46e0,15748014,15750751,false,interior_boundary,0xf288e44c7e5baa05b2de9d916e53b67c183e46e0,false,,,answer,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,3,0,true,0,0,0,13,0,0,true,0,0,false,44310564,44232298,FUSE-UBIScheme-0xd253a5203817225e9768c05e5996d642fb96ba86.json,96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f +FUSE,122,0xd253a5203817225e9768c05e5996d642fb96ba86,3,0x0d7014649e6f5979d2a09a3d3ad2d3ae3eefb42e,15750751,15750869,false,interior_boundary,0x0d7014649e6f5979d2a09a3d3ad2d3ae3eefb42e,false,,,answer,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,3,0,true,0,0,0,13,0,0,true,0,0,false,44310564,44232298,FUSE-UBIScheme-0xd253a5203817225e9768c05e5996d642fb96ba86.json,96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f +FUSE,122,0xd253a5203817225e9768c05e5996d642fb96ba86,4,0x8294378a45b52389d45b623d0191f7285f4f047f,15750869,15750920,false,interior_boundary,0x8294378a45b52389d45b623d0191f7285f4f047f,false,,,answer,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,3,0,true,0,0,0,13,0,0,true,0,0,false,44310564,44232298,FUSE-UBIScheme-0xd253a5203817225e9768c05e5996d642fb96ba86.json,96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f +FUSE,122,0xd253a5203817225e9768c05e5996d642fb96ba86,5,0xa99ba154223052b8c5fd92b3f5df9eb08b72d5fc,15750920,15750929,false,interior_boundary,0xa99ba154223052b8c5fd92b3f5df9eb08b72d5fc,false,,,answer,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,3,0,true,0,0,0,13,0,0,true,0,0,false,44310564,44232298,FUSE-UBIScheme-0xd253a5203817225e9768c05e5996d642fb96ba86.json,96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f +FUSE,122,0xd253a5203817225e9768c05e5996d642fb96ba86,6,0x8294378a45b52389d45b623d0191f7285f4f047f,15750929,15751049,false,interior_boundary,0x8294378a45b52389d45b623d0191f7285f4f047f,false,,,answer,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,3,0,true,0,0,0,13,0,0,true,0,0,false,44310564,44232298,FUSE-UBIScheme-0xd253a5203817225e9768c05e5996d642fb96ba86.json,96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f +FUSE,122,0xd253a5203817225e9768c05e5996d642fb96ba86,7,0x76eb96616514adac35152155bbc614272f0601b3,15751049,17896941,false,interior_boundary,0x76eb96616514adac35152155bbc614272f0601b3,false,,,answer,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,3,0,true,0,0,0,13,0,0,true,0,0,false,44310564,44232298,FUSE-UBIScheme-0xd253a5203817225e9768c05e5996d642fb96ba86.json,96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f +FUSE,122,0xd253a5203817225e9768c05e5996d642fb96ba86,8,0x11f077ae87952948de96b975a805ebaa20eada12,17896941,17913778,false,interior_boundary,0x11f077ae87952948de96b975a805ebaa20eada12,false,,,answer,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,3,0,true,0,0,0,13,0,0,true,0,0,false,44310564,44232298,FUSE-UBIScheme-0xd253a5203817225e9768c05e5996d642fb96ba86.json,96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f +FUSE,122,0xd253a5203817225e9768c05e5996d642fb96ba86,9,0x306cd90bfefb7e409f089a1bde1aa77bbc4cb660,17913778,17913899,false,interior_boundary,0x306cd90bfefb7e409f089a1bde1aa77bbc4cb660,false,,,answer,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,3,0,true,0,0,0,13,0,0,true,0,0,false,44310564,44232298,FUSE-UBIScheme-0xd253a5203817225e9768c05e5996d642fb96ba86.json,96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f +FUSE,122,0xd253a5203817225e9768c05e5996d642fb96ba86,10,0xb22764dce0960b61c5a8d688f075857632917a93,17913899,17927761,false,interior_boundary,0xb22764dce0960b61c5a8d688f075857632917a93,false,,,answer,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,3,0,true,0,0,0,13,0,0,true,0,0,false,44310564,44232298,FUSE-UBIScheme-0xd253a5203817225e9768c05e5996d642fb96ba86.json,96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f +FUSE,122,0xd253a5203817225e9768c05e5996d642fb96ba86,11,0xbb6dff610ecbea25a6c57b086ef92c6724306a76,17927761,25635053,false,interior_boundary,0xbb6dff610ecbea25a6c57b086ef92c6724306a76,false,,,answer,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,3,0,true,0,0,0,13,0,0,true,0,0,false,44310564,44232298,FUSE-UBIScheme-0xd253a5203817225e9768c05e5996d642fb96ba86.json,96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f +FUSE,122,0xd253a5203817225e9768c05e5996d642fb96ba86,12,0x1c90f733e1724bd1db47f84cde4f9e83087cfb6d,25635053,38729068,false,interior_boundary,0x1c90f733e1724bd1db47f84cde4f9e83087cfb6d,false,,,answer,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,3,0,true,0,0,0,13,0,0,true,0,0,false,44310564,44232298,FUSE-UBIScheme-0xd253a5203817225e9768c05e5996d642fb96ba86.json,96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f +FUSE,122,0xd253a5203817225e9768c05e5996d642fb96ba86,13,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,38729068,9223372036854775807,true,interior_boundary,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,false,,,answer,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,3,0,true,0,0,0,13,0,0,true,0,0,false,44310564,44232298,FUSE-UBIScheme-0xd253a5203817225e9768c05e5996d642fb96ba86.json,96554e0f843a866a4e4fdee57e0e165a3ce2b3a105c5df61c665a6f91ad61f7f +CELO,42220,0x36829d1cda92fff5782d5d48991620664fc857d3,1,0xdbc8860618482f703a4047340b8639b1452f96ec,18003063,18795892,false,creation_initialisation,0xdbc8860618482f703a4047340b8639b1452f96ec,false,,,answer,0x4072cb2d7e95def1559f6f72491039fe0534fa37,3,0,false,17,0,0,8,5,0,true,0,0,false,78698174,78286906,CELO-Invites-0x36829d1cda92fff5782d5d48991620664fc857d3.json,d69865ff84b5d38adb4dc6c0978fa46abde037b35cdb492734d29a55a7728cae +CELO,42220,0x36829d1cda92fff5782d5d48991620664fc857d3,2,0x61760d949357066ae29c469b70a91934273e4ef3,18795892,20211506,false,interior_boundary,0x61760d949357066ae29c469b70a91934273e4ef3,false,,,answer,0x4072cb2d7e95def1559f6f72491039fe0534fa37,3,0,false,17,0,0,8,5,0,true,0,0,false,78698174,78286906,CELO-Invites-0x36829d1cda92fff5782d5d48991620664fc857d3.json,d69865ff84b5d38adb4dc6c0978fa46abde037b35cdb492734d29a55a7728cae +CELO,42220,0x36829d1cda92fff5782d5d48991620664fc857d3,3,0x142e6d0afdd09c8629970b5fb0cf9798a3d21f89,20211506,20645578,false,interior_boundary,0x142e6d0afdd09c8629970b5fb0cf9798a3d21f89,false,,,answer,0x4072cb2d7e95def1559f6f72491039fe0534fa37,3,0,false,17,0,0,8,5,0,true,0,0,false,78698174,78286906,CELO-Invites-0x36829d1cda92fff5782d5d48991620664fc857d3.json,d69865ff84b5d38adb4dc6c0978fa46abde037b35cdb492734d29a55a7728cae +CELO,42220,0x36829d1cda92fff5782d5d48991620664fc857d3,4,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,20645578,24428495,false,interior_boundary,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,false,,,answer,0x4072cb2d7e95def1559f6f72491039fe0534fa37,3,0,false,17,0,0,8,5,0,true,0,0,false,78698174,78286906,CELO-Invites-0x36829d1cda92fff5782d5d48991620664fc857d3.json,d69865ff84b5d38adb4dc6c0978fa46abde037b35cdb492734d29a55a7728cae +CELO,42220,0x36829d1cda92fff5782d5d48991620664fc857d3,5,0xd2e26679b4d21cb501ebbc99744c29ed061a6b8c,24428495,24518263,false,interior_boundary,0xd2e26679b4d21cb501ebbc99744c29ed061a6b8c,false,,,answer,0x4072cb2d7e95def1559f6f72491039fe0534fa37,3,0,false,17,0,0,8,5,0,true,0,0,false,78698174,78286906,CELO-Invites-0x36829d1cda92fff5782d5d48991620664fc857d3.json,d69865ff84b5d38adb4dc6c0978fa46abde037b35cdb492734d29a55a7728cae +CELO,42220,0x36829d1cda92fff5782d5d48991620664fc857d3,6,0x87c222b6212b8352c48b7047e5c97c8797535a09,24518263,24600260,false,interior_boundary,0x87c222b6212b8352c48b7047e5c97c8797535a09,false,,,answer,0x4072cb2d7e95def1559f6f72491039fe0534fa37,3,0,false,17,0,0,8,5,0,true,0,0,false,78698174,78286906,CELO-Invites-0x36829d1cda92fff5782d5d48991620664fc857d3.json,d69865ff84b5d38adb4dc6c0978fa46abde037b35cdb492734d29a55a7728cae +CELO,42220,0x36829d1cda92fff5782d5d48991620664fc857d3,7,0xf2196f8c2ba0674a8b00369cd65fab3f54b080a0,24600260,61165821,false,interior_boundary,0xf2196f8c2ba0674a8b00369cd65fab3f54b080a0,false,,,answer,0x4072cb2d7e95def1559f6f72491039fe0534fa37,3,0,false,17,0,0,8,5,0,true,0,0,false,78698174,78286906,CELO-Invites-0x36829d1cda92fff5782d5d48991620664fc857d3.json,d69865ff84b5d38adb4dc6c0978fa46abde037b35cdb492734d29a55a7728cae +CELO,42220,0x36829d1cda92fff5782d5d48991620664fc857d3,8,0x4072cb2d7e95def1559f6f72491039fe0534fa37,61165821,9223372036854775807,true,interior_boundary,0x4072cb2d7e95def1559f6f72491039fe0534fa37,false,,,answer,0x4072cb2d7e95def1559f6f72491039fe0534fa37,3,0,false,17,0,0,8,5,0,true,0,0,false,78698174,78286906,CELO-Invites-0x36829d1cda92fff5782d5d48991620664fc857d3.json,d69865ff84b5d38adb4dc6c0978fa46abde037b35cdb492734d29a55a7728cae +CELO,42220,0x43d72ff17701b2da814620735c39c620ce0ea4a1,1,0xedbe438cd865992fdb72dd252e6055a71b02be72,18006679,19276072,false,creation_initialisation,0xedbe438cd865992fdb72dd252e6055a71b02be72,false,,,answer,0x43f0eb66ea3c2d9552241525aa1af6607227dfbf,2,1,false,9,0,0,4,3,0,true,0,0,false,78698174,78286906,CELO-UBIScheme-0x43d72ff17701b2da814620735c39c620ce0ea4a1.json,23ed554b63b086930ca3ea996cb5c1a705d4433ad29f650f1b69fb4fa8f0248e +CELO,42220,0x43d72ff17701b2da814620735c39c620ce0ea4a1,2,0x854f84ef0d9abc1e0afb4e96c962d5456b62214e,19276072,23063176,false,interior_boundary,0x854f84ef0d9abc1e0afb4e96c962d5456b62214e,false,,,answer,0x43f0eb66ea3c2d9552241525aa1af6607227dfbf,2,1,false,9,0,0,4,3,0,true,0,0,false,78698174,78286906,CELO-UBIScheme-0x43d72ff17701b2da814620735c39c620ce0ea4a1.json,23ed554b63b086930ca3ea996cb5c1a705d4433ad29f650f1b69fb4fa8f0248e +CELO,42220,0x43d72ff17701b2da814620735c39c620ce0ea4a1,3,0xe8fcbac4bd18f80301450e428518e9dedc183a26,23063176,50351048,false,interior_boundary,0xe8fcbac4bd18f80301450e428518e9dedc183a26,false,,,answer,0x43f0eb66ea3c2d9552241525aa1af6607227dfbf,2,1,false,9,0,0,4,3,0,true,0,0,false,78698174,78286906,CELO-UBIScheme-0x43d72ff17701b2da814620735c39c620ce0ea4a1.json,23ed554b63b086930ca3ea996cb5c1a705d4433ad29f650f1b69fb4fa8f0248e +CELO,42220,0x43d72ff17701b2da814620735c39c620ce0ea4a1,4,0x43f0eb66ea3c2d9552241525aa1af6607227dfbf,50351048,9223372036854775807,true,interior_boundary,0x43f0eb66ea3c2d9552241525aa1af6607227dfbf,false,,,answer,0x43f0eb66ea3c2d9552241525aa1af6607227dfbf,2,1,false,9,0,0,4,3,0,true,0,0,false,78698174,78286906,CELO-UBIScheme-0x43d72ff17701b2da814620735c39c620ce0ea4a1.json,23ed554b63b086930ca3ea996cb5c1a705d4433ad29f650f1b69fb4fa8f0248e diff --git a/projects/onchain-analytics/gd_dbt/seeds/era_intervals.csv b/projects/onchain-analytics/gd_dbt/seeds/era_intervals.csv new file mode 100644 index 0000000..96d50e6 --- /dev/null +++ b/projects/onchain-analytics/gd_dbt/seeds/era_intervals.csv @@ -0,0 +1,263 @@ +chain,chain_id,proxy_address,valid_from_block,valid_to_block,implementation,abi_id,confidence_grade,evidence_receipt_uri,contract_name,era_index,is_live +ETHEREUM,1,0x02416eb83cff1f19163f21010149c3867f3261e1,14132483,9223372036854775807,0x02416eb83cff1f19163f21010149c3867f3261e1,0x19d236ce0180396e675601e31fe953bba57e046cfcfee783c621862b4696e065,inferred,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x02416eb83cff1f19163f21010149c3867f3261e1/era=1,StakingContractsV2,1,true +ETHEREUM,1,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,14338654,16240765,0x4a10354b8e1928c38cc6a738cd2748fa1c818cea,0xbb78513636d0bcb8076eb8dded78b38961998755abb5d65b2b29b04109c8135b,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x0c6c80d2061afa35e160f3799411d83bdeea0a5a/era=1,GoodFundManager,1,false +ETHEREUM,1,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,16240765,18190480,0x53b3c6b18a03a9a0c3487cf1230eea1eb9a38a0a,0x3069da8e333310c4eee88b81b810e14ededc06f5904a64dd8198129ae82eb4d4,slot_bisected,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x0c6c80d2061afa35e160f3799411d83bdeea0a5a/era=2,GoodFundManager,2,false +ETHEREUM,1,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,18190480,22165594,0x4a37a8d7cdb43d89b4dbd7ecfaeaf9bd39e24929,0x1603edb57ff936d52c7ff4f3696a591f39bf8b46b8e93cf5591de63473bf48ba,slot_bisected,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x0c6c80d2061afa35e160f3799411d83bdeea0a5a/era=3,GoodFundManager,3,false +ETHEREUM,1,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,22165594,9223372036854775807,0xaacbaab8571cbeceb46ba85b5981efdb8928545e,0x80dcb898400e373e62b938941ea18dba14b621a35ec858897bdee60bb21a5b64,slot_bisected,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x0c6c80d2061afa35e160f3799411d83bdeea0a5a/era=4,GoodFundManager,4,true +ETHEREUM,1,0x169e633a2d1e6c10dd91238ba11c4a708dfef37c,10606498,9223372036854775807,0x169e633a2d1e6c10dd91238ba11c4a708dfef37c,0x4b79b5c8aee6da0f7b393e8b53e6265ef7320a1d16184c65bd3841b5aa3d700d,inferred,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x169e633a2d1e6c10dd91238ba11c4a708dfef37c/era=1,GAS_PRICE_ORACLE,1,true +ETHEREUM,1,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,10561463,9223372036854775807,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,0x8a27316984da83331e574723efd0810faf4d7065f3037b8778d9c572ea49c6d8,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x1ecfd1afb601c406ff0e13c3485f2d75699b6817/era=1,Avatar,1,true +ETHEREUM,1,0x3ff2d8eb2573819a9ef7167d2ba6fd6d31b17f4f,14338483,9223372036854775807,0x3ff2d8eb2573819a9ef7167d2ba6fd6d31b17f4f,0xcce057daa357d310d82f1bba3c24f93cb7c7b0d8d00d185c1c8395abbbaf036b,inferred,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x3ff2d8eb2573819a9ef7167d2ba6fd6d31b17f4f/era=1,StakingContractsV3,1,true +ETHEREUM,1,0x5766cf4b2fdb09d986eb1783d276013c224e28c8,14338550,22165594,0x5f78ed3a4fdde9e9d91d3707a847fb4ad820ce26,0x23c18a3cc25e04ccd645243059a51da30d3ed25a321c6997f8db86ef90573106,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x5766cf4b2fdb09d986eb1783d276013c224e28c8/era=1,StakersDistribution,1,false +ETHEREUM,1,0x5766cf4b2fdb09d986eb1783d276013c224e28c8,22165594,9223372036854775807,0x92c69a12c2ffc54afcfa320be7305ffd0f5782e0,0xdb6b68ed9eb7db3045bc8fdf06a2da5d34164ff07e810f4e5c270cbdd24d479b,slot_bisected,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x5766cf4b2fdb09d986eb1783d276013c224e28c8/era=2,StakersDistribution,2,true +ETHEREUM,1,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,14380642,22165594,0x92af163505c05d63a4f7478c01b9af9be369c143,0x6eaae71845e0c65ee44592019c400d81c9ebca6b3a544cdc10368c6af43f4216,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x57ee6ceff51cb30ecb1245934a882c500fbec1e9/era=1,CompoundVotingMachine,1,false +ETHEREUM,1,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,22165594,9223372036854775807,0x807d0066d60a0a8312b6d191f60a6938a527e971,0x0d5e8f324a69af2b72f2d9e3266036966ba2bcfd2d594f82c28b0ab275d6d5ed,slot_bisected,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x57ee6ceff51cb30ecb1245934a882c500fbec1e9/era=2,CompoundVotingMachine,2,true +ETHEREUM,1,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,8983575,9223372036854775807,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,0x3f1d4a4e2a03855c7ee8f6f2477c1245752a5ca3ef28d59e8fd509efe59ef877,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x5d3a536e4d6dbd6114cc1ead35777bab948e3643/era=1,cDAI,1,true +ETHEREUM,1,0x5f4ec3df9cbd43714fe2740f5e3616155c5b8419,10606501,9223372036854775807,0x5f4ec3df9cbd43714fe2740f5e3616155c5b8419,0x4b79b5c8aee6da0f7b393e8b53e6265ef7320a1d16184c65bd3841b5aa3d700d,inferred,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x5f4ec3df9cbd43714fe2740f5e3616155c5b8419/era=1,ETH_USD_ORACLE,1,true +ETHEREUM,1,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,14344739,14352686,0x0a5dcf330ba39434dbda59b982a3dd09759cc788,0x824339abb39e2b39cb85a8e45048c2eb366c9110a4918c2ea2d1f102f0354367,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x603b8c0f110e037b51a381cbcacabb8d6c6e4543/era=1,GReputation,1,false +ETHEREUM,1,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,14352686,16885600,0x438eb12a081041b525731c34086de3ed31658dee,0x40781353ff48e1d9fe0feada2bf9c447956538f67d1b9a2f0d72d7c1fe8cc7be,slot_bisected,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x603b8c0f110e037b51a381cbcacabb8d6c6e4543/era=2,GReputation,2,false +ETHEREUM,1,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,16885600,9223372036854775807,0x634e25b6ffde325d5beb8c6c2d8af6d543b6ff7f,0x0b6ff946fd1ad1ebc33dd134a57713419b8ac0fdecbd56db74ffcf6266909cc5,slot_bisected,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x603b8c0f110e037b51a381cbcacabb8d6c6e4543/era=3,GReputation,3,true +ETHEREUM,1,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,10561463,9223372036854775807,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,0x554945bfa422af5800554ef7b37f229465f13208db908d482249f1dd9803a3c0,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x67c5870b4a41d4ebef24d2456547a03f1f3e094b/era=1,GoodDollar,1,true +ETHEREUM,1,0x6b175474e89094c44da98b954eedeac495271d0f,8928158,9223372036854775807,0x6b175474e89094c44da98b954eedeac495271d0f,0x4e36f96ee1667a663dfaac57c4d185a0e369a3a217e0079d49620f34f85d1ac7,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x6b175474e89094c44da98b954eedeac495271d0f/era=1,DAI,1,true +ETHEREUM,1,0x765277eebeca2e31912c9946eae1021199b39c61,12242619,9223372036854775807,0x765277eebeca2e31912c9946eae1021199b39c61,0xf8548d4270316b12fe3628b1d57ba1d79cd8a97861793af639eb0ee1ba330356,inferred,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x765277eebeca2e31912c9946eae1021199b39c61/era=1,MultichainRouter,1,true +ETHEREUM,1,0x76e76e10ac308a1d54a00f9df27edce4801f288b,10561341,9223372036854775807,0x76e76e10ac308a1d54a00f9df27edce4801f288b,0x83c740a8ac588a566556553a334afdfded5add581f27efc0215d3ccfd842eaad,inferred,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x76e76e10ac308a1d54a00f9df27edce4801f288b/era=1,Identity,1,true +ETHEREUM,1,0x773616e4d11a78f511299002da57a0a94577f1f4,10606425,9223372036854775807,0x773616e4d11a78f511299002da57a0a94577f1f4,0x4b79b5c8aee6da0f7b393e8b53e6265ef7320a1d16184c65bd3841b5aa3d700d,inferred,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x773616e4d11a78f511299002da57a0a94577f1f4/era=1,DAI_ETH_ORACLE,1,true +ETHEREUM,1,0x78cc5ab2f0990b5fe58f95baebf8f37879534aeb,14338308,9223372036854775807,0x78cc5ab2f0990b5fe58f95baebf8f37879534aeb,0x883ade859bcf2356e3b7cd3523018b571087dced077a1ed4ac45a4c96d8d3980,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x78cc5ab2f0990b5fe58f95baebf8f37879534aeb/era=1,CompoundStakingFactory,1,true +ETHEREUM,1,0x7a250d5630b4cf539739df2c5dacb4c659f2488d,10207858,9223372036854775807,0x7a250d5630b4cf539739df2c5dacb4c659f2488d,0xa324bc7db3d091b6f1a2d526e48a9c7039e03b3cc35f7d44b15ac7a1544c11d2,inferred,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x7a250d5630b4cf539739df2c5dacb4c659f2488d/era=1,UNISWAP_ROUTER,1,true +ETHEREUM,1,0x7b7246c78e2f900d17646ff0cb2ec47d6ba10754,14338454,9223372036854775807,0x7b7246c78e2f900d17646ff0cb2ec47d6ba10754,0x581fa12f95a355336e4fff7a6b5a324f6f93c8c1de4c4e0a3d839c3d8219db04,inferred,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x7b7246c78e2f900d17646ff0cb2ec47d6ba10754/era=1,StakingContractsV3,1,true +ETHEREUM,1,0x8eec64bb6807c0178f96277cce6a334b4e565e5c,10569456,9223372036854775807,0x8eec64bb6807c0178f96277cce6a334b4e565e5c,0x8afd3472b2ba7c9664301e1db0e1a4ff03e1d4abf7037870060aec9479e95d88,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x8eec64bb6807c0178f96277cce6a334b4e565e5c/era=1,Contribution,1,true +ETHEREUM,1,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,10561463,9223372036854775807,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,0x1cce4814ac502cec7e982e73d29bdc95e9094476ba971b6777f8abd4a415fc26,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3/era=1,Controller,1,true +ETHEREUM,1,0x98fa532dd5c3a6b66fbf370813803192de4e0abd,14296277,22165594,0xbebbd9538d594619d36d48666e12d8c9f8372736,0x26322c949531dde942496f5930d4820de88a98c486980fc5f4f43cbe5ea5a594,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x98fa532dd5c3a6b66fbf370813803192de4e0abd/era=1,ExchangeHelper,1,false +ETHEREUM,1,0x98fa532dd5c3a6b66fbf370813803192de4e0abd,22165594,9223372036854775807,0x24614ad257f4d09fccaec024c65c40c060e73e9d,0xcbdb11d6fd35031a639ffb1834cbce6879073b685912f740dd2a9b4ada1dd2b8,slot_bisected,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0x98fa532dd5c3a6b66fbf370813803192de4e0abd/era=2,ExchangeHelper,2,true +ETHEREUM,1,0xa049894d5dcad406b7c827d6dc6a0b58ca4ae73a,10566777,9223372036854775807,0xa049894d5dcad406b7c827d6dc6a0b58ca4ae73a,0xd17f840b97128d5f5ecc258913b071648460f9c11298c00d21cb478907f2ac03,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xa049894d5dcad406b7c827d6dc6a0b58ca4ae73a/era=1,BancorFormula,1,true +ETHEREUM,1,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,14296271,16174339,0x865193da25c4fe135421fca78d2bd061b6efd744,0xb04200c786691948f77f0a7be422af88e22b5a424ee637df3f722a6e45a9de10,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xa150a825d425b36329d8294eef8bd0fe68f8f6e0/era=1,GoodReserveCDai,1,false +ETHEREUM,1,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,16174339,18190480,0x6e1c3f516ffd14852f9b25f21af13b6ce98dace5,0xa6ee500bfe454a9e75a1741294ee0b7729c3f510b5022de40246caa38c53a2cc,slot_bisected,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xa150a825d425b36329d8294eef8bd0fe68f8f6e0/era=2,GoodReserveCDai,2,false +ETHEREUM,1,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,18190480,22165594,0x2793a5887f53b025f49f7a9249d66f4671bce29b,0x2befbf5a304c75892209914c0a756d8c1c8bf82dd6508e3656eba753d100ad1f,slot_bisected,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xa150a825d425b36329d8294eef8bd0fe68f8f6e0/era=3,GoodReserveCDai,3,false +ETHEREUM,1,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,22165594,9223372036854775807,0x18bcdf79a724648bf34eb06701be81bd072a2384,0x43410466ac894d865cff8f6bbeaf0ede8804ae379f6260a2cd7c8ea0ac9ddc05,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xa150a825d425b36329d8294eef8bd0fe68f8f6e0/era=4,GoodReserveCDai,4,true +ETHEREUM,1,0xa2db14c68ab35e620fea5bf07d65e9bff84c994c,11512052,9223372036854775807,0xa2db14c68ab35e620fea5bf07d65e9bff84c994c,0x2b57f0728a5ffe03a475faab83005c468d0f669c0a473f87425e3edb6101ec8a,inferred,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xa2db14c68ab35e620fea5bf07d65e9bff84c994c/era=1,ProxyAdmin,1,true +ETHEREUM,1,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,18162554,18162562,0x0000000000000000000000000000000000000000,impl:0x0000000000000000000000000000000000000000,inferred,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5/era=1,MpbBridge,1,false +ETHEREUM,1,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,18162562,22165594,0xf19fb90fa4ddb67c330b41ad4d64ef75b9d8cd33,0x2e5d3e54855f5864dc7e6abf562989a74a3fc1e020b976c592a79a7b2da9c408,slot_bisected,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5/era=2,MpbBridge,2,false +ETHEREUM,1,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,22165594,23940256,0x618fae127b803eabf72f9e86a88a7505eebf218a,0xf89052533300161b0a7d20c5eb600d0850f5c95fb48f1e2727825b231cd1b0aa,slot_bisected,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5/era=3,MpbBridge,3,false +ETHEREUM,1,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,23940256,24641278,0x12ab702f015d3302f3cc0c4aba0626a127d06a07,0xd28a518f866e7d53b195a37a71eb04cc68fee21d7cb991427934b6f9d53e1fc2,slot_bisected,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5/era=4,MpbBridge,4,false +ETHEREUM,1,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,24641278,9223372036854775807,0x3a2d0a9ef558b42af5ff8d27fe438b466fa7692f,0x104d6ab3b6a95b2ebf4cfb4a6cb485f5e4b5ef02c3d119c07e43322bbd5daacf,slot_bisected,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5/era=5,MpbBridge,5,true +ETHEREUM,1,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,16167621,17661435,0x42cda1bd60cc66ab2e2411e8c93db436c8a27060,0x15354959eb9bdda169ce6b338a64f4949ca5fd2fc4fa790fc506f7b62f221520,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0/era=1,DistributionHelper,1,false +ETHEREUM,1,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,17661435,18190480,0x16171d113d9592b77cec52b8cc4bdd6f5810daef,0xf80378215ded3a92155f1331c852040bbabb670f2aa13da253d5af430ab7082d,slot_bisected,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0/era=2,DistributionHelper,2,false +ETHEREUM,1,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,18190480,18719715,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,0xb95001d06c848c5680808debf2aba0ed20f162ec873722d17784acf0aeb7acdc,slot_bisected,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0/era=3,DistributionHelper,3,false +ETHEREUM,1,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,18719715,22165594,0xa339b7f4e95a93d2c6569cb139ad034c3b9caa77,0x6b215c6b5d9777cc6f1f5f2130a9b2c9fe16e933e18b076243e9181c446921f1,slot_bisected,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0/era=4,DistributionHelper,4,false +ETHEREUM,1,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,22165594,9223372036854775807,0xae2cd2a9513215961d344a2581dcab678598eedf,0xc3767b93a60456d6aa441ce3d8b319a5e479d9bde160f4dc87bedfc70558f73f,slot_bisected,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0/era=5,DistributionHelper,5,true +ETHEREUM,1,0xc00e94cb662c3520282e6f5717214004a7f26888,9601359,9223372036854775807,0xc00e94cb662c3520282e6f5717214004a7f26888,0x9398f9b1f117941e8e25a4aff4d11754f48933cc3c08101975e3306e98d88c2a,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xc00e94cb662c3520282e6f5717214004a7f26888/era=1,COMP,1,true +ETHEREUM,1,0xd17652350cfd2a37ba2f947c910987a3b1a1c60d,14809447,9223372036854775807,0xd17652350cfd2a37ba2f947c910987a3b1a1c60d,0x48c30df8d84160f9085fffbc3ff8a72e42be14aca8ad94626249d836a1392565,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xd17652350cfd2a37ba2f947c910987a3b1a1c60d/era=1,AnyGoodDollar,1,true +ETHEREUM,1,0xd33ba17c8a644c585089145e86e282fada6f3bfd,13701103,9223372036854775807,0xd33ba17c8a644c585089145e86e282fada6f3bfd,0x80648f5b74b165322f61c0e45e315077d1eb8776607f893ce654bbc483382c54,inferred,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xd33ba17c8a644c585089145e86e282fada6f3bfd/era=1,StakingContracts,1,true +ETHEREUM,1,0xd5d11ee582c8931f336fbcd135e98cee4db8ccb0,11238178,9223372036854775807,0xd5d11ee582c8931f336fbcd135e98cee4db8ccb0,0x2d05a6bd0ad793d9459975bf7760dcbfefa24baf8c7f70efa4aab6b52db668bb,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xd5d11ee582c8931f336fbcd135e98cee4db8ccb0/era=1,ForeignBridge,1,true +ETHEREUM,1,0xda85fced9bd193526b7667f2ad1fd4a0f900d3a7,14294877,9223372036854775807,0xda85fced9bd193526b7667f2ad1fd4a0f900d3a7,0x1a30c8ca34283aa6a8722d626c290a575108a1e4d7d018db6faf46c77e1f19a3,inferred,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xda85fced9bd193526b7667f2ad1fd4a0f900d3a7/era=1,ProxyFactory,1,true +ETHEREUM,1,0xdac6a0c973ba7cf3526de456affa43ab421f659f,14296152,22165594,0xb3ff03c8a42506ba58b1127cd4b5928c7ed70a03,0x3ed7a72aaa5e00bea85f4c5a6b7cefc973c2e1e7a42754ed1812b5fa735ed268,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xdac6a0c973ba7cf3526de456affa43ab421f659f/era=1,GoodMarketMaker,1,false +ETHEREUM,1,0xdac6a0c973ba7cf3526de456affa43ab421f659f,22165594,9223372036854775807,0x8520633e40574e9550f6a0436b0f8d56f3b99bd0,0xfdd8235cfa88eea23f3dba545fdf43e6c4cf831b3dea3e2331c60606eaf380d1,slot_bisected,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xdac6a0c973ba7cf3526de456affa43ab421f659f/era=2,GoodMarketMaker,2,true +ETHEREUM,1,0xe0c5daa7cc6f88d29505f702a53bb5e67600e7ec,16060725,9223372036854775807,0xe0c5daa7cc6f88d29505f702a53bb5e67600e7ec,0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000,inferred,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xe0c5daa7cc6f88d29505f702a53bb5e67600e7ec/era=1,GuardiansSafe,1,true +ETHEREUM,1,0xec6dce387b1616a0c44ff2e4fa9e90e53cf14eb0,14295851,9223372036854775807,0xeb151e175d3d53032c2c185052e48c8c2d5c245d,0xce45d07e83296b1ea2bdaf7be5635193dda560b978c1afe17b4e87667f2b507a,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xec6dce387b1616a0c44ff2e4fa9e90e53cf14eb0/era=1,NameService,1,true +ETHEREUM,1,0xf4411c22766947db2da39ad534a040b770b51153,14338311,9223372036854775807,0xf4411c22766947db2da39ad534a040b770b51153,0xe5c076c8e4675670baa06fb5f76fee3dc8ef6f48b7c7df96efe4790d773e1771,announced,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xf4411c22766947db2da39ad534a040b770b51153/era=1,AaveStakingFactory,1,true +ETHEREUM,1,0xf4c34bed7dd779485692bb1857acf9c561b45010,14132483,9223372036854775807,0xf4c34bed7dd779485692bb1857acf9c561b45010,0x6d7aa6e4422780f33acf8093fdbe3669832ad519486c8396b7320ba429c62497,inferred,gd_dbt/seeds/contract_deployments.csv#ETHEREUM/0xf4c34bed7dd779485692bb1857acf9c561b45010/era=1,StakingContractsV2,1,true +XDC,50,0x1e5154bf5e31ff56051bbd45958b879fb7a290fe,95143608,9223372036854775807,0x653c67be5b3739708e84b61641253822405d78d8,0xaa0ffd7041640c8b913e2b76301b0ffa064ee7a84aad1d43b631dac209b7f747,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0x1e5154bf5e31ff56051bbd45958b879fb7a290fe/era=1,NameService,1,true +XDC,50,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,95143598,9223372036854775807,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,0x8a27316984da83331e574723efd0810faf4d7065f3037b8778d9c572ea49c6d8,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0x21eac3fe218307bee0463f77ebca3b50f452c0ce/era=1,Avatar,1,true +XDC,50,0x22867567e2d80f2049200e25c6f31cb6ec2f0faf,95249624,9223372036854775807,0xea12bb3917cf6ae2fde97ce4756177703426d41f,0x1a2a42df99ac104b92c4f611df6d9d8e136aecf0875ac9be4dd49ab1be300c5c,corroborated,gd_dbt/seeds/era_boundary_evidence.csv#XDC/0x22867567e2d80f2049200e25c6f31cb6ec2f0faf/era=1,UBIScheme,1,true +XDC,50,0x2431f53afda24130722dbeb9f9b1b0b8d2fbb197,100111919,9223372036854775807,0x2431f53afda24130722dbeb9f9b1b0b8d2fbb197,0x83c1d603e8c3ed0dbd3a813582014dc03b823fa18aa71c5fa7786f5640837fff,inferred,gd_dbt/seeds/contract_deployments.csv#XDC/0x2431f53afda24130722dbeb9f9b1b0b8d2fbb197/era=1,UpdateReserveRatio,1,true +XDC,50,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,95143058,100340676,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,0x01ec062dc685b7aec5b7e7574302648c016d25423b86a8a999cbf05ee6ed3a85,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0x27a4a02c9ed591e1a86e2e5d05870292c34622c9/era=1,Identity,1,false +XDC,50,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,100340676,9223372036854775807,0x28830934ad2146e7a273fd394f706571c2d09373,0x307c50e010de98eed4870743567fd1ad954811f59b99752b709dc18bbf868eab,slot_bisected,gd_dbt/seeds/contract_deployments.csv#XDC/0x27a4a02c9ed591e1a86e2e5d05870292c34622c9/era=2,Identity,2,true +XDC,50,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,100091095,100340676,0xd9ce916d711977d5b27697a13964556b4fb8af1d,0x65d8c817bac8f41eb34548c15ad6ae5e744da2bd5373916df3b8e63f1fecd916,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41/era=1,MentoExchangeProvider,1,false +XDC,50,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,100340676,9223372036854775807,0xe930cde20f60d0a4fc9487874861ae259f5bed48,0x5ed71ccf7c4789f438827e074bc8bba84c7fc2c615495b12a2f9c51398a8b0d5,slot_bisected,gd_dbt/seeds/contract_deployments.csv#XDC/0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41/era=2,MentoExchangeProvider,2,true +XDC,50,0x3b9edecc4286ba33ea6e27119c2a4db99829839d,59782347,9223372036854775807,0x3b9edecc4286ba33ea6e27119c2a4db99829839d,0xec362365703d4ab51bd8adfb8f580413cba66e152720928a7c975d5197f2d07a,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0x3b9edecc4286ba33ea6e27119c2a4db99829839d/era=1,UniswapV3Router,1,true +XDC,50,0x5557e9def86ad6564462741a7a3f3679c1223f5d,100091095,9223372036854775807,0x7288d592e1b9013c668801f722be650993d2925a,0x9da4f4203282696d49deb0c241e49e0ff09f8b6da2d463f69f3fc98e66899a74,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0x5557e9def86ad6564462741a7a3f3679c1223f5d/era=1,MentoExpansionController,1,true +XDC,50,0x5be34022c26fa03a8d6926314a42414c7ca2df51,95142721,9223372036854775807,0x5be34022c26fa03a8d6926314a42414c7ca2df51,0x7f63d978bb61348d9321e9e9a382a2f88679edb38c483385333d4dbb0760fea9,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0x5be34022c26fa03a8d6926314a42414c7ca2df51/era=1,ProxyFactory,1,true +XDC,50,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,95144743,95866130,0xa7f4717bf6e7d27d7c855d5f4a869e96bd16d873,0x9e231a1f32074c2535d1793d1a863dbe4ddb5438f6f6ef526fd87ab683dff181,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0x66fc1be551f752706130b6f54d84141f8c2ae8bb/era=1,AdminWallet,1,false +XDC,50,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,95866130,9223372036854775807,0x68dbe795ee2219437299bb23d70311e3b7c69f9a,0xb18bdf42222c3100c99f40bbb2fe56734e863977f1beebe0527148d2b44b70b5,slot_bisected,gd_dbt/seeds/contract_deployments.csv#XDC/0x66fc1be551f752706130b6f54d84141f8c2ae8bb/era=2,AdminWallet,2,true +XDC,50,0x6bd698566632bf2e81e2278f1656cb24aaf06d2e,95144756,100123036,0xb22bb27d920a4efdafaa03a51e8a4c41e4cc4217,0x5da156e5a7ff212885d03e8f52531c50f273d7b9410a07177379859562a5acc5,corroborated,gd_dbt/seeds/era_boundary_evidence.csv#XDC/0x6bd698566632bf2e81e2278f1656cb24aaf06d2e/era=1,Invites,1,false +XDC,50,0x6bd698566632bf2e81e2278f1656cb24aaf06d2e,100123036,9223372036854775807,0x783548481a6ca92b6589365161b31e3ed64d0c3c,0x9c0c0028170b3295f0555171e63b4150b56b7ec427b9f26eb0c21a8dd7662df5,corroborated,gd_dbt/seeds/era_boundary_evidence.csv#XDC/0x6bd698566632bf2e81e2278f1656cb24aaf06d2e/era=2,Invites,2,true +XDC,50,0x725244458f011551dde1104c9728746eebea19f9,93357551,9223372036854775807,0x725244458f011551dde1104c9728746eebea19f9,0x511ddd7509fe316b6a954e51453cbfa51e42e7ab82becf2360066ddf1b2084fb,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0x725244458f011551dde1104c9728746eebea19f9/era=1,StaticOracle,1,true +XDC,50,0x7344da1be296f03fbb8082adac5696058b5a9bd9,95144750,95325786,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,0x3072e58a72b2536637e3827c180dc2763faaeb267035deec1436b343afedb4c6,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0x7344da1be296f03fbb8082adac5696058b5a9bd9/era=1,Faucet,1,false +XDC,50,0x7344da1be296f03fbb8082adac5696058b5a9bd9,95325786,95327264,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,0x68755099f25764af194ff16c1f4a6fd14bdd4bd89a1c3f6832649a36508e6533,slot_bisected,gd_dbt/seeds/contract_deployments.csv#XDC/0x7344da1be296f03fbb8082adac5696058b5a9bd9/era=2,Faucet,2,false +XDC,50,0x7344da1be296f03fbb8082adac5696058b5a9bd9,95327264,9223372036854775807,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,0xe8429a22753ce3f82c856a7f5dee88264782d956d615db983d0cd5ec8e9fb325,slot_bisected,gd_dbt/seeds/contract_deployments.csv#XDC/0x7344da1be296f03fbb8082adac5696058b5a9bd9/era=3,Faucet,3,true +XDC,50,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,95143598,9223372036854775807,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,0x1cce4814ac502cec7e982e73d29bdc95e9094476ba971b6777f8abd4a415fc26,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03/era=1,Controller,1,true +XDC,50,0x8471406c3bff67cc6538481c8550364bda6ca691,98383258,9223372036854775807,0x8471406c3bff67cc6538481c8550364bda6ca691,0xdd44d5a52707f76ac1bb4147820056bd47ca2c90f79d82fdaeb19b7d180179b4,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0x8471406c3bff67cc6538481c8550364bda6ca691/era=1,MentoProxyAdmin,1,true +XDC,50,0x88de45906d4f5a57315c133620cfa484cb297541,100091095,100340676,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,0x58558a86a3aced5b23ae279244bd285f68c9d6d0a20cf283b7a40a0784697831,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0x88de45906d4f5a57315c133620cfa484cb297541/era=1,MentoBroker,1,false +XDC,50,0x88de45906d4f5a57315c133620cfa484cb297541,100340676,9223372036854775807,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,0x2e63673ca3232bd818d12804ade7e1d688b7c11da7812d0237a3564e99cd0fb7,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0x88de45906d4f5a57315c133620cfa484cb297541/era=2,MentoBroker,2,true +XDC,50,0x94a3240f484a04f5e3d524f528d02694c109463b,100091095,100340676,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,0xe5750e9acc0322eae552526478b90a1a762ea401bf9094ff36daa6d0e4669020,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0x94a3240f484a04f5e3d524f528d02694c109463b/era=1,MentoReserve,1,false +XDC,50,0x94a3240f484a04f5e3d524f528d02694c109463b,100340676,9223372036854775807,0xbdaa65e8175875340365d76a660bb2a7a4efe909,0xe5750e9acc0322eae552526478b90a1a762ea401bf9094ff36daa6d0e4669020,slot_bisected,gd_dbt/seeds/contract_deployments.csv#XDC/0x94a3240f484a04f5e3d524f528d02694c109463b/era=2,MentoReserve,2,true +XDC,50,0x951857744785e80e2de051c32ee7b25f9c458c42,42776215,9223372036854775807,0x951857744785e80e2de051c32ee7b25f9c458c42,0x4e0fcac36e857c9408b310cc1b8dfe2c3e8aff8c199ea1df31c4ebdaccdcc57e,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0x951857744785e80e2de051c32ee7b25f9c458c42/era=1,WXDC,1,true +XDC,50,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,95254417,95254421,0x0000000000000000000000000000000000000000,impl:0x0000000000000000000000000000000000000000,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5/era=1,MpbBridge,1,false +XDC,50,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,95254421,96841591,0xa7bfc0d36300b5978cfa18301446cad3e855ae06,0x039a036cd2a30cc1536d5b5a368c77e7bd870ae3d59c0b699dd5b51439b17838,slot_bisected,gd_dbt/seeds/contract_deployments.csv#XDC/0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5/era=2,MpbBridge,2,false +XDC,50,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,96841591,100340676,0xe4cfa18a3d0a7d77faa42961ee943c9221d61937,0xa5b7233c025a48d44655a945ead941546d2a69fad9cc2dec4c1a1ef033498a08,slot_bisected,gd_dbt/seeds/contract_deployments.csv#XDC/0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5/era=3,MpbBridge,3,false +XDC,50,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,100340676,9223372036854775807,0x00f7f61080ef40d3832c8c06e8a2af757839e1f7,0xbacb5fa708349d8fba6d008557d8ed01abb888eb445b8d4bd1b2cceaef833d62,slot_bisected,gd_dbt/seeds/contract_deployments.csv#XDC/0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5/era=4,MpbBridge,4,true +XDC,50,0xaa52bb8110fe38d0d2d2af0b85c3a3ee622ca455,87230719,9223372036854775807,0xaa52bb8110fe38d0d2d2af0b85c3a3ee622ca455,0x5a20e5e77f75c2bc855c4e93352437bfc53301ea95935350f2f4799e898ddd48,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0xaa52bb8110fe38d0d2d2af0b85c3a3ee622ca455/era=1,UniswapV3RouterOfficial,1,true +XDC,50,0xb8a0d4b97327a0b6dd0705dc290ae26aa38a7d2b,100111925,9223372036854775807,0x971fdacd201cdaa741db06d580eb634b02307926,0x409c0dc6ff42f770c99147d26af9e12a6f90e807bf198937bfe5a59f0179116c,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0xb8a0d4b97327a0b6dd0705dc290ae26aa38a7d2b/era=1,DistributionHelper,1,true +XDC,50,0xe0c5daa7cc6f88d29505f702a53bb5e67600e7ec,95134102,9223372036854775807,0xe0c5daa7cc6f88d29505f702a53bb5e67600e7ec,0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0xe0c5daa7cc6f88d29505f702a53bb5e67600e7ec/era=1,GuardiansSafe,1,true +XDC,50,0xe8861a20452db53df685f1d9e6b7017de3db0e46,97033779,9223372036854775807,0xe8861a20452db53df685f1d9e6b7017de3db0e46,0x554fc53842f02a76351be11bad71cbd6ff31cbd4a8b4c0513f068e12527fb720,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0xe8861a20452db53df685f1d9e6b7017de3db0e46/era=1,BulkWhitelist,1,true +XDC,50,0xec2136843a983885aebf2feb3931f73a8ebee50c,95143070,95143245,0x0000000000000000000000000000000000000000,impl:0x0000000000000000000000000000000000000000,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0xec2136843a983885aebf2feb3931f73a8ebee50c/era=1,GoodDollar,1,false +XDC,50,0xec2136843a983885aebf2feb3931f73a8ebee50c,95143245,107529281,0x6936441113610483cc5b6a7adec4b45303b297a9,0xf1ef96de94aefc5848537637a56767402734cf35f4763e1f4e326c3e56ee457a,slot_bisected,gd_dbt/seeds/contract_deployments.csv#XDC/0xec2136843a983885aebf2feb3931f73a8ebee50c/era=2,GoodDollar,2,false +XDC,50,0xec2136843a983885aebf2feb3931f73a8ebee50c,107529281,9223372036854775807,0x1db2f592014a9394604bf6381f025754579547ec,0x2157adffb2622cfac69e299e2de636551391eddba892b5dd0c1b9f6469bb38f5,slot_bisected,gd_dbt/seeds/contract_deployments.csv#XDC/0xec2136843a983885aebf2feb3931f73a8ebee50c/era=3,GoodDollar,3,true +XDC,50,0xf4e9af892a09f04b7408266777198206e7f80d46,95143060,9223372036854775807,0xf4e9af892a09f04b7408266777198206e7f80d46,0xb10599b90c45878333139dfa098974b8df30eba5596654ef05c46daa2a6f0847,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0xf4e9af892a09f04b7408266777198206e7f80d46/era=1,FeeFormula,1,true +XDC,50,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,92678020,9223372036854775807,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,0x231f4b29fe5be8f3ae57a88ce9c67fed31128c6588cd35e4da397f04f6cbc1c3,announced,gd_dbt/seeds/contract_deployments.csv#XDC/0xfa2958cb79b0491cc627c1557f441ef849ca8eb1/era=1,CUSD,1,true +CELO,42220,0x00851a91a3c4e9a4c1b48df827bacc1f884bde28,20262304,9223372036854775807,0x00851a91a3c4e9a4c1b48df827bacc1f884bde28,0x86143ea0f1beb35753eec610670dc4ca6a7dc9924fba2f76851456201041c5e5,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x00851a91a3c4e9a4c1b48df827bacc1f884bde28/era=1,StaticOracle,1,true +CELO,42220,0x00e533b7d6255d05b7f15034b1c989c21f51b91c,21006324,9223372036854775807,0x00e533b7d6255d05b7f15034b1c989c21f51b91c,0x047ee7c00427bb66d4412b5748c158d3a8e3330166dd6e5a849ec2e4d9fc728c,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x00e533b7d6255d05b7f15034b1c989c21f51b91c/era=1,BuyGDFactory,1,true +CELO,42220,0x07f86b39728be613062bc7413fc2ca7293eef022,17714580,9223372036854775807,0x07f86b39728be613062bc7413fc2ca7293eef022,0xe0ce44f796f8c819bdba6334eb56f0ab6be2936af74486a2c2ccae17e0d17b1f,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x07f86b39728be613062bc7413fc2ca7293eef022/era=1,PoolGdMcusdV2,1,true +CELO,42220,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,17237959,9223372036854775807,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,0x1cce4814ac502cec7e982e73d29bdc95e9094476ba971b6777f8abd4a415fc26,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e/era=1,Controller,1,true +CELO,42220,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,21818995,9223372036854775807,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,0x81108761c6a03889b76abe78e2a059fa23bcdd3a028668984e17f95a5651e2f1,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51/era=1,PoolGdUsdgloV3Hi2,1,true +CELO,42220,0x0f5db7a64a6a64052693676ca898ec7f7a94ff4e,17237962,9223372036854775807,0xed9c5987e7109bb43a8a1a40a726b275e4eb4ace,0x0b90907ca330b6cb3ee57cdba11984e10cd8e5e5f004a3284c246ff6ea90ceab,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x0f5db7a64a6a64052693676ca898ec7f7a94ff4e/era=1,NameService,1,true +CELO,42220,0x1151867da39003695eed28fafa871079c91884c9,17237953,9223372036854775807,0x1151867da39003695eed28fafa871079c91884c9,0xb10599b90c45878333139dfa098974b8df30eba5596654ef05c46daa2a6f0847,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x1151867da39003695eed28fafa871079c91884c9/era=1,FeeFormula,1,true +CELO,42220,0x1f3d49414e4b7b32a5e23fbca71778df760d97a3,61141715,9223372036854775807,0x1f3d49414e4b7b32a5e23fbca71778df760d97a3,0x83c1d603e8c3ed0dbd3a813582014dc03b823fa18aa71c5fa7786f5640837fff,inferred,gd_dbt/seeds/contract_deployments.csv#CELO/0x1f3d49414e4b7b32a5e23fbca71778df760d97a3/era=1,UpdateReserveRatio,1,true +CELO,42220,0x1f60c4c7037c6766924a43666b781ed1479587a2,22909812,9223372036854775807,0x1f60c4c7037c6766924a43666b781ed1479587a2,0xb0deea380b10aaab11e12102a20b31fa11fd7ddfbed72761ad30cd6933e143b9,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x1f60c4c7037c6766924a43666b781ed1479587a2/era=1,BuyGDFactoryV2,1,true +CELO,42220,0x25878951ae130014e827e6f54fd3b4cca057a7e8,17713819,9223372036854775807,0x25878951ae130014e827e6f54fd3b4cca057a7e8,0xe0ce44f796f8c819bdba6334eb56f0ab6be2936af74486a2c2ccae17e0d17b1f,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x25878951ae130014e827e6f54fd3b4cca057a7e8/era=1,PoolGdCeloV2,1,true +CELO,42220,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,16393503,18349124,0x7dc6b57adae1aaa94e01a3049cd42b8adce5090c,0x7423f597fdcfb7c349e024be728df2d0c05e3337e615808c64b8c0994ff66a5c,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca/era=1,SuperfluidIDAv1,1,false +CELO,42220,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,18349124,19952321,0xd399e2fb5f4cf3722a11f65b88fab6b2b8621005,0x131499da5b515b0f696d9e320b87b3258838287f30bcde867d1648ba1bd83471,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca/era=2,SuperfluidIDAv1,2,false +CELO,42220,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,19952321,20091409,0x507c3a7c6ccc253884a2e3a3ee2a211cc7e796a6,0x0103da8886a08479c1249b11691d702669168e2f64f65595db70270ee66859f0,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca/era=3,SuperfluidIDAv1,3,false +CELO,42220,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,20091409,21146434,0x2622bfc83f429bf313341857850a1dde09685855,0x005ec5ffe135e03f2feacd794c02fe50aabc4dd3c572eb0dcc023023bb2a215f,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca/era=4,SuperfluidIDAv1,4,false +CELO,42220,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,21146434,23701580,0xd48317ccdac2ca3fd5e3c58c32da3a7c517937b6,0x0799b7eb67f8bf5f1db451db0b501b02796bedddfe80efa2a991ff28f1a4df4c,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca/era=5,SuperfluidIDAv1,5,false +CELO,42220,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,23701580,24738429,0xfb2b126660be2fdeba254b1f6e4348644e8482e7,0xfafd5fc7ae369d3fce5cc48edaa0de12d57761ce316328b0228d358d69b9ee65,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca/era=6,SuperfluidIDAv1,6,false +CELO,42220,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,24738429,26706819,0x2e4861b1f56a67473b7bf0dd1ef85e9e9fa5ad75,0x3f185f2c62fd18472510fbb526fc17a7bf9b0da44f028195dacb1f1ad6b85e2c,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca/era=7,SuperfluidIDAv1,7,false +CELO,42220,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,26706819,28853698,0x0de6448cc883168076f7b10449bc7024d42f7910,0xd1000660be8820603092f51c3c5435be3cc133c9f7a2e47a745fd159d4d45bc4,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca/era=8,SuperfluidIDAv1,8,false +CELO,42220,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,28853698,29627986,0x466be9ef50dec3c22eaa4f070e9c9ceaaccd1e75,0xb86b086999fdf33a2056b5fb2d92686006ff58f9d59216ad9ceea32e456af822,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca/era=9,SuperfluidIDAv1,9,false +CELO,42220,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,29627986,33928238,0xb84c98d9b51d0e32114c60c500e17ea79dfd0daf,0x5144e6bd0aff5ec0dc215c75db7a2e5a6ea9539e21f10ac47bce49108c1f1798,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca/era=10,SuperfluidIDAv1,10,false +CELO,42220,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,33928238,39643668,0xd59ba9a84fa02e3687bb0694e459b3c1d76586f9,0x4c0dce8901dea2158d8f1edcc42bc70261cce1f74e58f4f0ef5ca644a44427b6,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca/era=11,SuperfluidIDAv1,11,false +CELO,42220,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,39643668,52777129,0xf0ec6a8842ca72aec8a4d4573e731242389e18a8,0x3b0de12889b24499a458af0c481b84c9a572276f46a6faf92f7a5e9de2107226,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca/era=12,SuperfluidIDAv1,12,false +CELO,42220,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,52777129,61309260,0x1d38a1f81216b73c05a10eac5e84f566d4d9d8da,0xfb7ddd181f516de9d0f9448a3aa6faab8aaba0d4296d4df8793f1f09a9fb9d8f,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca/era=13,SuperfluidIDAv1,13,false +CELO,42220,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,61309260,9223372036854775807,0x295cef78e76564b124b948a05dbd6522c3ec76b1,0x062b6f052bfc1eeb46d77828aecf61f2c118d08d8dbdd4bd6672e42f1fed0fbb,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca/era=14,SuperfluidIDAv1,14,true +CELO,42220,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,43985163,9223372036854775807,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,0x3ed9587168a0fe70acc18971f52cba06f18bcd4b4b5ba2f0590b8c17b1c0cdca,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x288dc841a52fca2707c6947b3a777c5e56cd87bc/era=1,UniswapV4PoolManager,1,true +CELO,42220,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,31415857,61416834,0xd9ce916d711977d5b27697a13964556b4fb8af1d,0x65d8c817bac8f41eb34548c15ad6ae5e744da2bd5373916df3b8e63f1fecd916,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41/era=1,MentoExchangeProvider,1,false +CELO,42220,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,61416834,9223372036854775807,0xe930cde20f60d0a4fc9487874861ae259f5bed48,0x5ed71ccf7c4789f438827e074bc8bba84c7fc2c615495b12a2f9c51398a8b0d5,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41/era=2,MentoExchangeProvider,2,true +CELO,42220,0x308b7405272d11494716e30c6e972dbf6fb89555,23675300,23701580,0x7ffce315b2014546ba461d54eded7aac70df4f53,0xb786d4ce6758e6e6e6c95c8f4dd32c3f605575b77a97d676cc77e0a357557ae6,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x308b7405272d11494716e30c6e972dbf6fb89555/era=1,SuperfluidGDAv1,1,false +CELO,42220,0x308b7405272d11494716e30c6e972dbf6fb89555,23701580,24738429,0x554a8acef6c689a74b25b1c41f58fa2e678162b5,0x339ef1ccdc96ea6e5f945d0869f69e68d704e5aee4a3f0fb47e920233f2e58e2,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x308b7405272d11494716e30c6e972dbf6fb89555/era=2,SuperfluidGDAv1,2,false +CELO,42220,0x308b7405272d11494716e30c6e972dbf6fb89555,24738429,26706819,0xc70ce47df817f25bfbb4fb66fd42326ad306f27d,0x2f10ed30f32aac01825d800417aa9a035350611a8846ab187ad2f5683030b04b,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x308b7405272d11494716e30c6e972dbf6fb89555/era=3,SuperfluidGDAv1,3,false +CELO,42220,0x308b7405272d11494716e30c6e972dbf6fb89555,26706819,27058151,0xab1286ab62d0dffd994f4b2d72b24eaa9e295562,0x467730c607a2af26278920b99602bba2ae00fa99735aa8b92b7c31d4aeb1e01d,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x308b7405272d11494716e30c6e972dbf6fb89555/era=4,SuperfluidGDAv1,4,false +CELO,42220,0x308b7405272d11494716e30c6e972dbf6fb89555,27058151,27279493,0xe72830e7ebbff8ce0866059de83cacd4263acd08,0x78428255afad1008379da37854d51a8c6be3020f156dcc65a2f150180332cb71,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x308b7405272d11494716e30c6e972dbf6fb89555/era=5,SuperfluidGDAv1,5,false +CELO,42220,0x308b7405272d11494716e30c6e972dbf6fb89555,27279493,28853698,0xb75bd19c682e62e6a0c35399bb3a2538fcc9cef6,0x51a1f5d9659cf4db2e53be47120a0b772ad7156ff8cb7e2383659deeb66e9deb,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x308b7405272d11494716e30c6e972dbf6fb89555/era=6,SuperfluidGDAv1,6,false +CELO,42220,0x308b7405272d11494716e30c6e972dbf6fb89555,28853698,29627986,0x6fc99f5591b51583ba15a8c2572408257a1d2797,0x4f906e557ab9ee6a7b78ddfc34f24a3ac478263d6a6ee139c0a45c028dd762a4,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x308b7405272d11494716e30c6e972dbf6fb89555/era=7,SuperfluidGDAv1,7,false +CELO,42220,0x308b7405272d11494716e30c6e972dbf6fb89555,29627986,33928238,0xa0844efaf9a6803e9fa379ee59d44d3ef581ea3f,0x3a8c483a4085356d3be9ba5fa9861d796479f2b012f1e6a6b4d59f1c20741303,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x308b7405272d11494716e30c6e972dbf6fb89555/era=8,SuperfluidGDAv1,8,false +CELO,42220,0x308b7405272d11494716e30c6e972dbf6fb89555,33928238,39643668,0xc8f6f1720e6266445b3b53b9b9870b25ade5154e,0x6d6bcbc09347c139ac7030309ad6974266386ded295636658d837996e388cb56,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x308b7405272d11494716e30c6e972dbf6fb89555/era=9,SuperfluidGDAv1,9,false +CELO,42220,0x308b7405272d11494716e30c6e972dbf6fb89555,39643668,44995009,0x96c3c2d23d143301cf363a02cb7fe3596d2834d7,0x2327ceb8850a68dabe52cebd96a38eb4f32cdec27395a3b52877751c3c2468d8,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x308b7405272d11494716e30c6e972dbf6fb89555/era=10,SuperfluidGDAv1,10,false +CELO,42220,0x308b7405272d11494716e30c6e972dbf6fb89555,44995009,52777129,0x4c78cad0cc7152fa8f64ce5298a2d5216c7e4d81,0xead9a7e206538e62c0f6e4dd33621dc98ba53e3352e3214034d618bc44478abe,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x308b7405272d11494716e30c6e972dbf6fb89555/era=11,SuperfluidGDAv1,11,false +CELO,42220,0x308b7405272d11494716e30c6e972dbf6fb89555,52777129,61309260,0xa347bdc5965323f92ccd950a8b7012c0e438e178,0x5a8b677cd86a18a93c7ae21271fd141fa249950147262c7da8088b683e28d3a0,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x308b7405272d11494716e30c6e972dbf6fb89555/era=12,SuperfluidGDAv1,12,false +CELO,42220,0x308b7405272d11494716e30c6e972dbf6fb89555,61309260,74797088,0x20dd21b94b88cbeee338c7ffd6124f716c0b54b2,0xabe37902c5582ed6ca1fa60c4c6e6956d4abaa1c701b43c219536457fa63c893,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x308b7405272d11494716e30c6e972dbf6fb89555/era=13,SuperfluidGDAv1,13,false +CELO,42220,0x308b7405272d11494716e30c6e972dbf6fb89555,74797088,9223372036854775807,0x0fcddf2d5023219145e902cb3b0c44159ab59d61,0x1638d7614afb64812742f4e5df6511885567ff68515e7e74a16416107afa670e,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x308b7405272d11494716e30c6e972dbf6fb89555/era=14,SuperfluidGDAv1,14,true +CELO,42220,0x30afd0534daa29135308d048103b40dc1ba4518d,26952390,9223372036854775807,0x30afd0534daa29135308d048103b40dc1ba4518d,0x60344a20cbd88bedbfd88cec885b62ad50c025de6de11abf30abf652d86ebbc4,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x30afd0534daa29135308d048103b40dc1ba4518d/era=1,BulkWhitelist,1,true +CELO,42220,0x36829d1cda92fff5782d5d48991620664fc857d3,18003063,18795892,0xdbc8860618482f703a4047340b8639b1452f96ec,0xe65975cf95e2a884b17fff033799e3ea2f0a852c8b8ea018906dd136b66e639e,announced,gd_dbt/seeds/era_boundary_evidence.csv#CELO/0x36829d1cda92fff5782d5d48991620664fc857d3/era=1,Invites,1,false +CELO,42220,0x36829d1cda92fff5782d5d48991620664fc857d3,18795892,20211506,0x61760d949357066ae29c469b70a91934273e4ef3,0xb9b02551b4d049d0c13cfca61238ea61363f54e1d129dbbad9ed95646aca23cc,announced,gd_dbt/seeds/era_boundary_evidence.csv#CELO/0x36829d1cda92fff5782d5d48991620664fc857d3/era=2,Invites,2,false +CELO,42220,0x36829d1cda92fff5782d5d48991620664fc857d3,20211506,20645578,0x142e6d0afdd09c8629970b5fb0cf9798a3d21f89,0xe469498ecb04290fffe5eab6e1f064e4974fea90b4a6f63e1c7d14106793c001,announced,gd_dbt/seeds/era_boundary_evidence.csv#CELO/0x36829d1cda92fff5782d5d48991620664fc857d3/era=3,Invites,3,false +CELO,42220,0x36829d1cda92fff5782d5d48991620664fc857d3,20645578,24428495,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,0xb104188d6bf90a6f72c1278594cf06f53ea827a7fe85d91e1dc4167706903edd,announced,gd_dbt/seeds/era_boundary_evidence.csv#CELO/0x36829d1cda92fff5782d5d48991620664fc857d3/era=4,Invites,4,false +CELO,42220,0x36829d1cda92fff5782d5d48991620664fc857d3,24428495,24518263,0xd2e26679b4d21cb501ebbc99744c29ed061a6b8c,0x2009538d39810ef0f0f43438fa262223bcb744fd3e722af01c898afadb3e15a6,announced,gd_dbt/seeds/era_boundary_evidence.csv#CELO/0x36829d1cda92fff5782d5d48991620664fc857d3/era=5,Invites,5,false +CELO,42220,0x36829d1cda92fff5782d5d48991620664fc857d3,24518263,24600260,0x87c222b6212b8352c48b7047e5c97c8797535a09,0x1b8340f46186440723c9966efc1401b06da022e2ea896256168da6be8f783f84,announced,gd_dbt/seeds/era_boundary_evidence.csv#CELO/0x36829d1cda92fff5782d5d48991620664fc857d3/era=6,Invites,6,false +CELO,42220,0x36829d1cda92fff5782d5d48991620664fc857d3,24600260,61165821,0xf2196f8c2ba0674a8b00369cd65fab3f54b080a0,0x02225e275e9e2e265175be1ac585904205a1a49612c41c23b6a15238c05bdf0d,announced,gd_dbt/seeds/era_boundary_evidence.csv#CELO/0x36829d1cda92fff5782d5d48991620664fc857d3/era=7,Invites,7,false +CELO,42220,0x36829d1cda92fff5782d5d48991620664fc857d3,61165821,9223372036854775807,0x4072cb2d7e95def1559f6f72491039fe0534fa37,0xea995ee585fba0d4d31a119bcc206c76b7af8a7155b7c2ee1ca071e111b77ed5,slot_bisected,gd_dbt/seeds/era_boundary_evidence.csv#CELO/0x36829d1cda92fff5782d5d48991620664fc857d3/era=8,Invites,8,true +CELO,42220,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,31680016,9223372036854775807,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,0xced8cb884f76be736e2ac90f1bcc4eaadac233235a7da8dd813d9adbfeffbcce,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341/era=1,PoolGdUsdgloV3Hi,1,true +CELO,42220,0x437c699887779d0a95ad6349cfde7dfa716c005d,18862438,9223372036854775807,0x437c699887779d0a95ad6349cfde7dfa716c005d,0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x437c699887779d0a95ad6349cfde7dfa716c005d/era=1,CommunitySafe,1,true +CELO,42220,0x43d72ff17701b2da814620735c39c620ce0ea4a1,18006679,19276072,0xedbe438cd865992fdb72dd252e6055a71b02be72,0x0e581bfc2fe31489ffb4c73916e5eb871089492aab7d977d80cd563d3011e236,announced,gd_dbt/seeds/era_boundary_evidence.csv#CELO/0x43d72ff17701b2da814620735c39c620ce0ea4a1/era=1,UBIScheme,1,false +CELO,42220,0x43d72ff17701b2da814620735c39c620ce0ea4a1,19276072,23063176,0x854f84ef0d9abc1e0afb4e96c962d5456b62214e,0xa218cc030a5bf302bd79f7c0814e7d03ba74606098b00733d9751be6af84dbb8,announced,gd_dbt/seeds/era_boundary_evidence.csv#CELO/0x43d72ff17701b2da814620735c39c620ce0ea4a1/era=2,UBIScheme,2,false +CELO,42220,0x43d72ff17701b2da814620735c39c620ce0ea4a1,23063176,50351048,0xe8fcbac4bd18f80301450e428518e9dedc183a26,0x3588b09013666a632da7bb2559251b2efb62086be858ddaf9a604eb4340542c4,announced,gd_dbt/seeds/era_boundary_evidence.csv#CELO/0x43d72ff17701b2da814620735c39c620ce0ea4a1/era=3,UBIScheme,3,false +CELO,42220,0x43d72ff17701b2da814620735c39c620ce0ea4a1,50351048,9223372036854775807,0x43f0eb66ea3c2d9552241525aa1af6607227dfbf,0xdb2d70994b744a419372a0526da1e3bbe069a59e7569a9f3c0965d85d1b60ecd,slot_bisected,gd_dbt/seeds/era_boundary_evidence.csv#CELO/0x43d72ff17701b2da814620735c39c620ce0ea4a1/era=4,UBIScheme,4,true +CELO,42220,0x495d133b938596c9984d462f007b676bdc57ecec,17237959,9223372036854775807,0x495d133b938596c9984d462f007b676bdc57ecec,0x8a27316984da83331e574723efd0810faf4d7065f3037b8778d9c572ea49c6d8,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x495d133b938596c9984d462f007b676bdc57ecec/era=1,Avatar,1,true +CELO,42220,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,18003061,18481054,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,0x60adef4e58f448da1c484b8f64b875688ea6b17e6cf34531bc9530985d05be5e,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x4f93fa058b03953c851efaa2e4fc5c34afdfab84/era=1,Faucet,1,false +CELO,42220,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,18481054,18866025,0x91b6eed85458239f281f5ad46c8defd60ddef8b2,0xbdc69d3696a4a6de3cdd277f5b71e67bad0f19f0a433f3e6a4d4235257c28f7c,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x4f93fa058b03953c851efaa2e4fc5c34afdfab84/era=2,Faucet,2,false +CELO,42220,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,18866025,20299862,0xac92cea7b8936e769b00117e7428f7499c93f9db,0x1e06dc2d8337ea3aaa409d7742b21d35a686da7e31b7211ecd338bfea40aac9d,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x4f93fa058b03953c851efaa2e4fc5c34afdfab84/era=3,Faucet,3,false +CELO,42220,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,20299862,39388555,0x0cb76de990330b36b72c9b604a71d24eaa45ebf4,0xa342d94b354aa61ba8221b004ade990d040fb7de31385ca82ff9b0a65c649286,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x4f93fa058b03953c851efaa2e4fc5c34afdfab84/era=4,Faucet,4,false +CELO,42220,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,39388555,40258358,0x783548481a6ca92b6589365161b31e3ed64d0c3c,0xebabf487538a31aba764a34ab1ed1570d6795310a94f6d3d4309abc5b2f975dc,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x4f93fa058b03953c851efaa2e4fc5c34afdfab84/era=5,Faucet,5,false +CELO,42220,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,40258358,49737165,0xf224d5166fb194d8404a4a2d1d9fbb41866625ad,0xe5aa4f18fa67a7c1ac33d6277d9216f7adbec3f5cf027a50534f7ab929fadbdf,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x4f93fa058b03953c851efaa2e4fc5c34afdfab84/era=6,Faucet,6,false +CELO,42220,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,49737165,49740289,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,0x68755099f25764af194ff16c1f4a6fd14bdd4bd89a1c3f6832649a36508e6533,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x4f93fa058b03953c851efaa2e4fc5c34afdfab84/era=7,Faucet,7,false +CELO,42220,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,49740289,59605758,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,0xe8429a22753ce3f82c856a7f5dee88264782d956d615db983d0cd5ec8e9fb325,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x4f93fa058b03953c851efaa2e4fc5c34afdfab84/era=8,Faucet,8,false +CELO,42220,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,59605758,59606288,0x41ef166fb7d022ce9a90b47581f323d19fafbddd,0x368dbfc1d9f8d5f05945e140ed7b50750b906c2373068f38cc9e892ab0b66163,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x4f93fa058b03953c851efaa2e4fc5c34afdfab84/era=9,Faucet,9,false +CELO,42220,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,59606288,9223372036854775807,0x08fdf766694c353401350c225caeb9c631dc3288,0x60946ac381f89c0e81d17e75a66b09f5eb90e0846cbc50fba2e642a50f5373cc,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x4f93fa058b03953c851efaa2e4fc5c34afdfab84/era=10,Faucet,10,true +CELO,42220,0x5557e9def86ad6564462741a7a3f3679c1223f5d,31415857,9223372036854775807,0x7288d592e1b9013c668801f722be650993d2925a,0x9da4f4203282696d49deb0c241e49e0ff09f8b6da2d463f69f3fc98e66899a74,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x5557e9def86ad6564462741a7a3f3679c1223f5d/era=1,MentoExpansionController,1,true +CELO,42220,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,13037458,13254104,0xb0b86dd967655728218b7b87b10051a60758af82,0xc8359e84630f5907348cea1136429f5b91a3d0f687b57f20835a1146881f80e2,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x5566b6e4962ba83e05a426ad89031ec18e9cadd3/era=1,GoodDollarMintBurnWrapper,1,false +CELO,42220,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,13254104,13660450,0x413e395b10be6f39f2aa0d80eec48edb88738ac4,0x35f1a1bc56ad9ca11379afa307e637159af9caba0eafea55d97486882a3e4a33,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x5566b6e4962ba83e05a426ad89031ec18e9cadd3/era=2,GoodDollarMintBurnWrapper,2,false +CELO,42220,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,13660450,15806090,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,0xdfcf646513c464e512d4c0cac0bf69f5ecd5db669a5cba84244159daaba61c82,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x5566b6e4962ba83e05a426ad89031ec18e9cadd3/era=3,GoodDollarMintBurnWrapper,3,false +CELO,42220,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,15806090,17228965,0x0a36091884b8d7808d5fdb47cbdead457ea9803e,0x6a9b48197ba0fb19f74cf5467b1207f689120d97702df03bd2d90c90efff6100,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x5566b6e4962ba83e05a426ad89031ec18e9cadd3/era=4,GoodDollarMintBurnWrapper,4,false +CELO,42220,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,17228965,17239796,0xb3109ca8c7bf74fc5d28285ecf7fe498c21a0698,0x54ef0f8fab68d40828eeeabb66ea0f3d714be1a52894f55431d1c5c76be88d0c,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x5566b6e4962ba83e05a426ad89031ec18e9cadd3/era=5,GoodDollarMintBurnWrapper,5,false +CELO,42220,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,17239796,9223372036854775807,0x098148534ac15a44cff52387ba81ed929589ecaf,0x976528b459f21a7bd143cf3b456517b0a452da77a06e6749356da66a98548dfd,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x5566b6e4962ba83e05a426ad89031ec18e9cadd3/era=6,GoodDollarMintBurnWrapper,6,true +CELO,42220,0x5615cdab10dc425a742d643d949a7f474c01abc4,13916381,9223372036854775807,0x5615cdab10dc425a742d643d949a7f474c01abc4,0xec8b1d6527bdadca0f0158435b41f0a9518215005a39b1f286d6a3628b7f806c,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x5615cdab10dc425a742d643d949a7f474c01abc4/era=1,UniswapV3Router,1,true +CELO,42220,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,17237955,17237956,0x0000000000000000000000000000000000000000,impl:0x0000000000000000000000000000000000000000,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a/era=1,GoodDollar,1,false +CELO,42220,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,17237956,17238214,0xca903643aa81a2d67863079548f6b53a6dae43d7,0x6d4edf2a14e946bc4bc85ccd999d505d35a8c0a901030d95d96cf42312f36d85,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a/era=2,GoodDollar,2,false +CELO,42220,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,17238214,17260434,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,0xf6dcc0590e58b7501bb8701ad1ad658cf2b7de8ec3a8faa9b6d4f2fba8764fa2,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a/era=3,GoodDollar,3,false +CELO,42220,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,17260434,17271388,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,0x083fbabd4a581ff5a538068453614131f51ee536a0bce7bcc5aa716a55d7aa8d,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a/era=4,GoodDollar,4,false +CELO,42220,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,17271388,21746648,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,0x934f7100a5cf339f677c3822c76029b38a9e97438635450c878f8c4d58f4909a,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a/era=5,GoodDollar,5,false +CELO,42220,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,21746648,22596133,0xac862af0a463a5faebbe959e3483b41400f5bb38,0xbff04a2102f39ae6f66ae309cb4591635ca34f2459429261134e25411faf01fb,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a/era=6,GoodDollar,6,false +CELO,42220,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,22596133,77207809,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,0xa2d98dc81d3ca3bab7e5cdbe11a4860fbefde5b50a0c910c52a2504b146e2db5,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a/era=7,GoodDollar,7,false +CELO,42220,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,77207809,9223372036854775807,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,0x4650c5f121ca37da373278cb05efc0857704454f4a1afec72b6bc4058bd409d6,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a/era=8,GoodDollar,8,true +CELO,42220,0x62d5b84be28a183abb507e125b384122d2c25fae,5272596,9223372036854775807,0x62d5b84be28a183abb507e125b384122d2c25fae,0xdac4452e3e8e28193a714ff79e8268661235b1f73a3ccf61d85470d3ce89ed3b,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x62d5b84be28a183abb507e125b384122d2c25fae/era=1,UniswapV2Factory,1,true +CELO,42220,0x67fea58d5a5a4162ced847e13c2c81c73bf8aec4,25639915,9223372036854775807,0x67fea58d5a5a4162ced847e13c2c81c73bf8aec4,0xa99af02b020bfe03b92021add28ab8707c33a0d1887e01e67da39c5531fb9e85,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x67fea58d5a5a4162ced847e13c2c81c73bf8aec4/era=1,UniswapV3FactorySecond,1,true +CELO,42220,0x6b845effaf36c374e8e7cf543efa680f2f71f098,31415781,9223372036854775807,0x6db04d771e2ba750effbbad59dcca20381efb1c5,0xa1a06f022a982744ad4a646f9ced63087f65f2b7d4e29c4e92345f2714abb030,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x6b845effaf36c374e8e7cf543efa680f2f71f098/era=1,CeloDistributionHelper,1,true +CELO,42220,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,18002976,21368263,0xbfb5052aee113fc160c18ae85c9831dcd2b2fdc0,0xc67787fd2231f7326a2527db40332b920f33840fe942296e17be56f6125ac589,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x7119cd89d4792af90277d84cdffa3f2ab22a0022/era=1,AdminWallet,1,false +CELO,42220,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,21368263,21369184,0x24614ad257f4d09fccaec024c65c40c060e73e9d,0xe21dd06280946f5040f63cbfa0ea2b2e35e000ae528828935dbbaed0244177d7,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x7119cd89d4792af90277d84cdffa3f2ab22a0022/era=2,AdminWallet,2,false +CELO,42220,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,21369184,28227319,0xae2cd2a9513215961d344a2581dcab678598eedf,0xae2e0d5cd6fc590c4b6ce659efebd29bb417c359076b8ecd7ec4adf389379c00,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x7119cd89d4792af90277d84cdffa3f2ab22a0022/era=3,AdminWallet,3,false +CELO,42220,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,28227319,50872873,0x703856db9a5432964f081ff4dc46480738fae7bd,0xf15f2e31e0c7251bd3babc7f23dccff946ca6582daa5f0eee7e19d3424823619,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x7119cd89d4792af90277d84cdffa3f2ab22a0022/era=4,AdminWallet,4,false +CELO,42220,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,50872873,9223372036854775807,0xfef0ef0916c5c7745b201dc9e2d04483b1eb36f1,0x28708bf9f584205831cdf5ff571feb8c3fe60d1759a4edc4953eb2ffe8b88430,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x7119cd89d4792af90277d84cdffa3f2ab22a0022/era=5,AdminWallet,5,true +CELO,42220,0x765de816845861e75a25fca122bb6898b8b1282a,2957,2961,0x0000000000000000000000000000000000000000,impl:0x0000000000000000000000000000000000000000,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x765de816845861e75a25fca122bb6898b8b1282a/era=1,CUSD,1,false +CELO,42220,0x765de816845861e75a25fca122bb6898b8b1282a,2961,3629000,0xaa933baf03cfc55b8e4e0d7de479bcc12f189352,0xa23ae32221bdebb534ab6da55a2b31ca5cc931aa8b6def9bb5f8401e139d51d2,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x765de816845861e75a25fca122bb6898b8b1282a/era=2,CUSD,2,false +CELO,42220,0x765de816845861e75a25fca122bb6898b8b1282a,3629000,5822108,0x7e327831c644f2b1fef642079f116181bc471cb3,0xfd545fc18c7a1a554e36aeb4392a9d532ba2911131296f6a5d1d5a478ffbe4e1,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x765de816845861e75a25fca122bb6898b8b1282a/era=3,CUSD,3,false +CELO,42220,0x765de816845861e75a25fca122bb6898b8b1282a,5822108,9105530,0x2c4c1f3e06d494bcc03e93b373637cc4333cbd7d,0xe4c43237f59abc7e640bd1a1e60fe5d81b77b5522ad3459aede9f1e17c3d0b46,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x765de816845861e75a25fca122bb6898b8b1282a/era=4,CUSD,4,false +CELO,42220,0x765de816845861e75a25fca122bb6898b8b1282a,9105530,18635694,0x18e6bfdc909063f7445e410a5495264619495bcb,0x040dda9403fdb8661a907d59b7aa0b98d8d163e35647e41c4e697d669036367b,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x765de816845861e75a25fca122bb6898b8b1282a/era=5,CUSD,5,false +CELO,42220,0x765de816845861e75a25fca122bb6898b8b1282a,18635694,23065563,0x7ae2f384fe14ead85779f9224558862d6d3e4f28,0xd73ed2d40adbb84367cd834fa834bb09eb4f67e668215e8895635930c8d7b714,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x765de816845861e75a25fca122bb6898b8b1282a/era=6,CUSD,6,false +CELO,42220,0x765de816845861e75a25fca122bb6898b8b1282a,23065563,60666007,0x434563b0604be100f04b7ae485bcafe3c9d8850e,0x659d421716b8eac9026199a99ab15d277dc163a46f48ac5ebf9e1462a6d85170,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x765de816845861e75a25fca122bb6898b8b1282a/era=7,CUSD,7,false +CELO,42220,0x765de816845861e75a25fca122bb6898b8b1282a,60666007,60745284,0x4b9b0e94197b7b2b11d311239e1420106ce7a2a2,0x43c6a9f2bbd66e2a2cff43250a380b0fbbf4880e865b163303a849bf45a71ca8,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x765de816845861e75a25fca122bb6898b8b1282a/era=8,CUSD,8,false +CELO,42220,0x765de816845861e75a25fca122bb6898b8b1282a,60745284,9223372036854775807,0x815795c30d0758a297b08cd4e0643620c974c318,0xd5be5b27724e5f68e90b0765f4a2bc883b6847812356d4ef33ac38ed277a30cf,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x765de816845861e75a25fca122bb6898b8b1282a/era=9,CUSD,9,true +CELO,42220,0x82825d0554fa07f7fc52ab63c961f330fdefa8e8,13916379,9223372036854775807,0x82825d0554fa07f7fc52ab63c961f330fdefa8e8,0x557b5bc80c7000c05bac66693aff2264927a0a22ea1f80d590449b52d515aa34,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x82825d0554fa07f7fc52ab63c961f330fdefa8e8/era=1,UniswapQouter,1,true +CELO,42220,0x8471406c3bff67cc6538481c8550364bda6ca691,31415855,9223372036854775807,0x8471406c3bff67cc6538481c8550364bda6ca691,0xdd44d5a52707f76ac1bb4147820056bd47ca2c90f79d82fdaeb19b7d180179b4,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x8471406c3bff67cc6538481c8550364bda6ca691/era=1,MentoProxyAdmin,1,true +CELO,42220,0x88de45906d4f5a57315c133620cfa484cb297541,31415857,61416834,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,0x58558a86a3aced5b23ae279244bd285f68c9d6d0a20cf283b7a40a0784697831,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x88de45906d4f5a57315c133620cfa484cb297541/era=1,MentoBroker,1,false +CELO,42220,0x88de45906d4f5a57315c133620cfa484cb297541,61416834,9223372036854775807,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,0x2e63673ca3232bd818d12804ade7e1d688b7c11da7812d0237a3564e99cd0fb7,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x88de45906d4f5a57315c133620cfa484cb297541/era=2,MentoBroker,2,true +CELO,42220,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,40596860,9223372036854775807,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,0x84fe2b52e16ffad7d7e40b57117e8ee7ab3c7e4c3edb2acfc9a7dee556f25a47,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x8b393470bef8bb27a9a5169531b4eba5209b0b26/era=1,PoolGdCeloV3Mid,1,true +CELO,42220,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,19916922,9223372036854775807,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,0x98890919ba4af6d5acadd5f3bf6b6387333d595bf974ef93adfd993d79acf92c,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x9491d57c5687ab75726423b55ac2d87d1cda2c3f/era=1,PoolGdUsdmV3,1,true +CELO,42220,0x94a3240f484a04f5e3d524f528d02694c109463b,31415856,9223372036854775807,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,0xe5750e9acc0322eae552526478b90a1a762ea401bf9094ff36daa6d0e4669020,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x94a3240f484a04f5e3d524f528d02694c109463b/era=1,MentoReserve,1,true +CELO,42220,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,21108554,9223372036854775807,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,0x4571767e06d5040fa5e97ac1a4d2552c38d18a335a34e1f9315558f06a3bae3d,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f/era=1,PoolGdUsdgloV3Low,1,true +CELO,42220,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,16393492,18349124,0x25cc912cc038f1791734f39ceb4d8bffb32c7c61,0x75e9777e4dc04eb4239f29c5d7f293dc476140250658aa342ae46dc5943dcaba,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad/era=1,SuperfluidCFAv1,1,false +CELO,42220,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,18349124,19952321,0xe40983c2476032a0915600b9472b3141aa5b5ba9,0x7d085cb6ac5adcabb2282b7790fd4b6ce42dba3bf82c7984db6c9a8ea98e611f,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad/era=2,SuperfluidCFAv1,2,false +CELO,42220,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,19952321,20091409,0x5f001c3915084186b9109fb9dc1e978c98f854b0,0xfd8e2cc384599300dce3e61069f0d2ce1313164acf549816f25fb59f548f543d,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad/era=3,SuperfluidCFAv1,3,false +CELO,42220,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,20091409,21146434,0x9f9eed9bbc38e9e0514fd9dfcc0bca9869a9c534,0x2ef2c7bfba9b8dca88af2515f2a4aa08cde06f64b0af0a15c90068db7f8c6d1c,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad/era=4,SuperfluidCFAv1,4,false +CELO,42220,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,21146434,23701580,0x4247ba6c3658fa5c0f523bacea8d0b97af1a175e,0x1c984c77810263353e0e29c4f8d46f24622b7bb0ed55499cc51aeae7c834554c,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad/era=5,SuperfluidCFAv1,5,false +CELO,42220,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,23701580,24738429,0xdf3f4b9e4e67a21c868d043a92ae921ff0ebadbb,0xbd691ecb50633ce343c9f1cd04c7789a1cbb1e075621e3209809c1482b3e78f3,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad/era=6,SuperfluidCFAv1,6,false +CELO,42220,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,24738429,26706819,0xe3f6ec0676b9ce5d759580e1d526dee31678c283,0x85d3c06af86a7ad69fb86b1dc069dcacff6cba81fdcce7fa857eae31d3fc31dc,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad/era=7,SuperfluidCFAv1,7,false +CELO,42220,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,26706819,27058151,0x247f65bd849d686147330978aa7521457c5a83bf,0x20b540bd27dd1019829f59165480a11522745d5fb13a6815102e65452d36236f,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad/era=8,SuperfluidCFAv1,8,false +CELO,42220,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,27058151,28853698,0x81398af97997f3973416d312939f790636719195,0x942776f307798a9174da8bc44d2dc4f24469b24ce6d3974e35f4280a7e88f846,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad/era=9,SuperfluidCFAv1,9,false +CELO,42220,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,28853698,29627986,0xf10e526e33f3f377e5b11d62e091fe3f4162a3d0,0x0b9f6edffde404761e0993c5b1712631e782dd372af34820a9ea0dd95aed21ca,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad/era=10,SuperfluidCFAv1,10,false +CELO,42220,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,29627986,33928238,0x75e58f16f95ac530789d22e55713c9f8dc22444c,0xd4b756d9a39c0ac5df7daeda534d2ab144410bab2a665553566f0f2b7f9246fe,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad/era=11,SuperfluidCFAv1,11,false +CELO,42220,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,33928238,39643668,0x511cba3de92db7891967e21dbd7c4571531ab84b,0xb4e15d60d54a173a5cfe3820cb03c0f7ecb514f015a7ab934c6b76ab6849aeac,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad/era=12,SuperfluidCFAv1,12,false +CELO,42220,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,39643668,52777129,0xd571f5ec96a5b362d10615ff999f06fac4c9e141,0xacf7e26bc301a35fe1ba129370a5af1d3e8555c6610bc768c8f7183e3f18903a,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad/era=13,SuperfluidCFAv1,13,false +CELO,42220,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,52777129,61309260,0x57897b796ece6633fc7c0c6490b4eb84d58509e5,0xcc3e5b55fc44f61f11120b6ad3973f97782035b82eb55455a2589a2a37a4c623,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad/era=14,SuperfluidCFAv1,14,false +CELO,42220,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,61309260,74797088,0x7e115385bdbd12fb943a099320c41224b4fa96f4,0x938d286c9bc510c3815ee4df6bc0c94e47770008998c9c0c05f8f35c6ca0d4c1,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad/era=15,SuperfluidCFAv1,15,false +CELO,42220,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,74797088,9223372036854775807,0x88bb53dea50691cc41094cde84f88d6afb8ca499,0xfb234d8843f0d85344c9a28a31c61b75c71866116caed48021c0419b16be14ca,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad/era=16,SuperfluidCFAv1,16,true +CELO,42220,0xa2521e8f5a990903fdd8afa6570c52526e7e0d5e,16375699,9223372036854775807,0xa2521e8f5a990903fdd8afa6570c52526e7e0d5e,0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0xa2521e8f5a990903fdd8afa6570c52526e7e0d5e/era=1,GuardiansSafe,1,true +CELO,42220,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,21473545,21473546,0x0000000000000000000000000000000000000000,impl:0x0000000000000000000000000000000000000000,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5/era=1,MpbBridge,1,false +CELO,42220,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,21473546,23063176,0xd0a3fad8d7887f8264414ddd3290ed1782fb4658,0x3cf5b0c8c76f42b66f9fdea7cc3fa15f701f158458a5d0ed4e5a7966e5cbb891,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5/era=2,MpbBridge,2,false +CELO,42220,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,23063176,31525116,0x691de730d97d545c141d13ed5e9c12b7cb384a73,0x61ac5f3f5751317589d19866c83ec842c45e2e38869f22973b935ed691ac8f88,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5/era=3,MpbBridge,3,false +CELO,42220,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,31525116,50351048,0x2537f22e7b2d5d14e7f571fa67fcd846d73317f6,0xf73e0601329e2c0be422f8110b8d9e72950ec58d1a23d0aebf931dc07aa742f9,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5/era=4,MpbBridge,4,false +CELO,42220,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,50351048,52958251,0x7bdaf2fb332761b2a6a565a43ccb0acfc36d2c3d,0x1624abfee3f1e647d995471b9cd0434db19d19df21e57b80046ae86f52c9df34,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5/era=5,MpbBridge,5,false +CELO,42220,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,52958251,61416834,0xf3eab7018d74e7df95a5d8dc70987c0539bdf48f,0x7fd33bb337b7565f86a2f7099feb87a2b4f446b94151b7c68b4091eadfb0b369,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5/era=6,MpbBridge,6,false +CELO,42220,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,61416834,9223372036854775807,0x3edd30a1cd94dd6d3329b5ebaff5aa4e0a4e4a55,0x29296c3a605737b0ad6dcd4b9040193cc76a01bf8488220f789e13219be9a5a5,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5/era=7,MpbBridge,7,true +CELO,42220,0xa4ff07cf81c02cfd356184879d953970ca957585,16393469,16393473,0x0000000000000000000000000000000000000000,impl:0x0000000000000000000000000000000000000000,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0xa4ff07cf81c02cfd356184879d953970ca957585/era=1,SuperfluidHost,1,false +CELO,42220,0xa4ff07cf81c02cfd356184879d953970ca957585,16393473,18349124,0xf37a766fb6684fa86842f88380e786c2bd32ba4c,0x191b0b9c7e52f28242fb40f248e987dc8aa98ee003548293837c02ac582c0fa7,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa4ff07cf81c02cfd356184879d953970ca957585/era=2,SuperfluidHost,2,false +CELO,42220,0xa4ff07cf81c02cfd356184879d953970ca957585,18349124,19952321,0x109412e3c84f0539b43d39db691b08c90f58dc7c,0xbad743f142e85dab71de287f4efced306d2dd49c2522aa8e5937581d1fa2caea,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa4ff07cf81c02cfd356184879d953970ca957585/era=3,SuperfluidHost,3,false +CELO,42220,0xa4ff07cf81c02cfd356184879d953970ca957585,19952321,20091409,0x15f0ca26781c3852f8166ed2ebce5d18265cceb7,0x79c0bf6cc0a97404a1ba4f04a21491ed3dd432ffd8c792578680a79363aa9030,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa4ff07cf81c02cfd356184879d953970ca957585/era=4,SuperfluidHost,4,false +CELO,42220,0xa4ff07cf81c02cfd356184879d953970ca957585,20091409,21146434,0xe01f8743677da897f4e7de9073b57bf034fc2433,0xbe25805f704e9912841503d6f91e3570d8bf75dea127874a0afb35a0c0c566d0,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa4ff07cf81c02cfd356184879d953970ca957585/era=5,SuperfluidHost,5,false +CELO,42220,0xa4ff07cf81c02cfd356184879d953970ca957585,21146434,23701580,0xb8f12031d79615f3faf6ec5f9795057e55e3069a,0xd402dc49770a98fa224b4f55fc6d7d6a937655d3c788084771133ebbaea954f5,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa4ff07cf81c02cfd356184879d953970ca957585/era=6,SuperfluidHost,6,false +CELO,42220,0xa4ff07cf81c02cfd356184879d953970ca957585,23701580,24738429,0x143ea239159155b408e71cdbe836e8cfd6766732,0x7c07df056c3c6dab1e3fe96a6d7d8453b594969f72fa151a5c8b47063613532f,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa4ff07cf81c02cfd356184879d953970ca957585/era=7,SuperfluidHost,7,false +CELO,42220,0xa4ff07cf81c02cfd356184879d953970ca957585,24738429,26706819,0xddc77ec35a571c98c7465b51f152e4888835bee6,0x57164c7f8472925746087e8db09c807893b00780c5a1c92c8faf1743b48977f8,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa4ff07cf81c02cfd356184879d953970ca957585/era=8,SuperfluidHost,8,false +CELO,42220,0xa4ff07cf81c02cfd356184879d953970ca957585,26706819,27058151,0xcf3f4fa77f4427f6a1c1a96556194b40fc9dbf02,0x2878db05fa2818412b3dc91044e48209e42aed3f5912e5153ef076c953099914,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa4ff07cf81c02cfd356184879d953970ca957585/era=9,SuperfluidHost,9,false +CELO,42220,0xa4ff07cf81c02cfd356184879d953970ca957585,27058151,27279493,0x78743a68d52c9d6ccf3ff4558f3af510592e3c2d,0x29b712122f26431d8f811f6b06e233dadd2e5efd3d1d73e693753da543178401,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa4ff07cf81c02cfd356184879d953970ca957585/era=10,SuperfluidHost,10,false +CELO,42220,0xa4ff07cf81c02cfd356184879d953970ca957585,27279493,28853698,0x862f59081fc7907f940be4227b9f485d700e6cdd,0xbdd0248aee9f9d9cd42b1ec49b695e18234162ea5f5fd7f3bf3f2a1db1ea1d4c,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa4ff07cf81c02cfd356184879d953970ca957585/era=11,SuperfluidHost,11,false +CELO,42220,0xa4ff07cf81c02cfd356184879d953970ca957585,28853698,29627986,0xae50ba6b0f7412dfd2061bfcd15c2d63f36af143,0x5e9cb99ff4ba661eb86d8c7a44f90f36a2ad1fbeabd1769133e6d34c726fd95a,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa4ff07cf81c02cfd356184879d953970ca957585/era=12,SuperfluidHost,12,false +CELO,42220,0xa4ff07cf81c02cfd356184879d953970ca957585,29627986,33928238,0xf26967f92151487f8c6642199c3441b02398d19e,0xd725780f0e452fc2e98ba0b229c1854c34e9882a5550c03501406c8fcc98f3d0,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa4ff07cf81c02cfd356184879d953970ca957585/era=13,SuperfluidHost,13,false +CELO,42220,0xa4ff07cf81c02cfd356184879d953970ca957585,33928238,39643668,0x9a19773ebe33c5917012c2bb982bc683d91ec600,0x49e13d9d72661dfdb490a8a67c32fef72a7b212bdaaabf0c9cc231818377de45,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa4ff07cf81c02cfd356184879d953970ca957585/era=14,SuperfluidHost,14,false +CELO,42220,0xa4ff07cf81c02cfd356184879d953970ca957585,39643668,44995009,0x97620d4d7950223963f00db25f12b4ac1d4eed99,0x271879ac911f8440a875974a04b54db30b8a5f63898975a041489de41f36554c,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa4ff07cf81c02cfd356184879d953970ca957585/era=15,SuperfluidHost,15,false +CELO,42220,0xa4ff07cf81c02cfd356184879d953970ca957585,44995009,52777129,0x3b526b50709a5551030673be284bc9c1e38351ac,0x6f43af90345b70565298e49768034ab0ff782c995fd5fdb26c0871f6ded40fe1,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa4ff07cf81c02cfd356184879d953970ca957585/era=16,SuperfluidHost,16,false +CELO,42220,0xa4ff07cf81c02cfd356184879d953970ca957585,52777129,61309260,0x8e03f0edb581e8b6aad80eece89b3028388f4b53,0x5f3453e79f1aaac3f7dfe0c14452701fd8f3501ec000334f70bc80f9e9dcbf7b,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa4ff07cf81c02cfd356184879d953970ca957585/era=17,SuperfluidHost,17,false +CELO,42220,0xa4ff07cf81c02cfd356184879d953970ca957585,61309260,74797088,0xf17e88391b68c2a5972131f5044fd6ace665f221,0x19a7ec64380e14852eee8d4a0f7bdb4a15c98dd9e8359f42a0cc2316415b759e,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa4ff07cf81c02cfd356184879d953970ca957585/era=18,SuperfluidHost,18,false +CELO,42220,0xa4ff07cf81c02cfd356184879d953970ca957585,74797088,76632579,0xc899724f32859e8169e607a23448e4b487b4dc04,0x61f96160837a684e3c8b66ebac18d6c0517947e8d3789d8833f567592d3ea40d,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa4ff07cf81c02cfd356184879d953970ca957585/era=19,SuperfluidHost,19,false +CELO,42220,0xa4ff07cf81c02cfd356184879d953970ca957585,76632579,9223372036854775807,0x724676722b69b8b0e5fcf030de796047e771e5f9,0xdb6e855c140ab4a6e967d9ddb3d022b5fb39cf6956ff6677bbddf9f7ef334e70,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xa4ff07cf81c02cfd356184879d953970ca957585/era=20,SuperfluidHost,20,true +CELO,42220,0xa9000aa66903b5e26f88fa8462739cdcf7956ea6,17237958,9223372036854775807,0x4be0c7f9c468b174dfeba304d8bd6af000948a79,0x47c7e53ea14ed9e7757ba2640dfbdcb6ddf21ef2bc9578d9d2c4e92e53ebeea0,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0xa9000aa66903b5e26f88fa8462739cdcf7956ea6/era=1,GReputation,1,true +CELO,42220,0xafe208a311b21f13ef87e33a90049fc17a7acdec,13916355,9223372036854775807,0xafe208a311b21f13ef87e33a90049fc17a7acdec,0x5960f2f785dd273f0eeb9624f32a9f93bd1560dc1335171d22411d48296d79b3,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0xafe208a311b21f13ef87e33a90049fc17a7acdec/era=1,UniswapV3Factory,1,true +CELO,42220,0xb1c87d3270d4a23bc1fcca8be53af11e4773d89d,72905831,9223372036854775807,0xb1c87d3270d4a23bc1fcca8be53af11e4773d89d,0x2c25daa8960a888e9b92aa463cfe8770a5b7afcf0d7359dcd1bf3b344c8be1a8,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0xb1c87d3270d4a23bc1fcca8be53af11e4773d89d/era=1,BUYGDFactoryV3,1,true +CELO,42220,0xb27d247f5c2a61d2cb6b6e67fee51d839447e97d,18105474,9223372036854775807,0xb27d247f5c2a61d2cb6b6e67fee51d839447e97d,0xc7ffb78edacaf8c162f803f1d06d60a0f7959fef40e59c642134256cbe714fac,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0xb27d247f5c2a61d2cb6b6e67fee51d839447e97d/era=1,OneTimePayments,1,true +CELO,42220,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,17237952,18314662,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,0x8a3716a5117789bfbb058b671557334c9f95d40631126f92b67f977ba7e44fe7,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0xc361a6e67822a0edc17d899227dd9fc50bd62f42/era=1,Identity,1,false +CELO,42220,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,18314662,19163670,0x7d3033247d4a57b8193b6d9193fd56b45c3f794f,0x68684e4903b9e207776736097e4c0bc1be9043a4e83a8b1553a9327b0cc42142,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xc361a6e67822a0edc17d899227dd9fc50bd62f42/era=2,Identity,2,false +CELO,42220,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,19163670,50351048,0x3df6ea625866df8d0a61408a122c484b98f3184c,0x622b7abbc47d60c8a7493bde94d8e9164b244c4631dd33ed79590c739cdb0ced,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xc361a6e67822a0edc17d899227dd9fc50bd62f42/era=3,Identity,3,false +CELO,42220,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,50351048,61416834,0x1eeeb5ba9a9f8b84e52612884a4c18c78cc7413e,0x4bd0225a727e3608ce47277a685849547c779c35785388dffcb68a1064f49f23,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xc361a6e67822a0edc17d899227dd9fc50bd62f42/era=4,Identity,4,false +CELO,42220,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,61416834,9223372036854775807,0x0ecc03f4e3fa94fa6e2098428a3ad393b65933c9,0x0a43a8aa37ea56339ba7f8b8083eb95f17e582d1ccfb2c9f37b8436b195085ad,slot_bisected,gd_dbt/seeds/contract_deployments.csv#CELO/0xc361a6e67822a0edc17d899227dd9fc50bd62f42/era=5,Identity,5,true +CELO,42220,0xc413cc6c58f0c290e89ddaec83c2590017985eb7,31415775,9223372036854775807,0xc413cc6c58f0c290e89ddaec83c2590017985eb7,0xec07536d5a957fe23c6401f1d120012f7eec8637486054801d7915f025b2063b,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0xc413cc6c58f0c290e89ddaec83c2590017985eb7/era=1,MentoUpgradeHelper,1,true +CELO,42220,0xc9d09ba972b4eb6bb7347f2229fb6d50434ffca6,12956494,9223372036854775807,0xc9d09ba972b4eb6bb7347f2229fb6d50434ffca6,0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0xc9d09ba972b4eb6bb7347f2229fb6d50434ffca6/era=1,GuardiansSafeOld,1,true +CELO,42220,0xcb037f27eb3952222810966e28e0ceb650c65cd9,20750772,9223372036854775807,0xcb037f27eb3952222810966e28e0ceb650c65cd9,0xb444db86df9a51d5ea46b9174dbbf339e48710745d888234840a9ce5679968ed,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0xcb037f27eb3952222810966e28e0ceb650c65cd9/era=1,PoolGdCeloV3Hi,1,true +CELO,42220,0xd86cd6bb3c2a576b2c2cef4e047b1a7adc5be62d,17237868,9223372036854775807,0xd86cd6bb3c2a576b2c2cef4e047b1a7adc5be62d,0x7f63d978bb61348d9321e9e9a382a2f88679edb38c483385333d4dbb0760fea9,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0xd86cd6bb3c2a576b2c2cef4e047b1a7adc5be62d/era=1,ProxyFactory,1,true +CELO,42220,0xe45cab86609a16dfadec112fdd61e4ea80edaa8d,18468536,9223372036854775807,0xe45cab86609a16dfadec112fdd61e4ea80edaa8d,0x15ae5796a74f46cfb3b34a673823263ac0cbd3eb5bdb803a393516d0bc446375,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0xe45cab86609a16dfadec112fdd61e4ea80edaa8d/era=1,SwapHelper,1,true +CELO,42220,0xf27ee99622c3c9b264583dacb2cce056e194494f,10155435,9223372036854775807,0xf27ee99622c3c9b264583dacb2cce056e194494f,0xcd92052cccde60e3a65926c5a58ebf8ba7ddd85e99f8bd7af270fdec0a409495,announced,gd_dbt/seeds/contract_deployments.csv#CELO/0xf27ee99622c3c9b264583dacb2cce056e194494f/era=1,MultichainRouter,1,true diff --git a/projects/onchain-analytics/gd_dbt/seeds/event_surface.csv b/projects/onchain-analytics/gd_dbt/seeds/event_surface.csv new file mode 100644 index 0000000..ff1c144 --- /dev/null +++ b/projects/onchain-analytics/gd_dbt/seeds/event_surface.csv @@ -0,0 +1,2825 @@ +chain,chain_id,contract_name,proxy_address,era_index,implementation_address,event_name,event_signature,topic0,anonymous,indexed_positions,param_types,param_names,era_bound,era_bound_from_block,era_bound_to_block,abi_source,source,notes +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,1,0xbfb5052aee113fc160c18ae85c9831dcd2b2fdc0,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,1,0xbfb5052aee113fc160c18ae85c9831dcd2b2fdc0,AdminsAdded,AdminsAdded(address[]),0x45486b220020cc2482ad1a5e0ae4d5f0b5372cea1b48173f6273c616a5047269,false,0,address[],admins,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,1,0xbfb5052aee113fc160c18ae85c9831dcd2b2fdc0,AdminsRemoved,AdminsRemoved(address[]),0xd5e6894641b5030a67e637ab2e12da64d8aec689f8bd1328de2b04d6a439c810,false,0,address[],admins,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,1,0xbfb5052aee113fc160c18ae85c9831dcd2b2fdc0,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,1,0xbfb5052aee113fc160c18ae85c9831dcd2b2fdc0,GenericCall,"GenericCall(address,bytes,uint256,bool)",0x534b52c783549f909f9e743120524d0b7154058e4a54cdc895c2c0b587a1c7e0,false,0,address bytes uint256 bool,_contract _data _value _success,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,1,0xbfb5052aee113fc160c18ae85c9831dcd2b2fdc0,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,1,0xbfb5052aee113fc160c18ae85c9831dcd2b2fdc0,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,1,0xbfb5052aee113fc160c18ae85c9831dcd2b2fdc0,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,1,0xbfb5052aee113fc160c18ae85c9831dcd2b2fdc0,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,1,0xbfb5052aee113fc160c18ae85c9831dcd2b2fdc0,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,1,0xbfb5052aee113fc160c18ae85c9831dcd2b2fdc0,WalletTopped,"WalletTopped(address,uint256)",0xf60e56b8021f6ac77bd50d4acdbed9ad9e85107144d43090774a9ebe5ffed985,false,0,address uint256,user amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,2,0x24614ad257f4d09fccaec024c65c40c060e73e9d,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,2,0x24614ad257f4d09fccaec024c65c40c060e73e9d,AdminsAdded,AdminsAdded(address[]),0x45486b220020cc2482ad1a5e0ae4d5f0b5372cea1b48173f6273c616a5047269,false,0,address[],admins,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,2,0x24614ad257f4d09fccaec024c65c40c060e73e9d,AdminsRemoved,AdminsRemoved(address[]),0xd5e6894641b5030a67e637ab2e12da64d8aec689f8bd1328de2b04d6a439c810,false,0,address[],admins,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,2,0x24614ad257f4d09fccaec024c65c40c060e73e9d,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,2,0x24614ad257f4d09fccaec024c65c40c060e73e9d,GenericCall,"GenericCall(address,bytes,uint256,bool)",0x534b52c783549f909f9e743120524d0b7154058e4a54cdc895c2c0b587a1c7e0,false,0,address bytes uint256 bool,_contract _data _value _success,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,2,0x24614ad257f4d09fccaec024c65c40c060e73e9d,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,2,0x24614ad257f4d09fccaec024c65c40c060e73e9d,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,2,0x24614ad257f4d09fccaec024c65c40c060e73e9d,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,2,0x24614ad257f4d09fccaec024c65c40c060e73e9d,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,2,0x24614ad257f4d09fccaec024c65c40c060e73e9d,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,2,0x24614ad257f4d09fccaec024c65c40c060e73e9d,WalletTopped,"WalletTopped(address,uint256)",0xf60e56b8021f6ac77bd50d4acdbed9ad9e85107144d43090774a9ebe5ffed985,false,0,address uint256,user amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,3,0xae2cd2a9513215961d344a2581dcab678598eedf,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,3,0xae2cd2a9513215961d344a2581dcab678598eedf,AdminsAdded,AdminsAdded(address[]),0x45486b220020cc2482ad1a5e0ae4d5f0b5372cea1b48173f6273c616a5047269,false,0,address[],admins,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,3,0xae2cd2a9513215961d344a2581dcab678598eedf,AdminsRemoved,AdminsRemoved(address[]),0xd5e6894641b5030a67e637ab2e12da64d8aec689f8bd1328de2b04d6a439c810,false,0,address[],admins,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,3,0xae2cd2a9513215961d344a2581dcab678598eedf,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,3,0xae2cd2a9513215961d344a2581dcab678598eedf,GenericCall,"GenericCall(address,bytes,uint256,bool)",0x534b52c783549f909f9e743120524d0b7154058e4a54cdc895c2c0b587a1c7e0,false,0,address bytes uint256 bool,_contract _data _value _success,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,3,0xae2cd2a9513215961d344a2581dcab678598eedf,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,3,0xae2cd2a9513215961d344a2581dcab678598eedf,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,3,0xae2cd2a9513215961d344a2581dcab678598eedf,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,3,0xae2cd2a9513215961d344a2581dcab678598eedf,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,3,0xae2cd2a9513215961d344a2581dcab678598eedf,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,3,0xae2cd2a9513215961d344a2581dcab678598eedf,WalletTopped,"WalletTopped(address,uint256)",0xf60e56b8021f6ac77bd50d4acdbed9ad9e85107144d43090774a9ebe5ffed985,false,0,address uint256,user amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,4,0x703856db9a5432964f081ff4dc46480738fae7bd,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,4,0x703856db9a5432964f081ff4dc46480738fae7bd,AdminsAdded,AdminsAdded(address[]),0x45486b220020cc2482ad1a5e0ae4d5f0b5372cea1b48173f6273c616a5047269,false,0,address[],admins,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,4,0x703856db9a5432964f081ff4dc46480738fae7bd,AdminsRemoved,AdminsRemoved(address[]),0xd5e6894641b5030a67e637ab2e12da64d8aec689f8bd1328de2b04d6a439c810,false,0,address[],admins,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,4,0x703856db9a5432964f081ff4dc46480738fae7bd,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,4,0x703856db9a5432964f081ff4dc46480738fae7bd,GenericCall,"GenericCall(address,bytes,uint256,bool)",0x534b52c783549f909f9e743120524d0b7154058e4a54cdc895c2c0b587a1c7e0,false,0,address bytes uint256 bool,_contract _data _value _success,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,4,0x703856db9a5432964f081ff4dc46480738fae7bd,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,4,0x703856db9a5432964f081ff4dc46480738fae7bd,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,4,0x703856db9a5432964f081ff4dc46480738fae7bd,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,4,0x703856db9a5432964f081ff4dc46480738fae7bd,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,4,0x703856db9a5432964f081ff4dc46480738fae7bd,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,4,0x703856db9a5432964f081ff4dc46480738fae7bd,WalletTopped,"WalletTopped(address,uint256)",0xf60e56b8021f6ac77bd50d4acdbed9ad9e85107144d43090774a9ebe5ffed985,false,0,address uint256,user amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,5,0xfef0ef0916c5c7745b201dc9e2d04483b1eb36f1,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,5,0xfef0ef0916c5c7745b201dc9e2d04483b1eb36f1,AdminsAdded,AdminsAdded(address[]),0x45486b220020cc2482ad1a5e0ae4d5f0b5372cea1b48173f6273c616a5047269,false,0,address[],admins,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,5,0xfef0ef0916c5c7745b201dc9e2d04483b1eb36f1,AdminsRemoved,AdminsRemoved(address[]),0xd5e6894641b5030a67e637ab2e12da64d8aec689f8bd1328de2b04d6a439c810,false,0,address[],admins,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,5,0xfef0ef0916c5c7745b201dc9e2d04483b1eb36f1,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,5,0xfef0ef0916c5c7745b201dc9e2d04483b1eb36f1,GenericCall,"GenericCall(address,bytes,uint256,bool)",0x534b52c783549f909f9e743120524d0b7154058e4a54cdc895c2c0b587a1c7e0,false,0,address bytes uint256 bool,_contract _data _value _success,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,5,0xfef0ef0916c5c7745b201dc9e2d04483b1eb36f1,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,5,0xfef0ef0916c5c7745b201dc9e2d04483b1eb36f1,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,5,0xfef0ef0916c5c7745b201dc9e2d04483b1eb36f1,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,5,0xfef0ef0916c5c7745b201dc9e2d04483b1eb36f1,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,5,0xfef0ef0916c5c7745b201dc9e2d04483b1eb36f1,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,AdminWallet,0x7119cd89d4792af90277d84cdffa3f2ab22a0022,5,0xfef0ef0916c5c7745b201dc9e2d04483b1eb36f1,WalletTopped,"WalletTopped(address,uint256)",0xf60e56b8021f6ac77bd50d4acdbed9ad9e85107144d43090774a9ebe5ffed985,false,0,address uint256,user amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Avatar,0x495d133b938596c9984d462f007b676bdc57ecec,1,0x495d133b938596c9984d462f007b676bdc57ecec,ExternalTokenApproval,"ExternalTokenApproval(address,address,uint256)",0x3a48a4d6253b30fd10e57a347c1f9bcb0604946481fae0b2fdad6e74f2a9cbb3,false,0,address address uint256,_externalToken _spender _value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Avatar,0x495d133b938596c9984d462f007b676bdc57ecec,1,0x495d133b938596c9984d462f007b676bdc57ecec,ExternalTokenTransfer,"ExternalTokenTransfer(address,address,uint256)",0x49dc2a60d2599a7b6932d78fb694c30dfc596fe4e0282b5d0fd184b52472c04d,false,0 1,address address uint256,_externalToken _to _value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Avatar,0x495d133b938596c9984d462f007b676bdc57ecec,1,0x495d133b938596c9984d462f007b676bdc57ecec,ExternalTokenTransferFrom,"ExternalTokenTransferFrom(address,address,address,uint256)",0x179c15de44aa7ab84896301974328eb40b5b40fe01cfe0fee2924ea712c3e843,false,0,address address address uint256,_externalToken _from _to _value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Avatar,0x495d133b938596c9984d462f007b676bdc57ecec,1,0x495d133b938596c9984d462f007b676bdc57ecec,GenericCall,"GenericCall(address,bytes,uint256,bool)",0x534b52c783549f909f9e743120524d0b7154058e4a54cdc895c2c0b587a1c7e0,false,0,address bytes uint256 bool,_contract _data _value _success,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Avatar,0x495d133b938596c9984d462f007b676bdc57ecec,1,0x495d133b938596c9984d462f007b676bdc57ecec,MetaData,MetaData(string),0xf9deba4938ba20070ec5a45ddf59bccba49cf83124215228ec1232182ef0ba2b,false,,string,_metaData,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Avatar,0x495d133b938596c9984d462f007b676bdc57ecec,1,0x495d133b938596c9984d462f007b676bdc57ecec,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Avatar,0x495d133b938596c9984d462f007b676bdc57ecec,1,0x495d133b938596c9984d462f007b676bdc57ecec,ReceiveEther,"ReceiveEther(address,uint256)",0xf32a9f77675fd5917534c7746608fd3e309eac68fbdcbf5925e24ca97a704396,false,0,address uint256,_sender _value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Avatar,0x495d133b938596c9984d462f007b676bdc57ecec,1,0x495d133b938596c9984d462f007b676bdc57ecec,SendEther,"SendEther(uint256,address)",0x22fca66666089f39bc900dd6605b489df4aae6260cc8ea8257594cfb8c84926c,false,1,uint256 address,_amountInWei _to,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,BuyGDFactoryV2,0x1f60c4c7037c6766924a43666b781ed1479587a2,1,0x1f60c4c7037c6766924a43666b781ed1479587a2,GDSwapToCusd,"GDSwapToCusd(address,address,uint256,uint256,bytes)",0x252bc23e3fb01f9986fa157af621236fb8a706ea12622da296e7f2f30d4f1a56,false,,address address uint256 uint256 bytes,from to amountIn amountOut note,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,BUYGDFactoryV3,0xb1c87d3270d4a23bc1fcca8be53af11e4773d89d,1,0xb1c87d3270d4a23bc1fcca8be53af11e4773d89d,GDSwapToCusd,"GDSwapToCusd(address,address,uint256,uint256,bytes)",0x252bc23e3fb01f9986fa157af621236fb8a706ea12622da296e7f2f30d4f1a56,false,,address address uint256 uint256 bytes,from to amountIn amountOut note,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CeloDistributionHelper,0x6b845effaf36c374e8e7cf543efa680f2f71f098,1,0x6db04d771e2ba750effbbad59dcca20381efb1c5,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CeloDistributionHelper,0x6b845effaf36c374e8e7cf543efa680f2f71f098,1,0x6db04d771e2ba750effbbad59dcca20381efb1c5,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CeloDistributionHelper,0x6b845effaf36c374e8e7cf543efa680f2f71f098,1,0x6db04d771e2ba750effbbad59dcca20381efb1c5,BuyNativeFailed,BuyNativeFailed(string),0x030e3b8d0055568581a1db48e2c7222c3cb121c9d1c17d9d511a517d0b679cd9,false,,string,reason,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CeloDistributionHelper,0x6b845effaf36c374e8e7cf543efa680f2f71f098,1,0x6db04d771e2ba750effbbad59dcca20381efb1c5,Distribution,"Distribution(uint256,uint256,uint256,(uint32,uint32,address,uint8)[],uint256,uint256)",0xdbd53b67dd15f9594eee6de294654de25af4c2a14d79d76e47d08d83c8025f5d,false,,"uint256 uint256 uint256 (uint32,uint32,address,uint8)[] uint256 uint256",distributed startingBalance incomingAmount distributionRecipients gdSoldForGas nativeBoughtForGas,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CeloDistributionHelper,0x6b845effaf36c374e8e7cf543efa680f2f71f098,1,0x6db04d771e2ba750effbbad59dcca20381efb1c5,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CeloDistributionHelper,0x6b845effaf36c374e8e7cf543efa680f2f71f098,1,0x6db04d771e2ba750effbbad59dcca20381efb1c5,RecipientAdded,"RecipientAdded((uint32,uint32,address,uint8),uint256)",0x2e65f65347b2e76218df0b7b6b594a3862c81e85706795e700237093c47a3957,false,,"(uint32,uint32,address,uint8) uint256",recipient index,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CeloDistributionHelper,0x6b845effaf36c374e8e7cf543efa680f2f71f098,1,0x6db04d771e2ba750effbbad59dcca20381efb1c5,RecipientUpdated,"RecipientUpdated((uint32,uint32,address,uint8),uint256)",0xd26d9de175cfca2c3e0cad9d09c85f0ce6c7fa5257382d00dc26dc5fb25cd8df,false,,"(uint32,uint32,address,uint8) uint256",recipient index,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CeloDistributionHelper,0x6b845effaf36c374e8e7cf543efa680f2f71f098,1,0x6db04d771e2ba750effbbad59dcca20381efb1c5,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CeloDistributionHelper,0x6b845effaf36c374e8e7cf543efa680f2f71f098,1,0x6db04d771e2ba750effbbad59dcca20381efb1c5,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CeloDistributionHelper,0x6b845effaf36c374e8e7cf543efa680f2f71f098,1,0x6db04d771e2ba750effbbad59dcca20381efb1c5,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CeloDistributionHelper,0x6b845effaf36c374e8e7cf543efa680f2f71f098,1,0x6db04d771e2ba750effbbad59dcca20381efb1c5,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Controller,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,1,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,AddGlobalConstraint,"AddGlobalConstraint(address,bytes32,uint8)",0x78800d7333b8d0174a0845569e3913b7ce4a3c03ca444dd9904172fc14f2fdad,false,0,address bytes32 uint8,_globalConstraint _params _when,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Controller,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,1,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,BurnReputation,"BurnReputation(address,address,uint256)",0x186d8887e1b22f9d9b16849c36baa748950d09d9c9b67a4a6ea140eaad00c21c,false,0 1,address address uint256,_sender _from _amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Controller,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,1,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,MintReputation,"MintReputation(address,address,uint256)",0x837f2931e3df0592458212be4e470025f197feb7a8e39deb5b7f1f1d42e6f262,false,0 1,address address uint256,_sender _to _amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Controller,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,1,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,MintTokens,"MintTokens(address,address,uint256)",0x21f9c9a1a1f9a311a50f15fec5c1faa9e21fc9edf964f0fdecba5bd490484c5e,false,0 1,address address uint256,_sender _beneficiary _amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Controller,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,1,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,RegisterScheme,"RegisterScheme(address,address)",0x546816e99403df442acb68ef69562682a50762c20a3fb6b472f7af9923736cfc,false,0 1,address address,_sender _scheme,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Controller,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,1,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,RemoveGlobalConstraint,"RemoveGlobalConstraint(address,uint256,bool)",0xcdf1a50ea6b7de555bd409f8a4a53ea43c6dc6b4caa961889da9e005f21bbaa9,false,0,address uint256 bool,_globalConstraint _index _isPre,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Controller,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,1,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,UnregisterScheme,"UnregisterScheme(address,address)",0x10bb2cf04cb8b902a8e736d494f1a51003be6d4b16ef6fb95ce62c38445023bf,false,0 1,address address,_sender _scheme,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Controller,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,1,0x0be7c592374ee0bd0ccbfc76be758a138bcaec6e,UpgradeController,"UpgradeController(address,address)",0xdb7cbacf8df312d794506c0cc9af07f64d29ca075796ea2e950a3832cc9a63dd,false,0,address address,_oldController _newController,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,1,0x0000000000000000000000000000000000000000,ImplementationSet,ImplementationSet(address),0xab64f92ab780ecbf4f3866f57cee465ff36c89450dcce20237ca7a8d81fb7d13,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,1,0x0000000000000000000000000000000000000000,OwnerSet,OwnerSet(address),0x50146d0e3c60aa1d17a70635b05494f864e86144a2201275021014fbf08bafe2,false,0,address,owner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,2,0xaa933baf03cfc55b8e4e0d7de479bcc12f189352,ImplementationSet,ImplementationSet(address),0xab64f92ab780ecbf4f3866f57cee465ff36c89450dcce20237ca7a8d81fb7d13,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,2,0xaa933baf03cfc55b8e4e0d7de479bcc12f189352,OwnerSet,OwnerSet(address),0x50146d0e3c60aa1d17a70635b05494f864e86144a2201275021014fbf08bafe2,false,0,address,owner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,3,0x7e327831c644f2b1fef642079f116181bc471cb3,ImplementationSet,ImplementationSet(address),0xab64f92ab780ecbf4f3866f57cee465ff36c89450dcce20237ca7a8d81fb7d13,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,3,0x7e327831c644f2b1fef642079f116181bc471cb3,OwnerSet,OwnerSet(address),0x50146d0e3c60aa1d17a70635b05494f864e86144a2201275021014fbf08bafe2,false,0,address,owner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,4,0x2c4c1f3e06d494bcc03e93b373637cc4333cbd7d,ImplementationSet,ImplementationSet(address),0xab64f92ab780ecbf4f3866f57cee465ff36c89450dcce20237ca7a8d81fb7d13,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,4,0x2c4c1f3e06d494bcc03e93b373637cc4333cbd7d,OwnerSet,OwnerSet(address),0x50146d0e3c60aa1d17a70635b05494f864e86144a2201275021014fbf08bafe2,false,0,address,owner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,5,0x18e6bfdc909063f7445e410a5495264619495bcb,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,true,9105530,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6,7,8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,5,0x18e6bfdc909063f7445e410a5495264619495bcb,ImplementationSet,ImplementationSet(address),0xab64f92ab780ecbf4f3866f57cee465ff36c89450dcce20237ca7a8d81fb7d13,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,5,0x18e6bfdc909063f7445e410a5495264619495bcb,InflationFactorUpdated,"InflationFactorUpdated(uint256,uint256)",0x08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a97,false,,uint256 uint256,factor lastUpdated,true,9105530,23065563,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,5,0x18e6bfdc909063f7445e410a5495264619495bcb,InflationParametersUpdated,"InflationParametersUpdated(uint256,uint256,uint256)",0xa0035d6667ffb7d387c86c7228141c4a877e8ed831b267ac928a2f5b651c155d,false,,uint256 uint256 uint256,rate updatePeriod lastUpdated,true,9105530,23065563,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,5,0x18e6bfdc909063f7445e410a5495264619495bcb,OwnerSet,OwnerSet(address),0x50146d0e3c60aa1d17a70635b05494f864e86144a2201275021014fbf08bafe2,false,0,address,owner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,5,0x18e6bfdc909063f7445e410a5495264619495bcb,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,9105530,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6,7,8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,5,0x18e6bfdc909063f7445e410a5495264619495bcb,RegistrySet,RegistrySet(address),0x27fe5f0c1c3b1ed427cc63d0f05759ffdecf9aec9e18d31ef366fc8a6cb5dc3b,false,0,address,registryAddress,true,9105530,23065563,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,5,0x18e6bfdc909063f7445e410a5495264619495bcb,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,true,9105530,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6,7,8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,5,0x18e6bfdc909063f7445e410a5495264619495bcb,TransferComment,TransferComment(string),0xe5d4e30fb8364e57bc4d662a07d0cf36f4c34552004c4c3624620a2c1d1c03dc,false,,string,comment,true,9105530,60666007,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6,7 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,6,0x7ae2f384fe14ead85779f9224558862d6d3e4f28,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,true,9105530,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6,7,8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,6,0x7ae2f384fe14ead85779f9224558862d6d3e4f28,ImplementationSet,ImplementationSet(address),0xab64f92ab780ecbf4f3866f57cee465ff36c89450dcce20237ca7a8d81fb7d13,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,6,0x7ae2f384fe14ead85779f9224558862d6d3e4f28,InflationFactorUpdated,"InflationFactorUpdated(uint256,uint256)",0x08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a97,false,,uint256 uint256,factor lastUpdated,true,9105530,23065563,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,6,0x7ae2f384fe14ead85779f9224558862d6d3e4f28,InflationParametersUpdated,"InflationParametersUpdated(uint256,uint256,uint256)",0xa0035d6667ffb7d387c86c7228141c4a877e8ed831b267ac928a2f5b651c155d,false,,uint256 uint256 uint256,rate updatePeriod lastUpdated,true,9105530,23065563,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,6,0x7ae2f384fe14ead85779f9224558862d6d3e4f28,OwnerSet,OwnerSet(address),0x50146d0e3c60aa1d17a70635b05494f864e86144a2201275021014fbf08bafe2,false,0,address,owner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,6,0x7ae2f384fe14ead85779f9224558862d6d3e4f28,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,9105530,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6,7,8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,6,0x7ae2f384fe14ead85779f9224558862d6d3e4f28,RegistrySet,RegistrySet(address),0x27fe5f0c1c3b1ed427cc63d0f05759ffdecf9aec9e18d31ef366fc8a6cb5dc3b,false,0,address,registryAddress,true,9105530,23065563,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,6,0x7ae2f384fe14ead85779f9224558862d6d3e4f28,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,true,9105530,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6,7,8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,6,0x7ae2f384fe14ead85779f9224558862d6d3e4f28,TransferComment,TransferComment(string),0xe5d4e30fb8364e57bc4d662a07d0cf36f4c34552004c4c3624620a2c1d1c03dc,false,,string,comment,true,9105530,60666007,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6,7 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,7,0x434563b0604be100f04b7ae485bcafe3c9d8850e,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,true,9105530,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6,7,8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,7,0x434563b0604be100f04b7ae485bcafe3c9d8850e,BrokerUpdated,BrokerUpdated(address),0x865dab7821134b6eb27cba259b40e33bbc1b898e970a535a18a83147f380a51f,false,,address,broker,true,23065563,60666007,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 7 of 9 +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,7,0x434563b0604be100f04b7ae485bcafe3c9d8850e,ExchangeUpdated,ExchangeUpdated(address),0x403871c8d404db2d13402bd857192acd8f680acd7f2d6e1e5bf2128d013d7eaa,false,,address,exchange,true,23065563,60666007,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 7 of 9 +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,7,0x434563b0604be100f04b7ae485bcafe3c9d8850e,ImplementationSet,ImplementationSet(address),0xab64f92ab780ecbf4f3866f57cee465ff36c89450dcce20237ca7a8d81fb7d13,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,7,0x434563b0604be100f04b7ae485bcafe3c9d8850e,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,23065563,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 7,8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,7,0x434563b0604be100f04b7ae485bcafe3c9d8850e,OwnerSet,OwnerSet(address),0x50146d0e3c60aa1d17a70635b05494f864e86144a2201275021014fbf08bafe2,false,0,address,owner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,7,0x434563b0604be100f04b7ae485bcafe3c9d8850e,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,9105530,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6,7,8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,7,0x434563b0604be100f04b7ae485bcafe3c9d8850e,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,true,9105530,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6,7,8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,7,0x434563b0604be100f04b7ae485bcafe3c9d8850e,TransferComment,TransferComment(string),0xe5d4e30fb8364e57bc4d662a07d0cf36f4c34552004c4c3624620a2c1d1c03dc,false,,string,comment,true,9105530,60666007,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6,7 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,7,0x434563b0604be100f04b7ae485bcafe3c9d8850e,ValidatorsUpdated,ValidatorsUpdated(address),0x34edb180d960e50e3657f8fba1bf1f35c399c2bbad42b7e0f6561e6fb4ae3d7c,false,,address,validators,true,23065563,60666007,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 7 of 9 +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,8,0x4b9b0e94197b7b2b11d311239e1420106ce7a2a2,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,true,9105530,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6,7,8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,8,0x4b9b0e94197b7b2b11d311239e1420106ce7a2a2,BurnerUpdated,"BurnerUpdated(address,bool)",0xf0e5abe4ab32ea692e3889b4c146fd4ddae5f17bb40ab4feba97fb67a2d4de0f,false,0,address bool,burner isBurner,true,60666007,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,8,0x4b9b0e94197b7b2b11d311239e1420106ce7a2a2,ImplementationSet,ImplementationSet(address),0xab64f92ab780ecbf4f3866f57cee465ff36c89450dcce20237ca7a8d81fb7d13,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,8,0x4b9b0e94197b7b2b11d311239e1420106ce7a2a2,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,23065563,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 7,8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,8,0x4b9b0e94197b7b2b11d311239e1420106ce7a2a2,MinterUpdated,"MinterUpdated(address,bool)",0xb21afb9ce9be0a676f8f317ff0ca072fb89a4f8ce2d1b6fe80f8755c14f1cb19,false,0,address bool,minter isMinter,true,60666007,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,8,0x4b9b0e94197b7b2b11d311239e1420106ce7a2a2,OperatorUpdated,"OperatorUpdated(address,bool)",0x966c160e1c4dbc7df8d69af4ace01e9297c3cf016397b7914971f2fbfa32672d,false,0,address bool,operator isOperator,true,60666007,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,8,0x4b9b0e94197b7b2b11d311239e1420106ce7a2a2,OwnerSet,OwnerSet(address),0x50146d0e3c60aa1d17a70635b05494f864e86144a2201275021014fbf08bafe2,false,0,address,owner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,8,0x4b9b0e94197b7b2b11d311239e1420106ce7a2a2,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,9105530,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6,7,8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,8,0x4b9b0e94197b7b2b11d311239e1420106ce7a2a2,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,true,9105530,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6,7,8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,9,0x815795c30d0758a297b08cd4e0643620c974c318,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,true,9105530,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6,7,8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,9,0x815795c30d0758a297b08cd4e0643620c974c318,BurnerUpdated,"BurnerUpdated(address,bool)",0xf0e5abe4ab32ea692e3889b4c146fd4ddae5f17bb40ab4feba97fb67a2d4de0f,false,0,address bool,burner isBurner,true,60666007,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,9,0x815795c30d0758a297b08cd4e0643620c974c318,ImplementationSet,ImplementationSet(address),0xab64f92ab780ecbf4f3866f57cee465ff36c89450dcce20237ca7a8d81fb7d13,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,9,0x815795c30d0758a297b08cd4e0643620c974c318,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,23065563,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 7,8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,9,0x815795c30d0758a297b08cd4e0643620c974c318,MinterUpdated,"MinterUpdated(address,bool)",0xb21afb9ce9be0a676f8f317ff0ca072fb89a4f8ce2d1b6fe80f8755c14f1cb19,false,0,address bool,minter isMinter,true,60666007,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,9,0x815795c30d0758a297b08cd4e0643620c974c318,OperatorUpdated,"OperatorUpdated(address,bool)",0x966c160e1c4dbc7df8d69af4ace01e9297c3cf016397b7914971f2fbfa32672d,false,0,address bool,operator isOperator,true,60666007,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,9,0x815795c30d0758a297b08cd4e0643620c974c318,OwnerSet,OwnerSet(address),0x50146d0e3c60aa1d17a70635b05494f864e86144a2201275021014fbf08bafe2,false,0,address,owner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,9,0x815795c30d0758a297b08cd4e0643620c974c318,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,9105530,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6,7,8,9 of 9" +CELO,42220,CUSD,0x765de816845861e75a25fca122bb6898b8b1282a,9,0x815795c30d0758a297b08cd4e0643620c974c318,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,true,9105530,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6,7,8,9 of 9" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,1,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,1,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,1,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,1,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,1,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,1,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,1,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,1,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,WalletTopped,"WalletTopped(address,uint256,address,address)",0x7872034fbcc87890e73d66eac55389e0ffdba157b89a73bd2011157ebac1d66e,false,0 3,address uint256 address address,account amount whitelistedRoot relayerOrWhitelisted,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,2,0x91b6eed85458239f281f5ad46c8defd60ddef8b2,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,2,0x91b6eed85458239f281f5ad46c8defd60ddef8b2,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,2,0x91b6eed85458239f281f5ad46c8defd60ddef8b2,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,2,0x91b6eed85458239f281f5ad46c8defd60ddef8b2,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,2,0x91b6eed85458239f281f5ad46c8defd60ddef8b2,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,2,0x91b6eed85458239f281f5ad46c8defd60ddef8b2,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,2,0x91b6eed85458239f281f5ad46c8defd60ddef8b2,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,2,0x91b6eed85458239f281f5ad46c8defd60ddef8b2,WalletTopped,"WalletTopped(address,uint256,address,address)",0x7872034fbcc87890e73d66eac55389e0ffdba157b89a73bd2011157ebac1d66e,false,0 3,address uint256 address address,account amount whitelistedRoot relayerOrWhitelisted,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,3,0xac92cea7b8936e769b00117e7428f7499c93f9db,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,3,0xac92cea7b8936e769b00117e7428f7499c93f9db,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,3,0xac92cea7b8936e769b00117e7428f7499c93f9db,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,3,0xac92cea7b8936e769b00117e7428f7499c93f9db,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,3,0xac92cea7b8936e769b00117e7428f7499c93f9db,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,3,0xac92cea7b8936e769b00117e7428f7499c93f9db,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,3,0xac92cea7b8936e769b00117e7428f7499c93f9db,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,3,0xac92cea7b8936e769b00117e7428f7499c93f9db,WalletTopped,"WalletTopped(address,uint256,address,address)",0x7872034fbcc87890e73d66eac55389e0ffdba157b89a73bd2011157ebac1d66e,false,0 3,address uint256 address address,account amount whitelistedRoot relayerOrWhitelisted,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,4,0x0cb76de990330b36b72c9b604a71d24eaa45ebf4,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,4,0x0cb76de990330b36b72c9b604a71d24eaa45ebf4,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,4,0x0cb76de990330b36b72c9b604a71d24eaa45ebf4,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,4,0x0cb76de990330b36b72c9b604a71d24eaa45ebf4,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,4,0x0cb76de990330b36b72c9b604a71d24eaa45ebf4,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,4,0x0cb76de990330b36b72c9b604a71d24eaa45ebf4,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,4,0x0cb76de990330b36b72c9b604a71d24eaa45ebf4,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,4,0x0cb76de990330b36b72c9b604a71d24eaa45ebf4,WalletTopped,"WalletTopped(address,uint256,address,address)",0x7872034fbcc87890e73d66eac55389e0ffdba157b89a73bd2011157ebac1d66e,false,0 3,address uint256 address address,account amount whitelistedRoot relayerOrWhitelisted,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,5,0x783548481a6ca92b6589365161b31e3ed64d0c3c,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,5,0x783548481a6ca92b6589365161b31e3ed64d0c3c,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,5,0x783548481a6ca92b6589365161b31e3ed64d0c3c,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,5,0x783548481a6ca92b6589365161b31e3ed64d0c3c,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,5,0x783548481a6ca92b6589365161b31e3ed64d0c3c,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,5,0x783548481a6ca92b6589365161b31e3ed64d0c3c,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,5,0x783548481a6ca92b6589365161b31e3ed64d0c3c,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,5,0x783548481a6ca92b6589365161b31e3ed64d0c3c,WalletTopped,"WalletTopped(address,uint256,address,address)",0x7872034fbcc87890e73d66eac55389e0ffdba157b89a73bd2011157ebac1d66e,false,0 3,address uint256 address address,account amount whitelistedRoot relayerOrWhitelisted,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,6,0xf224d5166fb194d8404a4a2d1d9fbb41866625ad,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,6,0xf224d5166fb194d8404a4a2d1d9fbb41866625ad,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,6,0xf224d5166fb194d8404a4a2d1d9fbb41866625ad,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,6,0xf224d5166fb194d8404a4a2d1d9fbb41866625ad,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,6,0xf224d5166fb194d8404a4a2d1d9fbb41866625ad,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,6,0xf224d5166fb194d8404a4a2d1d9fbb41866625ad,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,6,0xf224d5166fb194d8404a4a2d1d9fbb41866625ad,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,6,0xf224d5166fb194d8404a4a2d1d9fbb41866625ad,WalletTopped,"WalletTopped(address,uint256,address,address)",0x7872034fbcc87890e73d66eac55389e0ffdba157b89a73bd2011157ebac1d66e,false,0 3,address uint256 address address,account amount whitelistedRoot relayerOrWhitelisted,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,7,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,7,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,7,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,7,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,7,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,7,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,7,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,7,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,WalletTopped,"WalletTopped(address,uint256,address,address)",0x7872034fbcc87890e73d66eac55389e0ffdba157b89a73bd2011157ebac1d66e,false,0 3,address uint256 address address,account amount whitelistedRoot relayerOrWhitelisted,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,8,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,8,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,8,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,8,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,8,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,8,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,8,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,8,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,WalletTopped,"WalletTopped(address,uint256,address,address)",0x7872034fbcc87890e73d66eac55389e0ffdba157b89a73bd2011157ebac1d66e,false,0 3,address uint256 address address,account amount whitelistedRoot relayerOrWhitelisted,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,9,0x41ef166fb7d022ce9a90b47581f323d19fafbddd,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,9,0x41ef166fb7d022ce9a90b47581f323d19fafbddd,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,9,0x41ef166fb7d022ce9a90b47581f323d19fafbddd,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,10,0x08fdf766694c353401350c225caeb9c631dc3288,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,10,0x08fdf766694c353401350c225caeb9c631dc3288,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,10,0x08fdf766694c353401350c225caeb9c631dc3288,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,10,0x08fdf766694c353401350c225caeb9c631dc3288,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,10,0x08fdf766694c353401350c225caeb9c631dc3288,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,10,0x08fdf766694c353401350c225caeb9c631dc3288,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,10,0x08fdf766694c353401350c225caeb9c631dc3288,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Faucet,0x4f93fa058b03953c851efaa2e4fc5c34afdfab84,10,0x08fdf766694c353401350c225caeb9c631dc3288,WalletTopped,"WalletTopped(address,uint256,address,address)",0x7872034fbcc87890e73d66eac55389e0ffdba157b89a73bd2011157ebac1d66e,false,0 3,address uint256 address address,account amount whitelistedRoot relayerOrWhitelisted,true,18003061,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10 of 10. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,FeeFormula,0x1151867da39003695eed28fafa871079c91884c9,1,0x1151867da39003695eed28fafa871079c91884c9,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,AgreementCreated,"AgreementCreated(address,bytes32,bytes32[])",0x770ea40a13a4644573ed785e5c7116890709947918747febc5add46feb531e2d,false,0,address bytes32 bytes32[],agreementClass id data,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,AgreementLiquidated,"AgreementLiquidated(address,bytes32,address,address,uint256)",0x8505c3d8f1f184f032cf0bc4cd80ee61c8b9d94f8907c3281bf0101a2610fe80,false,0 2 3,address bytes32 address address uint256,agreementClass id penaltyAccount rewardAccount rewardAmount,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,AgreementLiquidatedBy,"AgreementLiquidatedBy(address,address,bytes32,address,address,uint256,uint256)",0x5f22b60e58b1d6de858bc27c48d5a4653e052da99e083c1d88bb8c58e1abc8ef,false,1 3 4,address address bytes32 address address uint256 uint256,liquidatorAccount agreementClass id penaltyAccount bondAccount rewardAmount bailoutAmount,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,AgreementLiquidatedV2,"AgreementLiquidatedV2(address,bytes32,address,address,address,uint256,int256,bytes)",0xb8381a3ce157650e06186e3e8f4dd4dc29236f2688b6eed1893d0a60d7c6386f,false,0 2 3,address bytes32 address address address uint256 int256 bytes,agreementClass id liquidatorAccount targetAccount rewardAmountReceiver rewardAmount targetAccountBalanceDelta liquidationTypeData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,AgreementStateUpdated,"AgreementStateUpdated(address,address,uint256)",0x30f416fa68fca014a0f334464c64b000ba53e99b6d2afdea9d5ca756372d5985,false,0 1,address address uint256,agreementClass account slotId,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,AgreementTerminated,"AgreementTerminated(address,bytes32)",0x71a63dc095de07aa5512ad57a7596a39516317e316981a1cd71000057be1537b,false,0,address bytes32,agreementClass id,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,AgreementUpdated,"AgreementUpdated(address,bytes32,bytes32[])",0x0c4c547b3a4fcaa5be8353b3111472b124155bccc86de811d4a481c9e6e9faca,false,0,address bytes32 bytes32[],agreementClass id data,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,AuthorizedOperator,"AuthorizedOperator(address,address)",0xf4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f9,false,0 1,address address,operator tokenHolder,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,Bailout,"Bailout(address,uint256)",0xd6c9a04afc81e8c614310bbee6c9e84f5abe15b82038bf8347014ce0852e6ffd,false,0,address uint256,bailoutAccount bailoutAmount,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,Burned,"Burned(address,address,uint256,bytes,bytes)",0xa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098,false,0 1,address address uint256 bytes bytes,operator from amount data operatorData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,Minted,"Minted(address,address,uint256,bytes,bytes)",0x2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d,false,0 1,address address uint256 bytes bytes,operator to amount data operatorData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,RevokedOperator,"RevokedOperator(address,address)",0x50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa1,false,0 1,address address,operator tokenHolder,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,Sent,"Sent(address,address,address,uint256,bytes,bytes)",0x06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987,false,0 1 2,address address address uint256 bytes bytes,operator from to amount data operatorData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,TokenDowngraded,"TokenDowngraded(address,uint256)",0x3bc27981aebbb57f9247dc00fde9d6cd91e4b230083fec3238fedbcba1f9ab3d,false,0,address uint256,account amount,true,17237956,21746648,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,TokenUpgraded,"TokenUpgraded(address,uint256)",0x25ca84076773b0455db53621c459ddc84fe40840e4932a62706a032566f399df,false,0,address uint256,account amount,true,17237956,21746648,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,Transfer,"Transfer(address,address,uint256,bytes)",0xe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16,false,0 1,address address uint256 bytes,from to value data,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,2,0xca903643aa81a2d67863079548f6b53a6dae43d7,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,AgreementCreated,"AgreementCreated(address,bytes32,bytes32[])",0x770ea40a13a4644573ed785e5c7116890709947918747febc5add46feb531e2d,false,0,address bytes32 bytes32[],agreementClass id data,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,AgreementLiquidated,"AgreementLiquidated(address,bytes32,address,address,uint256)",0x8505c3d8f1f184f032cf0bc4cd80ee61c8b9d94f8907c3281bf0101a2610fe80,false,0 2 3,address bytes32 address address uint256,agreementClass id penaltyAccount rewardAccount rewardAmount,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,AgreementLiquidatedBy,"AgreementLiquidatedBy(address,address,bytes32,address,address,uint256,uint256)",0x5f22b60e58b1d6de858bc27c48d5a4653e052da99e083c1d88bb8c58e1abc8ef,false,1 3 4,address address bytes32 address address uint256 uint256,liquidatorAccount agreementClass id penaltyAccount bondAccount rewardAmount bailoutAmount,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,AgreementLiquidatedV2,"AgreementLiquidatedV2(address,bytes32,address,address,address,uint256,int256,bytes)",0xb8381a3ce157650e06186e3e8f4dd4dc29236f2688b6eed1893d0a60d7c6386f,false,0 2 3,address bytes32 address address address uint256 int256 bytes,agreementClass id liquidatorAccount targetAccount rewardAmountReceiver rewardAmount targetAccountBalanceDelta liquidationTypeData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,AgreementStateUpdated,"AgreementStateUpdated(address,address,uint256)",0x30f416fa68fca014a0f334464c64b000ba53e99b6d2afdea9d5ca756372d5985,false,0 1,address address uint256,agreementClass account slotId,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,AgreementTerminated,"AgreementTerminated(address,bytes32)",0x71a63dc095de07aa5512ad57a7596a39516317e316981a1cd71000057be1537b,false,0,address bytes32,agreementClass id,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,AgreementUpdated,"AgreementUpdated(address,bytes32,bytes32[])",0x0c4c547b3a4fcaa5be8353b3111472b124155bccc86de811d4a481c9e6e9faca,false,0,address bytes32 bytes32[],agreementClass id data,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,AuthorizedOperator,"AuthorizedOperator(address,address)",0xf4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f9,false,0 1,address address,operator tokenHolder,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,Bailout,"Bailout(address,uint256)",0xd6c9a04afc81e8c614310bbee6c9e84f5abe15b82038bf8347014ce0852e6ffd,false,0,address uint256,bailoutAccount bailoutAmount,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,Burned,"Burned(address,address,uint256,bytes,bytes)",0xa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098,false,0 1,address address uint256 bytes bytes,operator from amount data operatorData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,Minted,"Minted(address,address,uint256,bytes,bytes)",0x2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d,false,0 1,address address uint256 bytes bytes,operator to amount data operatorData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,RevokedOperator,"RevokedOperator(address,address)",0x50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa1,false,0 1,address address,operator tokenHolder,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,Sent,"Sent(address,address,address,uint256,bytes,bytes)",0x06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987,false,0 1 2,address address address uint256 bytes bytes,operator from to amount data operatorData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,TokenDowngraded,"TokenDowngraded(address,uint256)",0x3bc27981aebbb57f9247dc00fde9d6cd91e4b230083fec3238fedbcba1f9ab3d,false,0,address uint256,account amount,true,17237956,21746648,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,TokenUpgraded,"TokenUpgraded(address,uint256)",0x25ca84076773b0455db53621c459ddc84fe40840e4932a62706a032566f399df,false,0,address uint256,account amount,true,17237956,21746648,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,Transfer,"Transfer(address,address,uint256,bytes)",0xe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16,false,0 1,address address uint256 bytes,from to value data,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,3,0xf6b5f7a885cbc57d739adbee76e52a70bc04d795,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,AgreementCreated,"AgreementCreated(address,bytes32,bytes32[])",0x770ea40a13a4644573ed785e5c7116890709947918747febc5add46feb531e2d,false,0,address bytes32 bytes32[],agreementClass id data,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,AgreementLiquidated,"AgreementLiquidated(address,bytes32,address,address,uint256)",0x8505c3d8f1f184f032cf0bc4cd80ee61c8b9d94f8907c3281bf0101a2610fe80,false,0 2 3,address bytes32 address address uint256,agreementClass id penaltyAccount rewardAccount rewardAmount,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,AgreementLiquidatedBy,"AgreementLiquidatedBy(address,address,bytes32,address,address,uint256,uint256)",0x5f22b60e58b1d6de858bc27c48d5a4653e052da99e083c1d88bb8c58e1abc8ef,false,1 3 4,address address bytes32 address address uint256 uint256,liquidatorAccount agreementClass id penaltyAccount bondAccount rewardAmount bailoutAmount,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,AgreementLiquidatedV2,"AgreementLiquidatedV2(address,bytes32,address,address,address,uint256,int256,bytes)",0xb8381a3ce157650e06186e3e8f4dd4dc29236f2688b6eed1893d0a60d7c6386f,false,0 2 3,address bytes32 address address address uint256 int256 bytes,agreementClass id liquidatorAccount targetAccount rewardAmountReceiver rewardAmount targetAccountBalanceDelta liquidationTypeData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,AgreementStateUpdated,"AgreementStateUpdated(address,address,uint256)",0x30f416fa68fca014a0f334464c64b000ba53e99b6d2afdea9d5ca756372d5985,false,0 1,address address uint256,agreementClass account slotId,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,AgreementTerminated,"AgreementTerminated(address,bytes32)",0x71a63dc095de07aa5512ad57a7596a39516317e316981a1cd71000057be1537b,false,0,address bytes32,agreementClass id,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,AgreementUpdated,"AgreementUpdated(address,bytes32,bytes32[])",0x0c4c547b3a4fcaa5be8353b3111472b124155bccc86de811d4a481c9e6e9faca,false,0,address bytes32 bytes32[],agreementClass id data,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,AuthorizedOperator,"AuthorizedOperator(address,address)",0xf4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f9,false,0 1,address address,operator tokenHolder,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,Bailout,"Bailout(address,uint256)",0xd6c9a04afc81e8c614310bbee6c9e84f5abe15b82038bf8347014ce0852e6ffd,false,0,address uint256,bailoutAccount bailoutAmount,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,Burned,"Burned(address,address,uint256,bytes,bytes)",0xa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098,false,0 1,address address uint256 bytes bytes,operator from amount data operatorData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,Minted,"Minted(address,address,uint256,bytes,bytes)",0x2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d,false,0 1,address address uint256 bytes bytes,operator to amount data operatorData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,RevokedOperator,"RevokedOperator(address,address)",0x50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa1,false,0 1,address address,operator tokenHolder,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,Sent,"Sent(address,address,address,uint256,bytes,bytes)",0x06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987,false,0 1 2,address address address uint256 bytes bytes,operator from to amount data operatorData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,TokenDowngraded,"TokenDowngraded(address,uint256)",0x3bc27981aebbb57f9247dc00fde9d6cd91e4b230083fec3238fedbcba1f9ab3d,false,0,address uint256,account amount,true,17237956,21746648,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,TokenUpgraded,"TokenUpgraded(address,uint256)",0x25ca84076773b0455db53621c459ddc84fe40840e4932a62706a032566f399df,false,0,address uint256,account amount,true,17237956,21746648,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,Transfer,"Transfer(address,address,uint256,bytes)",0xe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16,false,0 1,address address uint256 bytes,from to value data,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,TransferFee,"TransferFee(address,address,uint256,uint256,bool)",0x3eba86eb3c0ea121e35980d4acae6eb9f1cdf0bf7c0c08443798cfd6e5299de3,false,,address address uint256 uint256 bool,from to amount fee senderPays,true,17260434,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,4,0x2e54a29275ffccbbdb42816ee1dd8d7e610c4cb4,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,AgreementCreated,"AgreementCreated(address,bytes32,bytes32[])",0x770ea40a13a4644573ed785e5c7116890709947918747febc5add46feb531e2d,false,0,address bytes32 bytes32[],agreementClass id data,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,AgreementLiquidated,"AgreementLiquidated(address,bytes32,address,address,uint256)",0x8505c3d8f1f184f032cf0bc4cd80ee61c8b9d94f8907c3281bf0101a2610fe80,false,0 2 3,address bytes32 address address uint256,agreementClass id penaltyAccount rewardAccount rewardAmount,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,AgreementLiquidatedBy,"AgreementLiquidatedBy(address,address,bytes32,address,address,uint256,uint256)",0x5f22b60e58b1d6de858bc27c48d5a4653e052da99e083c1d88bb8c58e1abc8ef,false,1 3 4,address address bytes32 address address uint256 uint256,liquidatorAccount agreementClass id penaltyAccount bondAccount rewardAmount bailoutAmount,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,AgreementLiquidatedV2,"AgreementLiquidatedV2(address,bytes32,address,address,address,uint256,int256,bytes)",0xb8381a3ce157650e06186e3e8f4dd4dc29236f2688b6eed1893d0a60d7c6386f,false,0 2 3,address bytes32 address address address uint256 int256 bytes,agreementClass id liquidatorAccount targetAccount rewardAmountReceiver rewardAmount targetAccountBalanceDelta liquidationTypeData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,AgreementStateUpdated,"AgreementStateUpdated(address,address,uint256)",0x30f416fa68fca014a0f334464c64b000ba53e99b6d2afdea9d5ca756372d5985,false,0 1,address address uint256,agreementClass account slotId,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,AgreementTerminated,"AgreementTerminated(address,bytes32)",0x71a63dc095de07aa5512ad57a7596a39516317e316981a1cd71000057be1537b,false,0,address bytes32,agreementClass id,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,AgreementUpdated,"AgreementUpdated(address,bytes32,bytes32[])",0x0c4c547b3a4fcaa5be8353b3111472b124155bccc86de811d4a481c9e6e9faca,false,0,address bytes32 bytes32[],agreementClass id data,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,AuthorizedOperator,"AuthorizedOperator(address,address)",0xf4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f9,false,0 1,address address,operator tokenHolder,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,Bailout,"Bailout(address,uint256)",0xd6c9a04afc81e8c614310bbee6c9e84f5abe15b82038bf8347014ce0852e6ffd,false,0,address uint256,bailoutAccount bailoutAmount,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,Burned,"Burned(address,address,uint256,bytes,bytes)",0xa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098,false,0 1,address address uint256 bytes bytes,operator from amount data operatorData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,Minted,"Minted(address,address,uint256,bytes,bytes)",0x2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d,false,0 1,address address uint256 bytes bytes,operator to amount data operatorData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,RevokedOperator,"RevokedOperator(address,address)",0x50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa1,false,0 1,address address,operator tokenHolder,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,Sent,"Sent(address,address,address,uint256,bytes,bytes)",0x06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987,false,0 1 2,address address address uint256 bytes bytes,operator from to amount data operatorData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,TokenDowngraded,"TokenDowngraded(address,uint256)",0x3bc27981aebbb57f9247dc00fde9d6cd91e4b230083fec3238fedbcba1f9ab3d,false,0,address uint256,account amount,true,17237956,21746648,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,TokenUpgraded,"TokenUpgraded(address,uint256)",0x25ca84076773b0455db53621c459ddc84fe40840e4932a62706a032566f399df,false,0,address uint256,account amount,true,17237956,21746648,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,Transfer,"Transfer(address,address,uint256,bytes)",0xe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16,false,0 1,address address uint256 bytes,from to value data,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,TransferFee,"TransferFee(address,address,uint256,uint256,bool)",0x3eba86eb3c0ea121e35980d4acae6eb9f1cdf0bf7c0c08443798cfd6e5299de3,false,,address address uint256 uint256 bool,from to amount fee senderPays,true,17260434,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,5,0xc9995e270b4f0d3d73e3f0133d0ceeb8455d7649,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,AgreementCreated,"AgreementCreated(address,bytes32,bytes32[])",0x770ea40a13a4644573ed785e5c7116890709947918747febc5add46feb531e2d,false,0,address bytes32 bytes32[],agreementClass id data,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,AgreementLiquidated,"AgreementLiquidated(address,bytes32,address,address,uint256)",0x8505c3d8f1f184f032cf0bc4cd80ee61c8b9d94f8907c3281bf0101a2610fe80,false,0 2 3,address bytes32 address address uint256,agreementClass id penaltyAccount rewardAccount rewardAmount,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,AgreementLiquidatedBy,"AgreementLiquidatedBy(address,address,bytes32,address,address,uint256,uint256)",0x5f22b60e58b1d6de858bc27c48d5a4653e052da99e083c1d88bb8c58e1abc8ef,false,1 3 4,address address bytes32 address address uint256 uint256,liquidatorAccount agreementClass id penaltyAccount bondAccount rewardAmount bailoutAmount,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,AgreementLiquidatedV2,"AgreementLiquidatedV2(address,bytes32,address,address,address,uint256,int256,bytes)",0xb8381a3ce157650e06186e3e8f4dd4dc29236f2688b6eed1893d0a60d7c6386f,false,0 2 3,address bytes32 address address address uint256 int256 bytes,agreementClass id liquidatorAccount targetAccount rewardAmountReceiver rewardAmount targetAccountBalanceDelta liquidationTypeData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,AgreementStateUpdated,"AgreementStateUpdated(address,address,uint256)",0x30f416fa68fca014a0f334464c64b000ba53e99b6d2afdea9d5ca756372d5985,false,0 1,address address uint256,agreementClass account slotId,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,AgreementTerminated,"AgreementTerminated(address,bytes32)",0x71a63dc095de07aa5512ad57a7596a39516317e316981a1cd71000057be1537b,false,0,address bytes32,agreementClass id,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,AgreementUpdated,"AgreementUpdated(address,bytes32,bytes32[])",0x0c4c547b3a4fcaa5be8353b3111472b124155bccc86de811d4a481c9e6e9faca,false,0,address bytes32 bytes32[],agreementClass id data,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,AuthorizedOperator,"AuthorizedOperator(address,address)",0xf4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f9,false,0 1,address address,operator tokenHolder,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,Bailout,"Bailout(address,uint256)",0xd6c9a04afc81e8c614310bbee6c9e84f5abe15b82038bf8347014ce0852e6ffd,false,0,address uint256,bailoutAccount bailoutAmount,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,Burned,"Burned(address,address,uint256,bytes,bytes)",0xa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098,false,0 1,address address uint256 bytes bytes,operator from amount data operatorData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,ConstantInflowNFTCreated,ConstantInflowNFTCreated(address),0x8837af285f4d380af9227df9ebafa13d992b487fa6d7a4366bd4154576085b89,false,0,address,constantInflowNFT,true,21746648,77207809,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 6,7 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,ConstantOutflowNFTCreated,ConstantOutflowNFTCreated(address),0xcf554eb342edf010a94e07701ae91e99e90b769f649f03aeb1153654ddd43c01,false,0,address,constantOutflowNFT,true,21746648,77207809,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 6,7 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,Minted,"Minted(address,address,uint256,bytes,bytes)",0x2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d,false,0 1,address address uint256 bytes bytes,operator to amount data operatorData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,RevokedOperator,"RevokedOperator(address,address)",0x50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa1,false,0 1,address address,operator tokenHolder,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,Sent,"Sent(address,address,address,uint256,bytes,bytes)",0x06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987,false,0 1 2,address address address uint256 bytes bytes,operator from to amount data operatorData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,Transfer,"Transfer(address,address,uint256,bytes)",0xe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16,false,0 1,address address uint256 bytes,from to value data,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,TransferFee,"TransferFee(address,address,uint256,uint256,bool)",0x3eba86eb3c0ea121e35980d4acae6eb9f1cdf0bf7c0c08443798cfd6e5299de3,false,,address address uint256 uint256 bool,from to amount fee senderPays,true,17260434,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,6,0xac862af0a463a5faebbe959e3483b41400f5bb38,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,AgreementCreated,"AgreementCreated(address,bytes32,bytes32[])",0x770ea40a13a4644573ed785e5c7116890709947918747febc5add46feb531e2d,false,0,address bytes32 bytes32[],agreementClass id data,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,AgreementLiquidated,"AgreementLiquidated(address,bytes32,address,address,uint256)",0x8505c3d8f1f184f032cf0bc4cd80ee61c8b9d94f8907c3281bf0101a2610fe80,false,0 2 3,address bytes32 address address uint256,agreementClass id penaltyAccount rewardAccount rewardAmount,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,AgreementLiquidatedBy,"AgreementLiquidatedBy(address,address,bytes32,address,address,uint256,uint256)",0x5f22b60e58b1d6de858bc27c48d5a4653e052da99e083c1d88bb8c58e1abc8ef,false,1 3 4,address address bytes32 address address uint256 uint256,liquidatorAccount agreementClass id penaltyAccount bondAccount rewardAmount bailoutAmount,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,AgreementLiquidatedV2,"AgreementLiquidatedV2(address,bytes32,address,address,address,uint256,int256,bytes)",0xb8381a3ce157650e06186e3e8f4dd4dc29236f2688b6eed1893d0a60d7c6386f,false,0 2 3,address bytes32 address address address uint256 int256 bytes,agreementClass id liquidatorAccount targetAccount rewardAmountReceiver rewardAmount targetAccountBalanceDelta liquidationTypeData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,AgreementStateUpdated,"AgreementStateUpdated(address,address,uint256)",0x30f416fa68fca014a0f334464c64b000ba53e99b6d2afdea9d5ca756372d5985,false,0 1,address address uint256,agreementClass account slotId,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,AgreementTerminated,"AgreementTerminated(address,bytes32)",0x71a63dc095de07aa5512ad57a7596a39516317e316981a1cd71000057be1537b,false,0,address bytes32,agreementClass id,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,AgreementUpdated,"AgreementUpdated(address,bytes32,bytes32[])",0x0c4c547b3a4fcaa5be8353b3111472b124155bccc86de811d4a481c9e6e9faca,false,0,address bytes32 bytes32[],agreementClass id data,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,AuthorizedOperator,"AuthorizedOperator(address,address)",0xf4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f9,false,0 1,address address,operator tokenHolder,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,Bailout,"Bailout(address,uint256)",0xd6c9a04afc81e8c614310bbee6c9e84f5abe15b82038bf8347014ce0852e6ffd,false,0,address uint256,bailoutAccount bailoutAmount,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,Burned,"Burned(address,address,uint256,bytes,bytes)",0xa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098,false,0 1,address address uint256 bytes bytes,operator from amount data operatorData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,ConstantInflowNFTCreated,ConstantInflowNFTCreated(address),0x8837af285f4d380af9227df9ebafa13d992b487fa6d7a4366bd4154576085b89,false,0,address,constantInflowNFT,true,21746648,77207809,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 6,7 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,ConstantOutflowNFTCreated,ConstantOutflowNFTCreated(address),0xcf554eb342edf010a94e07701ae91e99e90b769f649f03aeb1153654ddd43c01,false,0,address,constantOutflowNFT,true,21746648,77207809,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 6,7 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,Minted,"Minted(address,address,uint256,bytes,bytes)",0x2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d,false,0 1,address address uint256 bytes bytes,operator to amount data operatorData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,RevokedOperator,"RevokedOperator(address,address)",0x50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa1,false,0 1,address address,operator tokenHolder,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,Sent,"Sent(address,address,address,uint256,bytes,bytes)",0x06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987,false,0 1 2,address address address uint256 bytes bytes,operator from to amount data operatorData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,Transfer,"Transfer(address,address,uint256,bytes)",0xe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16,false,0 1,address address uint256 bytes,from to value data,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,TransferFee,"TransferFee(address,address,uint256,uint256,bool)",0x3eba86eb3c0ea121e35980d4acae6eb9f1cdf0bf7c0c08443798cfd6e5299de3,false,,address address uint256 uint256 bool,from to amount fee senderPays,true,17260434,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,7,0x880c4641702d5e12d6a881bb6d8fc425e98cb398,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,AgreementCreated,"AgreementCreated(address,bytes32,bytes32[])",0x770ea40a13a4644573ed785e5c7116890709947918747febc5add46feb531e2d,false,0,address bytes32 bytes32[],agreementClass id data,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,AgreementLiquidated,"AgreementLiquidated(address,bytes32,address,address,uint256)",0x8505c3d8f1f184f032cf0bc4cd80ee61c8b9d94f8907c3281bf0101a2610fe80,false,0 2 3,address bytes32 address address uint256,agreementClass id penaltyAccount rewardAccount rewardAmount,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,AgreementLiquidatedBy,"AgreementLiquidatedBy(address,address,bytes32,address,address,uint256,uint256)",0x5f22b60e58b1d6de858bc27c48d5a4653e052da99e083c1d88bb8c58e1abc8ef,false,1 3 4,address address bytes32 address address uint256 uint256,liquidatorAccount agreementClass id penaltyAccount bondAccount rewardAmount bailoutAmount,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,AgreementLiquidatedV2,"AgreementLiquidatedV2(address,bytes32,address,address,address,uint256,int256,bytes)",0xb8381a3ce157650e06186e3e8f4dd4dc29236f2688b6eed1893d0a60d7c6386f,false,0 2 3,address bytes32 address address address uint256 int256 bytes,agreementClass id liquidatorAccount targetAccount rewardAmountReceiver rewardAmount targetAccountBalanceDelta liquidationTypeData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,AgreementStateUpdated,"AgreementStateUpdated(address,address,uint256)",0x30f416fa68fca014a0f334464c64b000ba53e99b6d2afdea9d5ca756372d5985,false,0 1,address address uint256,agreementClass account slotId,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,AgreementTerminated,"AgreementTerminated(address,bytes32)",0x71a63dc095de07aa5512ad57a7596a39516317e316981a1cd71000057be1537b,false,0,address bytes32,agreementClass id,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,AgreementUpdated,"AgreementUpdated(address,bytes32,bytes32[])",0x0c4c547b3a4fcaa5be8353b3111472b124155bccc86de811d4a481c9e6e9faca,false,0,address bytes32 bytes32[],agreementClass id data,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,AuthorizedOperator,"AuthorizedOperator(address,address)",0xf4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f9,false,0 1,address address,operator tokenHolder,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,Bailout,"Bailout(address,uint256)",0xd6c9a04afc81e8c614310bbee6c9e84f5abe15b82038bf8347014ce0852e6ffd,false,0,address uint256,bailoutAccount bailoutAmount,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,BlockedUpdated,"BlockedUpdated(address,bool)",0x148a86796e0fc2ba3270f94c00ce0af947ccc7a4db4269c66c9dd1eb883e90a5,false,0,address bool,account blocked,true,77207809,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 8 of 8 +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,Burned,"Burned(address,address,uint256,bytes,bytes)",0xa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098,false,0 1,address address uint256 bytes bytes,operator from amount data operatorData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,Minted,"Minted(address,address,uint256,bytes,bytes)",0x2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d,false,0 1,address address uint256 bytes bytes,operator to amount data operatorData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,RevokedOperator,"RevokedOperator(address,address)",0x50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa1,false,0 1,address address,operator tokenHolder,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,Sent,"Sent(address,address,address,uint256,bytes,bytes)",0x06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987,false,0 1 2,address address address uint256 bytes bytes,operator from to amount data operatorData,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,Transfer,"Transfer(address,address,uint256,bytes)",0xe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16,false,0 1,address address uint256 bytes,from to value data,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,TransferFee,"TransferFee(address,address,uint256,uint256,bool)",0x3eba86eb3c0ea121e35980d4acae6eb9f1cdf0bf7c0c08443798cfd6e5299de3,false,,address address uint256 uint256 bool,from to amount fee senderPays,true,17260434,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 4,5,6,7,8 of 8" +CELO,42220,GoodDollar,0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a,8,0xaabaac2282681ec667339d70d7ebf7f1720ca1de,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,true,17237956,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8 of 8" +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,1,0xb0b86dd967655728218b7b87b10051a60758af82,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,1,0xb0b86dd967655728218b7b87b10051a60758af82,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,1,0xb0b86dd967655728218b7b87b10051a60758af82,LogSwapin,"LogSwapin(bytes32,address,uint256)",0x05d0634fe981be85c22e2942a880821b70095d84e152c3ea3c17a4e4250d9d61,false,0 1,bytes32 address uint256,txhash account amount,true,13037458,13254104,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 1 of 6 +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,1,0xb0b86dd967655728218b7b87b10051a60758af82,LogSwapout,"LogSwapout(address,address,uint256)",0x6b616089d04950dc06c45c6dd787d657980543f89651aec47924752c7d16c888,false,0 1,address address uint256,account bindaddr amount,true,13037458,13254104,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 1 of 6 +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,1,0xb0b86dd967655728218b7b87b10051a60758af82,Paused,Paused(bytes32),0x0cb09dc71d57eeec2046f6854976717e4874a3cf2d6ddeddde337e5b6de6ba31,false,,bytes32,role,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,1,0xb0b86dd967655728218b7b87b10051a60758af82,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,1,0xb0b86dd967655728218b7b87b10051a60758af82,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,1,0xb0b86dd967655728218b7b87b10051a60758af82,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,1,0xb0b86dd967655728218b7b87b10051a60758af82,Unpaused,Unpaused(bytes32),0xd05bfc2250abb0f8fd265a54c53a24359c5484af63cad2e4ce87c78ab751395a,false,,bytes32,role,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,1,0xb0b86dd967655728218b7b87b10051a60758af82,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,2,0x413e395b10be6f39f2aa0d80eec48edb88738ac4,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,2,0x413e395b10be6f39f2aa0d80eec48edb88738ac4,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,2,0x413e395b10be6f39f2aa0d80eec48edb88738ac4,Paused,Paused(bytes32),0x0cb09dc71d57eeec2046f6854976717e4874a3cf2d6ddeddde337e5b6de6ba31,false,,bytes32,role,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,2,0x413e395b10be6f39f2aa0d80eec48edb88738ac4,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,2,0x413e395b10be6f39f2aa0d80eec48edb88738ac4,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,2,0x413e395b10be6f39f2aa0d80eec48edb88738ac4,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,2,0x413e395b10be6f39f2aa0d80eec48edb88738ac4,SendOrMint,"SendOrMint(address,uint256,uint256,uint256)",0xa8b929cf00516e52f11a148f9b3aa339a3244b6cdd411adf3aca9c99efa25f3d,false,,address uint256 uint256 uint256,to amount sent minted,true,13254104,13660450,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 2 of 6 +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,2,0x413e395b10be6f39f2aa0d80eec48edb88738ac4,Unpaused,Unpaused(bytes32),0xd05bfc2250abb0f8fd265a54c53a24359c5484af63cad2e4ce87c78ab751395a,false,,bytes32,role,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,2,0x413e395b10be6f39f2aa0d80eec48edb88738ac4,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,3,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,3,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,3,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,MinterSet,"MinterSet(address,uint256,uint256,uint32,bool,bool)",0x64a94d85fa67264f10e0e93df73a2ff08456ca0794348685caf0464a1cfa0f6e,false,,address uint256 uint256 uint32 bool bool,minter totalMintCap perTxCap bps rewardsRole isUpdate,true,13660450,15806090,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 3 of 6 +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,3,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,Paused,Paused(bytes32),0x0cb09dc71d57eeec2046f6854976717e4874a3cf2d6ddeddde337e5b6de6ba31,false,,bytes32,role,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,3,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,3,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,3,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,3,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,SendOrMint,"SendOrMint(address,uint256,uint256,uint256,uint256)",0x311d20328a364ee3281fa8e3c385e7bfef800e2f1305017a27c5df12a2fae261,false,,address uint256 uint256 uint256 uint256,to amount sent minted outstandingMintDebt,true,13660450,15806090,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 3 of 6 +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,3,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,Unpaused,Unpaused(bytes32),0xd05bfc2250abb0f8fd265a54c53a24359c5484af63cad2e4ce87c78ab751395a,false,,bytes32,role,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,3,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,4,0x0a36091884b8d7808d5fdb47cbdead457ea9803e,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,4,0x0a36091884b8d7808d5fdb47cbdead457ea9803e,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,4,0x0a36091884b8d7808d5fdb47cbdead457ea9803e,Burned,"Burned(address,address,uint256)",0x6ab368f832c266c8eb942b84fbcaa20aedc24a699d2a05fae2568028733b1d09,false,,address address uint256,minter to amount,true,15806090,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 4,5,6 of 6" +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,4,0x0a36091884b8d7808d5fdb47cbdead457ea9803e,Minted,"Minted(address,address,uint256)",0x9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0,false,,address address uint256,minter to amount,true,15806090,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 4,5,6 of 6" +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,4,0x0a36091884b8d7808d5fdb47cbdead457ea9803e,MinterSet,"MinterSet(address,uint256,uint256,uint32,uint256,uint256,uint32,bool,bool)",0x58c3ceb7d4f068706ddc92911fae8701fac2c91c60bcc1b56ec7a6f56001aa5e,false,,address uint256 uint256 uint32 uint256 uint256 uint32 bool bool,minter totalMintCapIn perTxCapIn bpsIn totalMintCapOut perTxCapOut bpsOut rewardsRole isUpdate,true,15806090,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 4,5,6 of 6" +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,4,0x0a36091884b8d7808d5fdb47cbdead457ea9803e,Paused,Paused(bytes32),0x0cb09dc71d57eeec2046f6854976717e4874a3cf2d6ddeddde337e5b6de6ba31,false,,bytes32,role,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,4,0x0a36091884b8d7808d5fdb47cbdead457ea9803e,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,4,0x0a36091884b8d7808d5fdb47cbdead457ea9803e,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,4,0x0a36091884b8d7808d5fdb47cbdead457ea9803e,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,4,0x0a36091884b8d7808d5fdb47cbdead457ea9803e,SendOrMint,"SendOrMint(address,address,uint256,uint256,uint256,uint256)",0xdea51570922020f525c1f30d8c1c57bd3cffe5632d70d13aaf8f8451388dbd95,false,,address address uint256 uint256 uint256 uint256,rewarder to amount sent minted outstandingMintDebt,true,15806090,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 4,5,6 of 6" +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,4,0x0a36091884b8d7808d5fdb47cbdead457ea9803e,Unpaused,Unpaused(bytes32),0xd05bfc2250abb0f8fd265a54c53a24359c5484af63cad2e4ce87c78ab751395a,false,,bytes32,role,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,4,0x0a36091884b8d7808d5fdb47cbdead457ea9803e,UpdateFrequencySet,UpdateFrequencySet(uint128),0x5497ec04d2873f2e2d376db2bb24e7e57851278c75fc1fcc9aab4db5fb70d223,false,,uint128,newFrequency,true,15806090,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 4,5,6 of 6" +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,4,0x0a36091884b8d7808d5fdb47cbdead457ea9803e,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,5,0xb3109ca8c7bf74fc5d28285ecf7fe498c21a0698,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,5,0xb3109ca8c7bf74fc5d28285ecf7fe498c21a0698,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,5,0xb3109ca8c7bf74fc5d28285ecf7fe498c21a0698,Burned,"Burned(address,address,uint256)",0x6ab368f832c266c8eb942b84fbcaa20aedc24a699d2a05fae2568028733b1d09,false,,address address uint256,minter to amount,true,15806090,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 4,5,6 of 6" +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,5,0xb3109ca8c7bf74fc5d28285ecf7fe498c21a0698,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,17228965,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6 of 6" +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,5,0xb3109ca8c7bf74fc5d28285ecf7fe498c21a0698,Minted,"Minted(address,address,uint256)",0x9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0,false,,address address uint256,minter to amount,true,15806090,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 4,5,6 of 6" +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,5,0xb3109ca8c7bf74fc5d28285ecf7fe498c21a0698,MinterSet,"MinterSet(address,uint256,uint256,uint32,uint256,uint256,uint32,bool,bool)",0x58c3ceb7d4f068706ddc92911fae8701fac2c91c60bcc1b56ec7a6f56001aa5e,false,,address uint256 uint256 uint32 uint256 uint256 uint32 bool bool,minter totalMintCapIn perTxCapIn bpsIn totalMintCapOut perTxCapOut bpsOut rewardsRole isUpdate,true,15806090,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 4,5,6 of 6" +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,5,0xb3109ca8c7bf74fc5d28285ecf7fe498c21a0698,Paused,Paused(bytes32),0x0cb09dc71d57eeec2046f6854976717e4874a3cf2d6ddeddde337e5b6de6ba31,false,,bytes32,role,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,5,0xb3109ca8c7bf74fc5d28285ecf7fe498c21a0698,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,5,0xb3109ca8c7bf74fc5d28285ecf7fe498c21a0698,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,5,0xb3109ca8c7bf74fc5d28285ecf7fe498c21a0698,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,5,0xb3109ca8c7bf74fc5d28285ecf7fe498c21a0698,SendOrMint,"SendOrMint(address,address,uint256,uint256,uint256,uint256)",0xdea51570922020f525c1f30d8c1c57bd3cffe5632d70d13aaf8f8451388dbd95,false,,address address uint256 uint256 uint256 uint256,rewarder to amount sent minted outstandingMintDebt,true,15806090,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 4,5,6 of 6" +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,5,0xb3109ca8c7bf74fc5d28285ecf7fe498c21a0698,Unpaused,Unpaused(bytes32),0xd05bfc2250abb0f8fd265a54c53a24359c5484af63cad2e4ce87c78ab751395a,false,,bytes32,role,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,5,0xb3109ca8c7bf74fc5d28285ecf7fe498c21a0698,UpdateFrequencySet,UpdateFrequencySet(uint128),0x5497ec04d2873f2e2d376db2bb24e7e57851278c75fc1fcc9aab4db5fb70d223,false,,uint128,newFrequency,true,15806090,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 4,5,6 of 6" +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,5,0xb3109ca8c7bf74fc5d28285ecf7fe498c21a0698,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,6,0x098148534ac15a44cff52387ba81ed929589ecaf,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,6,0x098148534ac15a44cff52387ba81ed929589ecaf,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,6,0x098148534ac15a44cff52387ba81ed929589ecaf,Burned,"Burned(address,address,uint256)",0x6ab368f832c266c8eb942b84fbcaa20aedc24a699d2a05fae2568028733b1d09,false,,address address uint256,minter to amount,true,15806090,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 4,5,6 of 6" +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,6,0x098148534ac15a44cff52387ba81ed929589ecaf,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,17228965,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 5,6 of 6" +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,6,0x098148534ac15a44cff52387ba81ed929589ecaf,Minted,"Minted(address,address,uint256)",0x9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0,false,,address address uint256,minter to amount,true,15806090,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 4,5,6 of 6" +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,6,0x098148534ac15a44cff52387ba81ed929589ecaf,MinterSet,"MinterSet(address,uint256,uint256,uint32,uint256,uint256,uint32,bool,bool)",0x58c3ceb7d4f068706ddc92911fae8701fac2c91c60bcc1b56ec7a6f56001aa5e,false,,address uint256 uint256 uint32 uint256 uint256 uint32 bool bool,minter totalMintCapIn perTxCapIn bpsIn totalMintCapOut perTxCapOut bpsOut rewardsRole isUpdate,true,15806090,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 4,5,6 of 6" +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,6,0x098148534ac15a44cff52387ba81ed929589ecaf,Paused,Paused(bytes32),0x0cb09dc71d57eeec2046f6854976717e4874a3cf2d6ddeddde337e5b6de6ba31,false,,bytes32,role,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,6,0x098148534ac15a44cff52387ba81ed929589ecaf,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,6,0x098148534ac15a44cff52387ba81ed929589ecaf,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,6,0x098148534ac15a44cff52387ba81ed929589ecaf,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,6,0x098148534ac15a44cff52387ba81ed929589ecaf,SendOrMint,"SendOrMint(address,address,uint256,uint256,uint256,uint256)",0xdea51570922020f525c1f30d8c1c57bd3cffe5632d70d13aaf8f8451388dbd95,false,,address address uint256 uint256 uint256 uint256,rewarder to amount sent minted outstandingMintDebt,true,15806090,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 4,5,6 of 6" +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,6,0x098148534ac15a44cff52387ba81ed929589ecaf,Unpaused,Unpaused(bytes32),0xd05bfc2250abb0f8fd265a54c53a24359c5484af63cad2e4ce87c78ab751395a,false,,bytes32,role,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,6,0x098148534ac15a44cff52387ba81ed929589ecaf,UpdateFrequencySet,UpdateFrequencySet(uint128),0x5497ec04d2873f2e2d376db2bb24e7e57851278c75fc1fcc9aab4db5fb70d223,false,,uint128,newFrequency,true,15806090,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 4,5,6 of 6" +CELO,42220,GoodDollarMintBurnWrapper,0x5566b6e4962ba83e05a426ad89031ec18e9cadd3,6,0x098148534ac15a44cff52387ba81ed929589ecaf,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GReputation,0xa9000aa66903b5e26f88fa8462739cdcf7956ea6,1,0x4be0c7f9c468b174dfeba304d8bd6af000948a79,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GReputation,0xa9000aa66903b5e26f88fa8462739cdcf7956ea6,1,0x4be0c7f9c468b174dfeba304d8bd6af000948a79,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GReputation,0xa9000aa66903b5e26f88fa8462739cdcf7956ea6,1,0x4be0c7f9c468b174dfeba304d8bd6af000948a79,Burn,"Burn(address,uint256)",0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5,false,0,address uint256,_from _amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GReputation,0xa9000aa66903b5e26f88fa8462739cdcf7956ea6,1,0x4be0c7f9c468b174dfeba304d8bd6af000948a79,DelegateVotesChanged,"DelegateVotesChanged(address,address,uint256,uint256)",0x8553411b8bbb348336351063649aa1f4fa74c4935f5c4386469a017df33a1f66,false,0 1,address address uint256 uint256,delegate delegator previousBalance newBalance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GReputation,0xa9000aa66903b5e26f88fa8462739cdcf7956ea6,1,0x4be0c7f9c468b174dfeba304d8bd6af000948a79,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GReputation,0xa9000aa66903b5e26f88fa8462739cdcf7956ea6,1,0x4be0c7f9c468b174dfeba304d8bd6af000948a79,Mint,"Mint(address,uint256)",0x0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885,false,0,address uint256,_to _amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GReputation,0xa9000aa66903b5e26f88fa8462739cdcf7956ea6,1,0x4be0c7f9c468b174dfeba304d8bd6af000948a79,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GReputation,0xa9000aa66903b5e26f88fa8462739cdcf7956ea6,1,0x4be0c7f9c468b174dfeba304d8bd6af000948a79,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GReputation,0xa9000aa66903b5e26f88fa8462739cdcf7956ea6,1,0x4be0c7f9c468b174dfeba304d8bd6af000948a79,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GReputation,0xa9000aa66903b5e26f88fa8462739cdcf7956ea6,1,0x4be0c7f9c468b174dfeba304d8bd6af000948a79,StateHash,"StateHash(string,bytes32,uint256)",0x5298f094d368dc1c18dca22952c4ea2cb8b115d7c70a18269735b0f4ed0f4913,false,,string bytes32 uint256,blockchain merkleRoot totalSupply,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GReputation,0xa9000aa66903b5e26f88fa8462739cdcf7956ea6,1,0x4be0c7f9c468b174dfeba304d8bd6af000948a79,StateHashProof,"StateHashProof(string,address,uint256)",0x1c708de3afb744b96b84aa0fbf440e683fac3130cce82a8f01eb94b5e67610a0,false,1,string address uint256,blockchain user repBalance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,GReputation,0xa9000aa66903b5e26f88fa8462739cdcf7956ea6,1,0x4be0c7f9c468b174dfeba304d8bd6af000948a79,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,BlacklistAdded,BlacklistAdded(address),0x44d5fe68b00f68950fb9c1ff0a61ef7f747b1a36359a7e3a7f3324db4b878967,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,BlacklistRemoved,BlacklistRemoved(address),0x1747ca720b1a174a464b6513ace29b1d3190b5f632b9f34147017c81425bfde8,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,ContractAdded,ContractAdded(address),0x89c66952b48f3e96bf1d8ba1b63189520fd988a6979b8b740bd5c5d8dc53e205,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,ContractRemoved,ContractRemoved(address),0x8d30d41865a0b811b9545d879520d2dde9f4cc49e4241f486ad9752bc904b565,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,WhitelistedAdded,WhitelistedAdded(address),0xee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,WhitelistedAuthenticated,"WhitelistedAuthenticated(address,uint256)",0xb2a82fce6d8c7a633efe9579f77b4edb96bfdf171a49bfc2ce666dc543a1f500,false,0,address uint256,account timestamp,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,WhitelistedRemoved,WhitelistedRemoved(address),0x270d9b30cf5b0793bbfd54c9d5b94aeb49462b8148399000265144a8722da6b6,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,2,0x7d3033247d4a57b8193b6d9193fd56b45c3f794f,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,2,0x7d3033247d4a57b8193b6d9193fd56b45c3f794f,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,2,0x7d3033247d4a57b8193b6d9193fd56b45c3f794f,BlacklistAdded,BlacklistAdded(address),0x44d5fe68b00f68950fb9c1ff0a61ef7f747b1a36359a7e3a7f3324db4b878967,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,2,0x7d3033247d4a57b8193b6d9193fd56b45c3f794f,BlacklistRemoved,BlacklistRemoved(address),0x1747ca720b1a174a464b6513ace29b1d3190b5f632b9f34147017c81425bfde8,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,2,0x7d3033247d4a57b8193b6d9193fd56b45c3f794f,ContractAdded,ContractAdded(address),0x89c66952b48f3e96bf1d8ba1b63189520fd988a6979b8b740bd5c5d8dc53e205,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,2,0x7d3033247d4a57b8193b6d9193fd56b45c3f794f,ContractRemoved,ContractRemoved(address),0x8d30d41865a0b811b9545d879520d2dde9f4cc49e4241f486ad9752bc904b565,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,2,0x7d3033247d4a57b8193b6d9193fd56b45c3f794f,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,2,0x7d3033247d4a57b8193b6d9193fd56b45c3f794f,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,2,0x7d3033247d4a57b8193b6d9193fd56b45c3f794f,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,2,0x7d3033247d4a57b8193b6d9193fd56b45c3f794f,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,2,0x7d3033247d4a57b8193b6d9193fd56b45c3f794f,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,2,0x7d3033247d4a57b8193b6d9193fd56b45c3f794f,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,2,0x7d3033247d4a57b8193b6d9193fd56b45c3f794f,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,2,0x7d3033247d4a57b8193b6d9193fd56b45c3f794f,WhitelistedAdded,WhitelistedAdded(address),0xee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,2,0x7d3033247d4a57b8193b6d9193fd56b45c3f794f,WhitelistedAuthenticated,"WhitelistedAuthenticated(address,uint256)",0xb2a82fce6d8c7a633efe9579f77b4edb96bfdf171a49bfc2ce666dc543a1f500,false,0,address uint256,account timestamp,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,2,0x7d3033247d4a57b8193b6d9193fd56b45c3f794f,WhitelistedRemoved,WhitelistedRemoved(address),0x270d9b30cf5b0793bbfd54c9d5b94aeb49462b8148399000265144a8722da6b6,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,3,0x3df6ea625866df8d0a61408a122c484b98f3184c,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,3,0x3df6ea625866df8d0a61408a122c484b98f3184c,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,3,0x3df6ea625866df8d0a61408a122c484b98f3184c,BlacklistAdded,BlacklistAdded(address),0x44d5fe68b00f68950fb9c1ff0a61ef7f747b1a36359a7e3a7f3324db4b878967,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,3,0x3df6ea625866df8d0a61408a122c484b98f3184c,BlacklistRemoved,BlacklistRemoved(address),0x1747ca720b1a174a464b6513ace29b1d3190b5f632b9f34147017c81425bfde8,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,3,0x3df6ea625866df8d0a61408a122c484b98f3184c,ContractAdded,ContractAdded(address),0x89c66952b48f3e96bf1d8ba1b63189520fd988a6979b8b740bd5c5d8dc53e205,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,3,0x3df6ea625866df8d0a61408a122c484b98f3184c,ContractRemoved,ContractRemoved(address),0x8d30d41865a0b811b9545d879520d2dde9f4cc49e4241f486ad9752bc904b565,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,3,0x3df6ea625866df8d0a61408a122c484b98f3184c,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,3,0x3df6ea625866df8d0a61408a122c484b98f3184c,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,3,0x3df6ea625866df8d0a61408a122c484b98f3184c,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,3,0x3df6ea625866df8d0a61408a122c484b98f3184c,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,3,0x3df6ea625866df8d0a61408a122c484b98f3184c,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,3,0x3df6ea625866df8d0a61408a122c484b98f3184c,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,3,0x3df6ea625866df8d0a61408a122c484b98f3184c,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,3,0x3df6ea625866df8d0a61408a122c484b98f3184c,WhitelistedAdded,WhitelistedAdded(address),0xee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,3,0x3df6ea625866df8d0a61408a122c484b98f3184c,WhitelistedAuthenticated,"WhitelistedAuthenticated(address,uint256)",0xb2a82fce6d8c7a633efe9579f77b4edb96bfdf171a49bfc2ce666dc543a1f500,false,0,address uint256,account timestamp,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,3,0x3df6ea625866df8d0a61408a122c484b98f3184c,WhitelistedRemoved,WhitelistedRemoved(address),0x270d9b30cf5b0793bbfd54c9d5b94aeb49462b8148399000265144a8722da6b6,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,4,0x1eeeb5ba9a9f8b84e52612884a4c18c78cc7413e,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,4,0x1eeeb5ba9a9f8b84e52612884a4c18c78cc7413e,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,4,0x1eeeb5ba9a9f8b84e52612884a4c18c78cc7413e,BlacklistAdded,BlacklistAdded(address),0x44d5fe68b00f68950fb9c1ff0a61ef7f747b1a36359a7e3a7f3324db4b878967,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,4,0x1eeeb5ba9a9f8b84e52612884a4c18c78cc7413e,BlacklistRemoved,BlacklistRemoved(address),0x1747ca720b1a174a464b6513ace29b1d3190b5f632b9f34147017c81425bfde8,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,4,0x1eeeb5ba9a9f8b84e52612884a4c18c78cc7413e,ContractAdded,ContractAdded(address),0x89c66952b48f3e96bf1d8ba1b63189520fd988a6979b8b740bd5c5d8dc53e205,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,4,0x1eeeb5ba9a9f8b84e52612884a4c18c78cc7413e,ContractRemoved,ContractRemoved(address),0x8d30d41865a0b811b9545d879520d2dde9f4cc49e4241f486ad9752bc904b565,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,4,0x1eeeb5ba9a9f8b84e52612884a4c18c78cc7413e,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,4,0x1eeeb5ba9a9f8b84e52612884a4c18c78cc7413e,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,4,0x1eeeb5ba9a9f8b84e52612884a4c18c78cc7413e,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,4,0x1eeeb5ba9a9f8b84e52612884a4c18c78cc7413e,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,4,0x1eeeb5ba9a9f8b84e52612884a4c18c78cc7413e,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,4,0x1eeeb5ba9a9f8b84e52612884a4c18c78cc7413e,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,4,0x1eeeb5ba9a9f8b84e52612884a4c18c78cc7413e,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,4,0x1eeeb5ba9a9f8b84e52612884a4c18c78cc7413e,WhitelistedAdded,WhitelistedAdded(address),0xee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,4,0x1eeeb5ba9a9f8b84e52612884a4c18c78cc7413e,WhitelistedAuthenticated,"WhitelistedAuthenticated(address,uint256)",0xb2a82fce6d8c7a633efe9579f77b4edb96bfdf171a49bfc2ce666dc543a1f500,false,0,address uint256,account timestamp,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,4,0x1eeeb5ba9a9f8b84e52612884a4c18c78cc7413e,WhitelistedRemoved,WhitelistedRemoved(address),0x270d9b30cf5b0793bbfd54c9d5b94aeb49462b8148399000265144a8722da6b6,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,5,0x0ecc03f4e3fa94fa6e2098428a3ad393b65933c9,AccountConnected,"AccountConnected(address,address)",0x18f7736ef54539debd9afd3c9500b106e12ae7c70e685f5a5efd727b1ce1d54c,false,0 1,address address,connected to,true,61416834,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 5 of 5 +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,5,0x0ecc03f4e3fa94fa6e2098428a3ad393b65933c9,AccountDisconnected,"AccountDisconnected(address,address)",0x7cdef5f9c5cb8ce728661ede956fef26cb91eb4d7d2180cc041b73f9fef568d2,false,0 1,address address,disconnected from,true,61416834,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 5 of 5 +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,5,0x0ecc03f4e3fa94fa6e2098428a3ad393b65933c9,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,5,0x0ecc03f4e3fa94fa6e2098428a3ad393b65933c9,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,5,0x0ecc03f4e3fa94fa6e2098428a3ad393b65933c9,BlacklistAdded,BlacklistAdded(address),0x44d5fe68b00f68950fb9c1ff0a61ef7f747b1a36359a7e3a7f3324db4b878967,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,5,0x0ecc03f4e3fa94fa6e2098428a3ad393b65933c9,BlacklistRemoved,BlacklistRemoved(address),0x1747ca720b1a174a464b6513ace29b1d3190b5f632b9f34147017c81425bfde8,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,5,0x0ecc03f4e3fa94fa6e2098428a3ad393b65933c9,ContractAdded,ContractAdded(address),0x89c66952b48f3e96bf1d8ba1b63189520fd988a6979b8b740bd5c5d8dc53e205,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,5,0x0ecc03f4e3fa94fa6e2098428a3ad393b65933c9,ContractRemoved,ContractRemoved(address),0x8d30d41865a0b811b9545d879520d2dde9f4cc49e4241f486ad9752bc904b565,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,5,0x0ecc03f4e3fa94fa6e2098428a3ad393b65933c9,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,5,0x0ecc03f4e3fa94fa6e2098428a3ad393b65933c9,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,5,0x0ecc03f4e3fa94fa6e2098428a3ad393b65933c9,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,5,0x0ecc03f4e3fa94fa6e2098428a3ad393b65933c9,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,5,0x0ecc03f4e3fa94fa6e2098428a3ad393b65933c9,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,5,0x0ecc03f4e3fa94fa6e2098428a3ad393b65933c9,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,5,0x0ecc03f4e3fa94fa6e2098428a3ad393b65933c9,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,5,0x0ecc03f4e3fa94fa6e2098428a3ad393b65933c9,WhitelistedAdded,WhitelistedAdded(address),0xee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,5,0x0ecc03f4e3fa94fa6e2098428a3ad393b65933c9,WhitelistedAuthenticated,"WhitelistedAuthenticated(address,uint256)",0xb2a82fce6d8c7a633efe9579f77b4edb96bfdf171a49bfc2ce666dc543a1f500,false,0,address uint256,account timestamp,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Identity,0xc361a6e67822a0edc17d899227dd9fc50bd62f42,5,0x0ecc03f4e3fa94fa6e2098428a3ad393b65933c9,WhitelistedRemoved,WhitelistedRemoved(address),0x270d9b30cf5b0793bbfd54c9d5b94aeb49462b8148399000265144a8722da6b6,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,1,0xdbc8860618482f703a4047340b8639b1452f96ec,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,1,0xdbc8860618482f703a4047340b8639b1452f96ec,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,1,0xdbc8860618482f703a4047340b8639b1452f96ec,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,1,0xdbc8860618482f703a4047340b8639b1452f96ec,InviteeJoined,"InviteeJoined(address,address)",0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051,false,0 1,address address,inviter invitee,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,1,0xdbc8860618482f703a4047340b8639b1452f96ec,InviterBounty,"InviterBounty(address,address,uint256,uint256,bool)",0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b,false,0 1,address address uint256 uint256 bool,inviter invitee bountyPaid inviterLevel earnedLevel,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,1,0xdbc8860618482f703a4047340b8639b1452f96ec,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,2,0x61760d949357066ae29c469b70a91934273e4ef3,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,2,0x61760d949357066ae29c469b70a91934273e4ef3,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,2,0x61760d949357066ae29c469b70a91934273e4ef3,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,2,0x61760d949357066ae29c469b70a91934273e4ef3,InviteeJoined,"InviteeJoined(address,address)",0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051,false,0 1,address address,inviter invitee,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,2,0x61760d949357066ae29c469b70a91934273e4ef3,InviterBounty,"InviterBounty(address,address,uint256,uint256,bool)",0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b,false,0 1,address address uint256 uint256 bool,inviter invitee bountyPaid inviterLevel earnedLevel,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,2,0x61760d949357066ae29c469b70a91934273e4ef3,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,3,0x142e6d0afdd09c8629970b5fb0cf9798a3d21f89,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,3,0x142e6d0afdd09c8629970b5fb0cf9798a3d21f89,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,3,0x142e6d0afdd09c8629970b5fb0cf9798a3d21f89,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,3,0x142e6d0afdd09c8629970b5fb0cf9798a3d21f89,InviteeJoined,"InviteeJoined(address,address)",0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051,false,0 1,address address,inviter invitee,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,3,0x142e6d0afdd09c8629970b5fb0cf9798a3d21f89,InviterBounty,"InviterBounty(address,address,uint256,uint256,bool)",0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b,false,0 1,address address uint256 uint256 bool,inviter invitee bountyPaid inviterLevel earnedLevel,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,3,0x142e6d0afdd09c8629970b5fb0cf9798a3d21f89,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,4,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,4,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,4,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,4,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,InviteeJoined,"InviteeJoined(address,address)",0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051,false,0 1,address address,inviter invitee,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,4,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,InviterBounty,"InviterBounty(address,address,uint256,uint256,bool)",0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b,false,0 1,address address uint256 uint256 bool,inviter invitee bountyPaid inviterLevel earnedLevel,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,4,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,5,0xd2e26679b4d21cb501ebbc99744c29ed061a6b8c,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,5,0xd2e26679b4d21cb501ebbc99744c29ed061a6b8c,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,5,0xd2e26679b4d21cb501ebbc99744c29ed061a6b8c,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,5,0xd2e26679b4d21cb501ebbc99744c29ed061a6b8c,InviteeJoined,"InviteeJoined(address,address)",0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051,false,0 1,address address,inviter invitee,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,5,0xd2e26679b4d21cb501ebbc99744c29ed061a6b8c,InviterBounty,"InviterBounty(address,address,uint256,uint256,bool)",0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b,false,0 1,address address uint256 uint256 bool,inviter invitee bountyPaid inviterLevel earnedLevel,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,5,0xd2e26679b4d21cb501ebbc99744c29ed061a6b8c,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,6,0x87c222b6212b8352c48b7047e5c97c8797535a09,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,6,0x87c222b6212b8352c48b7047e5c97c8797535a09,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,6,0x87c222b6212b8352c48b7047e5c97c8797535a09,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,6,0x87c222b6212b8352c48b7047e5c97c8797535a09,InviteeJoined,"InviteeJoined(address,address)",0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051,false,0 1,address address,inviter invitee,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,6,0x87c222b6212b8352c48b7047e5c97c8797535a09,InviterBounty,"InviterBounty(address,address,uint256,uint256,bool)",0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b,false,0 1,address address uint256 uint256 bool,inviter invitee bountyPaid inviterLevel earnedLevel,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,6,0x87c222b6212b8352c48b7047e5c97c8797535a09,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,7,0xf2196f8c2ba0674a8b00369cd65fab3f54b080a0,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,7,0xf2196f8c2ba0674a8b00369cd65fab3f54b080a0,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,7,0xf2196f8c2ba0674a8b00369cd65fab3f54b080a0,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,7,0xf2196f8c2ba0674a8b00369cd65fab3f54b080a0,InviteeJoined,"InviteeJoined(address,address)",0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051,false,0 1,address address,inviter invitee,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,7,0xf2196f8c2ba0674a8b00369cd65fab3f54b080a0,InviterBounty,"InviterBounty(address,address,uint256,uint256,bool)",0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b,false,0 1,address address uint256 uint256 bool,inviter invitee bountyPaid inviterLevel earnedLevel,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,7,0xf2196f8c2ba0674a8b00369cd65fab3f54b080a0,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,8,0x4072cb2d7e95def1559f6f72491039fe0534fa37,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,8,0x4072cb2d7e95def1559f6f72491039fe0534fa37,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,8,0x4072cb2d7e95def1559f6f72491039fe0534fa37,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,8,0x4072cb2d7e95def1559f6f72491039fe0534fa37,InviteeJoined,"InviteeJoined(address,address)",0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051,false,0 1,address address,inviter invitee,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,8,0x4072cb2d7e95def1559f6f72491039fe0534fa37,InviterBounty,"InviterBounty(address,address,uint256,uint256,bool)",0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b,false,0 1,address address uint256 uint256 bool,inviter invitee bountyPaid inviterLevel earnedLevel,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,Invites,0x36829d1cda92fff5782d5d48991620664fc857d3,8,0x4072cb2d7e95def1559f6f72491039fe0534fa37,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,1,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,1,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,1,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,ExchangeProviderAdded,ExchangeProviderAdded(address),0x2ee2cb0721ec60b86190cae5c48e25064b69b35abad32452a4ec99d232033de2,false,0,address,exchangeProvider,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,1,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,ExchangeProviderRemoved,ExchangeProviderRemoved(address),0x29e92ab2e30f4f74283034c28c451b6faac986b554f1808101eb6418bdba19d4,false,0,address,exchangeProvider,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,1,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,1,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,ReserveSet,"ReserveSet(address,address)",0xb69e1c416d8be92ac92c8e97e77c4626fba5e6ab50161099f659ea3303479e50,false,0 1,address address,newAddress prevAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,1,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,Swap,"Swap(address,bytes32,address,address,address,uint256,uint256)",0xe7b046415cac9de47940c3087e06db13a0e058ccf53ac5f0edd49ebb4c2c3a6f,false,1 2 3,address bytes32 address address address uint256 uint256,exchangeProvider exchangeId trader tokenIn tokenOut amountIn amountOut,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,1,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,TradingLimitConfigured,"TradingLimitConfigured(bytes32,address,(uint32,uint32,int48,int48,int48,uint8))",0x1a082a1efaf1549c18917ddcb1f759680c29371609e24f4b946e93acf4ce5ad2,false,,"bytes32 address (uint32,uint32,int48,int48,int48,uint8)",exchangeId token config,true,31415857,61416834,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 1 of 2 +CELO,42220,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,1,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,2,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,2,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,2,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,ExchangeProviderAdded,ExchangeProviderAdded(address),0x2ee2cb0721ec60b86190cae5c48e25064b69b35abad32452a4ec99d232033de2,false,0,address,exchangeProvider,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,2,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,ExchangeProviderRemoved,ExchangeProviderRemoved(address),0x29e92ab2e30f4f74283034c28c451b6faac986b554f1808101eb6418bdba19d4,false,0,address,exchangeProvider,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,2,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,2,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,ReserveSet,"ReserveSet(address,address)",0xb69e1c416d8be92ac92c8e97e77c4626fba5e6ab50161099f659ea3303479e50,false,0 1,address address,newAddress prevAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,2,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,Swap,"Swap(address,bytes32,address,address,address,uint256,uint256)",0xe7b046415cac9de47940c3087e06db13a0e058ccf53ac5f0edd49ebb4c2c3a6f,false,1 2 3,address bytes32 address address address uint256 uint256,exchangeProvider exchangeId trader tokenIn tokenOut amountIn amountOut,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,2,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,TradingLimitConfigured,"TradingLimitConfigured(bytes32,address,(uint32,uint32,int48,int48,int48,int48,int48,uint8))",0x3ed50aa123e1e547aa90fcf88624ef8278d253e252bb1feac75eda93e1905bb6,false,,"bytes32 address (uint32,uint32,int48,int48,int48,int48,int48,uint8)",exchangeId token config,true,61416834,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 2 of 2 +CELO,42220,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,2,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,AvatarUpdated,AvatarUpdated(address),0x67b34afe551279f03ead7ef1a0ecd16bec18f83ab1a9834c7fda2627374aae9a,false,0,address,AVATAR,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,BrokerUpdated,BrokerUpdated(address),0x865dab7821134b6eb27cba259b40e33bbc1b898e970a535a18a83147f380a51f,false,0,address,newBroker,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,ExchangeCreated,"ExchangeCreated(bytes32,address,address)",0xef64f1477da1dc2a681adfafd64ea6aea317bc2b4b289d3cb83ed28e06a0eca7,false,0 1 2,bytes32 address address,exchangeId reserveAsset tokenAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,ExchangeDestroyed,"ExchangeDestroyed(bytes32,address,address)",0x72508491fc70b128eac87e7e09c111008dbf1a965572c407dc568853bfffb4c3,false,0 1 2,bytes32 address address,exchangeId reserveAsset tokenAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,ExitContributionSet,"ExitContributionSet(bytes32,uint256)",0x1af751293d0291cca774a2d8152b5eaf650ff3b8243976f64402e7b70344c936,false,0,bytes32 uint256,exchangeId exitContribution,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,ExpansionControllerUpdated,ExpansionControllerUpdated(address),0x6791df7c014d19acfc9b7e3a5d48588a876b014fdd3321f193fef6b0ae785c24,false,0,address,expansionController,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,ReserveRatioUpdated,"ReserveRatioUpdated(bytes32,uint32)",0x79f5414ef686d317caad619bee58ae93a7a214651f1d0819d4ce5cb1dde57e9a,false,0,bytes32 uint32,exchangeId reserveRatio,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,ReserveUpdated,ReserveUpdated(address),0x0b248ab246a87e452fbedee8dc12dfc53e3f3bfdc6920999062c56dea4ab522a,false,0,address,newReserve,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,AvatarUpdated,AvatarUpdated(address),0x67b34afe551279f03ead7ef1a0ecd16bec18f83ab1a9834c7fda2627374aae9a,false,0,address,AVATAR,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,BrokerUpdated,BrokerUpdated(address),0x865dab7821134b6eb27cba259b40e33bbc1b898e970a535a18a83147f380a51f,false,0,address,newBroker,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,ExchangeCreated,"ExchangeCreated(bytes32,address,address)",0xef64f1477da1dc2a681adfafd64ea6aea317bc2b4b289d3cb83ed28e06a0eca7,false,0 1 2,bytes32 address address,exchangeId reserveAsset tokenAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,ExchangeDestroyed,"ExchangeDestroyed(bytes32,address,address)",0x72508491fc70b128eac87e7e09c111008dbf1a965572c407dc568853bfffb4c3,false,0 1 2,bytes32 address address,exchangeId reserveAsset tokenAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,ExchangeUpdated,"ExchangeUpdated(bytes32,address,address)",0x795d5a71e23aab4c26a0763c6014c82fd9eae5c5e22fa2540301d2e9ee21f974,false,0 1 2,bytes32 address address,exchangeId reserveAsset tokenAddress,true,61416834,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 2 of 2 +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,ExitContributionSet,"ExitContributionSet(bytes32,uint256)",0x1af751293d0291cca774a2d8152b5eaf650ff3b8243976f64402e7b70344c936,false,0,bytes32 uint256,exchangeId exitContribution,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,ExpansionControllerUpdated,ExpansionControllerUpdated(address),0x6791df7c014d19acfc9b7e3a5d48588a876b014fdd3321f193fef6b0ae785c24,false,0,address,expansionController,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,ReserveRatioUpdated,"ReserveRatioUpdated(bytes32,uint32)",0x79f5414ef686d317caad619bee58ae93a7a214651f1d0819d4ce5cb1dde57e9a,false,0,bytes32 uint32,exchangeId reserveRatio,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,ReserveUpdated,ReserveUpdated(address),0x0b248ab246a87e452fbedee8dc12dfc53e3f3bfdc6920999062c56dea4ab522a,false,0,address,newReserve,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,AvatarUpdated,AvatarUpdated(address),0x67b34afe551279f03ead7ef1a0ecd16bec18f83ab1a9834c7fda2627374aae9a,false,0,address,avatar,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,DistributionHelperUpdated,DistributionHelperUpdated(address),0x37bb6eaf6f31a018c4328eb0343706d73df678b663b21b972351d2528f755af5,false,0,address,distributionHelper,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,ExpansionConfigSet,"ExpansionConfigSet(bytes32,uint64,uint32)",0xec7bd652042d4e7ac612fa1ad2901ce09f76d87ddf816a2c139dd24e3485e3ae,false,0,bytes32 uint64 uint32,exchangeId expansionRate expansionFrequency,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,ExpansionUBIMinted,"ExpansionUBIMinted(bytes32,uint256)",0x0781f173380ed4227560d90be8abf115523ae75bb917c0de637ce6cfbde0011b,false,0,bytes32 uint256,exchangeId amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,GoodDollarExchangeProviderUpdated,GoodDollarExchangeProviderUpdated(address),0xbbee0329d0a3c6241c11b82178f5039a54f654d789f3d9cbb471bf12f0c77e8f,false,0,address,exchangeProvider,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,InterestUBIMinted,"InterestUBIMinted(bytes32,uint256)",0x16414a884759b367b2c78dab8035003a0b744b3b41128d432aa29045743d0116,false,0,bytes32 uint256,exchangeId amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,ReserveUpdated,ReserveUpdated(address),0x0b248ab246a87e452fbedee8dc12dfc53e3f3bfdc6920999062c56dea4ab522a,false,0,address,reserve,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,RewardMinted,"RewardMinted(bytes32,address,uint256)",0x45a9b25eb22877783b22873a81ab6e03cff8a14dbe2013660999213bdc4067b1,false,0 1,bytes32 address uint256,exchangeId to amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoProxyAdmin,0x8471406c3bff67cc6538481c8550364bda6ca691,1,0x8471406c3bff67cc6538481c8550364bda6ca691,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,AssetAllocationSet,"AssetAllocationSet(bytes32[],uint256[])",0x55b488abd19ae7621712324d3d42c2ef7a9575f64f5503103286a1161fb40855,false,,bytes32[] uint256[],symbols weights,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,CollateralAssetAdded,CollateralAssetAdded(address),0x0c7515883121475b5d9289febf21a9de4ad53f18349a856d90c7acd6e099600b,false,,address,collateralAsset,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,CollateralAssetRemoved,CollateralAssetRemoved(address),0x4336391ada1af9dcb966fed43ebafa4404719b6d8e42c765ab28e3abc9a24e7a,false,,address,collateralAsset,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,DailySpendingRatioForCollateralAssetSet,"DailySpendingRatioForCollateralAssetSet(address,uint256)",0x15ff5079dfbf448e4bb45ac83498c2ecb0833ad35916946bb683ccb49f8013a3,false,,address uint256,collateralAsset collateralAssetDailySpendingRatios,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,DailySpendingRatioSet,DailySpendingRatioSet(uint256),0xb08f0607338ad77f5b08ccf831e533cefcc2d373c173e87a8f61144f1d82be1e,false,,uint256,ratio,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,ExchangeSpenderAdded,ExchangeSpenderAdded(address),0x71bccdb89fff4d914e3d2e472b327e3debaf4c4d6f1dfe528f430447e4cbcf5f,false,0,address,exchangeSpender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,ExchangeSpenderRemoved,ExchangeSpenderRemoved(address),0x20aaa18caa668680a42b328a15fd50d580bac65d8bd346e104355473c6373ff3,false,0,address,exchangeSpender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,OtherReserveAddressAdded,OtherReserveAddressAdded(address),0xd78793225285ecf9cf5f0f84b1cdc335c2cb4d6810ff0b9fd156ad6026c89cea,false,0,address,otherReserveAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,OtherReserveAddressRemoved,"OtherReserveAddressRemoved(address,uint256)",0x89b4ee5cecfdfb246ede373c10283b5038afe56a531fc1d2f3ed8c5507a52fcb,false,0,address uint256,otherReserveAddress index,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,RegistrySet,RegistrySet(address),0x27fe5f0c1c3b1ed427cc63d0f05759ffdecf9aec9e18d31ef366fc8a6cb5dc3b,false,0,address,registryAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,ReserveCollateralAssetsTransferred,"ReserveCollateralAssetsTransferred(address,address,uint256,address)",0xc171b15fb47a5beb3e11b1951d4518544f699edd6acd893d8695c91703922b60,false,0 1,address address uint256 address,spender to value token,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,ReserveGoldTransferred,"ReserveGoldTransferred(address,address,uint256)",0x4dd1abe16ad3d4f829372dc77766ca2cce34e205af9b10f8cc1fab370425864f,false,0 1,address address uint256,spender to value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,SpenderAdded,SpenderAdded(address),0x3139419c41cdd7abca84fa19dd21118cd285d3e2ce1a9444e8161ce9fa62fdcd,false,0,address,spender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,SpenderRemoved,SpenderRemoved(address),0xab8cff50266d80b9c9d9703af934ca455b9218286bf4fcaa05653a564c499e4b,false,0,address,spender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,TobinTaxReserveRatioSet,TobinTaxReserveRatioSet(uint256),0x4da8e8b2223fbbb897200fb9dfb6b986c1b4188621114d407ee8ec363569fc37,false,,uint256,value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,TobinTaxSet,TobinTaxSet(uint256),0xfe69856ffb1b1d6cb00c1d8151726e6e95032b1666282eeb293ecadd58b29a6e,false,,uint256,value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,TobinTaxStalenessThresholdSet,TobinTaxStalenessThresholdSet(uint256),0x7bfe94ca3147f135fcd6d94ebf61d33fa34fbe904f933ccae66911b9548544f2,false,,uint256,value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,TokenAdded,TokenAdded(address),0x784c8f4dbf0ffedd6e72c76501c545a70f8b203b30a26ce542bf92ba87c248a4,false,0,address,token,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,TokenRemoved,"TokenRemoved(address,uint256)",0xbe9bb4bdca0a094babd75e3a98b1d2e2390633430d0a2f6e2b9970e2ee03fb2e,false,0,address uint256,token index,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,1,0x0000000000000000000000000000000000000000,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,1,0x0000000000000000000000000000000000000000,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,1,0x0000000000000000000000000000000000000000,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd0a3fad8d7887f8264414ddd3290ed1782fb4658,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd0a3fad8d7887f8264414ddd3290ed1782fb4658,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd0a3fad8d7887f8264414ddd3290ed1782fb4658,BridgeRequest,"BridgeRequest(address,address,uint256,uint256,uint256,uint8,uint256)",0xabeeb7182c7294cd8efcd40e9ff952c1b759c2165b3634aac589429de5d55ad0,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to targetChainId normalizedAmount timestamp bridge id,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd0a3fad8d7887f8264414ddd3290ed1782fb4658,ExecutedTransfer,"ExecutedTransfer(address,address,uint256,uint256,uint256,uint8,uint256)",0x6cf712ce908185c8c38a073b7315f79687e7440fb057d9d1ca76a2509a1282ee,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to normalizedAmount fee sourceChainId bridge id,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd0a3fad8d7887f8264414ddd3290ed1782fb4658,FalseSender,"FalseSender(uint256,address)",0x1eafb58197ea0dc76b9278ccad47f61a239f00b017d89a19081a89321cce213d,false,,uint256 address,sourceChainId sourceAddress,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd0a3fad8d7887f8264414ddd3290ed1782fb4658,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd0a3fad8d7887f8264414ddd3290ed1782fb4658,MessageFailed,"MessageFailed(uint16,bytes,uint64,bytes,bytes)",0xe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c,false,,uint16 bytes uint64 bytes bytes,_srcChainId _srcAddress _nonce _payload _reason,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd0a3fad8d7887f8264414ddd3290ed1782fb4658,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd0a3fad8d7887f8264414ddd3290ed1782fb4658,RetryMessageSuccess,"RetryMessageSuccess(uint16,bytes,uint64,bytes32)",0xc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e5,false,,uint16 bytes uint64 bytes32,_srcChainId _srcAddress _nonce _payloadHash,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd0a3fad8d7887f8264414ddd3290ed1782fb4658,SetMinDstGas,"SetMinDstGas(uint16,uint16,uint256)",0x9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0,false,,uint16 uint16 uint256,_dstChainId _type _minDstGas,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd0a3fad8d7887f8264414ddd3290ed1782fb4658,SetPrecrime,SetPrecrime(address),0x5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b,false,,address,precrime,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd0a3fad8d7887f8264414ddd3290ed1782fb4658,SetTrustedRemote,"SetTrustedRemote(uint16,bytes)",0xfa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab,false,,uint16 bytes,_remoteChainId _path,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd0a3fad8d7887f8264414ddd3290ed1782fb4658,SetTrustedRemoteAddress,"SetTrustedRemoteAddress(uint16,bytes)",0x8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce,false,,uint16 bytes,_remoteChainId _remoteAddress,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd0a3fad8d7887f8264414ddd3290ed1782fb4658,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x691de730d97d545c141d13ed5e9c12b7cb384a73,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x691de730d97d545c141d13ed5e9c12b7cb384a73,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x691de730d97d545c141d13ed5e9c12b7cb384a73,BridgeRequest,"BridgeRequest(address,address,uint256,uint256,uint256,uint8,uint256)",0xabeeb7182c7294cd8efcd40e9ff952c1b759c2165b3634aac589429de5d55ad0,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to targetChainId normalizedAmount timestamp bridge id,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x691de730d97d545c141d13ed5e9c12b7cb384a73,ExecutedTransfer,"ExecutedTransfer(address,address,uint256,uint256,uint256,uint8,uint256)",0x6cf712ce908185c8c38a073b7315f79687e7440fb057d9d1ca76a2509a1282ee,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to normalizedAmount fee sourceChainId bridge id,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x691de730d97d545c141d13ed5e9c12b7cb384a73,FalseSender,"FalseSender(uint256,address)",0x1eafb58197ea0dc76b9278ccad47f61a239f00b017d89a19081a89321cce213d,false,,uint256 address,sourceChainId sourceAddress,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x691de730d97d545c141d13ed5e9c12b7cb384a73,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x691de730d97d545c141d13ed5e9c12b7cb384a73,MessageFailed,"MessageFailed(uint16,bytes,uint64,bytes,bytes)",0xe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c,false,,uint16 bytes uint64 bytes bytes,_srcChainId _srcAddress _nonce _payload _reason,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x691de730d97d545c141d13ed5e9c12b7cb384a73,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x691de730d97d545c141d13ed5e9c12b7cb384a73,RetryMessageSuccess,"RetryMessageSuccess(uint16,bytes,uint64,bytes32)",0xc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e5,false,,uint16 bytes uint64 bytes32,_srcChainId _srcAddress _nonce _payloadHash,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x691de730d97d545c141d13ed5e9c12b7cb384a73,SetMinDstGas,"SetMinDstGas(uint16,uint16,uint256)",0x9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0,false,,uint16 uint16 uint256,_dstChainId _type _minDstGas,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x691de730d97d545c141d13ed5e9c12b7cb384a73,SetPrecrime,SetPrecrime(address),0x5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b,false,,address,precrime,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x691de730d97d545c141d13ed5e9c12b7cb384a73,SetTrustedRemote,"SetTrustedRemote(uint16,bytes)",0xfa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab,false,,uint16 bytes,_remoteChainId _path,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x691de730d97d545c141d13ed5e9c12b7cb384a73,SetTrustedRemoteAddress,"SetTrustedRemoteAddress(uint16,bytes)",0x8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce,false,,uint16 bytes,_remoteChainId _remoteAddress,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x691de730d97d545c141d13ed5e9c12b7cb384a73,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x2537f22e7b2d5d14e7f571fa67fcd846d73317f6,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x2537f22e7b2d5d14e7f571fa67fcd846d73317f6,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x2537f22e7b2d5d14e7f571fa67fcd846d73317f6,BridgeRequest,"BridgeRequest(address,address,uint256,uint256,uint256,uint8,uint256)",0xabeeb7182c7294cd8efcd40e9ff952c1b759c2165b3634aac589429de5d55ad0,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to targetChainId normalizedAmount timestamp bridge id,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x2537f22e7b2d5d14e7f571fa67fcd846d73317f6,ExecutedTransfer,"ExecutedTransfer(address,address,uint256,uint256,uint256,uint8,uint256)",0x6cf712ce908185c8c38a073b7315f79687e7440fb057d9d1ca76a2509a1282ee,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to normalizedAmount fee sourceChainId bridge id,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x2537f22e7b2d5d14e7f571fa67fcd846d73317f6,FalseSender,"FalseSender(uint256,address)",0x1eafb58197ea0dc76b9278ccad47f61a239f00b017d89a19081a89321cce213d,false,,uint256 address,sourceChainId sourceAddress,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x2537f22e7b2d5d14e7f571fa67fcd846d73317f6,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x2537f22e7b2d5d14e7f571fa67fcd846d73317f6,MessageFailed,"MessageFailed(uint16,bytes,uint64,bytes,bytes)",0xe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c,false,,uint16 bytes uint64 bytes bytes,_srcChainId _srcAddress _nonce _payload _reason,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x2537f22e7b2d5d14e7f571fa67fcd846d73317f6,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x2537f22e7b2d5d14e7f571fa67fcd846d73317f6,RetryMessageSuccess,"RetryMessageSuccess(uint16,bytes,uint64,bytes32)",0xc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e5,false,,uint16 bytes uint64 bytes32,_srcChainId _srcAddress _nonce _payloadHash,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x2537f22e7b2d5d14e7f571fa67fcd846d73317f6,SetMinDstGas,"SetMinDstGas(uint16,uint16,uint256)",0x9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0,false,,uint16 uint16 uint256,_dstChainId _type _minDstGas,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x2537f22e7b2d5d14e7f571fa67fcd846d73317f6,SetPrecrime,SetPrecrime(address),0x5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b,false,,address,precrime,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x2537f22e7b2d5d14e7f571fa67fcd846d73317f6,SetTrustedRemote,"SetTrustedRemote(uint16,bytes)",0xfa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab,false,,uint16 bytes,_remoteChainId _path,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x2537f22e7b2d5d14e7f571fa67fcd846d73317f6,SetTrustedRemoteAddress,"SetTrustedRemoteAddress(uint16,bytes)",0x8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce,false,,uint16 bytes,_remoteChainId _remoteAddress,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x2537f22e7b2d5d14e7f571fa67fcd846d73317f6,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x7bdaf2fb332761b2a6a565a43ccb0acfc36d2c3d,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x7bdaf2fb332761b2a6a565a43ccb0acfc36d2c3d,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x7bdaf2fb332761b2a6a565a43ccb0acfc36d2c3d,BridgeRequest,"BridgeRequest(address,address,uint256,uint256,uint256,uint8,uint256)",0xabeeb7182c7294cd8efcd40e9ff952c1b759c2165b3634aac589429de5d55ad0,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to targetChainId normalizedAmount timestamp bridge id,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x7bdaf2fb332761b2a6a565a43ccb0acfc36d2c3d,ExecutedTransfer,"ExecutedTransfer(address,address,uint256,uint256,uint256,uint8,uint256)",0x6cf712ce908185c8c38a073b7315f79687e7440fb057d9d1ca76a2509a1282ee,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to normalizedAmount fee sourceChainId bridge id,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x7bdaf2fb332761b2a6a565a43ccb0acfc36d2c3d,FalseSender,"FalseSender(uint256,address)",0x1eafb58197ea0dc76b9278ccad47f61a239f00b017d89a19081a89321cce213d,false,,uint256 address,sourceChainId sourceAddress,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x7bdaf2fb332761b2a6a565a43ccb0acfc36d2c3d,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x7bdaf2fb332761b2a6a565a43ccb0acfc36d2c3d,MessageFailed,"MessageFailed(uint16,bytes,uint64,bytes,bytes)",0xe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c,false,,uint16 bytes uint64 bytes bytes,_srcChainId _srcAddress _nonce _payload _reason,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x7bdaf2fb332761b2a6a565a43ccb0acfc36d2c3d,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x7bdaf2fb332761b2a6a565a43ccb0acfc36d2c3d,RetryMessageSuccess,"RetryMessageSuccess(uint16,bytes,uint64,bytes32)",0xc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e5,false,,uint16 bytes uint64 bytes32,_srcChainId _srcAddress _nonce _payloadHash,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x7bdaf2fb332761b2a6a565a43ccb0acfc36d2c3d,SetMinDstGas,"SetMinDstGas(uint16,uint16,uint256)",0x9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0,false,,uint16 uint16 uint256,_dstChainId _type _minDstGas,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x7bdaf2fb332761b2a6a565a43ccb0acfc36d2c3d,SetPrecrime,SetPrecrime(address),0x5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b,false,,address,precrime,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x7bdaf2fb332761b2a6a565a43ccb0acfc36d2c3d,SetTrustedRemote,"SetTrustedRemote(uint16,bytes)",0xfa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab,false,,uint16 bytes,_remoteChainId _path,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x7bdaf2fb332761b2a6a565a43ccb0acfc36d2c3d,SetTrustedRemoteAddress,"SetTrustedRemoteAddress(uint16,bytes)",0x8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce,false,,uint16 bytes,_remoteChainId _remoteAddress,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x7bdaf2fb332761b2a6a565a43ccb0acfc36d2c3d,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xf3eab7018d74e7df95a5d8dc70987c0539bdf48f,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xf3eab7018d74e7df95a5d8dc70987c0539bdf48f,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xf3eab7018d74e7df95a5d8dc70987c0539bdf48f,BridgeRequest,"BridgeRequest(address,address,uint256,uint256,uint256,uint8,uint256)",0xabeeb7182c7294cd8efcd40e9ff952c1b759c2165b3634aac589429de5d55ad0,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to targetChainId normalizedAmount timestamp bridge id,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xf3eab7018d74e7df95a5d8dc70987c0539bdf48f,ExecutedTransfer,"ExecutedTransfer(address,address,uint256,uint256,uint256,uint8,uint256)",0x6cf712ce908185c8c38a073b7315f79687e7440fb057d9d1ca76a2509a1282ee,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to normalizedAmount fee sourceChainId bridge id,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xf3eab7018d74e7df95a5d8dc70987c0539bdf48f,FalseSender,"FalseSender(uint256,address)",0x1eafb58197ea0dc76b9278ccad47f61a239f00b017d89a19081a89321cce213d,false,,uint256 address,sourceChainId sourceAddress,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xf3eab7018d74e7df95a5d8dc70987c0539bdf48f,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xf3eab7018d74e7df95a5d8dc70987c0539bdf48f,MessageFailed,"MessageFailed(uint16,bytes,uint64,bytes,bytes)",0xe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c,false,,uint16 bytes uint64 bytes bytes,_srcChainId _srcAddress _nonce _payload _reason,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xf3eab7018d74e7df95a5d8dc70987c0539bdf48f,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xf3eab7018d74e7df95a5d8dc70987c0539bdf48f,RetryMessageSuccess,"RetryMessageSuccess(uint16,bytes,uint64,bytes32)",0xc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e5,false,,uint16 bytes uint64 bytes32,_srcChainId _srcAddress _nonce _payloadHash,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xf3eab7018d74e7df95a5d8dc70987c0539bdf48f,SetMinDstGas,"SetMinDstGas(uint16,uint16,uint256)",0x9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0,false,,uint16 uint16 uint256,_dstChainId _type _minDstGas,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xf3eab7018d74e7df95a5d8dc70987c0539bdf48f,SetPrecrime,SetPrecrime(address),0x5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b,false,,address,precrime,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xf3eab7018d74e7df95a5d8dc70987c0539bdf48f,SetTrustedRemote,"SetTrustedRemote(uint16,bytes)",0xfa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab,false,,uint16 bytes,_remoteChainId _path,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xf3eab7018d74e7df95a5d8dc70987c0539bdf48f,SetTrustedRemoteAddress,"SetTrustedRemoteAddress(uint16,bytes)",0x8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce,false,,uint16 bytes,_remoteChainId _remoteAddress,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xf3eab7018d74e7df95a5d8dc70987c0539bdf48f,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,7,0x3edd30a1cd94dd6d3329b5ebaff5aa4e0a4e4a55,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,7,0x3edd30a1cd94dd6d3329b5ebaff5aa4e0a4e4a55,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,7,0x3edd30a1cd94dd6d3329b5ebaff5aa4e0a4e4a55,BridgeRequest,"BridgeRequest(address,address,uint256,uint256,uint256,uint8,uint256)",0xabeeb7182c7294cd8efcd40e9ff952c1b759c2165b3634aac589429de5d55ad0,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to targetChainId normalizedAmount timestamp bridge id,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,7,0x3edd30a1cd94dd6d3329b5ebaff5aa4e0a4e4a55,ExecutedTransfer,"ExecutedTransfer(address,address,uint256,uint256,uint256,uint8,uint256)",0x6cf712ce908185c8c38a073b7315f79687e7440fb057d9d1ca76a2509a1282ee,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to normalizedAmount fee sourceChainId bridge id,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,7,0x3edd30a1cd94dd6d3329b5ebaff5aa4e0a4e4a55,FalseSender,"FalseSender(uint256,address)",0x1eafb58197ea0dc76b9278ccad47f61a239f00b017d89a19081a89321cce213d,false,,uint256 address,sourceChainId sourceAddress,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,7,0x3edd30a1cd94dd6d3329b5ebaff5aa4e0a4e4a55,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,7,0x3edd30a1cd94dd6d3329b5ebaff5aa4e0a4e4a55,MessageFailed,"MessageFailed(uint16,bytes,uint64,bytes,bytes)",0xe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c,false,,uint16 bytes uint64 bytes bytes,_srcChainId _srcAddress _nonce _payload _reason,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,7,0x3edd30a1cd94dd6d3329b5ebaff5aa4e0a4e4a55,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,7,0x3edd30a1cd94dd6d3329b5ebaff5aa4e0a4e4a55,RetryMessageSuccess,"RetryMessageSuccess(uint16,bytes,uint64,bytes32)",0xc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e5,false,,uint16 bytes uint64 bytes32,_srcChainId _srcAddress _nonce _payloadHash,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,7,0x3edd30a1cd94dd6d3329b5ebaff5aa4e0a4e4a55,SetMinDstGas,"SetMinDstGas(uint16,uint16,uint256)",0x9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0,false,,uint16 uint16 uint256,_dstChainId _type _minDstGas,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,7,0x3edd30a1cd94dd6d3329b5ebaff5aa4e0a4e4a55,SetPrecrime,SetPrecrime(address),0x5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b,false,,address,precrime,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,7,0x3edd30a1cd94dd6d3329b5ebaff5aa4e0a4e4a55,SetTrustedRemote,"SetTrustedRemote(uint16,bytes)",0xfa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab,false,,uint16 bytes,_remoteChainId _path,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,7,0x3edd30a1cd94dd6d3329b5ebaff5aa4e0a4e4a55,SetTrustedRemoteAddress,"SetTrustedRemoteAddress(uint16,bytes)",0x8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce,false,,uint16 bytes,_remoteChainId _remoteAddress,true,21473546,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7 of 7" +CELO,42220,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,7,0x3edd30a1cd94dd6d3329b5ebaff5aa4e0a4e4a55,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MultichainRouter,0xf27ee99622c3c9b264583dacb2cce056e194494f,1,0xf27ee99622c3c9b264583dacb2cce056e194494f,LogAnySwapIn,"LogAnySwapIn(bytes32,address,address,uint256,uint256,uint256)",0xaac9ce45fe3adf5143598c4f18a369591a20a3384aedaf1b525d29127e1fcd55,false,0 1 2,bytes32 address address uint256 uint256 uint256,txhash token to amount fromChainID toChainID,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MultichainRouter,0xf27ee99622c3c9b264583dacb2cce056e194494f,1,0xf27ee99622c3c9b264583dacb2cce056e194494f,LogAnySwapOut,"LogAnySwapOut(address,address,address,uint256,uint256,uint256)",0x97116cf6cd4f6412bb47914d6db18da9e16ab2142f543b86e207c24fbd16b23a,false,0 1 2,address address address uint256 uint256 uint256,token from to amount fromChainID toChainID,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MultichainRouter,0xf27ee99622c3c9b264583dacb2cce056e194494f,1,0xf27ee99622c3c9b264583dacb2cce056e194494f,LogAnySwapTradeTokensForNative,"LogAnySwapTradeTokensForNative(address[],address,address,uint256,uint256,uint256,uint256)",0x278277e0209c347189add7bd92411973b5f6b8644f7ac62ea1be984ce993f8f4,false,1 2,address[] address address uint256 uint256 uint256 uint256,path from to amountIn amountOutMin fromChainID toChainID,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MultichainRouter,0xf27ee99622c3c9b264583dacb2cce056e194494f,1,0xf27ee99622c3c9b264583dacb2cce056e194494f,LogAnySwapTradeTokensForTokens,"LogAnySwapTradeTokensForTokens(address[],address,address,uint256,uint256,uint256,uint256)",0xfea6abdf4fd32f20966dff7619354cd82cd43dc78a3bee479f04c74dbfc585b3,false,1 2,address[] address address uint256 uint256 uint256 uint256,path from to amountIn amountOutMin fromChainID toChainID,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MultichainRouter,0xf27ee99622c3c9b264583dacb2cce056e194494f,1,0xf27ee99622c3c9b264583dacb2cce056e194494f,LogChangeMPC,"LogChangeMPC(address,address,uint256,uint256)",0xcda32bc39904597666dfa9f9c845714756e1ffffad55b52e0d344673a2198121,false,0 1 2,address address uint256 uint256,oldMPC newMPC effectiveTime chainID,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,MultichainRouter,0xf27ee99622c3c9b264583dacb2cce056e194494f,1,0xf27ee99622c3c9b264583dacb2cce056e194494f,LogChangeRouter,"LogChangeRouter(address,address,uint256)",0x7eefe162042d50d604dca716bef4ff4c5e318a056f712c0195d016f78089955a,false,0 1,address address uint256,oldRouter newRouter chainID,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,NameService,0x0f5db7a64a6a64052693676ca898ec7f7a94ff4e,1,0xed9c5987e7109bb43a8a1a40a726b275e4eb4ace,AddressChanged,"AddressChanged(string,address)",0x135cf55549d8538a41f19f46cc85625da93e68b63484cca8fcb9aaf19e520137,false,,string address,name addr,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,NameService,0x0f5db7a64a6a64052693676ca898ec7f7a94ff4e,1,0xed9c5987e7109bb43a8a1a40a726b275e4eb4ace,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,NameService,0x0f5db7a64a6a64052693676ca898ec7f7a94ff4e,1,0xed9c5987e7109bb43a8a1a40a726b275e4eb4ace,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,NameService,0x0f5db7a64a6a64052693676ca898ec7f7a94ff4e,1,0xed9c5987e7109bb43a8a1a40a726b275e4eb4ace,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,NameService,0x0f5db7a64a6a64052693676ca898ec7f7a94ff4e,1,0xed9c5987e7109bb43a8a1a40a726b275e4eb4ace,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,OneTimePayments,0xb27d247f5c2a61d2cb6b6e67fee51d839447e97d,1,0xb27d247f5c2a61d2cb6b6e67fee51d839447e97d,PaymentCancel,"PaymentCancel(address,address,uint256)",0xb1f6a8f6b8fb527cfeec0df589160bc2a92ff715097117cb250e823c7106bc2f,false,0,address address uint256,from paymentId amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,OneTimePayments,0xb27d247f5c2a61d2cb6b6e67fee51d839447e97d,1,0xb27d247f5c2a61d2cb6b6e67fee51d839447e97d,PaymentDeposit,"PaymentDeposit(address,address,uint256)",0x6c9f23ee41b34196a6e871314d55c3a0cce3399afc5d09755d171ea06547e073,false,0,address address uint256,from paymentId amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,OneTimePayments,0xb27d247f5c2a61d2cb6b6e67fee51d839447e97d,1,0xb27d247f5c2a61d2cb6b6e67fee51d839447e97d,PaymentWithdraw,"PaymentWithdraw(address,address,address,uint256)",0x39ca68a9f5d8038e871ef25a6622a56579cda4a6eedf63813574d23652e94048,false,0 1 2,address address address uint256,from to paymentId amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV2,0x25878951ae130014e827e6f54fd3b4cca057a7e8,1,0x25878951ae130014e827e6f54fd3b4cca057a7e8,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV2,0x25878951ae130014e827e6f54fd3b4cca057a7e8,1,0x25878951ae130014e827e6f54fd3b4cca057a7e8,Burn,"Burn(address,uint256,uint256,address)",0xdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496,false,0 3,address uint256 uint256 address,sender amount0 amount1 to,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV2,0x25878951ae130014e827e6f54fd3b4cca057a7e8,1,0x25878951ae130014e827e6f54fd3b4cca057a7e8,Mint,"Mint(address,uint256,uint256)",0x4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f,false,0,address uint256 uint256,sender amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV2,0x25878951ae130014e827e6f54fd3b4cca057a7e8,1,0x25878951ae130014e827e6f54fd3b4cca057a7e8,Swap,"Swap(address,uint256,uint256,uint256,uint256,address)",0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822,false,0 5,address uint256 uint256 uint256 uint256 address,sender amount0In amount1In amount0Out amount1Out to,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV2,0x25878951ae130014e827e6f54fd3b4cca057a7e8,1,0x25878951ae130014e827e6f54fd3b4cca057a7e8,Sync,"Sync(uint112,uint112)",0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1,false,,uint112 uint112,reserve0 reserve1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV2,0x25878951ae130014e827e6f54fd3b4cca057a7e8,1,0x25878951ae130014e827e6f54fd3b4cca057a7e8,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV3Hi,0xcb037f27eb3952222810966e28e0ceb650c65cd9,1,0xcb037f27eb3952222810966e28e0ceb650c65cd9,Burn,"Burn(address,int24,int24,uint128,uint256,uint256)",0x0c396cd989a39f4459b5fa1aed6a9a8dcdbc45908acfd67e028cd568da98982c,false,0 1 2,address int24 int24 uint128 uint256 uint256,owner tickLower tickUpper amount amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV3Hi,0xcb037f27eb3952222810966e28e0ceb650c65cd9,1,0xcb037f27eb3952222810966e28e0ceb650c65cd9,Collect,"Collect(address,address,int24,int24,uint128,uint128)",0x70935338e69775456a85ddef226c395fb668b63fa0115f5f20610b388e6ca9c0,false,0 2 3,address address int24 int24 uint128 uint128,owner recipient tickLower tickUpper amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV3Hi,0xcb037f27eb3952222810966e28e0ceb650c65cd9,1,0xcb037f27eb3952222810966e28e0ceb650c65cd9,CollectProtocol,"CollectProtocol(address,address,uint128,uint128)",0x596b573906218d3411850b26a6b437d6c4522fdb43d2d2386263f86d50b8b151,false,0 1,address address uint128 uint128,sender recipient amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV3Hi,0xcb037f27eb3952222810966e28e0ceb650c65cd9,1,0xcb037f27eb3952222810966e28e0ceb650c65cd9,Flash,"Flash(address,address,uint256,uint256,uint256,uint256)",0xbdbdb71d7860376ba52b25a5028beea23581364a40522f6bcfb86bb1f2dca633,false,0 1,address address uint256 uint256 uint256 uint256,sender recipient amount0 amount1 paid0 paid1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV3Hi,0xcb037f27eb3952222810966e28e0ceb650c65cd9,1,0xcb037f27eb3952222810966e28e0ceb650c65cd9,IncreaseObservationCardinalityNext,"IncreaseObservationCardinalityNext(uint16,uint16)",0xac49e518f90a358f652e4400164f05a5d8f7e35e7747279bc3a93dbf584e125a,false,,uint16 uint16,observationCardinalityNextOld observationCardinalityNextNew,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV3Hi,0xcb037f27eb3952222810966e28e0ceb650c65cd9,1,0xcb037f27eb3952222810966e28e0ceb650c65cd9,Initialize,"Initialize(uint160,int24)",0x98636036cb66a9c19a37435efc1e90142190214e8abeb821bdba3f2990dd4c95,false,,uint160 int24,sqrtPriceX96 tick,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV3Hi,0xcb037f27eb3952222810966e28e0ceb650c65cd9,1,0xcb037f27eb3952222810966e28e0ceb650c65cd9,Mint,"Mint(address,address,int24,int24,uint128,uint256,uint256)",0x7a53080ba414158be7ec69b987b5fb7d07dee101fe85488f0853ae16239d0bde,false,1 2 3,address address int24 int24 uint128 uint256 uint256,sender owner tickLower tickUpper amount amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV3Hi,0xcb037f27eb3952222810966e28e0ceb650c65cd9,1,0xcb037f27eb3952222810966e28e0ceb650c65cd9,SetFeeProtocol,"SetFeeProtocol(uint8,uint8,uint8,uint8)",0x973d8d92bb299f4af6ce49b52a8adb85ae46b9f214c4c4fc06ac77401237b133,false,,uint8 uint8 uint8 uint8,feeProtocol0Old feeProtocol1Old feeProtocol0New feeProtocol1New,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV3Hi,0xcb037f27eb3952222810966e28e0ceb650c65cd9,1,0xcb037f27eb3952222810966e28e0ceb650c65cd9,Swap,"Swap(address,address,int256,int256,uint160,uint128,int24)",0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67,false,0 1,address address int256 int256 uint160 uint128 int24,sender recipient amount0 amount1 sqrtPriceX96 liquidity tick,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV3Mid,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,1,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,Burn,"Burn(address,int24,int24,uint128,uint256,uint256)",0x0c396cd989a39f4459b5fa1aed6a9a8dcdbc45908acfd67e028cd568da98982c,false,0 1 2,address int24 int24 uint128 uint256 uint256,owner tickLower tickUpper amount amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV3Mid,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,1,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,Collect,"Collect(address,address,int24,int24,uint128,uint128)",0x70935338e69775456a85ddef226c395fb668b63fa0115f5f20610b388e6ca9c0,false,0 2 3,address address int24 int24 uint128 uint128,owner recipient tickLower tickUpper amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV3Mid,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,1,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,CollectProtocol,"CollectProtocol(address,address,uint128,uint128)",0x596b573906218d3411850b26a6b437d6c4522fdb43d2d2386263f86d50b8b151,false,0 1,address address uint128 uint128,sender recipient amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV3Mid,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,1,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,Flash,"Flash(address,address,uint256,uint256,uint256,uint256)",0xbdbdb71d7860376ba52b25a5028beea23581364a40522f6bcfb86bb1f2dca633,false,0 1,address address uint256 uint256 uint256 uint256,sender recipient amount0 amount1 paid0 paid1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV3Mid,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,1,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,IncreaseObservationCardinalityNext,"IncreaseObservationCardinalityNext(uint16,uint16)",0xac49e518f90a358f652e4400164f05a5d8f7e35e7747279bc3a93dbf584e125a,false,,uint16 uint16,observationCardinalityNextOld observationCardinalityNextNew,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV3Mid,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,1,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,Initialize,"Initialize(uint160,int24)",0x98636036cb66a9c19a37435efc1e90142190214e8abeb821bdba3f2990dd4c95,false,,uint160 int24,sqrtPriceX96 tick,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV3Mid,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,1,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,Mint,"Mint(address,address,int24,int24,uint128,uint256,uint256)",0x7a53080ba414158be7ec69b987b5fb7d07dee101fe85488f0853ae16239d0bde,false,1 2 3,address address int24 int24 uint128 uint256 uint256,sender owner tickLower tickUpper amount amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV3Mid,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,1,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,SetFeeProtocol,"SetFeeProtocol(uint8,uint8,uint8,uint8)",0x973d8d92bb299f4af6ce49b52a8adb85ae46b9f214c4c4fc06ac77401237b133,false,,uint8 uint8 uint8 uint8,feeProtocol0Old feeProtocol1Old feeProtocol0New feeProtocol1New,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdCeloV3Mid,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,1,0x8b393470bef8bb27a9a5169531b4eba5209b0b26,Swap,"Swap(address,address,int256,int256,uint160,uint128,int24)",0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67,false,0 1,address address int256 int256 uint160 uint128 int24,sender recipient amount0 amount1 sqrtPriceX96 liquidity tick,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdMcusdV2,0x07f86b39728be613062bc7413fc2ca7293eef022,1,0x07f86b39728be613062bc7413fc2ca7293eef022,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdMcusdV2,0x07f86b39728be613062bc7413fc2ca7293eef022,1,0x07f86b39728be613062bc7413fc2ca7293eef022,Burn,"Burn(address,uint256,uint256,address)",0xdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496,false,0 3,address uint256 uint256 address,sender amount0 amount1 to,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdMcusdV2,0x07f86b39728be613062bc7413fc2ca7293eef022,1,0x07f86b39728be613062bc7413fc2ca7293eef022,Mint,"Mint(address,uint256,uint256)",0x4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f,false,0,address uint256 uint256,sender amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdMcusdV2,0x07f86b39728be613062bc7413fc2ca7293eef022,1,0x07f86b39728be613062bc7413fc2ca7293eef022,Swap,"Swap(address,uint256,uint256,uint256,uint256,address)",0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822,false,0 5,address uint256 uint256 uint256 uint256 address,sender amount0In amount1In amount0Out amount1Out to,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdMcusdV2,0x07f86b39728be613062bc7413fc2ca7293eef022,1,0x07f86b39728be613062bc7413fc2ca7293eef022,Sync,"Sync(uint112,uint112)",0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1,false,,uint112 uint112,reserve0 reserve1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdMcusdV2,0x07f86b39728be613062bc7413fc2ca7293eef022,1,0x07f86b39728be613062bc7413fc2ca7293eef022,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Hi,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,1,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,Burn,"Burn(address,int24,int24,uint128,uint256,uint256)",0x0c396cd989a39f4459b5fa1aed6a9a8dcdbc45908acfd67e028cd568da98982c,false,0 1 2,address int24 int24 uint128 uint256 uint256,owner tickLower tickUpper amount amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Hi,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,1,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,Collect,"Collect(address,address,int24,int24,uint128,uint128)",0x70935338e69775456a85ddef226c395fb668b63fa0115f5f20610b388e6ca9c0,false,0 2 3,address address int24 int24 uint128 uint128,owner recipient tickLower tickUpper amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Hi,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,1,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,CollectProtocol,"CollectProtocol(address,address,uint128,uint128)",0x596b573906218d3411850b26a6b437d6c4522fdb43d2d2386263f86d50b8b151,false,0 1,address address uint128 uint128,sender recipient amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Hi,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,1,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,Flash,"Flash(address,address,uint256,uint256,uint256,uint256)",0xbdbdb71d7860376ba52b25a5028beea23581364a40522f6bcfb86bb1f2dca633,false,0 1,address address uint256 uint256 uint256 uint256,sender recipient amount0 amount1 paid0 paid1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Hi,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,1,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,IncreaseObservationCardinalityNext,"IncreaseObservationCardinalityNext(uint16,uint16)",0xac49e518f90a358f652e4400164f05a5d8f7e35e7747279bc3a93dbf584e125a,false,,uint16 uint16,observationCardinalityNextOld observationCardinalityNextNew,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Hi,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,1,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,Initialize,"Initialize(uint160,int24)",0x98636036cb66a9c19a37435efc1e90142190214e8abeb821bdba3f2990dd4c95,false,,uint160 int24,sqrtPriceX96 tick,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Hi,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,1,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,Mint,"Mint(address,address,int24,int24,uint128,uint256,uint256)",0x7a53080ba414158be7ec69b987b5fb7d07dee101fe85488f0853ae16239d0bde,false,1 2 3,address address int24 int24 uint128 uint256 uint256,sender owner tickLower tickUpper amount amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Hi,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,1,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,SetFeeProtocol,"SetFeeProtocol(uint8,uint8,uint8,uint8)",0x973d8d92bb299f4af6ce49b52a8adb85ae46b9f214c4c4fc06ac77401237b133,false,,uint8 uint8 uint8 uint8,feeProtocol0Old feeProtocol1Old feeProtocol0New feeProtocol1New,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Hi,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,1,0x3d9e27c04076288ebfdc4815b4f6d81b0ed1b341,Swap,"Swap(address,address,int256,int256,uint160,uint128,int24)",0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67,false,0 1,address address int256 int256 uint160 uint128 int24,sender recipient amount0 amount1 sqrtPriceX96 liquidity tick,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Hi2,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,1,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,Burn,"Burn(address,int24,int24,uint128,uint256,uint256)",0x0c396cd989a39f4459b5fa1aed6a9a8dcdbc45908acfd67e028cd568da98982c,false,0 1 2,address int24 int24 uint128 uint256 uint256,owner tickLower tickUpper amount amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Hi2,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,1,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,Collect,"Collect(address,address,int24,int24,uint128,uint128)",0x70935338e69775456a85ddef226c395fb668b63fa0115f5f20610b388e6ca9c0,false,0 2 3,address address int24 int24 uint128 uint128,owner recipient tickLower tickUpper amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Hi2,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,1,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,CollectProtocol,"CollectProtocol(address,address,uint128,uint128)",0x596b573906218d3411850b26a6b437d6c4522fdb43d2d2386263f86d50b8b151,false,0 1,address address uint128 uint128,sender recipient amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Hi2,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,1,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,Flash,"Flash(address,address,uint256,uint256,uint256,uint256)",0xbdbdb71d7860376ba52b25a5028beea23581364a40522f6bcfb86bb1f2dca633,false,0 1,address address uint256 uint256 uint256 uint256,sender recipient amount0 amount1 paid0 paid1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Hi2,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,1,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,IncreaseObservationCardinalityNext,"IncreaseObservationCardinalityNext(uint16,uint16)",0xac49e518f90a358f652e4400164f05a5d8f7e35e7747279bc3a93dbf584e125a,false,,uint16 uint16,observationCardinalityNextOld observationCardinalityNextNew,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Hi2,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,1,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,Initialize,"Initialize(uint160,int24)",0x98636036cb66a9c19a37435efc1e90142190214e8abeb821bdba3f2990dd4c95,false,,uint160 int24,sqrtPriceX96 tick,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Hi2,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,1,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,Mint,"Mint(address,address,int24,int24,uint128,uint256,uint256)",0x7a53080ba414158be7ec69b987b5fb7d07dee101fe85488f0853ae16239d0bde,false,1 2 3,address address int24 int24 uint128 uint256 uint256,sender owner tickLower tickUpper amount amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Hi2,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,1,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,SetFeeProtocol,"SetFeeProtocol(uint8,uint8,uint8,uint8)",0x973d8d92bb299f4af6ce49b52a8adb85ae46b9f214c4c4fc06ac77401237b133,false,,uint8 uint8 uint8 uint8,feeProtocol0Old feeProtocol1Old feeProtocol0New feeProtocol1New,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Hi2,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,1,0x0dbb0769b00d01d241ba4f7b2891fb5c2a975d51,Swap,"Swap(address,address,int256,int256,uint160,uint128,int24)",0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67,false,0 1,address address int256 int256 uint160 uint128 int24,sender recipient amount0 amount1 sqrtPriceX96 liquidity tick,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Low,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,1,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,Burn,"Burn(address,int24,int24,uint128,uint256,uint256)",0x0c396cd989a39f4459b5fa1aed6a9a8dcdbc45908acfd67e028cd568da98982c,false,0 1 2,address int24 int24 uint128 uint256 uint256,owner tickLower tickUpper amount amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Low,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,1,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,Collect,"Collect(address,address,int24,int24,uint128,uint128)",0x70935338e69775456a85ddef226c395fb668b63fa0115f5f20610b388e6ca9c0,false,0 2 3,address address int24 int24 uint128 uint128,owner recipient tickLower tickUpper amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Low,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,1,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,CollectProtocol,"CollectProtocol(address,address,uint128,uint128)",0x596b573906218d3411850b26a6b437d6c4522fdb43d2d2386263f86d50b8b151,false,0 1,address address uint128 uint128,sender recipient amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Low,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,1,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,Flash,"Flash(address,address,uint256,uint256,uint256,uint256)",0xbdbdb71d7860376ba52b25a5028beea23581364a40522f6bcfb86bb1f2dca633,false,0 1,address address uint256 uint256 uint256 uint256,sender recipient amount0 amount1 paid0 paid1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Low,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,1,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,IncreaseObservationCardinalityNext,"IncreaseObservationCardinalityNext(uint16,uint16)",0xac49e518f90a358f652e4400164f05a5d8f7e35e7747279bc3a93dbf584e125a,false,,uint16 uint16,observationCardinalityNextOld observationCardinalityNextNew,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Low,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,1,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,Initialize,"Initialize(uint160,int24)",0x98636036cb66a9c19a37435efc1e90142190214e8abeb821bdba3f2990dd4c95,false,,uint160 int24,sqrtPriceX96 tick,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Low,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,1,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,Mint,"Mint(address,address,int24,int24,uint128,uint256,uint256)",0x7a53080ba414158be7ec69b987b5fb7d07dee101fe85488f0853ae16239d0bde,false,1 2 3,address address int24 int24 uint128 uint256 uint256,sender owner tickLower tickUpper amount amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Low,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,1,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,SetFeeProtocol,"SetFeeProtocol(uint8,uint8,uint8,uint8)",0x973d8d92bb299f4af6ce49b52a8adb85ae46b9f214c4c4fc06ac77401237b133,false,,uint8 uint8 uint8 uint8,feeProtocol0Old feeProtocol1Old feeProtocol0New feeProtocol1New,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdgloV3Low,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,1,0x991f1aa7e0901f9ab3d583846bf5be0ebace1d7f,Swap,"Swap(address,address,int256,int256,uint160,uint128,int24)",0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67,false,0 1,address address int256 int256 uint160 uint128 int24,sender recipient amount0 amount1 sqrtPriceX96 liquidity tick,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdmV3,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,1,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,Burn,"Burn(address,int24,int24,uint128,uint256,uint256)",0x0c396cd989a39f4459b5fa1aed6a9a8dcdbc45908acfd67e028cd568da98982c,false,0 1 2,address int24 int24 uint128 uint256 uint256,owner tickLower tickUpper amount amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdmV3,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,1,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,Collect,"Collect(address,address,int24,int24,uint128,uint128)",0x70935338e69775456a85ddef226c395fb668b63fa0115f5f20610b388e6ca9c0,false,0 2 3,address address int24 int24 uint128 uint128,owner recipient tickLower tickUpper amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdmV3,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,1,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,CollectProtocol,"CollectProtocol(address,address,uint128,uint128)",0x596b573906218d3411850b26a6b437d6c4522fdb43d2d2386263f86d50b8b151,false,0 1,address address uint128 uint128,sender recipient amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdmV3,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,1,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,Flash,"Flash(address,address,uint256,uint256,uint256,uint256)",0xbdbdb71d7860376ba52b25a5028beea23581364a40522f6bcfb86bb1f2dca633,false,0 1,address address uint256 uint256 uint256 uint256,sender recipient amount0 amount1 paid0 paid1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdmV3,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,1,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,IncreaseObservationCardinalityNext,"IncreaseObservationCardinalityNext(uint16,uint16)",0xac49e518f90a358f652e4400164f05a5d8f7e35e7747279bc3a93dbf584e125a,false,,uint16 uint16,observationCardinalityNextOld observationCardinalityNextNew,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdmV3,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,1,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,Initialize,"Initialize(uint160,int24)",0x98636036cb66a9c19a37435efc1e90142190214e8abeb821bdba3f2990dd4c95,false,,uint160 int24,sqrtPriceX96 tick,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdmV3,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,1,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,Mint,"Mint(address,address,int24,int24,uint128,uint256,uint256)",0x7a53080ba414158be7ec69b987b5fb7d07dee101fe85488f0853ae16239d0bde,false,1 2 3,address address int24 int24 uint128 uint256 uint256,sender owner tickLower tickUpper amount amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdmV3,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,1,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,SetFeeProtocol,"SetFeeProtocol(uint8,uint8,uint8,uint8)",0x973d8d92bb299f4af6ce49b52a8adb85ae46b9f214c4c4fc06ac77401237b133,false,,uint8 uint8 uint8 uint8,feeProtocol0Old feeProtocol1Old feeProtocol0New feeProtocol1New,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,PoolGdUsdmV3,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,1,0x9491d57c5687ab75726423b55ac2d87d1cda2c3f,Swap,"Swap(address,address,int256,int256,uint160,uint128,int24)",0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67,false,0 1,address address int256 int256 uint160 uint128 int24,sender recipient amount0 amount1 sqrtPriceX96 liquidity tick,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,ProxyFactory,0xd86cd6bb3c2a576b2c2cef4e047b1a7adc5be62d,1,0xd86cd6bb3c2a576b2c2cef4e047b1a7adc5be62d,ContractCreated,ContractCreated(address),0xcf78cf0d6f3d8371e1075c69c492ab4ec5d8cf23a1a239b6a51a1d00be7ca312,false,,address,addr,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,ProxyFactory,0xd86cd6bb3c2a576b2c2cef4e047b1a7adc5be62d,1,0xd86cd6bb3c2a576b2c2cef4e047b1a7adc5be62d,ProxyCreated,ProxyCreated(address),0x00fffc2da0b561cae30d9826d37709e9421c4725faebc226cbbb7ef5fc5e7349,false,,address,proxy,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,StaticOracle,0x00851a91a3c4e9a4c1b48df827bacc1f884bde28,1,0x00851a91a3c4e9a4c1b48df827bacc1f884bde28,OracleCreated,OracleCreated(address),0x5dba83b2e4f5ef7ead6ae8f4902f5335ce28561a5207952f0b0a9d9f3a01a1b7,false,,address,oracle,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,1,0x25cc912cc038f1791734f39ceb4d8bffb32c7c61,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,1,0x25cc912cc038f1791734f39ceb4d8bffb32c7c61,FlowOperatorUpdated,"FlowOperatorUpdated(address,address,address,uint8,int96)",0xc0d5d3a6ac18cc1769788c925e6e7fc89cd47e4270a42884736fa9b3ec09f3a8,false,0 1 2,address address address uint8 int96,token sender flowOperator permissions flowRateAllowance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,1,0x25cc912cc038f1791734f39ceb4d8bffb32c7c61,FlowUpdated,"FlowUpdated(address,address,address,int96,int256,int256,bytes)",0x57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e,false,0 1 2,address address address int96 int256 int256 bytes,token sender receiver flowRate totalSenderFlowRate totalReceiverFlowRate userData,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,1,0x25cc912cc038f1791734f39ceb4d8bffb32c7c61,FlowUpdatedExtension,"FlowUpdatedExtension(address,uint256)",0x71e0c98e270fc3084227b473f176924d5303ece8c639e679998a2d7dc8e70f74,false,0,address uint256,flowOperator deposit,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,1,0x25cc912cc038f1791734f39ceb4d8bffb32c7c61,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,2,0xe40983c2476032a0915600b9472b3141aa5b5ba9,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,2,0xe40983c2476032a0915600b9472b3141aa5b5ba9,FlowOperatorUpdated,"FlowOperatorUpdated(address,address,address,uint8,int96)",0xc0d5d3a6ac18cc1769788c925e6e7fc89cd47e4270a42884736fa9b3ec09f3a8,false,0 1 2,address address address uint8 int96,token sender flowOperator permissions flowRateAllowance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,2,0xe40983c2476032a0915600b9472b3141aa5b5ba9,FlowUpdated,"FlowUpdated(address,address,address,int96,int256,int256,bytes)",0x57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e,false,0 1 2,address address address int96 int256 int256 bytes,token sender receiver flowRate totalSenderFlowRate totalReceiverFlowRate userData,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,2,0xe40983c2476032a0915600b9472b3141aa5b5ba9,FlowUpdatedExtension,"FlowUpdatedExtension(address,uint256)",0x71e0c98e270fc3084227b473f176924d5303ece8c639e679998a2d7dc8e70f74,false,0,address uint256,flowOperator deposit,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,2,0xe40983c2476032a0915600b9472b3141aa5b5ba9,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,3,0x5f001c3915084186b9109fb9dc1e978c98f854b0,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,3,0x5f001c3915084186b9109fb9dc1e978c98f854b0,FlowOperatorUpdated,"FlowOperatorUpdated(address,address,address,uint8,int96)",0xc0d5d3a6ac18cc1769788c925e6e7fc89cd47e4270a42884736fa9b3ec09f3a8,false,0 1 2,address address address uint8 int96,token sender flowOperator permissions flowRateAllowance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,3,0x5f001c3915084186b9109fb9dc1e978c98f854b0,FlowUpdated,"FlowUpdated(address,address,address,int96,int256,int256,bytes)",0x57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e,false,0 1 2,address address address int96 int256 int256 bytes,token sender receiver flowRate totalSenderFlowRate totalReceiverFlowRate userData,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,3,0x5f001c3915084186b9109fb9dc1e978c98f854b0,FlowUpdatedExtension,"FlowUpdatedExtension(address,uint256)",0x71e0c98e270fc3084227b473f176924d5303ece8c639e679998a2d7dc8e70f74,false,0,address uint256,flowOperator deposit,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,3,0x5f001c3915084186b9109fb9dc1e978c98f854b0,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,4,0x9f9eed9bbc38e9e0514fd9dfcc0bca9869a9c534,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,4,0x9f9eed9bbc38e9e0514fd9dfcc0bca9869a9c534,FlowOperatorUpdated,"FlowOperatorUpdated(address,address,address,uint8,int96)",0xc0d5d3a6ac18cc1769788c925e6e7fc89cd47e4270a42884736fa9b3ec09f3a8,false,0 1 2,address address address uint8 int96,token sender flowOperator permissions flowRateAllowance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,4,0x9f9eed9bbc38e9e0514fd9dfcc0bca9869a9c534,FlowUpdated,"FlowUpdated(address,address,address,int96,int256,int256,bytes)",0x57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e,false,0 1 2,address address address int96 int256 int256 bytes,token sender receiver flowRate totalSenderFlowRate totalReceiverFlowRate userData,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,4,0x9f9eed9bbc38e9e0514fd9dfcc0bca9869a9c534,FlowUpdatedExtension,"FlowUpdatedExtension(address,uint256)",0x71e0c98e270fc3084227b473f176924d5303ece8c639e679998a2d7dc8e70f74,false,0,address uint256,flowOperator deposit,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,4,0x9f9eed9bbc38e9e0514fd9dfcc0bca9869a9c534,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,5,0x4247ba6c3658fa5c0f523bacea8d0b97af1a175e,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,5,0x4247ba6c3658fa5c0f523bacea8d0b97af1a175e,FlowOperatorUpdated,"FlowOperatorUpdated(address,address,address,uint8,int96)",0xc0d5d3a6ac18cc1769788c925e6e7fc89cd47e4270a42884736fa9b3ec09f3a8,false,0 1 2,address address address uint8 int96,token sender flowOperator permissions flowRateAllowance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,5,0x4247ba6c3658fa5c0f523bacea8d0b97af1a175e,FlowUpdated,"FlowUpdated(address,address,address,int96,int256,int256,bytes)",0x57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e,false,0 1 2,address address address int96 int256 int256 bytes,token sender receiver flowRate totalSenderFlowRate totalReceiverFlowRate userData,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,5,0x4247ba6c3658fa5c0f523bacea8d0b97af1a175e,FlowUpdatedExtension,"FlowUpdatedExtension(address,uint256)",0x71e0c98e270fc3084227b473f176924d5303ece8c639e679998a2d7dc8e70f74,false,0,address uint256,flowOperator deposit,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,5,0x4247ba6c3658fa5c0f523bacea8d0b97af1a175e,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,6,0xdf3f4b9e4e67a21c868d043a92ae921ff0ebadbb,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,6,0xdf3f4b9e4e67a21c868d043a92ae921ff0ebadbb,FlowOperatorUpdated,"FlowOperatorUpdated(address,address,address,uint8,int96)",0xc0d5d3a6ac18cc1769788c925e6e7fc89cd47e4270a42884736fa9b3ec09f3a8,false,0 1 2,address address address uint8 int96,token sender flowOperator permissions flowRateAllowance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,6,0xdf3f4b9e4e67a21c868d043a92ae921ff0ebadbb,FlowUpdated,"FlowUpdated(address,address,address,int96,int256,int256,bytes)",0x57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e,false,0 1 2,address address address int96 int256 int256 bytes,token sender receiver flowRate totalSenderFlowRate totalReceiverFlowRate userData,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,6,0xdf3f4b9e4e67a21c868d043a92ae921ff0ebadbb,FlowUpdatedExtension,"FlowUpdatedExtension(address,uint256)",0x71e0c98e270fc3084227b473f176924d5303ece8c639e679998a2d7dc8e70f74,false,0,address uint256,flowOperator deposit,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,6,0xdf3f4b9e4e67a21c868d043a92ae921ff0ebadbb,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,7,0xe3f6ec0676b9ce5d759580e1d526dee31678c283,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,7,0xe3f6ec0676b9ce5d759580e1d526dee31678c283,FlowOperatorUpdated,"FlowOperatorUpdated(address,address,address,uint8,int96)",0xc0d5d3a6ac18cc1769788c925e6e7fc89cd47e4270a42884736fa9b3ec09f3a8,false,0 1 2,address address address uint8 int96,token sender flowOperator permissions flowRateAllowance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,7,0xe3f6ec0676b9ce5d759580e1d526dee31678c283,FlowUpdated,"FlowUpdated(address,address,address,int96,int256,int256,bytes)",0x57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e,false,0 1 2,address address address int96 int256 int256 bytes,token sender receiver flowRate totalSenderFlowRate totalReceiverFlowRate userData,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,7,0xe3f6ec0676b9ce5d759580e1d526dee31678c283,FlowUpdatedExtension,"FlowUpdatedExtension(address,uint256)",0x71e0c98e270fc3084227b473f176924d5303ece8c639e679998a2d7dc8e70f74,false,0,address uint256,flowOperator deposit,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,7,0xe3f6ec0676b9ce5d759580e1d526dee31678c283,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,8,0x247f65bd849d686147330978aa7521457c5a83bf,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,8,0x247f65bd849d686147330978aa7521457c5a83bf,FlowOperatorUpdated,"FlowOperatorUpdated(address,address,address,uint8,int96)",0xc0d5d3a6ac18cc1769788c925e6e7fc89cd47e4270a42884736fa9b3ec09f3a8,false,0 1 2,address address address uint8 int96,token sender flowOperator permissions flowRateAllowance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,8,0x247f65bd849d686147330978aa7521457c5a83bf,FlowUpdated,"FlowUpdated(address,address,address,int96,int256,int256,bytes)",0x57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e,false,0 1 2,address address address int96 int256 int256 bytes,token sender receiver flowRate totalSenderFlowRate totalReceiverFlowRate userData,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,8,0x247f65bd849d686147330978aa7521457c5a83bf,FlowUpdatedExtension,"FlowUpdatedExtension(address,uint256)",0x71e0c98e270fc3084227b473f176924d5303ece8c639e679998a2d7dc8e70f74,false,0,address uint256,flowOperator deposit,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,8,0x247f65bd849d686147330978aa7521457c5a83bf,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,9,0x81398af97997f3973416d312939f790636719195,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,9,0x81398af97997f3973416d312939f790636719195,FlowOperatorUpdated,"FlowOperatorUpdated(address,address,address,uint8,int96)",0xc0d5d3a6ac18cc1769788c925e6e7fc89cd47e4270a42884736fa9b3ec09f3a8,false,0 1 2,address address address uint8 int96,token sender flowOperator permissions flowRateAllowance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,9,0x81398af97997f3973416d312939f790636719195,FlowUpdated,"FlowUpdated(address,address,address,int96,int256,int256,bytes)",0x57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e,false,0 1 2,address address address int96 int256 int256 bytes,token sender receiver flowRate totalSenderFlowRate totalReceiverFlowRate userData,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,9,0x81398af97997f3973416d312939f790636719195,FlowUpdatedExtension,"FlowUpdatedExtension(address,uint256)",0x71e0c98e270fc3084227b473f176924d5303ece8c639e679998a2d7dc8e70f74,false,0,address uint256,flowOperator deposit,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,9,0x81398af97997f3973416d312939f790636719195,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,10,0xf10e526e33f3f377e5b11d62e091fe3f4162a3d0,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,10,0xf10e526e33f3f377e5b11d62e091fe3f4162a3d0,FlowOperatorUpdated,"FlowOperatorUpdated(address,address,address,uint8,int96)",0xc0d5d3a6ac18cc1769788c925e6e7fc89cd47e4270a42884736fa9b3ec09f3a8,false,0 1 2,address address address uint8 int96,token sender flowOperator permissions flowRateAllowance,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,10,0xf10e526e33f3f377e5b11d62e091fe3f4162a3d0,FlowUpdated,"FlowUpdated(address,address,address,int96,int256,int256,bytes)",0x57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e,false,0 1 2,address address address int96 int256 int256 bytes,token sender receiver flowRate totalSenderFlowRate totalReceiverFlowRate userData,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,10,0xf10e526e33f3f377e5b11d62e091fe3f4162a3d0,FlowUpdatedExtension,"FlowUpdatedExtension(address,uint256)",0x71e0c98e270fc3084227b473f176924d5303ece8c639e679998a2d7dc8e70f74,false,0,address uint256,flowOperator deposit,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,10,0xf10e526e33f3f377e5b11d62e091fe3f4162a3d0,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,11,0x75e58f16f95ac530789d22e55713c9f8dc22444c,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,11,0x75e58f16f95ac530789d22e55713c9f8dc22444c,FlowOperatorUpdated,"FlowOperatorUpdated(address,address,address,uint8,int96)",0xc0d5d3a6ac18cc1769788c925e6e7fc89cd47e4270a42884736fa9b3ec09f3a8,false,0 1 2,address address address uint8 int96,token sender flowOperator permissions flowRateAllowance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,11,0x75e58f16f95ac530789d22e55713c9f8dc22444c,FlowUpdated,"FlowUpdated(address,address,address,int96,int256,int256,bytes)",0x57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e,false,0 1 2,address address address int96 int256 int256 bytes,token sender receiver flowRate totalSenderFlowRate totalReceiverFlowRate userData,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,11,0x75e58f16f95ac530789d22e55713c9f8dc22444c,FlowUpdatedExtension,"FlowUpdatedExtension(address,uint256)",0x71e0c98e270fc3084227b473f176924d5303ece8c639e679998a2d7dc8e70f74,false,0,address uint256,flowOperator deposit,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,11,0x75e58f16f95ac530789d22e55713c9f8dc22444c,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,12,0x511cba3de92db7891967e21dbd7c4571531ab84b,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,12,0x511cba3de92db7891967e21dbd7c4571531ab84b,FlowOperatorUpdated,"FlowOperatorUpdated(address,address,address,uint8,int96)",0xc0d5d3a6ac18cc1769788c925e6e7fc89cd47e4270a42884736fa9b3ec09f3a8,false,0 1 2,address address address uint8 int96,token sender flowOperator permissions flowRateAllowance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,12,0x511cba3de92db7891967e21dbd7c4571531ab84b,FlowUpdated,"FlowUpdated(address,address,address,int96,int256,int256,bytes)",0x57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e,false,0 1 2,address address address int96 int256 int256 bytes,token sender receiver flowRate totalSenderFlowRate totalReceiverFlowRate userData,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,12,0x511cba3de92db7891967e21dbd7c4571531ab84b,FlowUpdatedExtension,"FlowUpdatedExtension(address,uint256)",0x71e0c98e270fc3084227b473f176924d5303ece8c639e679998a2d7dc8e70f74,false,0,address uint256,flowOperator deposit,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,12,0x511cba3de92db7891967e21dbd7c4571531ab84b,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,13,0xd571f5ec96a5b362d10615ff999f06fac4c9e141,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,13,0xd571f5ec96a5b362d10615ff999f06fac4c9e141,FlowOperatorUpdated,"FlowOperatorUpdated(address,address,address,uint8,int96)",0xc0d5d3a6ac18cc1769788c925e6e7fc89cd47e4270a42884736fa9b3ec09f3a8,false,0 1 2,address address address uint8 int96,token sender flowOperator permissions flowRateAllowance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,13,0xd571f5ec96a5b362d10615ff999f06fac4c9e141,FlowUpdated,"FlowUpdated(address,address,address,int96,int256,int256,bytes)",0x57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e,false,0 1 2,address address address int96 int256 int256 bytes,token sender receiver flowRate totalSenderFlowRate totalReceiverFlowRate userData,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,13,0xd571f5ec96a5b362d10615ff999f06fac4c9e141,FlowUpdatedExtension,"FlowUpdatedExtension(address,uint256)",0x71e0c98e270fc3084227b473f176924d5303ece8c639e679998a2d7dc8e70f74,false,0,address uint256,flowOperator deposit,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,13,0xd571f5ec96a5b362d10615ff999f06fac4c9e141,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,14,0x57897b796ece6633fc7c0c6490b4eb84d58509e5,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,14,0x57897b796ece6633fc7c0c6490b4eb84d58509e5,FlowOperatorUpdated,"FlowOperatorUpdated(address,address,address,uint8,int96)",0xc0d5d3a6ac18cc1769788c925e6e7fc89cd47e4270a42884736fa9b3ec09f3a8,false,0 1 2,address address address uint8 int96,token sender flowOperator permissions flowRateAllowance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,14,0x57897b796ece6633fc7c0c6490b4eb84d58509e5,FlowUpdated,"FlowUpdated(address,address,address,int96,int256,int256,bytes)",0x57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e,false,0 1 2,address address address int96 int256 int256 bytes,token sender receiver flowRate totalSenderFlowRate totalReceiverFlowRate userData,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,14,0x57897b796ece6633fc7c0c6490b4eb84d58509e5,FlowUpdatedExtension,"FlowUpdatedExtension(address,uint256)",0x71e0c98e270fc3084227b473f176924d5303ece8c639e679998a2d7dc8e70f74,false,0,address uint256,flowOperator deposit,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,14,0x57897b796ece6633fc7c0c6490b4eb84d58509e5,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,15,0x7e115385bdbd12fb943a099320c41224b4fa96f4,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,15,0x7e115385bdbd12fb943a099320c41224b4fa96f4,FlowOperatorUpdated,"FlowOperatorUpdated(address,address,address,uint8,int96)",0xc0d5d3a6ac18cc1769788c925e6e7fc89cd47e4270a42884736fa9b3ec09f3a8,false,0 1 2,address address address uint8 int96,token sender flowOperator permissions flowRateAllowance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,15,0x7e115385bdbd12fb943a099320c41224b4fa96f4,FlowUpdated,"FlowUpdated(address,address,address,int96,int256,int256,bytes)",0x57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e,false,0 1 2,address address address int96 int256 int256 bytes,token sender receiver flowRate totalSenderFlowRate totalReceiverFlowRate userData,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,15,0x7e115385bdbd12fb943a099320c41224b4fa96f4,FlowUpdatedExtension,"FlowUpdatedExtension(address,uint256)",0x71e0c98e270fc3084227b473f176924d5303ece8c639e679998a2d7dc8e70f74,false,0,address uint256,flowOperator deposit,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,15,0x7e115385bdbd12fb943a099320c41224b4fa96f4,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,16,0x88bb53dea50691cc41094cde84f88d6afb8ca499,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,16,0x88bb53dea50691cc41094cde84f88d6afb8ca499,FlowOperatorUpdated,"FlowOperatorUpdated(address,address,address,uint8,int96)",0xc0d5d3a6ac18cc1769788c925e6e7fc89cd47e4270a42884736fa9b3ec09f3a8,false,0 1 2,address address address uint8 int96,token sender flowOperator permissions flowRateAllowance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,16,0x88bb53dea50691cc41094cde84f88d6afb8ca499,FlowUpdated,"FlowUpdated(address,address,address,int96,int256,int256,bytes)",0x57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e,false,0 1 2,address address address int96 int256 int256 bytes,token sender receiver flowRate totalSenderFlowRate totalReceiverFlowRate userData,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,16,0x88bb53dea50691cc41094cde84f88d6afb8ca499,FlowUpdatedExtension,"FlowUpdatedExtension(address,uint256)",0x71e0c98e270fc3084227b473f176924d5303ece8c639e679998a2d7dc8e70f74,false,0,address uint256,flowOperator deposit,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidCFAv1,0x9d369e78e1a682ce0f8d9ad849bea4fe1c3bd3ad,16,0x88bb53dea50691cc41094cde84f88d6afb8ca499,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,1,0x7ffce315b2014546ba461d54eded7aac70df4f53,BufferAdjusted,"BufferAdjusted(address,address,address,int256,uint256,uint256)",0x589f74ba61521b98a96e2f65e02028ca5af0c5990e3d9536176b37ee6b620137,false,0 1 2,address address address int256 uint256 uint256,token pool from bufferDelta newBufferAmount totalBufferAmount,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,1,0x7ffce315b2014546ba461d54eded7aac70df4f53,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,1,0x7ffce315b2014546ba461d54eded7aac70df4f53,FlowDistributionUpdated,"FlowDistributionUpdated(address,address,address,address,int96,int96,int96,address,int96,bytes)",0xc4bd0e4bfe3a83cbd5a7a71bb33bcb6bed9e0c24d710f3fb51c85caf1cd3af36,false,0 1 2,address address address address int96 int96 int96 address int96 bytes,token pool distributor operator oldFlowRate newDistributorToPoolFlowRate newTotalDistributionFlowRate adjustmentFlowRecipient adjustmentFlowRate userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,1,0x7ffce315b2014546ba461d54eded7aac70df4f53,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,1,0x7ffce315b2014546ba461d54eded7aac70df4f53,InstantDistributionUpdated,"InstantDistributionUpdated(address,address,address,address,uint256,uint256,bytes)",0x6e8348961b299f365797c30cd18a91284b046858689eeb6150a5ba432fe6583e,false,0 1 2,address address address address uint256 uint256 bytes,token pool distributor operator requestedAmount actualAmount userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,1,0x7ffce315b2014546ba461d54eded7aac70df4f53,PoolConnectionUpdated,"PoolConnectionUpdated(address,address,address,bool,bytes)",0xf357a2e6919da4efedb0301baf1caaed2bca70b115b913f9add41bbefc75c9b3,false,0 1 2,address address address bool bytes,token pool account connected userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,1,0x7ffce315b2014546ba461d54eded7aac70df4f53,PoolCreated,"PoolCreated(address,address,address)",0x9c5d829b9b23efc461f9aeef91979ec04bb903feb3bee4f26d22114abfc7335b,false,0 1,address address address,token admin pool,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,2,0x554a8acef6c689a74b25b1c41f58fa2e678162b5,BufferAdjusted,"BufferAdjusted(address,address,address,int256,uint256,uint256)",0x589f74ba61521b98a96e2f65e02028ca5af0c5990e3d9536176b37ee6b620137,false,0 1 2,address address address int256 uint256 uint256,token pool from bufferDelta newBufferAmount totalBufferAmount,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,2,0x554a8acef6c689a74b25b1c41f58fa2e678162b5,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,2,0x554a8acef6c689a74b25b1c41f58fa2e678162b5,FlowDistributionUpdated,"FlowDistributionUpdated(address,address,address,address,int96,int96,int96,address,int96,bytes)",0xc4bd0e4bfe3a83cbd5a7a71bb33bcb6bed9e0c24d710f3fb51c85caf1cd3af36,false,0 1 2,address address address address int96 int96 int96 address int96 bytes,token pool distributor operator oldFlowRate newDistributorToPoolFlowRate newTotalDistributionFlowRate adjustmentFlowRecipient adjustmentFlowRate userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,2,0x554a8acef6c689a74b25b1c41f58fa2e678162b5,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,2,0x554a8acef6c689a74b25b1c41f58fa2e678162b5,InstantDistributionUpdated,"InstantDistributionUpdated(address,address,address,address,uint256,uint256,bytes)",0x6e8348961b299f365797c30cd18a91284b046858689eeb6150a5ba432fe6583e,false,0 1 2,address address address address uint256 uint256 bytes,token pool distributor operator requestedAmount actualAmount userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,2,0x554a8acef6c689a74b25b1c41f58fa2e678162b5,PoolConnectionUpdated,"PoolConnectionUpdated(address,address,address,bool,bytes)",0xf357a2e6919da4efedb0301baf1caaed2bca70b115b913f9add41bbefc75c9b3,false,0 1 2,address address address bool bytes,token pool account connected userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,2,0x554a8acef6c689a74b25b1c41f58fa2e678162b5,PoolCreated,"PoolCreated(address,address,address)",0x9c5d829b9b23efc461f9aeef91979ec04bb903feb3bee4f26d22114abfc7335b,false,0 1,address address address,token admin pool,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,3,0xc70ce47df817f25bfbb4fb66fd42326ad306f27d,BufferAdjusted,"BufferAdjusted(address,address,address,int256,uint256,uint256)",0x589f74ba61521b98a96e2f65e02028ca5af0c5990e3d9536176b37ee6b620137,false,0 1 2,address address address int256 uint256 uint256,token pool from bufferDelta newBufferAmount totalBufferAmount,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,3,0xc70ce47df817f25bfbb4fb66fd42326ad306f27d,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,3,0xc70ce47df817f25bfbb4fb66fd42326ad306f27d,FlowDistributionUpdated,"FlowDistributionUpdated(address,address,address,address,int96,int96,int96,address,int96,bytes)",0xc4bd0e4bfe3a83cbd5a7a71bb33bcb6bed9e0c24d710f3fb51c85caf1cd3af36,false,0 1 2,address address address address int96 int96 int96 address int96 bytes,token pool distributor operator oldFlowRate newDistributorToPoolFlowRate newTotalDistributionFlowRate adjustmentFlowRecipient adjustmentFlowRate userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,3,0xc70ce47df817f25bfbb4fb66fd42326ad306f27d,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,3,0xc70ce47df817f25bfbb4fb66fd42326ad306f27d,InstantDistributionUpdated,"InstantDistributionUpdated(address,address,address,address,uint256,uint256,bytes)",0x6e8348961b299f365797c30cd18a91284b046858689eeb6150a5ba432fe6583e,false,0 1 2,address address address address uint256 uint256 bytes,token pool distributor operator requestedAmount actualAmount userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,3,0xc70ce47df817f25bfbb4fb66fd42326ad306f27d,PoolConnectionUpdated,"PoolConnectionUpdated(address,address,address,bool,bytes)",0xf357a2e6919da4efedb0301baf1caaed2bca70b115b913f9add41bbefc75c9b3,false,0 1 2,address address address bool bytes,token pool account connected userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,3,0xc70ce47df817f25bfbb4fb66fd42326ad306f27d,PoolCreated,"PoolCreated(address,address,address)",0x9c5d829b9b23efc461f9aeef91979ec04bb903feb3bee4f26d22114abfc7335b,false,0 1,address address address,token admin pool,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,4,0xab1286ab62d0dffd994f4b2d72b24eaa9e295562,BufferAdjusted,"BufferAdjusted(address,address,address,int256,uint256,uint256)",0x589f74ba61521b98a96e2f65e02028ca5af0c5990e3d9536176b37ee6b620137,false,0 1 2,address address address int256 uint256 uint256,token pool from bufferDelta newBufferAmount totalBufferAmount,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,4,0xab1286ab62d0dffd994f4b2d72b24eaa9e295562,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,4,0xab1286ab62d0dffd994f4b2d72b24eaa9e295562,FlowDistributionUpdated,"FlowDistributionUpdated(address,address,address,address,int96,int96,int96,address,int96,bytes)",0xc4bd0e4bfe3a83cbd5a7a71bb33bcb6bed9e0c24d710f3fb51c85caf1cd3af36,false,0 1 2,address address address address int96 int96 int96 address int96 bytes,token pool distributor operator oldFlowRate newDistributorToPoolFlowRate newTotalDistributionFlowRate adjustmentFlowRecipient adjustmentFlowRate userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,4,0xab1286ab62d0dffd994f4b2d72b24eaa9e295562,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,4,0xab1286ab62d0dffd994f4b2d72b24eaa9e295562,InstantDistributionUpdated,"InstantDistributionUpdated(address,address,address,address,uint256,uint256,bytes)",0x6e8348961b299f365797c30cd18a91284b046858689eeb6150a5ba432fe6583e,false,0 1 2,address address address address uint256 uint256 bytes,token pool distributor operator requestedAmount actualAmount userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,4,0xab1286ab62d0dffd994f4b2d72b24eaa9e295562,PoolConnectionUpdated,"PoolConnectionUpdated(address,address,address,bool,bytes)",0xf357a2e6919da4efedb0301baf1caaed2bca70b115b913f9add41bbefc75c9b3,false,0 1 2,address address address bool bytes,token pool account connected userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,4,0xab1286ab62d0dffd994f4b2d72b24eaa9e295562,PoolCreated,"PoolCreated(address,address,address)",0x9c5d829b9b23efc461f9aeef91979ec04bb903feb3bee4f26d22114abfc7335b,false,0 1,address address address,token admin pool,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,5,0xe72830e7ebbff8ce0866059de83cacd4263acd08,BufferAdjusted,"BufferAdjusted(address,address,address,int256,uint256,uint256)",0x589f74ba61521b98a96e2f65e02028ca5af0c5990e3d9536176b37ee6b620137,false,0 1 2,address address address int256 uint256 uint256,token pool from bufferDelta newBufferAmount totalBufferAmount,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,5,0xe72830e7ebbff8ce0866059de83cacd4263acd08,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,5,0xe72830e7ebbff8ce0866059de83cacd4263acd08,FlowDistributionUpdated,"FlowDistributionUpdated(address,address,address,address,int96,int96,int96,address,int96,bytes)",0xc4bd0e4bfe3a83cbd5a7a71bb33bcb6bed9e0c24d710f3fb51c85caf1cd3af36,false,0 1 2,address address address address int96 int96 int96 address int96 bytes,token pool distributor operator oldFlowRate newDistributorToPoolFlowRate newTotalDistributionFlowRate adjustmentFlowRecipient adjustmentFlowRate userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,5,0xe72830e7ebbff8ce0866059de83cacd4263acd08,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,5,0xe72830e7ebbff8ce0866059de83cacd4263acd08,InstantDistributionUpdated,"InstantDistributionUpdated(address,address,address,address,uint256,uint256,bytes)",0x6e8348961b299f365797c30cd18a91284b046858689eeb6150a5ba432fe6583e,false,0 1 2,address address address address uint256 uint256 bytes,token pool distributor operator requestedAmount actualAmount userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,5,0xe72830e7ebbff8ce0866059de83cacd4263acd08,PoolConnectionUpdated,"PoolConnectionUpdated(address,address,address,bool,bytes)",0xf357a2e6919da4efedb0301baf1caaed2bca70b115b913f9add41bbefc75c9b3,false,0 1 2,address address address bool bytes,token pool account connected userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,5,0xe72830e7ebbff8ce0866059de83cacd4263acd08,PoolCreated,"PoolCreated(address,address,address)",0x9c5d829b9b23efc461f9aeef91979ec04bb903feb3bee4f26d22114abfc7335b,false,0 1,address address address,token admin pool,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,6,0xb75bd19c682e62e6a0c35399bb3a2538fcc9cef6,BufferAdjusted,"BufferAdjusted(address,address,address,int256,uint256,uint256)",0x589f74ba61521b98a96e2f65e02028ca5af0c5990e3d9536176b37ee6b620137,false,0 1 2,address address address int256 uint256 uint256,token pool from bufferDelta newBufferAmount totalBufferAmount,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,6,0xb75bd19c682e62e6a0c35399bb3a2538fcc9cef6,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,6,0xb75bd19c682e62e6a0c35399bb3a2538fcc9cef6,FlowDistributionUpdated,"FlowDistributionUpdated(address,address,address,address,int96,int96,int96,address,int96,bytes)",0xc4bd0e4bfe3a83cbd5a7a71bb33bcb6bed9e0c24d710f3fb51c85caf1cd3af36,false,0 1 2,address address address address int96 int96 int96 address int96 bytes,token pool distributor operator oldFlowRate newDistributorToPoolFlowRate newTotalDistributionFlowRate adjustmentFlowRecipient adjustmentFlowRate userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,6,0xb75bd19c682e62e6a0c35399bb3a2538fcc9cef6,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,6,0xb75bd19c682e62e6a0c35399bb3a2538fcc9cef6,InstantDistributionUpdated,"InstantDistributionUpdated(address,address,address,address,uint256,uint256,bytes)",0x6e8348961b299f365797c30cd18a91284b046858689eeb6150a5ba432fe6583e,false,0 1 2,address address address address uint256 uint256 bytes,token pool distributor operator requestedAmount actualAmount userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,6,0xb75bd19c682e62e6a0c35399bb3a2538fcc9cef6,PoolConnectionUpdated,"PoolConnectionUpdated(address,address,address,bool,bytes)",0xf357a2e6919da4efedb0301baf1caaed2bca70b115b913f9add41bbefc75c9b3,false,0 1 2,address address address bool bytes,token pool account connected userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,6,0xb75bd19c682e62e6a0c35399bb3a2538fcc9cef6,PoolCreated,"PoolCreated(address,address,address)",0x9c5d829b9b23efc461f9aeef91979ec04bb903feb3bee4f26d22114abfc7335b,false,0 1,address address address,token admin pool,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,8,0xa0844efaf9a6803e9fa379ee59d44d3ef581ea3f,BufferAdjusted,"BufferAdjusted(address,address,address,int256,uint256,uint256)",0x589f74ba61521b98a96e2f65e02028ca5af0c5990e3d9536176b37ee6b620137,false,0 1 2,address address address int256 uint256 uint256,token pool from bufferDelta newBufferAmount totalBufferAmount,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,8,0xa0844efaf9a6803e9fa379ee59d44d3ef581ea3f,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,8,0xa0844efaf9a6803e9fa379ee59d44d3ef581ea3f,FlowDistributionUpdated,"FlowDistributionUpdated(address,address,address,address,int96,int96,int96,address,int96,bytes)",0xc4bd0e4bfe3a83cbd5a7a71bb33bcb6bed9e0c24d710f3fb51c85caf1cd3af36,false,0 1 2,address address address address int96 int96 int96 address int96 bytes,token pool distributor operator oldFlowRate newDistributorToPoolFlowRate newTotalDistributionFlowRate adjustmentFlowRecipient adjustmentFlowRate userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,8,0xa0844efaf9a6803e9fa379ee59d44d3ef581ea3f,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,8,0xa0844efaf9a6803e9fa379ee59d44d3ef581ea3f,InstantDistributionUpdated,"InstantDistributionUpdated(address,address,address,address,uint256,uint256,bytes)",0x6e8348961b299f365797c30cd18a91284b046858689eeb6150a5ba432fe6583e,false,0 1 2,address address address address uint256 uint256 bytes,token pool distributor operator requestedAmount actualAmount userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,8,0xa0844efaf9a6803e9fa379ee59d44d3ef581ea3f,PoolConnectionUpdated,"PoolConnectionUpdated(address,address,address,bool,bytes)",0xf357a2e6919da4efedb0301baf1caaed2bca70b115b913f9add41bbefc75c9b3,false,0 1 2,address address address bool bytes,token pool account connected userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,8,0xa0844efaf9a6803e9fa379ee59d44d3ef581ea3f,PoolCreated,"PoolCreated(address,address,address)",0x9c5d829b9b23efc461f9aeef91979ec04bb903feb3bee4f26d22114abfc7335b,false,0 1,address address address,token admin pool,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,9,0xc8f6f1720e6266445b3b53b9b9870b25ade5154e,BufferAdjusted,"BufferAdjusted(address,address,address,int256,uint256,uint256)",0x589f74ba61521b98a96e2f65e02028ca5af0c5990e3d9536176b37ee6b620137,false,0 1 2,address address address int256 uint256 uint256,token pool from bufferDelta newBufferAmount totalBufferAmount,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,9,0xc8f6f1720e6266445b3b53b9b9870b25ade5154e,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,9,0xc8f6f1720e6266445b3b53b9b9870b25ade5154e,FlowDistributionUpdated,"FlowDistributionUpdated(address,address,address,address,int96,int96,int96,address,int96,bytes)",0xc4bd0e4bfe3a83cbd5a7a71bb33bcb6bed9e0c24d710f3fb51c85caf1cd3af36,false,0 1 2,address address address address int96 int96 int96 address int96 bytes,token pool distributor operator oldFlowRate newDistributorToPoolFlowRate newTotalDistributionFlowRate adjustmentFlowRecipient adjustmentFlowRate userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,9,0xc8f6f1720e6266445b3b53b9b9870b25ade5154e,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,9,0xc8f6f1720e6266445b3b53b9b9870b25ade5154e,InstantDistributionUpdated,"InstantDistributionUpdated(address,address,address,address,uint256,uint256,bytes)",0x6e8348961b299f365797c30cd18a91284b046858689eeb6150a5ba432fe6583e,false,0 1 2,address address address address uint256 uint256 bytes,token pool distributor operator requestedAmount actualAmount userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,9,0xc8f6f1720e6266445b3b53b9b9870b25ade5154e,PoolConnectionUpdated,"PoolConnectionUpdated(address,address,address,bool,bytes)",0xf357a2e6919da4efedb0301baf1caaed2bca70b115b913f9add41bbefc75c9b3,false,0 1 2,address address address bool bytes,token pool account connected userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,9,0xc8f6f1720e6266445b3b53b9b9870b25ade5154e,PoolCreated,"PoolCreated(address,address,address)",0x9c5d829b9b23efc461f9aeef91979ec04bb903feb3bee4f26d22114abfc7335b,false,0 1,address address address,token admin pool,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,10,0x96c3c2d23d143301cf363a02cb7fe3596d2834d7,BufferAdjusted,"BufferAdjusted(address,address,address,int256,uint256,uint256)",0x589f74ba61521b98a96e2f65e02028ca5af0c5990e3d9536176b37ee6b620137,false,0 1 2,address address address int256 uint256 uint256,token pool from bufferDelta newBufferAmount totalBufferAmount,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,10,0x96c3c2d23d143301cf363a02cb7fe3596d2834d7,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,10,0x96c3c2d23d143301cf363a02cb7fe3596d2834d7,FlowDistributionUpdated,"FlowDistributionUpdated(address,address,address,address,int96,int96,int96,address,int96,bytes)",0xc4bd0e4bfe3a83cbd5a7a71bb33bcb6bed9e0c24d710f3fb51c85caf1cd3af36,false,0 1 2,address address address address int96 int96 int96 address int96 bytes,token pool distributor operator oldFlowRate newDistributorToPoolFlowRate newTotalDistributionFlowRate adjustmentFlowRecipient adjustmentFlowRate userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,10,0x96c3c2d23d143301cf363a02cb7fe3596d2834d7,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,10,0x96c3c2d23d143301cf363a02cb7fe3596d2834d7,InstantDistributionUpdated,"InstantDistributionUpdated(address,address,address,address,uint256,uint256,bytes)",0x6e8348961b299f365797c30cd18a91284b046858689eeb6150a5ba432fe6583e,false,0 1 2,address address address address uint256 uint256 bytes,token pool distributor operator requestedAmount actualAmount userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,10,0x96c3c2d23d143301cf363a02cb7fe3596d2834d7,PoolConnectionUpdated,"PoolConnectionUpdated(address,address,address,bool,bytes)",0xf357a2e6919da4efedb0301baf1caaed2bca70b115b913f9add41bbefc75c9b3,false,0 1 2,address address address bool bytes,token pool account connected userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,10,0x96c3c2d23d143301cf363a02cb7fe3596d2834d7,PoolCreated,"PoolCreated(address,address,address)",0x9c5d829b9b23efc461f9aeef91979ec04bb903feb3bee4f26d22114abfc7335b,false,0 1,address address address,token admin pool,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,11,0x4c78cad0cc7152fa8f64ce5298a2d5216c7e4d81,BufferAdjusted,"BufferAdjusted(address,address,address,int256,uint256,uint256)",0x589f74ba61521b98a96e2f65e02028ca5af0c5990e3d9536176b37ee6b620137,false,0 1 2,address address address int256 uint256 uint256,token pool from bufferDelta newBufferAmount totalBufferAmount,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,11,0x4c78cad0cc7152fa8f64ce5298a2d5216c7e4d81,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,11,0x4c78cad0cc7152fa8f64ce5298a2d5216c7e4d81,FlowDistributionUpdated,"FlowDistributionUpdated(address,address,address,address,int96,int96,int96,address,int96,bytes)",0xc4bd0e4bfe3a83cbd5a7a71bb33bcb6bed9e0c24d710f3fb51c85caf1cd3af36,false,0 1 2,address address address address int96 int96 int96 address int96 bytes,token pool distributor operator oldFlowRate newDistributorToPoolFlowRate newTotalDistributionFlowRate adjustmentFlowRecipient adjustmentFlowRate userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,11,0x4c78cad0cc7152fa8f64ce5298a2d5216c7e4d81,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,11,0x4c78cad0cc7152fa8f64ce5298a2d5216c7e4d81,InstantDistributionUpdated,"InstantDistributionUpdated(address,address,address,address,uint256,uint256,bytes)",0x6e8348961b299f365797c30cd18a91284b046858689eeb6150a5ba432fe6583e,false,0 1 2,address address address address uint256 uint256 bytes,token pool distributor operator requestedAmount actualAmount userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,11,0x4c78cad0cc7152fa8f64ce5298a2d5216c7e4d81,PoolConnectionUpdated,"PoolConnectionUpdated(address,address,address,bool,bytes)",0xf357a2e6919da4efedb0301baf1caaed2bca70b115b913f9add41bbefc75c9b3,false,0 1 2,address address address bool bytes,token pool account connected userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,11,0x4c78cad0cc7152fa8f64ce5298a2d5216c7e4d81,PoolCreated,"PoolCreated(address,address,address)",0x9c5d829b9b23efc461f9aeef91979ec04bb903feb3bee4f26d22114abfc7335b,false,0 1,address address address,token admin pool,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,12,0xa347bdc5965323f92ccd950a8b7012c0e438e178,BufferAdjusted,"BufferAdjusted(address,address,address,int256,uint256,uint256)",0x589f74ba61521b98a96e2f65e02028ca5af0c5990e3d9536176b37ee6b620137,false,0 1 2,address address address int256 uint256 uint256,token pool from bufferDelta newBufferAmount totalBufferAmount,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,12,0xa347bdc5965323f92ccd950a8b7012c0e438e178,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,12,0xa347bdc5965323f92ccd950a8b7012c0e438e178,FlowDistributionUpdated,"FlowDistributionUpdated(address,address,address,address,int96,int96,int96,address,int96,bytes)",0xc4bd0e4bfe3a83cbd5a7a71bb33bcb6bed9e0c24d710f3fb51c85caf1cd3af36,false,0 1 2,address address address address int96 int96 int96 address int96 bytes,token pool distributor operator oldFlowRate newDistributorToPoolFlowRate newTotalDistributionFlowRate adjustmentFlowRecipient adjustmentFlowRate userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,12,0xa347bdc5965323f92ccd950a8b7012c0e438e178,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,12,0xa347bdc5965323f92ccd950a8b7012c0e438e178,InstantDistributionUpdated,"InstantDistributionUpdated(address,address,address,address,uint256,uint256,bytes)",0x6e8348961b299f365797c30cd18a91284b046858689eeb6150a5ba432fe6583e,false,0 1 2,address address address address uint256 uint256 bytes,token pool distributor operator requestedAmount actualAmount userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,12,0xa347bdc5965323f92ccd950a8b7012c0e438e178,PoolConnectionUpdated,"PoolConnectionUpdated(address,address,address,bool,bytes)",0xf357a2e6919da4efedb0301baf1caaed2bca70b115b913f9add41bbefc75c9b3,false,0 1 2,address address address bool bytes,token pool account connected userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,12,0xa347bdc5965323f92ccd950a8b7012c0e438e178,PoolCreated,"PoolCreated(address,address,address)",0x9c5d829b9b23efc461f9aeef91979ec04bb903feb3bee4f26d22114abfc7335b,false,0 1,address address address,token admin pool,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,13,0x20dd21b94b88cbeee338c7ffd6124f716c0b54b2,BufferAdjusted,"BufferAdjusted(address,address,address,int256,uint256,uint256)",0x589f74ba61521b98a96e2f65e02028ca5af0c5990e3d9536176b37ee6b620137,false,0 1 2,address address address int256 uint256 uint256,token pool from bufferDelta newBufferAmount totalBufferAmount,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,13,0x20dd21b94b88cbeee338c7ffd6124f716c0b54b2,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,13,0x20dd21b94b88cbeee338c7ffd6124f716c0b54b2,FlowDistributionUpdated,"FlowDistributionUpdated(address,address,address,address,int96,int96,int96,address,int96,bytes)",0xc4bd0e4bfe3a83cbd5a7a71bb33bcb6bed9e0c24d710f3fb51c85caf1cd3af36,false,0 1 2,address address address address int96 int96 int96 address int96 bytes,token pool distributor operator oldFlowRate newDistributorToPoolFlowRate newTotalDistributionFlowRate adjustmentFlowRecipient adjustmentFlowRate userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,13,0x20dd21b94b88cbeee338c7ffd6124f716c0b54b2,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,13,0x20dd21b94b88cbeee338c7ffd6124f716c0b54b2,InstantDistributionUpdated,"InstantDistributionUpdated(address,address,address,address,uint256,uint256,bytes)",0x6e8348961b299f365797c30cd18a91284b046858689eeb6150a5ba432fe6583e,false,0 1 2,address address address address uint256 uint256 bytes,token pool distributor operator requestedAmount actualAmount userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,13,0x20dd21b94b88cbeee338c7ffd6124f716c0b54b2,PoolConnectionUpdated,"PoolConnectionUpdated(address,address,address,bool,bytes)",0xf357a2e6919da4efedb0301baf1caaed2bca70b115b913f9add41bbefc75c9b3,false,0 1 2,address address address bool bytes,token pool account connected userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,13,0x20dd21b94b88cbeee338c7ffd6124f716c0b54b2,PoolCreated,"PoolCreated(address,address,address)",0x9c5d829b9b23efc461f9aeef91979ec04bb903feb3bee4f26d22114abfc7335b,false,0 1,address address address,token admin pool,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,14,0x0fcddf2d5023219145e902cb3b0c44159ab59d61,BufferAdjusted,"BufferAdjusted(address,address,address,int256,uint256,uint256)",0x589f74ba61521b98a96e2f65e02028ca5af0c5990e3d9536176b37ee6b620137,false,0 1 2,address address address int256 uint256 uint256,token pool from bufferDelta newBufferAmount totalBufferAmount,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,14,0x0fcddf2d5023219145e902cb3b0c44159ab59d61,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,14,0x0fcddf2d5023219145e902cb3b0c44159ab59d61,FlowDistributionUpdated,"FlowDistributionUpdated(address,address,address,address,int96,int96,int96,address,int96,bytes)",0xc4bd0e4bfe3a83cbd5a7a71bb33bcb6bed9e0c24d710f3fb51c85caf1cd3af36,false,0 1 2,address address address address int96 int96 int96 address int96 bytes,token pool distributor operator oldFlowRate newDistributorToPoolFlowRate newTotalDistributionFlowRate adjustmentFlowRecipient adjustmentFlowRate userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,14,0x0fcddf2d5023219145e902cb3b0c44159ab59d61,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,14,0x0fcddf2d5023219145e902cb3b0c44159ab59d61,InstantDistributionUpdated,"InstantDistributionUpdated(address,address,address,address,uint256,uint256,bytes)",0x6e8348961b299f365797c30cd18a91284b046858689eeb6150a5ba432fe6583e,false,0 1 2,address address address address uint256 uint256 bytes,token pool distributor operator requestedAmount actualAmount userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,14,0x0fcddf2d5023219145e902cb3b0c44159ab59d61,PoolConnectionUpdated,"PoolConnectionUpdated(address,address,address,bool,bytes)",0xf357a2e6919da4efedb0301baf1caaed2bca70b115b913f9add41bbefc75c9b3,false,0 1 2,address address address bool bytes,token pool account connected userData,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidGDAv1,0x308b7405272d11494716e30c6e972dbf6fb89555,14,0x0fcddf2d5023219145e902cb3b0c44159ab59d61,PoolCreated,"PoolCreated(address,address,address)",0x9c5d829b9b23efc461f9aeef91979ec04bb903feb3bee4f26d22114abfc7335b,false,0 1,address address address,token admin pool,true,23675300,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,8,9,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,2,0xf37a766fb6684fa86842f88380e786c2bd32ba4c,AgreementClassRegistered,"AgreementClassRegistered(bytes32,address)",0x878135063a6cfb3bc333e534b1fdc83f4f12221cad6705c31c0567048a8bd3d1,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,2,0xf37a766fb6684fa86842f88380e786c2bd32ba4c,AgreementClassUpdated,"AgreementClassUpdated(bytes32,address)",0x9279aa773f2b588996032d8de89911555039f28b13a11a7c17074330bc082d9a,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,2,0xf37a766fb6684fa86842f88380e786c2bd32ba4c,AppRegistered,AppRegistered(address),0x0d540ad8f39e07d19909687352b9fa017405d93c91a6760981fbae9cf28bfef7,false,0,address,app,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,2,0xf37a766fb6684fa86842f88380e786c2bd32ba4c,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,2,0xf37a766fb6684fa86842f88380e786c2bd32ba4c,GovernanceReplaced,"GovernanceReplaced(address,address)",0x13abda02e63c790d0e2818b251282cfe5cbe0a8abd69c54bf5d2260c0907bd2e,false,,address address,oldGov newGov,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,2,0xf37a766fb6684fa86842f88380e786c2bd32ba4c,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,2,0xf37a766fb6684fa86842f88380e786c2bd32ba4c,Jail,"Jail(address,uint256)",0xbe3aa33bd245135e4e26b223d79d14ea479a47bff09f2b03c53838af1edbb14b,false,0,address uint256,app reason,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,2,0xf37a766fb6684fa86842f88380e786c2bd32ba4c,SuperTokenFactoryUpdated,SuperTokenFactoryUpdated(address),0xce13a9895a1719ad4493b2ac1a9bfb36070566161abab408e7ecbe586da8d499,false,,address,newFactory,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,2,0xf37a766fb6684fa86842f88380e786c2bd32ba4c,SuperTokenLogicUpdated,"SuperTokenLogicUpdated(address,address)",0x840acbd291b38534819f47f875839277e502f40e1c7bfea2c5fc2c8017442cd3,false,0,address address,token code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,3,0x109412e3c84f0539b43d39db691b08c90f58dc7c,AgreementClassRegistered,"AgreementClassRegistered(bytes32,address)",0x878135063a6cfb3bc333e534b1fdc83f4f12221cad6705c31c0567048a8bd3d1,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,3,0x109412e3c84f0539b43d39db691b08c90f58dc7c,AgreementClassUpdated,"AgreementClassUpdated(bytes32,address)",0x9279aa773f2b588996032d8de89911555039f28b13a11a7c17074330bc082d9a,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,3,0x109412e3c84f0539b43d39db691b08c90f58dc7c,AppRegistered,AppRegistered(address),0x0d540ad8f39e07d19909687352b9fa017405d93c91a6760981fbae9cf28bfef7,false,0,address,app,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,3,0x109412e3c84f0539b43d39db691b08c90f58dc7c,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,3,0x109412e3c84f0539b43d39db691b08c90f58dc7c,GovernanceReplaced,"GovernanceReplaced(address,address)",0x13abda02e63c790d0e2818b251282cfe5cbe0a8abd69c54bf5d2260c0907bd2e,false,,address address,oldGov newGov,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,3,0x109412e3c84f0539b43d39db691b08c90f58dc7c,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,3,0x109412e3c84f0539b43d39db691b08c90f58dc7c,Jail,"Jail(address,uint256)",0xbe3aa33bd245135e4e26b223d79d14ea479a47bff09f2b03c53838af1edbb14b,false,0,address uint256,app reason,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,3,0x109412e3c84f0539b43d39db691b08c90f58dc7c,SuperTokenFactoryUpdated,SuperTokenFactoryUpdated(address),0xce13a9895a1719ad4493b2ac1a9bfb36070566161abab408e7ecbe586da8d499,false,,address,newFactory,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,3,0x109412e3c84f0539b43d39db691b08c90f58dc7c,SuperTokenLogicUpdated,"SuperTokenLogicUpdated(address,address)",0x840acbd291b38534819f47f875839277e502f40e1c7bfea2c5fc2c8017442cd3,false,0,address address,token code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,4,0x15f0ca26781c3852f8166ed2ebce5d18265cceb7,AgreementClassRegistered,"AgreementClassRegistered(bytes32,address)",0x878135063a6cfb3bc333e534b1fdc83f4f12221cad6705c31c0567048a8bd3d1,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,4,0x15f0ca26781c3852f8166ed2ebce5d18265cceb7,AgreementClassUpdated,"AgreementClassUpdated(bytes32,address)",0x9279aa773f2b588996032d8de89911555039f28b13a11a7c17074330bc082d9a,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,4,0x15f0ca26781c3852f8166ed2ebce5d18265cceb7,AppRegistered,AppRegistered(address),0x0d540ad8f39e07d19909687352b9fa017405d93c91a6760981fbae9cf28bfef7,false,0,address,app,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,4,0x15f0ca26781c3852f8166ed2ebce5d18265cceb7,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,4,0x15f0ca26781c3852f8166ed2ebce5d18265cceb7,GovernanceReplaced,"GovernanceReplaced(address,address)",0x13abda02e63c790d0e2818b251282cfe5cbe0a8abd69c54bf5d2260c0907bd2e,false,,address address,oldGov newGov,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,4,0x15f0ca26781c3852f8166ed2ebce5d18265cceb7,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,4,0x15f0ca26781c3852f8166ed2ebce5d18265cceb7,Jail,"Jail(address,uint256)",0xbe3aa33bd245135e4e26b223d79d14ea479a47bff09f2b03c53838af1edbb14b,false,0,address uint256,app reason,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,4,0x15f0ca26781c3852f8166ed2ebce5d18265cceb7,SuperTokenFactoryUpdated,SuperTokenFactoryUpdated(address),0xce13a9895a1719ad4493b2ac1a9bfb36070566161abab408e7ecbe586da8d499,false,,address,newFactory,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,4,0x15f0ca26781c3852f8166ed2ebce5d18265cceb7,SuperTokenLogicUpdated,"SuperTokenLogicUpdated(address,address)",0x840acbd291b38534819f47f875839277e502f40e1c7bfea2c5fc2c8017442cd3,false,0,address address,token code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,5,0xe01f8743677da897f4e7de9073b57bf034fc2433,AgreementClassRegistered,"AgreementClassRegistered(bytes32,address)",0x878135063a6cfb3bc333e534b1fdc83f4f12221cad6705c31c0567048a8bd3d1,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,5,0xe01f8743677da897f4e7de9073b57bf034fc2433,AgreementClassUpdated,"AgreementClassUpdated(bytes32,address)",0x9279aa773f2b588996032d8de89911555039f28b13a11a7c17074330bc082d9a,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,5,0xe01f8743677da897f4e7de9073b57bf034fc2433,AppRegistered,AppRegistered(address),0x0d540ad8f39e07d19909687352b9fa017405d93c91a6760981fbae9cf28bfef7,false,0,address,app,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,5,0xe01f8743677da897f4e7de9073b57bf034fc2433,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,5,0xe01f8743677da897f4e7de9073b57bf034fc2433,GovernanceReplaced,"GovernanceReplaced(address,address)",0x13abda02e63c790d0e2818b251282cfe5cbe0a8abd69c54bf5d2260c0907bd2e,false,,address address,oldGov newGov,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,5,0xe01f8743677da897f4e7de9073b57bf034fc2433,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,5,0xe01f8743677da897f4e7de9073b57bf034fc2433,Jail,"Jail(address,uint256)",0xbe3aa33bd245135e4e26b223d79d14ea479a47bff09f2b03c53838af1edbb14b,false,0,address uint256,app reason,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,5,0xe01f8743677da897f4e7de9073b57bf034fc2433,SuperTokenFactoryUpdated,SuperTokenFactoryUpdated(address),0xce13a9895a1719ad4493b2ac1a9bfb36070566161abab408e7ecbe586da8d499,false,,address,newFactory,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,5,0xe01f8743677da897f4e7de9073b57bf034fc2433,SuperTokenLogicUpdated,"SuperTokenLogicUpdated(address,address)",0x840acbd291b38534819f47f875839277e502f40e1c7bfea2c5fc2c8017442cd3,false,0,address address,token code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,6,0xb8f12031d79615f3faf6ec5f9795057e55e3069a,AgreementClassRegistered,"AgreementClassRegistered(bytes32,address)",0x878135063a6cfb3bc333e534b1fdc83f4f12221cad6705c31c0567048a8bd3d1,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,6,0xb8f12031d79615f3faf6ec5f9795057e55e3069a,AgreementClassUpdated,"AgreementClassUpdated(bytes32,address)",0x9279aa773f2b588996032d8de89911555039f28b13a11a7c17074330bc082d9a,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,6,0xb8f12031d79615f3faf6ec5f9795057e55e3069a,AppRegistered,AppRegistered(address),0x0d540ad8f39e07d19909687352b9fa017405d93c91a6760981fbae9cf28bfef7,false,0,address,app,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,6,0xb8f12031d79615f3faf6ec5f9795057e55e3069a,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,6,0xb8f12031d79615f3faf6ec5f9795057e55e3069a,GovernanceReplaced,"GovernanceReplaced(address,address)",0x13abda02e63c790d0e2818b251282cfe5cbe0a8abd69c54bf5d2260c0907bd2e,false,,address address,oldGov newGov,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,6,0xb8f12031d79615f3faf6ec5f9795057e55e3069a,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,6,0xb8f12031d79615f3faf6ec5f9795057e55e3069a,Jail,"Jail(address,uint256)",0xbe3aa33bd245135e4e26b223d79d14ea479a47bff09f2b03c53838af1edbb14b,false,0,address uint256,app reason,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,6,0xb8f12031d79615f3faf6ec5f9795057e55e3069a,SuperTokenFactoryUpdated,SuperTokenFactoryUpdated(address),0xce13a9895a1719ad4493b2ac1a9bfb36070566161abab408e7ecbe586da8d499,false,,address,newFactory,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,6,0xb8f12031d79615f3faf6ec5f9795057e55e3069a,SuperTokenLogicUpdated,"SuperTokenLogicUpdated(address,address)",0x840acbd291b38534819f47f875839277e502f40e1c7bfea2c5fc2c8017442cd3,false,0,address address,token code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,7,0x143ea239159155b408e71cdbe836e8cfd6766732,AgreementClassRegistered,"AgreementClassRegistered(bytes32,address)",0x878135063a6cfb3bc333e534b1fdc83f4f12221cad6705c31c0567048a8bd3d1,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,7,0x143ea239159155b408e71cdbe836e8cfd6766732,AgreementClassUpdated,"AgreementClassUpdated(bytes32,address)",0x9279aa773f2b588996032d8de89911555039f28b13a11a7c17074330bc082d9a,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,7,0x143ea239159155b408e71cdbe836e8cfd6766732,AppRegistered,AppRegistered(address),0x0d540ad8f39e07d19909687352b9fa017405d93c91a6760981fbae9cf28bfef7,false,0,address,app,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,7,0x143ea239159155b408e71cdbe836e8cfd6766732,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,7,0x143ea239159155b408e71cdbe836e8cfd6766732,GovernanceReplaced,"GovernanceReplaced(address,address)",0x13abda02e63c790d0e2818b251282cfe5cbe0a8abd69c54bf5d2260c0907bd2e,false,,address address,oldGov newGov,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,7,0x143ea239159155b408e71cdbe836e8cfd6766732,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,7,0x143ea239159155b408e71cdbe836e8cfd6766732,Jail,"Jail(address,uint256)",0xbe3aa33bd245135e4e26b223d79d14ea479a47bff09f2b03c53838af1edbb14b,false,0,address uint256,app reason,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,7,0x143ea239159155b408e71cdbe836e8cfd6766732,PoolBeaconLogicUpdated,"PoolBeaconLogicUpdated(address,address)",0x052cea8931962dd445ef48b0b998d3056bd0705f437087d60fe3c46a3fa09e1f,false,0,address address,beaconProxy newBeaconLogic,true,23701580,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,7,0x143ea239159155b408e71cdbe836e8cfd6766732,SuperTokenFactoryUpdated,SuperTokenFactoryUpdated(address),0xce13a9895a1719ad4493b2ac1a9bfb36070566161abab408e7ecbe586da8d499,false,,address,newFactory,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,7,0x143ea239159155b408e71cdbe836e8cfd6766732,SuperTokenLogicUpdated,"SuperTokenLogicUpdated(address,address)",0x840acbd291b38534819f47f875839277e502f40e1c7bfea2c5fc2c8017442cd3,false,0,address address,token code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,8,0xddc77ec35a571c98c7465b51f152e4888835bee6,AgreementClassRegistered,"AgreementClassRegistered(bytes32,address)",0x878135063a6cfb3bc333e534b1fdc83f4f12221cad6705c31c0567048a8bd3d1,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,8,0xddc77ec35a571c98c7465b51f152e4888835bee6,AgreementClassUpdated,"AgreementClassUpdated(bytes32,address)",0x9279aa773f2b588996032d8de89911555039f28b13a11a7c17074330bc082d9a,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,8,0xddc77ec35a571c98c7465b51f152e4888835bee6,AppRegistered,AppRegistered(address),0x0d540ad8f39e07d19909687352b9fa017405d93c91a6760981fbae9cf28bfef7,false,0,address,app,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,8,0xddc77ec35a571c98c7465b51f152e4888835bee6,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,8,0xddc77ec35a571c98c7465b51f152e4888835bee6,GovernanceReplaced,"GovernanceReplaced(address,address)",0x13abda02e63c790d0e2818b251282cfe5cbe0a8abd69c54bf5d2260c0907bd2e,false,,address address,oldGov newGov,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,8,0xddc77ec35a571c98c7465b51f152e4888835bee6,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,8,0xddc77ec35a571c98c7465b51f152e4888835bee6,Jail,"Jail(address,uint256)",0xbe3aa33bd245135e4e26b223d79d14ea479a47bff09f2b03c53838af1edbb14b,false,0,address uint256,app reason,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,8,0xddc77ec35a571c98c7465b51f152e4888835bee6,PoolBeaconLogicUpdated,"PoolBeaconLogicUpdated(address,address)",0x052cea8931962dd445ef48b0b998d3056bd0705f437087d60fe3c46a3fa09e1f,false,0,address address,beaconProxy newBeaconLogic,true,23701580,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,8,0xddc77ec35a571c98c7465b51f152e4888835bee6,SuperTokenFactoryUpdated,SuperTokenFactoryUpdated(address),0xce13a9895a1719ad4493b2ac1a9bfb36070566161abab408e7ecbe586da8d499,false,,address,newFactory,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,8,0xddc77ec35a571c98c7465b51f152e4888835bee6,SuperTokenLogicUpdated,"SuperTokenLogicUpdated(address,address)",0x840acbd291b38534819f47f875839277e502f40e1c7bfea2c5fc2c8017442cd3,false,0,address address,token code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,9,0xcf3f4fa77f4427f6a1c1a96556194b40fc9dbf02,AgreementClassRegistered,"AgreementClassRegistered(bytes32,address)",0x878135063a6cfb3bc333e534b1fdc83f4f12221cad6705c31c0567048a8bd3d1,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,9,0xcf3f4fa77f4427f6a1c1a96556194b40fc9dbf02,AgreementClassUpdated,"AgreementClassUpdated(bytes32,address)",0x9279aa773f2b588996032d8de89911555039f28b13a11a7c17074330bc082d9a,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,9,0xcf3f4fa77f4427f6a1c1a96556194b40fc9dbf02,AppRegistered,AppRegistered(address),0x0d540ad8f39e07d19909687352b9fa017405d93c91a6760981fbae9cf28bfef7,false,0,address,app,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,9,0xcf3f4fa77f4427f6a1c1a96556194b40fc9dbf02,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,9,0xcf3f4fa77f4427f6a1c1a96556194b40fc9dbf02,GovernanceReplaced,"GovernanceReplaced(address,address)",0x13abda02e63c790d0e2818b251282cfe5cbe0a8abd69c54bf5d2260c0907bd2e,false,,address address,oldGov newGov,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,9,0xcf3f4fa77f4427f6a1c1a96556194b40fc9dbf02,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,9,0xcf3f4fa77f4427f6a1c1a96556194b40fc9dbf02,Jail,"Jail(address,uint256)",0xbe3aa33bd245135e4e26b223d79d14ea479a47bff09f2b03c53838af1edbb14b,false,0,address uint256,app reason,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,9,0xcf3f4fa77f4427f6a1c1a96556194b40fc9dbf02,PoolBeaconLogicUpdated,"PoolBeaconLogicUpdated(address,address)",0x052cea8931962dd445ef48b0b998d3056bd0705f437087d60fe3c46a3fa09e1f,false,0,address address,beaconProxy newBeaconLogic,true,23701580,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,9,0xcf3f4fa77f4427f6a1c1a96556194b40fc9dbf02,SuperTokenFactoryUpdated,SuperTokenFactoryUpdated(address),0xce13a9895a1719ad4493b2ac1a9bfb36070566161abab408e7ecbe586da8d499,false,,address,newFactory,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,9,0xcf3f4fa77f4427f6a1c1a96556194b40fc9dbf02,SuperTokenLogicUpdated,"SuperTokenLogicUpdated(address,address)",0x840acbd291b38534819f47f875839277e502f40e1c7bfea2c5fc2c8017442cd3,false,0,address address,token code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,10,0x78743a68d52c9d6ccf3ff4558f3af510592e3c2d,AgreementClassRegistered,"AgreementClassRegistered(bytes32,address)",0x878135063a6cfb3bc333e534b1fdc83f4f12221cad6705c31c0567048a8bd3d1,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,10,0x78743a68d52c9d6ccf3ff4558f3af510592e3c2d,AgreementClassUpdated,"AgreementClassUpdated(bytes32,address)",0x9279aa773f2b588996032d8de89911555039f28b13a11a7c17074330bc082d9a,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,10,0x78743a68d52c9d6ccf3ff4558f3af510592e3c2d,AppRegistered,AppRegistered(address),0x0d540ad8f39e07d19909687352b9fa017405d93c91a6760981fbae9cf28bfef7,false,0,address,app,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,10,0x78743a68d52c9d6ccf3ff4558f3af510592e3c2d,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,10,0x78743a68d52c9d6ccf3ff4558f3af510592e3c2d,GovernanceReplaced,"GovernanceReplaced(address,address)",0x13abda02e63c790d0e2818b251282cfe5cbe0a8abd69c54bf5d2260c0907bd2e,false,,address address,oldGov newGov,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,10,0x78743a68d52c9d6ccf3ff4558f3af510592e3c2d,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,10,0x78743a68d52c9d6ccf3ff4558f3af510592e3c2d,Jail,"Jail(address,uint256)",0xbe3aa33bd245135e4e26b223d79d14ea479a47bff09f2b03c53838af1edbb14b,false,0,address uint256,app reason,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,10,0x78743a68d52c9d6ccf3ff4558f3af510592e3c2d,PoolBeaconLogicUpdated,"PoolBeaconLogicUpdated(address,address)",0x052cea8931962dd445ef48b0b998d3056bd0705f437087d60fe3c46a3fa09e1f,false,0,address address,beaconProxy newBeaconLogic,true,23701580,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,10,0x78743a68d52c9d6ccf3ff4558f3af510592e3c2d,SuperTokenFactoryUpdated,SuperTokenFactoryUpdated(address),0xce13a9895a1719ad4493b2ac1a9bfb36070566161abab408e7ecbe586da8d499,false,,address,newFactory,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,10,0x78743a68d52c9d6ccf3ff4558f3af510592e3c2d,SuperTokenLogicUpdated,"SuperTokenLogicUpdated(address,address)",0x840acbd291b38534819f47f875839277e502f40e1c7bfea2c5fc2c8017442cd3,false,0,address address,token code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,11,0x862f59081fc7907f940be4227b9f485d700e6cdd,AgreementClassRegistered,"AgreementClassRegistered(bytes32,address)",0x878135063a6cfb3bc333e534b1fdc83f4f12221cad6705c31c0567048a8bd3d1,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,11,0x862f59081fc7907f940be4227b9f485d700e6cdd,AgreementClassUpdated,"AgreementClassUpdated(bytes32,address)",0x9279aa773f2b588996032d8de89911555039f28b13a11a7c17074330bc082d9a,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,11,0x862f59081fc7907f940be4227b9f485d700e6cdd,AppRegistered,AppRegistered(address),0x0d540ad8f39e07d19909687352b9fa017405d93c91a6760981fbae9cf28bfef7,false,0,address,app,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,11,0x862f59081fc7907f940be4227b9f485d700e6cdd,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,11,0x862f59081fc7907f940be4227b9f485d700e6cdd,GovernanceReplaced,"GovernanceReplaced(address,address)",0x13abda02e63c790d0e2818b251282cfe5cbe0a8abd69c54bf5d2260c0907bd2e,false,,address address,oldGov newGov,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,11,0x862f59081fc7907f940be4227b9f485d700e6cdd,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,11,0x862f59081fc7907f940be4227b9f485d700e6cdd,Jail,"Jail(address,uint256)",0xbe3aa33bd245135e4e26b223d79d14ea479a47bff09f2b03c53838af1edbb14b,false,0,address uint256,app reason,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,11,0x862f59081fc7907f940be4227b9f485d700e6cdd,PoolBeaconLogicUpdated,"PoolBeaconLogicUpdated(address,address)",0x052cea8931962dd445ef48b0b998d3056bd0705f437087d60fe3c46a3fa09e1f,false,0,address address,beaconProxy newBeaconLogic,true,23701580,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,11,0x862f59081fc7907f940be4227b9f485d700e6cdd,SuperTokenFactoryUpdated,SuperTokenFactoryUpdated(address),0xce13a9895a1719ad4493b2ac1a9bfb36070566161abab408e7ecbe586da8d499,false,,address,newFactory,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,11,0x862f59081fc7907f940be4227b9f485d700e6cdd,SuperTokenLogicUpdated,"SuperTokenLogicUpdated(address,address)",0x840acbd291b38534819f47f875839277e502f40e1c7bfea2c5fc2c8017442cd3,false,0,address address,token code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,13,0xf26967f92151487f8c6642199c3441b02398d19e,AgreementClassRegistered,"AgreementClassRegistered(bytes32,address)",0x878135063a6cfb3bc333e534b1fdc83f4f12221cad6705c31c0567048a8bd3d1,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,13,0xf26967f92151487f8c6642199c3441b02398d19e,AgreementClassUpdated,"AgreementClassUpdated(bytes32,address)",0x9279aa773f2b588996032d8de89911555039f28b13a11a7c17074330bc082d9a,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,13,0xf26967f92151487f8c6642199c3441b02398d19e,AppRegistered,AppRegistered(address),0x0d540ad8f39e07d19909687352b9fa017405d93c91a6760981fbae9cf28bfef7,false,0,address,app,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,13,0xf26967f92151487f8c6642199c3441b02398d19e,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,13,0xf26967f92151487f8c6642199c3441b02398d19e,GovernanceReplaced,"GovernanceReplaced(address,address)",0x13abda02e63c790d0e2818b251282cfe5cbe0a8abd69c54bf5d2260c0907bd2e,false,,address address,oldGov newGov,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,13,0xf26967f92151487f8c6642199c3441b02398d19e,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,13,0xf26967f92151487f8c6642199c3441b02398d19e,Jail,"Jail(address,uint256)",0xbe3aa33bd245135e4e26b223d79d14ea479a47bff09f2b03c53838af1edbb14b,false,0,address uint256,app reason,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,13,0xf26967f92151487f8c6642199c3441b02398d19e,PoolBeaconLogicUpdated,"PoolBeaconLogicUpdated(address,address)",0x052cea8931962dd445ef48b0b998d3056bd0705f437087d60fe3c46a3fa09e1f,false,0,address address,beaconProxy newBeaconLogic,true,23701580,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,13,0xf26967f92151487f8c6642199c3441b02398d19e,SuperTokenFactoryUpdated,SuperTokenFactoryUpdated(address),0xce13a9895a1719ad4493b2ac1a9bfb36070566161abab408e7ecbe586da8d499,false,,address,newFactory,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,13,0xf26967f92151487f8c6642199c3441b02398d19e,SuperTokenLogicUpdated,"SuperTokenLogicUpdated(address,address)",0x840acbd291b38534819f47f875839277e502f40e1c7bfea2c5fc2c8017442cd3,false,0,address address,token code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,14,0x9a19773ebe33c5917012c2bb982bc683d91ec600,AgreementClassRegistered,"AgreementClassRegistered(bytes32,address)",0x878135063a6cfb3bc333e534b1fdc83f4f12221cad6705c31c0567048a8bd3d1,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,14,0x9a19773ebe33c5917012c2bb982bc683d91ec600,AgreementClassUpdated,"AgreementClassUpdated(bytes32,address)",0x9279aa773f2b588996032d8de89911555039f28b13a11a7c17074330bc082d9a,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,14,0x9a19773ebe33c5917012c2bb982bc683d91ec600,AppRegistered,AppRegistered(address),0x0d540ad8f39e07d19909687352b9fa017405d93c91a6760981fbae9cf28bfef7,false,0,address,app,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,14,0x9a19773ebe33c5917012c2bb982bc683d91ec600,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,14,0x9a19773ebe33c5917012c2bb982bc683d91ec600,GovernanceReplaced,"GovernanceReplaced(address,address)",0x13abda02e63c790d0e2818b251282cfe5cbe0a8abd69c54bf5d2260c0907bd2e,false,,address address,oldGov newGov,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,14,0x9a19773ebe33c5917012c2bb982bc683d91ec600,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,14,0x9a19773ebe33c5917012c2bb982bc683d91ec600,Jail,"Jail(address,uint256)",0xbe3aa33bd245135e4e26b223d79d14ea479a47bff09f2b03c53838af1edbb14b,false,0,address uint256,app reason,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,14,0x9a19773ebe33c5917012c2bb982bc683d91ec600,PoolBeaconLogicUpdated,"PoolBeaconLogicUpdated(address,address)",0x052cea8931962dd445ef48b0b998d3056bd0705f437087d60fe3c46a3fa09e1f,false,0,address address,beaconProxy newBeaconLogic,true,23701580,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,14,0x9a19773ebe33c5917012c2bb982bc683d91ec600,SuperTokenFactoryUpdated,SuperTokenFactoryUpdated(address),0xce13a9895a1719ad4493b2ac1a9bfb36070566161abab408e7ecbe586da8d499,false,,address,newFactory,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,14,0x9a19773ebe33c5917012c2bb982bc683d91ec600,SuperTokenLogicUpdated,"SuperTokenLogicUpdated(address,address)",0x840acbd291b38534819f47f875839277e502f40e1c7bfea2c5fc2c8017442cd3,false,0,address address,token code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,15,0x97620d4d7950223963f00db25f12b4ac1d4eed99,AgreementClassRegistered,"AgreementClassRegistered(bytes32,address)",0x878135063a6cfb3bc333e534b1fdc83f4f12221cad6705c31c0567048a8bd3d1,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,15,0x97620d4d7950223963f00db25f12b4ac1d4eed99,AgreementClassUpdated,"AgreementClassUpdated(bytes32,address)",0x9279aa773f2b588996032d8de89911555039f28b13a11a7c17074330bc082d9a,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,15,0x97620d4d7950223963f00db25f12b4ac1d4eed99,AppRegistered,AppRegistered(address),0x0d540ad8f39e07d19909687352b9fa017405d93c91a6760981fbae9cf28bfef7,false,0,address,app,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,15,0x97620d4d7950223963f00db25f12b4ac1d4eed99,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,15,0x97620d4d7950223963f00db25f12b4ac1d4eed99,GovernanceReplaced,"GovernanceReplaced(address,address)",0x13abda02e63c790d0e2818b251282cfe5cbe0a8abd69c54bf5d2260c0907bd2e,false,,address address,oldGov newGov,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,15,0x97620d4d7950223963f00db25f12b4ac1d4eed99,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,15,0x97620d4d7950223963f00db25f12b4ac1d4eed99,Jail,"Jail(address,uint256)",0xbe3aa33bd245135e4e26b223d79d14ea479a47bff09f2b03c53838af1edbb14b,false,0,address uint256,app reason,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,15,0x97620d4d7950223963f00db25f12b4ac1d4eed99,PoolBeaconLogicUpdated,"PoolBeaconLogicUpdated(address,address)",0x052cea8931962dd445ef48b0b998d3056bd0705f437087d60fe3c46a3fa09e1f,false,0,address address,beaconProxy newBeaconLogic,true,23701580,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,15,0x97620d4d7950223963f00db25f12b4ac1d4eed99,SuperTokenFactoryUpdated,SuperTokenFactoryUpdated(address),0xce13a9895a1719ad4493b2ac1a9bfb36070566161abab408e7ecbe586da8d499,false,,address,newFactory,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,15,0x97620d4d7950223963f00db25f12b4ac1d4eed99,SuperTokenLogicUpdated,"SuperTokenLogicUpdated(address,address)",0x840acbd291b38534819f47f875839277e502f40e1c7bfea2c5fc2c8017442cd3,false,0,address address,token code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,16,0x3b526b50709a5551030673be284bc9c1e38351ac,AgreementClassRegistered,"AgreementClassRegistered(bytes32,address)",0x878135063a6cfb3bc333e534b1fdc83f4f12221cad6705c31c0567048a8bd3d1,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,16,0x3b526b50709a5551030673be284bc9c1e38351ac,AgreementClassUpdated,"AgreementClassUpdated(bytes32,address)",0x9279aa773f2b588996032d8de89911555039f28b13a11a7c17074330bc082d9a,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,16,0x3b526b50709a5551030673be284bc9c1e38351ac,AppRegistered,AppRegistered(address),0x0d540ad8f39e07d19909687352b9fa017405d93c91a6760981fbae9cf28bfef7,false,0,address,app,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,16,0x3b526b50709a5551030673be284bc9c1e38351ac,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,16,0x3b526b50709a5551030673be284bc9c1e38351ac,GovernanceReplaced,"GovernanceReplaced(address,address)",0x13abda02e63c790d0e2818b251282cfe5cbe0a8abd69c54bf5d2260c0907bd2e,false,,address address,oldGov newGov,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,16,0x3b526b50709a5551030673be284bc9c1e38351ac,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,16,0x3b526b50709a5551030673be284bc9c1e38351ac,Jail,"Jail(address,uint256)",0xbe3aa33bd245135e4e26b223d79d14ea479a47bff09f2b03c53838af1edbb14b,false,0,address uint256,app reason,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,16,0x3b526b50709a5551030673be284bc9c1e38351ac,PoolBeaconLogicUpdated,"PoolBeaconLogicUpdated(address,address)",0x052cea8931962dd445ef48b0b998d3056bd0705f437087d60fe3c46a3fa09e1f,false,0,address address,beaconProxy newBeaconLogic,true,23701580,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,16,0x3b526b50709a5551030673be284bc9c1e38351ac,SuperTokenFactoryUpdated,SuperTokenFactoryUpdated(address),0xce13a9895a1719ad4493b2ac1a9bfb36070566161abab408e7ecbe586da8d499,false,,address,newFactory,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,16,0x3b526b50709a5551030673be284bc9c1e38351ac,SuperTokenLogicUpdated,"SuperTokenLogicUpdated(address,address)",0x840acbd291b38534819f47f875839277e502f40e1c7bfea2c5fc2c8017442cd3,false,0,address address,token code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,17,0x8e03f0edb581e8b6aad80eece89b3028388f4b53,AgreementClassRegistered,"AgreementClassRegistered(bytes32,address)",0x878135063a6cfb3bc333e534b1fdc83f4f12221cad6705c31c0567048a8bd3d1,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,17,0x8e03f0edb581e8b6aad80eece89b3028388f4b53,AgreementClassUpdated,"AgreementClassUpdated(bytes32,address)",0x9279aa773f2b588996032d8de89911555039f28b13a11a7c17074330bc082d9a,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,17,0x8e03f0edb581e8b6aad80eece89b3028388f4b53,AppRegistered,AppRegistered(address),0x0d540ad8f39e07d19909687352b9fa017405d93c91a6760981fbae9cf28bfef7,false,0,address,app,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,17,0x8e03f0edb581e8b6aad80eece89b3028388f4b53,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,17,0x8e03f0edb581e8b6aad80eece89b3028388f4b53,GovernanceReplaced,"GovernanceReplaced(address,address)",0x13abda02e63c790d0e2818b251282cfe5cbe0a8abd69c54bf5d2260c0907bd2e,false,,address address,oldGov newGov,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,17,0x8e03f0edb581e8b6aad80eece89b3028388f4b53,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,17,0x8e03f0edb581e8b6aad80eece89b3028388f4b53,Jail,"Jail(address,uint256)",0xbe3aa33bd245135e4e26b223d79d14ea479a47bff09f2b03c53838af1edbb14b,false,0,address uint256,app reason,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,17,0x8e03f0edb581e8b6aad80eece89b3028388f4b53,PoolBeaconLogicUpdated,"PoolBeaconLogicUpdated(address,address)",0x052cea8931962dd445ef48b0b998d3056bd0705f437087d60fe3c46a3fa09e1f,false,0,address address,beaconProxy newBeaconLogic,true,23701580,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,17,0x8e03f0edb581e8b6aad80eece89b3028388f4b53,SuperTokenFactoryUpdated,SuperTokenFactoryUpdated(address),0xce13a9895a1719ad4493b2ac1a9bfb36070566161abab408e7ecbe586da8d499,false,,address,newFactory,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,17,0x8e03f0edb581e8b6aad80eece89b3028388f4b53,SuperTokenLogicUpdated,"SuperTokenLogicUpdated(address,address)",0x840acbd291b38534819f47f875839277e502f40e1c7bfea2c5fc2c8017442cd3,false,0,address address,token code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,18,0xf17e88391b68c2a5972131f5044fd6ace665f221,AgreementClassRegistered,"AgreementClassRegistered(bytes32,address)",0x878135063a6cfb3bc333e534b1fdc83f4f12221cad6705c31c0567048a8bd3d1,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,18,0xf17e88391b68c2a5972131f5044fd6ace665f221,AgreementClassUpdated,"AgreementClassUpdated(bytes32,address)",0x9279aa773f2b588996032d8de89911555039f28b13a11a7c17074330bc082d9a,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,18,0xf17e88391b68c2a5972131f5044fd6ace665f221,AppRegistered,AppRegistered(address),0x0d540ad8f39e07d19909687352b9fa017405d93c91a6760981fbae9cf28bfef7,false,0,address,app,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,18,0xf17e88391b68c2a5972131f5044fd6ace665f221,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,18,0xf17e88391b68c2a5972131f5044fd6ace665f221,GovernanceReplaced,"GovernanceReplaced(address,address)",0x13abda02e63c790d0e2818b251282cfe5cbe0a8abd69c54bf5d2260c0907bd2e,false,,address address,oldGov newGov,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,18,0xf17e88391b68c2a5972131f5044fd6ace665f221,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,18,0xf17e88391b68c2a5972131f5044fd6ace665f221,Jail,"Jail(address,uint256)",0xbe3aa33bd245135e4e26b223d79d14ea479a47bff09f2b03c53838af1edbb14b,false,0,address uint256,app reason,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,18,0xf17e88391b68c2a5972131f5044fd6ace665f221,PoolBeaconLogicUpdated,"PoolBeaconLogicUpdated(address,address)",0x052cea8931962dd445ef48b0b998d3056bd0705f437087d60fe3c46a3fa09e1f,false,0,address address,beaconProxy newBeaconLogic,true,23701580,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,18,0xf17e88391b68c2a5972131f5044fd6ace665f221,SuperTokenFactoryUpdated,SuperTokenFactoryUpdated(address),0xce13a9895a1719ad4493b2ac1a9bfb36070566161abab408e7ecbe586da8d499,false,,address,newFactory,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,18,0xf17e88391b68c2a5972131f5044fd6ace665f221,SuperTokenLogicUpdated,"SuperTokenLogicUpdated(address,address)",0x840acbd291b38534819f47f875839277e502f40e1c7bfea2c5fc2c8017442cd3,false,0,address address,token code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,19,0xc899724f32859e8169e607a23448e4b487b4dc04,AgreementClassRegistered,"AgreementClassRegistered(bytes32,address)",0x878135063a6cfb3bc333e534b1fdc83f4f12221cad6705c31c0567048a8bd3d1,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,19,0xc899724f32859e8169e607a23448e4b487b4dc04,AgreementClassUpdated,"AgreementClassUpdated(bytes32,address)",0x9279aa773f2b588996032d8de89911555039f28b13a11a7c17074330bc082d9a,false,,bytes32 address,agreementType code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,19,0xc899724f32859e8169e607a23448e4b487b4dc04,AppRegistered,AppRegistered(address),0x0d540ad8f39e07d19909687352b9fa017405d93c91a6760981fbae9cf28bfef7,false,0,address,app,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,19,0xc899724f32859e8169e607a23448e4b487b4dc04,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,19,0xc899724f32859e8169e607a23448e4b487b4dc04,GovernanceReplaced,"GovernanceReplaced(address,address)",0x13abda02e63c790d0e2818b251282cfe5cbe0a8abd69c54bf5d2260c0907bd2e,false,,address address,oldGov newGov,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,19,0xc899724f32859e8169e607a23448e4b487b4dc04,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,19,0xc899724f32859e8169e607a23448e4b487b4dc04,Jail,"Jail(address,uint256)",0xbe3aa33bd245135e4e26b223d79d14ea479a47bff09f2b03c53838af1edbb14b,false,0,address uint256,app reason,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,19,0xc899724f32859e8169e607a23448e4b487b4dc04,PoolBeaconLogicUpdated,"PoolBeaconLogicUpdated(address,address)",0x052cea8931962dd445ef48b0b998d3056bd0705f437087d60fe3c46a3fa09e1f,false,0,address address,beaconProxy newBeaconLogic,true,23701580,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,19,0xc899724f32859e8169e607a23448e4b487b4dc04,SuperTokenFactoryUpdated,SuperTokenFactoryUpdated(address),0xce13a9895a1719ad4493b2ac1a9bfb36070566161abab408e7ecbe586da8d499,false,,address,newFactory,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidHost,0xa4ff07cf81c02cfd356184879d953970ca957585,19,0xc899724f32859e8169e607a23448e4b487b4dc04,SuperTokenLogicUpdated,"SuperTokenLogicUpdated(address,address)",0x840acbd291b38534819f47f875839277e502f40e1c7bfea2c5fc2c8017442cd3,false,0,address address,token code,true,16393473,76632579,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19 of 20. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,1,0x7dc6b57adae1aaa94e01a3049cd42b8adce5090c,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,1,0x7dc6b57adae1aaa94e01a3049cd42b8adce5090c,IndexCreated,"IndexCreated(address,address,uint32,bytes)",0x01ab8663165edfb7390d9e5f75d960a66dacf4f01fa9787e3a731c870d0da921,false,0 1 2,address address uint32 bytes,token publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,1,0x7dc6b57adae1aaa94e01a3049cd42b8adce5090c,IndexDistributionClaimed,"IndexDistributionClaimed(address,address,uint32,address,uint256)",0x467eccd248ef31c8bcef16d94856855799a8783aeef10f3759e43614059a6bb1,false,0 1 2,address address uint32 address uint256,token publisher indexId subscriber amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,1,0x7dc6b57adae1aaa94e01a3049cd42b8adce5090c,IndexSubscribed,"IndexSubscribed(address,address,uint32,address,bytes)",0x492d2641617cfaf24ac7328f85bc5bdf5113537d78dc7671afa4f49a73f053c2,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,1,0x7dc6b57adae1aaa94e01a3049cd42b8adce5090c,IndexUnitsUpdated,"IndexUnitsUpdated(address,address,uint32,address,uint128,bytes)",0x0115987243fd19d615b5ea62a80372a06a2b37fec378b148ee7a507c5c4c0a39,false,0 1 2,address address uint32 address uint128 bytes,token publisher indexId subscriber units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,1,0x7dc6b57adae1aaa94e01a3049cd42b8adce5090c,IndexUnsubscribed,"IndexUnsubscribed(address,address,uint32,address,bytes)",0xe1f8e9cd8061e5b251769965bda6ca9ef1674bc6541fb9131039fa53f024d142,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,1,0x7dc6b57adae1aaa94e01a3049cd42b8adce5090c,IndexUpdated,"IndexUpdated(address,address,uint32,uint128,uint128,uint128,uint128,bytes)",0x81e37f3d9f16cbf29a62d6a1c21d79b23ef29b54124ec44af43a50fffb9304f3,false,0 1 2,address address uint32 uint128 uint128 uint128 uint128 bytes,token publisher indexId oldIndexValue newIndexValue totalUnitsPending totalUnitsApproved userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,1,0x7dc6b57adae1aaa94e01a3049cd42b8adce5090c,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,1,0x7dc6b57adae1aaa94e01a3049cd42b8adce5090c,SubscriptionApproved,"SubscriptionApproved(address,address,address,uint32,bytes)",0xc0b8396b655615cdb85fe462a9a1792480816f909cd46d9517a940b386dfbf6b,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,1,0x7dc6b57adae1aaa94e01a3049cd42b8adce5090c,SubscriptionDistributionClaimed,"SubscriptionDistributionClaimed(address,address,address,uint32,uint256)",0x48a3d91d4a07e4982b081260e24f922bd33bb965882772d6de19c922c3eabdea,false,0 1,address address address uint32 uint256,token subscriber publisher indexId amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,1,0x7dc6b57adae1aaa94e01a3049cd42b8adce5090c,SubscriptionRevoked,"SubscriptionRevoked(address,address,address,uint32,bytes)",0x9e02127550b99adc8cc6ee332a36f31338facdbc396cebefce9a047247cd0455,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,1,0x7dc6b57adae1aaa94e01a3049cd42b8adce5090c,SubscriptionUnitsUpdated,"SubscriptionUnitsUpdated(address,address,address,uint32,uint128,bytes)",0xe0707ac7efb8b59c22189af8d004ed17dc9e4379e71b9066119b62c182524977,false,0 1,address address address uint32 uint128 bytes,token subscriber publisher indexId units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,2,0xd399e2fb5f4cf3722a11f65b88fab6b2b8621005,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,2,0xd399e2fb5f4cf3722a11f65b88fab6b2b8621005,IndexCreated,"IndexCreated(address,address,uint32,bytes)",0x01ab8663165edfb7390d9e5f75d960a66dacf4f01fa9787e3a731c870d0da921,false,0 1 2,address address uint32 bytes,token publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,2,0xd399e2fb5f4cf3722a11f65b88fab6b2b8621005,IndexDistributionClaimed,"IndexDistributionClaimed(address,address,uint32,address,uint256)",0x467eccd248ef31c8bcef16d94856855799a8783aeef10f3759e43614059a6bb1,false,0 1 2,address address uint32 address uint256,token publisher indexId subscriber amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,2,0xd399e2fb5f4cf3722a11f65b88fab6b2b8621005,IndexSubscribed,"IndexSubscribed(address,address,uint32,address,bytes)",0x492d2641617cfaf24ac7328f85bc5bdf5113537d78dc7671afa4f49a73f053c2,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,2,0xd399e2fb5f4cf3722a11f65b88fab6b2b8621005,IndexUnitsUpdated,"IndexUnitsUpdated(address,address,uint32,address,uint128,bytes)",0x0115987243fd19d615b5ea62a80372a06a2b37fec378b148ee7a507c5c4c0a39,false,0 1 2,address address uint32 address uint128 bytes,token publisher indexId subscriber units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,2,0xd399e2fb5f4cf3722a11f65b88fab6b2b8621005,IndexUnsubscribed,"IndexUnsubscribed(address,address,uint32,address,bytes)",0xe1f8e9cd8061e5b251769965bda6ca9ef1674bc6541fb9131039fa53f024d142,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,2,0xd399e2fb5f4cf3722a11f65b88fab6b2b8621005,IndexUpdated,"IndexUpdated(address,address,uint32,uint128,uint128,uint128,uint128,bytes)",0x81e37f3d9f16cbf29a62d6a1c21d79b23ef29b54124ec44af43a50fffb9304f3,false,0 1 2,address address uint32 uint128 uint128 uint128 uint128 bytes,token publisher indexId oldIndexValue newIndexValue totalUnitsPending totalUnitsApproved userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,2,0xd399e2fb5f4cf3722a11f65b88fab6b2b8621005,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,2,0xd399e2fb5f4cf3722a11f65b88fab6b2b8621005,SubscriptionApproved,"SubscriptionApproved(address,address,address,uint32,bytes)",0xc0b8396b655615cdb85fe462a9a1792480816f909cd46d9517a940b386dfbf6b,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,2,0xd399e2fb5f4cf3722a11f65b88fab6b2b8621005,SubscriptionDistributionClaimed,"SubscriptionDistributionClaimed(address,address,address,uint32,uint256)",0x48a3d91d4a07e4982b081260e24f922bd33bb965882772d6de19c922c3eabdea,false,0 1,address address address uint32 uint256,token subscriber publisher indexId amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,2,0xd399e2fb5f4cf3722a11f65b88fab6b2b8621005,SubscriptionRevoked,"SubscriptionRevoked(address,address,address,uint32,bytes)",0x9e02127550b99adc8cc6ee332a36f31338facdbc396cebefce9a047247cd0455,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,2,0xd399e2fb5f4cf3722a11f65b88fab6b2b8621005,SubscriptionUnitsUpdated,"SubscriptionUnitsUpdated(address,address,address,uint32,uint128,bytes)",0xe0707ac7efb8b59c22189af8d004ed17dc9e4379e71b9066119b62c182524977,false,0 1,address address address uint32 uint128 bytes,token subscriber publisher indexId units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,3,0x507c3a7c6ccc253884a2e3a3ee2a211cc7e796a6,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,3,0x507c3a7c6ccc253884a2e3a3ee2a211cc7e796a6,IndexCreated,"IndexCreated(address,address,uint32,bytes)",0x01ab8663165edfb7390d9e5f75d960a66dacf4f01fa9787e3a731c870d0da921,false,0 1 2,address address uint32 bytes,token publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,3,0x507c3a7c6ccc253884a2e3a3ee2a211cc7e796a6,IndexDistributionClaimed,"IndexDistributionClaimed(address,address,uint32,address,uint256)",0x467eccd248ef31c8bcef16d94856855799a8783aeef10f3759e43614059a6bb1,false,0 1 2,address address uint32 address uint256,token publisher indexId subscriber amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,3,0x507c3a7c6ccc253884a2e3a3ee2a211cc7e796a6,IndexSubscribed,"IndexSubscribed(address,address,uint32,address,bytes)",0x492d2641617cfaf24ac7328f85bc5bdf5113537d78dc7671afa4f49a73f053c2,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,3,0x507c3a7c6ccc253884a2e3a3ee2a211cc7e796a6,IndexUnitsUpdated,"IndexUnitsUpdated(address,address,uint32,address,uint128,bytes)",0x0115987243fd19d615b5ea62a80372a06a2b37fec378b148ee7a507c5c4c0a39,false,0 1 2,address address uint32 address uint128 bytes,token publisher indexId subscriber units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,3,0x507c3a7c6ccc253884a2e3a3ee2a211cc7e796a6,IndexUnsubscribed,"IndexUnsubscribed(address,address,uint32,address,bytes)",0xe1f8e9cd8061e5b251769965bda6ca9ef1674bc6541fb9131039fa53f024d142,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,3,0x507c3a7c6ccc253884a2e3a3ee2a211cc7e796a6,IndexUpdated,"IndexUpdated(address,address,uint32,uint128,uint128,uint128,uint128,bytes)",0x81e37f3d9f16cbf29a62d6a1c21d79b23ef29b54124ec44af43a50fffb9304f3,false,0 1 2,address address uint32 uint128 uint128 uint128 uint128 bytes,token publisher indexId oldIndexValue newIndexValue totalUnitsPending totalUnitsApproved userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,3,0x507c3a7c6ccc253884a2e3a3ee2a211cc7e796a6,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,3,0x507c3a7c6ccc253884a2e3a3ee2a211cc7e796a6,SubscriptionApproved,"SubscriptionApproved(address,address,address,uint32,bytes)",0xc0b8396b655615cdb85fe462a9a1792480816f909cd46d9517a940b386dfbf6b,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,3,0x507c3a7c6ccc253884a2e3a3ee2a211cc7e796a6,SubscriptionDistributionClaimed,"SubscriptionDistributionClaimed(address,address,address,uint32,uint256)",0x48a3d91d4a07e4982b081260e24f922bd33bb965882772d6de19c922c3eabdea,false,0 1,address address address uint32 uint256,token subscriber publisher indexId amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,3,0x507c3a7c6ccc253884a2e3a3ee2a211cc7e796a6,SubscriptionRevoked,"SubscriptionRevoked(address,address,address,uint32,bytes)",0x9e02127550b99adc8cc6ee332a36f31338facdbc396cebefce9a047247cd0455,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,3,0x507c3a7c6ccc253884a2e3a3ee2a211cc7e796a6,SubscriptionUnitsUpdated,"SubscriptionUnitsUpdated(address,address,address,uint32,uint128,bytes)",0xe0707ac7efb8b59c22189af8d004ed17dc9e4379e71b9066119b62c182524977,false,0 1,address address address uint32 uint128 bytes,token subscriber publisher indexId units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,4,0x2622bfc83f429bf313341857850a1dde09685855,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,4,0x2622bfc83f429bf313341857850a1dde09685855,IndexCreated,"IndexCreated(address,address,uint32,bytes)",0x01ab8663165edfb7390d9e5f75d960a66dacf4f01fa9787e3a731c870d0da921,false,0 1 2,address address uint32 bytes,token publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,4,0x2622bfc83f429bf313341857850a1dde09685855,IndexDistributionClaimed,"IndexDistributionClaimed(address,address,uint32,address,uint256)",0x467eccd248ef31c8bcef16d94856855799a8783aeef10f3759e43614059a6bb1,false,0 1 2,address address uint32 address uint256,token publisher indexId subscriber amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,4,0x2622bfc83f429bf313341857850a1dde09685855,IndexSubscribed,"IndexSubscribed(address,address,uint32,address,bytes)",0x492d2641617cfaf24ac7328f85bc5bdf5113537d78dc7671afa4f49a73f053c2,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,4,0x2622bfc83f429bf313341857850a1dde09685855,IndexUnitsUpdated,"IndexUnitsUpdated(address,address,uint32,address,uint128,bytes)",0x0115987243fd19d615b5ea62a80372a06a2b37fec378b148ee7a507c5c4c0a39,false,0 1 2,address address uint32 address uint128 bytes,token publisher indexId subscriber units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,4,0x2622bfc83f429bf313341857850a1dde09685855,IndexUnsubscribed,"IndexUnsubscribed(address,address,uint32,address,bytes)",0xe1f8e9cd8061e5b251769965bda6ca9ef1674bc6541fb9131039fa53f024d142,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,4,0x2622bfc83f429bf313341857850a1dde09685855,IndexUpdated,"IndexUpdated(address,address,uint32,uint128,uint128,uint128,uint128,bytes)",0x81e37f3d9f16cbf29a62d6a1c21d79b23ef29b54124ec44af43a50fffb9304f3,false,0 1 2,address address uint32 uint128 uint128 uint128 uint128 bytes,token publisher indexId oldIndexValue newIndexValue totalUnitsPending totalUnitsApproved userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,4,0x2622bfc83f429bf313341857850a1dde09685855,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,4,0x2622bfc83f429bf313341857850a1dde09685855,SubscriptionApproved,"SubscriptionApproved(address,address,address,uint32,bytes)",0xc0b8396b655615cdb85fe462a9a1792480816f909cd46d9517a940b386dfbf6b,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,4,0x2622bfc83f429bf313341857850a1dde09685855,SubscriptionDistributionClaimed,"SubscriptionDistributionClaimed(address,address,address,uint32,uint256)",0x48a3d91d4a07e4982b081260e24f922bd33bb965882772d6de19c922c3eabdea,false,0 1,address address address uint32 uint256,token subscriber publisher indexId amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,4,0x2622bfc83f429bf313341857850a1dde09685855,SubscriptionRevoked,"SubscriptionRevoked(address,address,address,uint32,bytes)",0x9e02127550b99adc8cc6ee332a36f31338facdbc396cebefce9a047247cd0455,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,4,0x2622bfc83f429bf313341857850a1dde09685855,SubscriptionUnitsUpdated,"SubscriptionUnitsUpdated(address,address,address,uint32,uint128,bytes)",0xe0707ac7efb8b59c22189af8d004ed17dc9e4379e71b9066119b62c182524977,false,0 1,address address address uint32 uint128 bytes,token subscriber publisher indexId units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,5,0xd48317ccdac2ca3fd5e3c58c32da3a7c517937b6,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,5,0xd48317ccdac2ca3fd5e3c58c32da3a7c517937b6,IndexCreated,"IndexCreated(address,address,uint32,bytes)",0x01ab8663165edfb7390d9e5f75d960a66dacf4f01fa9787e3a731c870d0da921,false,0 1 2,address address uint32 bytes,token publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,5,0xd48317ccdac2ca3fd5e3c58c32da3a7c517937b6,IndexDistributionClaimed,"IndexDistributionClaimed(address,address,uint32,address,uint256)",0x467eccd248ef31c8bcef16d94856855799a8783aeef10f3759e43614059a6bb1,false,0 1 2,address address uint32 address uint256,token publisher indexId subscriber amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,5,0xd48317ccdac2ca3fd5e3c58c32da3a7c517937b6,IndexSubscribed,"IndexSubscribed(address,address,uint32,address,bytes)",0x492d2641617cfaf24ac7328f85bc5bdf5113537d78dc7671afa4f49a73f053c2,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,5,0xd48317ccdac2ca3fd5e3c58c32da3a7c517937b6,IndexUnitsUpdated,"IndexUnitsUpdated(address,address,uint32,address,uint128,bytes)",0x0115987243fd19d615b5ea62a80372a06a2b37fec378b148ee7a507c5c4c0a39,false,0 1 2,address address uint32 address uint128 bytes,token publisher indexId subscriber units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,5,0xd48317ccdac2ca3fd5e3c58c32da3a7c517937b6,IndexUnsubscribed,"IndexUnsubscribed(address,address,uint32,address,bytes)",0xe1f8e9cd8061e5b251769965bda6ca9ef1674bc6541fb9131039fa53f024d142,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,5,0xd48317ccdac2ca3fd5e3c58c32da3a7c517937b6,IndexUpdated,"IndexUpdated(address,address,uint32,uint128,uint128,uint128,uint128,bytes)",0x81e37f3d9f16cbf29a62d6a1c21d79b23ef29b54124ec44af43a50fffb9304f3,false,0 1 2,address address uint32 uint128 uint128 uint128 uint128 bytes,token publisher indexId oldIndexValue newIndexValue totalUnitsPending totalUnitsApproved userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,5,0xd48317ccdac2ca3fd5e3c58c32da3a7c517937b6,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,5,0xd48317ccdac2ca3fd5e3c58c32da3a7c517937b6,SubscriptionApproved,"SubscriptionApproved(address,address,address,uint32,bytes)",0xc0b8396b655615cdb85fe462a9a1792480816f909cd46d9517a940b386dfbf6b,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,5,0xd48317ccdac2ca3fd5e3c58c32da3a7c517937b6,SubscriptionDistributionClaimed,"SubscriptionDistributionClaimed(address,address,address,uint32,uint256)",0x48a3d91d4a07e4982b081260e24f922bd33bb965882772d6de19c922c3eabdea,false,0 1,address address address uint32 uint256,token subscriber publisher indexId amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,5,0xd48317ccdac2ca3fd5e3c58c32da3a7c517937b6,SubscriptionRevoked,"SubscriptionRevoked(address,address,address,uint32,bytes)",0x9e02127550b99adc8cc6ee332a36f31338facdbc396cebefce9a047247cd0455,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,5,0xd48317ccdac2ca3fd5e3c58c32da3a7c517937b6,SubscriptionUnitsUpdated,"SubscriptionUnitsUpdated(address,address,address,uint32,uint128,bytes)",0xe0707ac7efb8b59c22189af8d004ed17dc9e4379e71b9066119b62c182524977,false,0 1,address address address uint32 uint128 bytes,token subscriber publisher indexId units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,6,0xfb2b126660be2fdeba254b1f6e4348644e8482e7,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,6,0xfb2b126660be2fdeba254b1f6e4348644e8482e7,IndexCreated,"IndexCreated(address,address,uint32,bytes)",0x01ab8663165edfb7390d9e5f75d960a66dacf4f01fa9787e3a731c870d0da921,false,0 1 2,address address uint32 bytes,token publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,6,0xfb2b126660be2fdeba254b1f6e4348644e8482e7,IndexDistributionClaimed,"IndexDistributionClaimed(address,address,uint32,address,uint256)",0x467eccd248ef31c8bcef16d94856855799a8783aeef10f3759e43614059a6bb1,false,0 1 2,address address uint32 address uint256,token publisher indexId subscriber amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,6,0xfb2b126660be2fdeba254b1f6e4348644e8482e7,IndexSubscribed,"IndexSubscribed(address,address,uint32,address,bytes)",0x492d2641617cfaf24ac7328f85bc5bdf5113537d78dc7671afa4f49a73f053c2,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,6,0xfb2b126660be2fdeba254b1f6e4348644e8482e7,IndexUnitsUpdated,"IndexUnitsUpdated(address,address,uint32,address,uint128,bytes)",0x0115987243fd19d615b5ea62a80372a06a2b37fec378b148ee7a507c5c4c0a39,false,0 1 2,address address uint32 address uint128 bytes,token publisher indexId subscriber units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,6,0xfb2b126660be2fdeba254b1f6e4348644e8482e7,IndexUnsubscribed,"IndexUnsubscribed(address,address,uint32,address,bytes)",0xe1f8e9cd8061e5b251769965bda6ca9ef1674bc6541fb9131039fa53f024d142,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,6,0xfb2b126660be2fdeba254b1f6e4348644e8482e7,IndexUpdated,"IndexUpdated(address,address,uint32,uint128,uint128,uint128,uint128,bytes)",0x81e37f3d9f16cbf29a62d6a1c21d79b23ef29b54124ec44af43a50fffb9304f3,false,0 1 2,address address uint32 uint128 uint128 uint128 uint128 bytes,token publisher indexId oldIndexValue newIndexValue totalUnitsPending totalUnitsApproved userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,6,0xfb2b126660be2fdeba254b1f6e4348644e8482e7,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,6,0xfb2b126660be2fdeba254b1f6e4348644e8482e7,SubscriptionApproved,"SubscriptionApproved(address,address,address,uint32,bytes)",0xc0b8396b655615cdb85fe462a9a1792480816f909cd46d9517a940b386dfbf6b,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,6,0xfb2b126660be2fdeba254b1f6e4348644e8482e7,SubscriptionDistributionClaimed,"SubscriptionDistributionClaimed(address,address,address,uint32,uint256)",0x48a3d91d4a07e4982b081260e24f922bd33bb965882772d6de19c922c3eabdea,false,0 1,address address address uint32 uint256,token subscriber publisher indexId amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,6,0xfb2b126660be2fdeba254b1f6e4348644e8482e7,SubscriptionRevoked,"SubscriptionRevoked(address,address,address,uint32,bytes)",0x9e02127550b99adc8cc6ee332a36f31338facdbc396cebefce9a047247cd0455,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,6,0xfb2b126660be2fdeba254b1f6e4348644e8482e7,SubscriptionUnitsUpdated,"SubscriptionUnitsUpdated(address,address,address,uint32,uint128,bytes)",0xe0707ac7efb8b59c22189af8d004ed17dc9e4379e71b9066119b62c182524977,false,0 1,address address address uint32 uint128 bytes,token subscriber publisher indexId units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,7,0x2e4861b1f56a67473b7bf0dd1ef85e9e9fa5ad75,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,7,0x2e4861b1f56a67473b7bf0dd1ef85e9e9fa5ad75,IndexCreated,"IndexCreated(address,address,uint32,bytes)",0x01ab8663165edfb7390d9e5f75d960a66dacf4f01fa9787e3a731c870d0da921,false,0 1 2,address address uint32 bytes,token publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,7,0x2e4861b1f56a67473b7bf0dd1ef85e9e9fa5ad75,IndexDistributionClaimed,"IndexDistributionClaimed(address,address,uint32,address,uint256)",0x467eccd248ef31c8bcef16d94856855799a8783aeef10f3759e43614059a6bb1,false,0 1 2,address address uint32 address uint256,token publisher indexId subscriber amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,7,0x2e4861b1f56a67473b7bf0dd1ef85e9e9fa5ad75,IndexSubscribed,"IndexSubscribed(address,address,uint32,address,bytes)",0x492d2641617cfaf24ac7328f85bc5bdf5113537d78dc7671afa4f49a73f053c2,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,7,0x2e4861b1f56a67473b7bf0dd1ef85e9e9fa5ad75,IndexUnitsUpdated,"IndexUnitsUpdated(address,address,uint32,address,uint128,bytes)",0x0115987243fd19d615b5ea62a80372a06a2b37fec378b148ee7a507c5c4c0a39,false,0 1 2,address address uint32 address uint128 bytes,token publisher indexId subscriber units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,7,0x2e4861b1f56a67473b7bf0dd1ef85e9e9fa5ad75,IndexUnsubscribed,"IndexUnsubscribed(address,address,uint32,address,bytes)",0xe1f8e9cd8061e5b251769965bda6ca9ef1674bc6541fb9131039fa53f024d142,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,7,0x2e4861b1f56a67473b7bf0dd1ef85e9e9fa5ad75,IndexUpdated,"IndexUpdated(address,address,uint32,uint128,uint128,uint128,uint128,bytes)",0x81e37f3d9f16cbf29a62d6a1c21d79b23ef29b54124ec44af43a50fffb9304f3,false,0 1 2,address address uint32 uint128 uint128 uint128 uint128 bytes,token publisher indexId oldIndexValue newIndexValue totalUnitsPending totalUnitsApproved userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,7,0x2e4861b1f56a67473b7bf0dd1ef85e9e9fa5ad75,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,7,0x2e4861b1f56a67473b7bf0dd1ef85e9e9fa5ad75,SubscriptionApproved,"SubscriptionApproved(address,address,address,uint32,bytes)",0xc0b8396b655615cdb85fe462a9a1792480816f909cd46d9517a940b386dfbf6b,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,7,0x2e4861b1f56a67473b7bf0dd1ef85e9e9fa5ad75,SubscriptionDistributionClaimed,"SubscriptionDistributionClaimed(address,address,address,uint32,uint256)",0x48a3d91d4a07e4982b081260e24f922bd33bb965882772d6de19c922c3eabdea,false,0 1,address address address uint32 uint256,token subscriber publisher indexId amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,7,0x2e4861b1f56a67473b7bf0dd1ef85e9e9fa5ad75,SubscriptionRevoked,"SubscriptionRevoked(address,address,address,uint32,bytes)",0x9e02127550b99adc8cc6ee332a36f31338facdbc396cebefce9a047247cd0455,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,7,0x2e4861b1f56a67473b7bf0dd1ef85e9e9fa5ad75,SubscriptionUnitsUpdated,"SubscriptionUnitsUpdated(address,address,address,uint32,uint128,bytes)",0xe0707ac7efb8b59c22189af8d004ed17dc9e4379e71b9066119b62c182524977,false,0 1,address address address uint32 uint128 bytes,token subscriber publisher indexId units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,8,0x0de6448cc883168076f7b10449bc7024d42f7910,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,8,0x0de6448cc883168076f7b10449bc7024d42f7910,IndexCreated,"IndexCreated(address,address,uint32,bytes)",0x01ab8663165edfb7390d9e5f75d960a66dacf4f01fa9787e3a731c870d0da921,false,0 1 2,address address uint32 bytes,token publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,8,0x0de6448cc883168076f7b10449bc7024d42f7910,IndexDistributionClaimed,"IndexDistributionClaimed(address,address,uint32,address,uint256)",0x467eccd248ef31c8bcef16d94856855799a8783aeef10f3759e43614059a6bb1,false,0 1 2,address address uint32 address uint256,token publisher indexId subscriber amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,8,0x0de6448cc883168076f7b10449bc7024d42f7910,IndexSubscribed,"IndexSubscribed(address,address,uint32,address,bytes)",0x492d2641617cfaf24ac7328f85bc5bdf5113537d78dc7671afa4f49a73f053c2,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,8,0x0de6448cc883168076f7b10449bc7024d42f7910,IndexUnitsUpdated,"IndexUnitsUpdated(address,address,uint32,address,uint128,bytes)",0x0115987243fd19d615b5ea62a80372a06a2b37fec378b148ee7a507c5c4c0a39,false,0 1 2,address address uint32 address uint128 bytes,token publisher indexId subscriber units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,8,0x0de6448cc883168076f7b10449bc7024d42f7910,IndexUnsubscribed,"IndexUnsubscribed(address,address,uint32,address,bytes)",0xe1f8e9cd8061e5b251769965bda6ca9ef1674bc6541fb9131039fa53f024d142,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,8,0x0de6448cc883168076f7b10449bc7024d42f7910,IndexUpdated,"IndexUpdated(address,address,uint32,uint128,uint128,uint128,uint128,bytes)",0x81e37f3d9f16cbf29a62d6a1c21d79b23ef29b54124ec44af43a50fffb9304f3,false,0 1 2,address address uint32 uint128 uint128 uint128 uint128 bytes,token publisher indexId oldIndexValue newIndexValue totalUnitsPending totalUnitsApproved userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,8,0x0de6448cc883168076f7b10449bc7024d42f7910,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,8,0x0de6448cc883168076f7b10449bc7024d42f7910,SubscriptionApproved,"SubscriptionApproved(address,address,address,uint32,bytes)",0xc0b8396b655615cdb85fe462a9a1792480816f909cd46d9517a940b386dfbf6b,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,8,0x0de6448cc883168076f7b10449bc7024d42f7910,SubscriptionDistributionClaimed,"SubscriptionDistributionClaimed(address,address,address,uint32,uint256)",0x48a3d91d4a07e4982b081260e24f922bd33bb965882772d6de19c922c3eabdea,false,0 1,address address address uint32 uint256,token subscriber publisher indexId amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,8,0x0de6448cc883168076f7b10449bc7024d42f7910,SubscriptionRevoked,"SubscriptionRevoked(address,address,address,uint32,bytes)",0x9e02127550b99adc8cc6ee332a36f31338facdbc396cebefce9a047247cd0455,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,8,0x0de6448cc883168076f7b10449bc7024d42f7910,SubscriptionUnitsUpdated,"SubscriptionUnitsUpdated(address,address,address,uint32,uint128,bytes)",0xe0707ac7efb8b59c22189af8d004ed17dc9e4379e71b9066119b62c182524977,false,0 1,address address address uint32 uint128 bytes,token subscriber publisher indexId units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,10,0xb84c98d9b51d0e32114c60c500e17ea79dfd0daf,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,10,0xb84c98d9b51d0e32114c60c500e17ea79dfd0daf,IndexCreated,"IndexCreated(address,address,uint32,bytes)",0x01ab8663165edfb7390d9e5f75d960a66dacf4f01fa9787e3a731c870d0da921,false,0 1 2,address address uint32 bytes,token publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,10,0xb84c98d9b51d0e32114c60c500e17ea79dfd0daf,IndexDistributionClaimed,"IndexDistributionClaimed(address,address,uint32,address,uint256)",0x467eccd248ef31c8bcef16d94856855799a8783aeef10f3759e43614059a6bb1,false,0 1 2,address address uint32 address uint256,token publisher indexId subscriber amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,10,0xb84c98d9b51d0e32114c60c500e17ea79dfd0daf,IndexSubscribed,"IndexSubscribed(address,address,uint32,address,bytes)",0x492d2641617cfaf24ac7328f85bc5bdf5113537d78dc7671afa4f49a73f053c2,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,10,0xb84c98d9b51d0e32114c60c500e17ea79dfd0daf,IndexUnitsUpdated,"IndexUnitsUpdated(address,address,uint32,address,uint128,bytes)",0x0115987243fd19d615b5ea62a80372a06a2b37fec378b148ee7a507c5c4c0a39,false,0 1 2,address address uint32 address uint128 bytes,token publisher indexId subscriber units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,10,0xb84c98d9b51d0e32114c60c500e17ea79dfd0daf,IndexUnsubscribed,"IndexUnsubscribed(address,address,uint32,address,bytes)",0xe1f8e9cd8061e5b251769965bda6ca9ef1674bc6541fb9131039fa53f024d142,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,10,0xb84c98d9b51d0e32114c60c500e17ea79dfd0daf,IndexUpdated,"IndexUpdated(address,address,uint32,uint128,uint128,uint128,uint128,bytes)",0x81e37f3d9f16cbf29a62d6a1c21d79b23ef29b54124ec44af43a50fffb9304f3,false,0 1 2,address address uint32 uint128 uint128 uint128 uint128 bytes,token publisher indexId oldIndexValue newIndexValue totalUnitsPending totalUnitsApproved userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,10,0xb84c98d9b51d0e32114c60c500e17ea79dfd0daf,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,10,0xb84c98d9b51d0e32114c60c500e17ea79dfd0daf,SubscriptionApproved,"SubscriptionApproved(address,address,address,uint32,bytes)",0xc0b8396b655615cdb85fe462a9a1792480816f909cd46d9517a940b386dfbf6b,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,10,0xb84c98d9b51d0e32114c60c500e17ea79dfd0daf,SubscriptionDistributionClaimed,"SubscriptionDistributionClaimed(address,address,address,uint32,uint256)",0x48a3d91d4a07e4982b081260e24f922bd33bb965882772d6de19c922c3eabdea,false,0 1,address address address uint32 uint256,token subscriber publisher indexId amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,10,0xb84c98d9b51d0e32114c60c500e17ea79dfd0daf,SubscriptionRevoked,"SubscriptionRevoked(address,address,address,uint32,bytes)",0x9e02127550b99adc8cc6ee332a36f31338facdbc396cebefce9a047247cd0455,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,10,0xb84c98d9b51d0e32114c60c500e17ea79dfd0daf,SubscriptionUnitsUpdated,"SubscriptionUnitsUpdated(address,address,address,uint32,uint128,bytes)",0xe0707ac7efb8b59c22189af8d004ed17dc9e4379e71b9066119b62c182524977,false,0 1,address address address uint32 uint128 bytes,token subscriber publisher indexId units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,11,0xd59ba9a84fa02e3687bb0694e459b3c1d76586f9,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,11,0xd59ba9a84fa02e3687bb0694e459b3c1d76586f9,IndexCreated,"IndexCreated(address,address,uint32,bytes)",0x01ab8663165edfb7390d9e5f75d960a66dacf4f01fa9787e3a731c870d0da921,false,0 1 2,address address uint32 bytes,token publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,11,0xd59ba9a84fa02e3687bb0694e459b3c1d76586f9,IndexDistributionClaimed,"IndexDistributionClaimed(address,address,uint32,address,uint256)",0x467eccd248ef31c8bcef16d94856855799a8783aeef10f3759e43614059a6bb1,false,0 1 2,address address uint32 address uint256,token publisher indexId subscriber amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,11,0xd59ba9a84fa02e3687bb0694e459b3c1d76586f9,IndexSubscribed,"IndexSubscribed(address,address,uint32,address,bytes)",0x492d2641617cfaf24ac7328f85bc5bdf5113537d78dc7671afa4f49a73f053c2,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,11,0xd59ba9a84fa02e3687bb0694e459b3c1d76586f9,IndexUnitsUpdated,"IndexUnitsUpdated(address,address,uint32,address,uint128,bytes)",0x0115987243fd19d615b5ea62a80372a06a2b37fec378b148ee7a507c5c4c0a39,false,0 1 2,address address uint32 address uint128 bytes,token publisher indexId subscriber units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,11,0xd59ba9a84fa02e3687bb0694e459b3c1d76586f9,IndexUnsubscribed,"IndexUnsubscribed(address,address,uint32,address,bytes)",0xe1f8e9cd8061e5b251769965bda6ca9ef1674bc6541fb9131039fa53f024d142,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,11,0xd59ba9a84fa02e3687bb0694e459b3c1d76586f9,IndexUpdated,"IndexUpdated(address,address,uint32,uint128,uint128,uint128,uint128,bytes)",0x81e37f3d9f16cbf29a62d6a1c21d79b23ef29b54124ec44af43a50fffb9304f3,false,0 1 2,address address uint32 uint128 uint128 uint128 uint128 bytes,token publisher indexId oldIndexValue newIndexValue totalUnitsPending totalUnitsApproved userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,11,0xd59ba9a84fa02e3687bb0694e459b3c1d76586f9,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,11,0xd59ba9a84fa02e3687bb0694e459b3c1d76586f9,SubscriptionApproved,"SubscriptionApproved(address,address,address,uint32,bytes)",0xc0b8396b655615cdb85fe462a9a1792480816f909cd46d9517a940b386dfbf6b,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,11,0xd59ba9a84fa02e3687bb0694e459b3c1d76586f9,SubscriptionDistributionClaimed,"SubscriptionDistributionClaimed(address,address,address,uint32,uint256)",0x48a3d91d4a07e4982b081260e24f922bd33bb965882772d6de19c922c3eabdea,false,0 1,address address address uint32 uint256,token subscriber publisher indexId amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,11,0xd59ba9a84fa02e3687bb0694e459b3c1d76586f9,SubscriptionRevoked,"SubscriptionRevoked(address,address,address,uint32,bytes)",0x9e02127550b99adc8cc6ee332a36f31338facdbc396cebefce9a047247cd0455,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,11,0xd59ba9a84fa02e3687bb0694e459b3c1d76586f9,SubscriptionUnitsUpdated,"SubscriptionUnitsUpdated(address,address,address,uint32,uint128,bytes)",0xe0707ac7efb8b59c22189af8d004ed17dc9e4379e71b9066119b62c182524977,false,0 1,address address address uint32 uint128 bytes,token subscriber publisher indexId units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,12,0xf0ec6a8842ca72aec8a4d4573e731242389e18a8,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,12,0xf0ec6a8842ca72aec8a4d4573e731242389e18a8,IndexCreated,"IndexCreated(address,address,uint32,bytes)",0x01ab8663165edfb7390d9e5f75d960a66dacf4f01fa9787e3a731c870d0da921,false,0 1 2,address address uint32 bytes,token publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,12,0xf0ec6a8842ca72aec8a4d4573e731242389e18a8,IndexDistributionClaimed,"IndexDistributionClaimed(address,address,uint32,address,uint256)",0x467eccd248ef31c8bcef16d94856855799a8783aeef10f3759e43614059a6bb1,false,0 1 2,address address uint32 address uint256,token publisher indexId subscriber amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,12,0xf0ec6a8842ca72aec8a4d4573e731242389e18a8,IndexSubscribed,"IndexSubscribed(address,address,uint32,address,bytes)",0x492d2641617cfaf24ac7328f85bc5bdf5113537d78dc7671afa4f49a73f053c2,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,12,0xf0ec6a8842ca72aec8a4d4573e731242389e18a8,IndexUnitsUpdated,"IndexUnitsUpdated(address,address,uint32,address,uint128,bytes)",0x0115987243fd19d615b5ea62a80372a06a2b37fec378b148ee7a507c5c4c0a39,false,0 1 2,address address uint32 address uint128 bytes,token publisher indexId subscriber units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,12,0xf0ec6a8842ca72aec8a4d4573e731242389e18a8,IndexUnsubscribed,"IndexUnsubscribed(address,address,uint32,address,bytes)",0xe1f8e9cd8061e5b251769965bda6ca9ef1674bc6541fb9131039fa53f024d142,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,12,0xf0ec6a8842ca72aec8a4d4573e731242389e18a8,IndexUpdated,"IndexUpdated(address,address,uint32,uint128,uint128,uint128,uint128,bytes)",0x81e37f3d9f16cbf29a62d6a1c21d79b23ef29b54124ec44af43a50fffb9304f3,false,0 1 2,address address uint32 uint128 uint128 uint128 uint128 bytes,token publisher indexId oldIndexValue newIndexValue totalUnitsPending totalUnitsApproved userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,12,0xf0ec6a8842ca72aec8a4d4573e731242389e18a8,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,12,0xf0ec6a8842ca72aec8a4d4573e731242389e18a8,SubscriptionApproved,"SubscriptionApproved(address,address,address,uint32,bytes)",0xc0b8396b655615cdb85fe462a9a1792480816f909cd46d9517a940b386dfbf6b,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,12,0xf0ec6a8842ca72aec8a4d4573e731242389e18a8,SubscriptionDistributionClaimed,"SubscriptionDistributionClaimed(address,address,address,uint32,uint256)",0x48a3d91d4a07e4982b081260e24f922bd33bb965882772d6de19c922c3eabdea,false,0 1,address address address uint32 uint256,token subscriber publisher indexId amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,12,0xf0ec6a8842ca72aec8a4d4573e731242389e18a8,SubscriptionRevoked,"SubscriptionRevoked(address,address,address,uint32,bytes)",0x9e02127550b99adc8cc6ee332a36f31338facdbc396cebefce9a047247cd0455,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,12,0xf0ec6a8842ca72aec8a4d4573e731242389e18a8,SubscriptionUnitsUpdated,"SubscriptionUnitsUpdated(address,address,address,uint32,uint128,bytes)",0xe0707ac7efb8b59c22189af8d004ed17dc9e4379e71b9066119b62c182524977,false,0 1,address address address uint32 uint128 bytes,token subscriber publisher indexId units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,13,0x1d38a1f81216b73c05a10eac5e84f566d4d9d8da,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,13,0x1d38a1f81216b73c05a10eac5e84f566d4d9d8da,IndexCreated,"IndexCreated(address,address,uint32,bytes)",0x01ab8663165edfb7390d9e5f75d960a66dacf4f01fa9787e3a731c870d0da921,false,0 1 2,address address uint32 bytes,token publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,13,0x1d38a1f81216b73c05a10eac5e84f566d4d9d8da,IndexDistributionClaimed,"IndexDistributionClaimed(address,address,uint32,address,uint256)",0x467eccd248ef31c8bcef16d94856855799a8783aeef10f3759e43614059a6bb1,false,0 1 2,address address uint32 address uint256,token publisher indexId subscriber amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,13,0x1d38a1f81216b73c05a10eac5e84f566d4d9d8da,IndexSubscribed,"IndexSubscribed(address,address,uint32,address,bytes)",0x492d2641617cfaf24ac7328f85bc5bdf5113537d78dc7671afa4f49a73f053c2,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,13,0x1d38a1f81216b73c05a10eac5e84f566d4d9d8da,IndexUnitsUpdated,"IndexUnitsUpdated(address,address,uint32,address,uint128,bytes)",0x0115987243fd19d615b5ea62a80372a06a2b37fec378b148ee7a507c5c4c0a39,false,0 1 2,address address uint32 address uint128 bytes,token publisher indexId subscriber units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,13,0x1d38a1f81216b73c05a10eac5e84f566d4d9d8da,IndexUnsubscribed,"IndexUnsubscribed(address,address,uint32,address,bytes)",0xe1f8e9cd8061e5b251769965bda6ca9ef1674bc6541fb9131039fa53f024d142,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,13,0x1d38a1f81216b73c05a10eac5e84f566d4d9d8da,IndexUpdated,"IndexUpdated(address,address,uint32,uint128,uint128,uint128,uint128,bytes)",0x81e37f3d9f16cbf29a62d6a1c21d79b23ef29b54124ec44af43a50fffb9304f3,false,0 1 2,address address uint32 uint128 uint128 uint128 uint128 bytes,token publisher indexId oldIndexValue newIndexValue totalUnitsPending totalUnitsApproved userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,13,0x1d38a1f81216b73c05a10eac5e84f566d4d9d8da,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,13,0x1d38a1f81216b73c05a10eac5e84f566d4d9d8da,SubscriptionApproved,"SubscriptionApproved(address,address,address,uint32,bytes)",0xc0b8396b655615cdb85fe462a9a1792480816f909cd46d9517a940b386dfbf6b,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,13,0x1d38a1f81216b73c05a10eac5e84f566d4d9d8da,SubscriptionDistributionClaimed,"SubscriptionDistributionClaimed(address,address,address,uint32,uint256)",0x48a3d91d4a07e4982b081260e24f922bd33bb965882772d6de19c922c3eabdea,false,0 1,address address address uint32 uint256,token subscriber publisher indexId amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,13,0x1d38a1f81216b73c05a10eac5e84f566d4d9d8da,SubscriptionRevoked,"SubscriptionRevoked(address,address,address,uint32,bytes)",0x9e02127550b99adc8cc6ee332a36f31338facdbc396cebefce9a047247cd0455,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,13,0x1d38a1f81216b73c05a10eac5e84f566d4d9d8da,SubscriptionUnitsUpdated,"SubscriptionUnitsUpdated(address,address,address,uint32,uint128,bytes)",0xe0707ac7efb8b59c22189af8d004ed17dc9e4379e71b9066119b62c182524977,false,0 1,address address address uint32 uint128 bytes,token subscriber publisher indexId units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,14,0x295cef78e76564b124b948a05dbd6522c3ec76b1,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,14,0x295cef78e76564b124b948a05dbd6522c3ec76b1,IndexCreated,"IndexCreated(address,address,uint32,bytes)",0x01ab8663165edfb7390d9e5f75d960a66dacf4f01fa9787e3a731c870d0da921,false,0 1 2,address address uint32 bytes,token publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,14,0x295cef78e76564b124b948a05dbd6522c3ec76b1,IndexDistributionClaimed,"IndexDistributionClaimed(address,address,uint32,address,uint256)",0x467eccd248ef31c8bcef16d94856855799a8783aeef10f3759e43614059a6bb1,false,0 1 2,address address uint32 address uint256,token publisher indexId subscriber amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,14,0x295cef78e76564b124b948a05dbd6522c3ec76b1,IndexSubscribed,"IndexSubscribed(address,address,uint32,address,bytes)",0x492d2641617cfaf24ac7328f85bc5bdf5113537d78dc7671afa4f49a73f053c2,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,14,0x295cef78e76564b124b948a05dbd6522c3ec76b1,IndexUnitsUpdated,"IndexUnitsUpdated(address,address,uint32,address,uint128,bytes)",0x0115987243fd19d615b5ea62a80372a06a2b37fec378b148ee7a507c5c4c0a39,false,0 1 2,address address uint32 address uint128 bytes,token publisher indexId subscriber units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,14,0x295cef78e76564b124b948a05dbd6522c3ec76b1,IndexUnsubscribed,"IndexUnsubscribed(address,address,uint32,address,bytes)",0xe1f8e9cd8061e5b251769965bda6ca9ef1674bc6541fb9131039fa53f024d142,false,0 1 2,address address uint32 address bytes,token publisher indexId subscriber userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,14,0x295cef78e76564b124b948a05dbd6522c3ec76b1,IndexUpdated,"IndexUpdated(address,address,uint32,uint128,uint128,uint128,uint128,bytes)",0x81e37f3d9f16cbf29a62d6a1c21d79b23ef29b54124ec44af43a50fffb9304f3,false,0 1 2,address address uint32 uint128 uint128 uint128 uint128 bytes,token publisher indexId oldIndexValue newIndexValue totalUnitsPending totalUnitsApproved userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,14,0x295cef78e76564b124b948a05dbd6522c3ec76b1,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,14,0x295cef78e76564b124b948a05dbd6522c3ec76b1,SubscriptionApproved,"SubscriptionApproved(address,address,address,uint32,bytes)",0xc0b8396b655615cdb85fe462a9a1792480816f909cd46d9517a940b386dfbf6b,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,14,0x295cef78e76564b124b948a05dbd6522c3ec76b1,SubscriptionDistributionClaimed,"SubscriptionDistributionClaimed(address,address,address,uint32,uint256)",0x48a3d91d4a07e4982b081260e24f922bd33bb965882772d6de19c922c3eabdea,false,0 1,address address address uint32 uint256,token subscriber publisher indexId amount,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,14,0x295cef78e76564b124b948a05dbd6522c3ec76b1,SubscriptionRevoked,"SubscriptionRevoked(address,address,address,uint32,bytes)",0x9e02127550b99adc8cc6ee332a36f31338facdbc396cebefce9a047247cd0455,false,0 1,address address address uint32 bytes,token subscriber publisher indexId userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SuperfluidIDAv1,0x26747fe93fac8bf28e1e24a558a2bc7e4d9846ca,14,0x295cef78e76564b124b948a05dbd6522c3ec76b1,SubscriptionUnitsUpdated,"SubscriptionUnitsUpdated(address,address,address,uint32,uint128,bytes)",0xe0707ac7efb8b59c22189af8d004ed17dc9e4379e71b9066119b62c182524977,false,0 1,address address address uint32 uint128 bytes,token subscriber publisher indexId units userData,true,16393503,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,3,4,5,6,7,8,10,11,12,13,14 of 14. NOT CONTIGUOUS: Removed and later restored" +CELO,42220,SwapHelper,0xe45cab86609a16dfadec112fdd61e4ea80edaa8d,1,0xe45cab86609a16dfadec112fdd61e4ea80edaa8d,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,SwapHelper,0xe45cab86609a16dfadec112fdd61e4ea80edaa8d,1,0xe45cab86609a16dfadec112fdd61e4ea80edaa8d,SwapHelper,"SwapHelper(address,address,address,address,uint256,uint256,uint256,uint8,address)",0x3522b0708d119a13dea0f03456205d091b8749ad6b9c8b2296ada66ee1c1b212,false,,address address address address uint256 uint256 uint256 uint8 address,from to inputToken outputToken inputAmount outputAmount minOutputAmount swapType router,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,1,0xedbe438cd865992fdb72dd252e6055a71b02be72,ActivatedUser,ActivatedUser(address),0x2f9cfaa2a5c422dfab45f7d0da071f030fc2d3a7a1f0a255c028eff9b6d3d936,false,0,address,account,true,18006679,19276072,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 1 of 4 +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,1,0xedbe438cd865992fdb72dd252e6055a71b02be72,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,1,0xedbe438cd865992fdb72dd252e6055a71b02be72,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,1,0xedbe438cd865992fdb72dd252e6055a71b02be72,CycleLengthSet,CycleLengthSet(uint256),0xa61e6cca2c12e2a0a493683acfe95b034f0f50d793434f4dfe3ba06ea201f344,false,,uint256,newCycleLength,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,1,0xedbe438cd865992fdb72dd252e6055a71b02be72,DaySet,DaySet(uint256),0x67eb03bd555181f9dd23f546e4331ddfb8b4a7d0c8d261ba44e037f30ce894ea,false,,uint256,newDay,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,1,0xedbe438cd865992fdb72dd252e6055a71b02be72,InactiveUserFished,"InactiveUserFished(address,address,uint256)",0x3c91d315d82534112f8ce552cb79133a14191077a2d715fd65cabd026fc27c74,false,0 1,address address uint256,caller fished_account claimAmount,true,18006679,19276072,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 1 of 4 +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,1,0xedbe438cd865992fdb72dd252e6055a71b02be72,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,1,0xedbe438cd865992fdb72dd252e6055a71b02be72,ShouldWithdrawFromDAOSet,ShouldWithdrawFromDAOSet(bool),0x6cd9a0fd2e006be39a9918bf56c85cae1d4f4599474483ff18cb93355ebaaf8e,false,,bool,ShouldWithdrawFromDAO,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,1,0xedbe438cd865992fdb72dd252e6055a71b02be72,TotalFished,TotalFished(uint256),0x72b174db45b7e58932cb0c6bf37a7158f40424a078b07677d823cafdb3db540f,false,,uint256,total,true,18006679,19276072,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 1 of 4 +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,1,0xedbe438cd865992fdb72dd252e6055a71b02be72,UBICalculated,"UBICalculated(uint256,uint256,uint256)",0x836fa39995340265746dfe9587d9fe5c5de35b7bce778afd9b124ce1cfeafdc4,false,,uint256 uint256 uint256,day dailyUbi blockNumber,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,1,0xedbe438cd865992fdb72dd252e6055a71b02be72,UBIClaimed,"UBIClaimed(address,uint256)",0x89ed24731df6b066e4c5186901fffdba18cd9a10f07494aff900bdee260d1304,false,0,address uint256,claimer amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,1,0xedbe438cd865992fdb72dd252e6055a71b02be72,UBICycleCalculated,"UBICycleCalculated(uint256,uint256,uint256,uint256)",0x83e0d535b9e84324e0a25922406398d6ff5f96d0c686204ee490e16d7670566f,false,,uint256 uint256 uint256 uint256,day pool cycleLength dailyUBIPool,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,1,0xedbe438cd865992fdb72dd252e6055a71b02be72,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,1,0xedbe438cd865992fdb72dd252e6055a71b02be72,WithdrawFromDao,"WithdrawFromDao(uint256,uint256)",0x3107ec7eaa50b775d2486c7a394472235804b6fe1c0d4b7bd1d79b09df60f2ba,false,,uint256 uint256,prevBalance newBalance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,2,0x854f84ef0d9abc1e0afb4e96c962d5456b62214e,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,2,0x854f84ef0d9abc1e0afb4e96c962d5456b62214e,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,2,0x854f84ef0d9abc1e0afb4e96c962d5456b62214e,CycleLengthSet,CycleLengthSet(uint256),0xa61e6cca2c12e2a0a493683acfe95b034f0f50d793434f4dfe3ba06ea201f344,false,,uint256,newCycleLength,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,2,0x854f84ef0d9abc1e0afb4e96c962d5456b62214e,DaySet,DaySet(uint256),0x67eb03bd555181f9dd23f546e4331ddfb8b4a7d0c8d261ba44e037f30ce894ea,false,,uint256,newDay,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,2,0x854f84ef0d9abc1e0afb4e96c962d5456b62214e,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,2,0x854f84ef0d9abc1e0afb4e96c962d5456b62214e,ShouldWithdrawFromDAOSet,ShouldWithdrawFromDAOSet(bool),0x6cd9a0fd2e006be39a9918bf56c85cae1d4f4599474483ff18cb93355ebaaf8e,false,,bool,ShouldWithdrawFromDAO,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,2,0x854f84ef0d9abc1e0afb4e96c962d5456b62214e,UBICalculated,"UBICalculated(uint256,uint256,uint256)",0x836fa39995340265746dfe9587d9fe5c5de35b7bce778afd9b124ce1cfeafdc4,false,,uint256 uint256 uint256,day dailyUbi blockNumber,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,2,0x854f84ef0d9abc1e0afb4e96c962d5456b62214e,UBIClaimed,"UBIClaimed(address,uint256)",0x89ed24731df6b066e4c5186901fffdba18cd9a10f07494aff900bdee260d1304,false,0,address uint256,claimer amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,2,0x854f84ef0d9abc1e0afb4e96c962d5456b62214e,UBICycleCalculated,"UBICycleCalculated(uint256,uint256,uint256,uint256)",0x83e0d535b9e84324e0a25922406398d6ff5f96d0c686204ee490e16d7670566f,false,,uint256 uint256 uint256 uint256,day pool cycleLength dailyUBIPool,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,2,0x854f84ef0d9abc1e0afb4e96c962d5456b62214e,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,2,0x854f84ef0d9abc1e0afb4e96c962d5456b62214e,WithdrawFromDao,"WithdrawFromDao(uint256,uint256)",0x3107ec7eaa50b775d2486c7a394472235804b6fe1c0d4b7bd1d79b09df60f2ba,false,,uint256 uint256,prevBalance newBalance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,3,0xe8fcbac4bd18f80301450e428518e9dedc183a26,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,3,0xe8fcbac4bd18f80301450e428518e9dedc183a26,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,3,0xe8fcbac4bd18f80301450e428518e9dedc183a26,CycleLengthSet,CycleLengthSet(uint256),0xa61e6cca2c12e2a0a493683acfe95b034f0f50d793434f4dfe3ba06ea201f344,false,,uint256,newCycleLength,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,3,0xe8fcbac4bd18f80301450e428518e9dedc183a26,DaySet,DaySet(uint256),0x67eb03bd555181f9dd23f546e4331ddfb8b4a7d0c8d261ba44e037f30ce894ea,false,,uint256,newDay,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,3,0xe8fcbac4bd18f80301450e428518e9dedc183a26,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,3,0xe8fcbac4bd18f80301450e428518e9dedc183a26,ShouldWithdrawFromDAOSet,ShouldWithdrawFromDAOSet(bool),0x6cd9a0fd2e006be39a9918bf56c85cae1d4f4599474483ff18cb93355ebaaf8e,false,,bool,ShouldWithdrawFromDAO,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,3,0xe8fcbac4bd18f80301450e428518e9dedc183a26,UBICalculated,"UBICalculated(uint256,uint256,uint256)",0x836fa39995340265746dfe9587d9fe5c5de35b7bce778afd9b124ce1cfeafdc4,false,,uint256 uint256 uint256,day dailyUbi blockNumber,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,3,0xe8fcbac4bd18f80301450e428518e9dedc183a26,UBIClaimed,"UBIClaimed(address,uint256)",0x89ed24731df6b066e4c5186901fffdba18cd9a10f07494aff900bdee260d1304,false,0,address uint256,claimer amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,3,0xe8fcbac4bd18f80301450e428518e9dedc183a26,UBICycleCalculated,"UBICycleCalculated(uint256,uint256,uint256,uint256)",0x83e0d535b9e84324e0a25922406398d6ff5f96d0c686204ee490e16d7670566f,false,,uint256 uint256 uint256 uint256,day pool cycleLength dailyUBIPool,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,3,0xe8fcbac4bd18f80301450e428518e9dedc183a26,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,3,0xe8fcbac4bd18f80301450e428518e9dedc183a26,WithdrawFromDao,"WithdrawFromDao(uint256,uint256)",0x3107ec7eaa50b775d2486c7a394472235804b6fe1c0d4b7bd1d79b09df60f2ba,false,,uint256 uint256,prevBalance newBalance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,4,0x43f0eb66ea3c2d9552241525aa1af6607227dfbf,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,4,0x43f0eb66ea3c2d9552241525aa1af6607227dfbf,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,4,0x43f0eb66ea3c2d9552241525aa1af6607227dfbf,CycleLengthSet,CycleLengthSet(uint256),0xa61e6cca2c12e2a0a493683acfe95b034f0f50d793434f4dfe3ba06ea201f344,false,,uint256,newCycleLength,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,4,0x43f0eb66ea3c2d9552241525aa1af6607227dfbf,DaySet,DaySet(uint256),0x67eb03bd555181f9dd23f546e4331ddfb8b4a7d0c8d261ba44e037f30ce894ea,false,,uint256,newDay,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,4,0x43f0eb66ea3c2d9552241525aa1af6607227dfbf,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,4,0x43f0eb66ea3c2d9552241525aa1af6607227dfbf,ShouldWithdrawFromDAOSet,ShouldWithdrawFromDAOSet(bool),0x6cd9a0fd2e006be39a9918bf56c85cae1d4f4599474483ff18cb93355ebaaf8e,false,,bool,ShouldWithdrawFromDAO,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,4,0x43f0eb66ea3c2d9552241525aa1af6607227dfbf,UBICalculated,"UBICalculated(uint256,uint256,uint256)",0x836fa39995340265746dfe9587d9fe5c5de35b7bce778afd9b124ce1cfeafdc4,false,,uint256 uint256 uint256,day dailyUbi blockNumber,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,4,0x43f0eb66ea3c2d9552241525aa1af6607227dfbf,UBIClaimed,"UBIClaimed(address,uint256)",0x89ed24731df6b066e4c5186901fffdba18cd9a10f07494aff900bdee260d1304,false,0,address uint256,claimer amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,4,0x43f0eb66ea3c2d9552241525aa1af6607227dfbf,UBICycleCalculated,"UBICycleCalculated(uint256,uint256,uint256,uint256)",0x83e0d535b9e84324e0a25922406398d6ff5f96d0c686204ee490e16d7670566f,false,,uint256 uint256 uint256 uint256,day pool cycleLength dailyUBIPool,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,4,0x43f0eb66ea3c2d9552241525aa1af6607227dfbf,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UBIScheme,0x43d72ff17701b2da814620735c39c620ce0ea4a1,4,0x43f0eb66ea3c2d9552241525aa1af6607227dfbf,WithdrawFromDao,"WithdrawFromDao(uint256,uint256)",0x3107ec7eaa50b775d2486c7a394472235804b6fe1c0d4b7bd1d79b09df60f2ba,false,,uint256 uint256,prevBalance newBalance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UniswapV2Factory,0x62d5b84be28a183abb507e125b384122d2c25fae,1,0x62d5b84be28a183abb507e125b384122d2c25fae,PairCreated,"PairCreated(address,address,address,uint256)",0x0d3648bd0f6ba80134a33ba9275ac585d9d315f0ad8355cddefde31afa28d0e9,false,0 1,address address address uint256,token0 token1 pair ,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UniswapV3Factory,0xafe208a311b21f13ef87e33a90049fc17a7acdec,1,0xafe208a311b21f13ef87e33a90049fc17a7acdec,FeeAmountEnabled,"FeeAmountEnabled(uint24,int24)",0xc66a3fdf07232cdd185febcc6579d408c241b47ae2f9907d84be655141eeaecc,false,0 1,uint24 int24,fee tickSpacing,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UniswapV3Factory,0xafe208a311b21f13ef87e33a90049fc17a7acdec,1,0xafe208a311b21f13ef87e33a90049fc17a7acdec,OwnerChanged,"OwnerChanged(address,address)",0xb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c,false,0 1,address address,oldOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UniswapV3Factory,0xafe208a311b21f13ef87e33a90049fc17a7acdec,1,0xafe208a311b21f13ef87e33a90049fc17a7acdec,PoolCreated,"PoolCreated(address,address,uint24,int24,address)",0x783cca1c0412dd0d695e784568c96da2e9c22ff989357a2e8b1d9b2b4e6b7118,false,0 1 2,address address uint24 int24 address,token0 token1 fee tickSpacing pool,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UniswapV3FactorySecond,0x67fea58d5a5a4162ced847e13c2c81c73bf8aec4,1,0x67fea58d5a5a4162ced847e13c2c81c73bf8aec4,FeeAmountEnabled,"FeeAmountEnabled(uint24,int24)",0xc66a3fdf07232cdd185febcc6579d408c241b47ae2f9907d84be655141eeaecc,false,0 1,uint24 int24,fee tickSpacing,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UniswapV3FactorySecond,0x67fea58d5a5a4162ced847e13c2c81c73bf8aec4,1,0x67fea58d5a5a4162ced847e13c2c81c73bf8aec4,OwnerChanged,"OwnerChanged(address,address)",0xb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c,false,0 1,address address,oldOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UniswapV3FactorySecond,0x67fea58d5a5a4162ced847e13c2c81c73bf8aec4,1,0x67fea58d5a5a4162ced847e13c2c81c73bf8aec4,PoolCreated,"PoolCreated(address,address,uint24,int24,address)",0x783cca1c0412dd0d695e784568c96da2e9c22ff989357a2e8b1d9b2b4e6b7118,false,0 1 2,address address uint24 int24 address,token0 token1 fee tickSpacing pool,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UniswapV4PoolManager,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,1,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,Approval,"Approval(address,address,uint256,uint256)",0xb3fd5071835887567a0671151121894ddccc2842f1d10bedad13e0d17cace9a7,false,0 1 2,address address uint256 uint256,owner spender id amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UniswapV4PoolManager,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,1,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,Donate,"Donate(bytes32,address,uint256,uint256)",0x29ef05caaff9404b7cb6d1c0e9bbae9eaa7ab2541feba1a9c4248594c08156cb,false,0 1,bytes32 address uint256 uint256,id sender amount0 amount1,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UniswapV4PoolManager,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,1,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,Initialize,"Initialize(bytes32,address,address,uint24,int24,address,uint160,int24)",0xdd466e674ea557f56295e2d0218a125ea4b4f0f6f3307b95f85e6110838d6438,false,0 1 2,bytes32 address address uint24 int24 address uint160 int24,id currency0 currency1 fee tickSpacing hooks sqrtPriceX96 tick,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UniswapV4PoolManager,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,1,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,ModifyLiquidity,"ModifyLiquidity(bytes32,address,int24,int24,int256,bytes32)",0xf208f4912782fd25c7f114ca3723a2d5dd6f3bcc3ac8db5af63baa85f711d5ec,false,0 1,bytes32 address int24 int24 int256 bytes32,id sender tickLower tickUpper liquidityDelta salt,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UniswapV4PoolManager,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,1,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,OperatorSet,"OperatorSet(address,address,bool)",0xceb576d9f15e4e200fdb5096d64d5dfd667e16def20c1eefd14256d8e3faa267,false,0 1,address address bool,owner operator approved,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UniswapV4PoolManager,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,1,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,user newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UniswapV4PoolManager,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,1,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,ProtocolFeeControllerUpdated,ProtocolFeeControllerUpdated(address),0xb4bd8ef53df690b9943d3318996006dbb82a25f54719d8c8035b516a2a5b8acc,false,0,address,protocolFeeController,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UniswapV4PoolManager,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,1,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,ProtocolFeeUpdated,"ProtocolFeeUpdated(bytes32,uint24)",0xe9c42593e71f84403b84352cd168d693e2c9fcd1fdbcc3feb21d92b43e6696f9,false,0,bytes32 uint24,id protocolFee,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UniswapV4PoolManager,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,1,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,Swap,"Swap(bytes32,address,int128,int128,uint160,uint128,int24,uint24)",0x40e9cecb9f5f1f1c5b9c97dec2917b7ee92e57ba5563708daca94dd84ad7112f,false,0 1,bytes32 address int128 int128 uint160 uint128 int24 uint24,id sender amount0 amount1 sqrtPriceX96 liquidity tick fee,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +CELO,42220,UniswapV4PoolManager,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,1,0x288dc841a52fca2707c6947b3a777c5e56cd87bc,Transfer,"Transfer(address,address,address,uint256,uint256)",0x1b3d7edb2e9c0b0e7c525b20aaaef0f5940d2ed71663c7d39266ecafac728859,false,1 2 3,address address address uint256 uint256,caller from to id amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,AaveStakingFactory,0xf4411c22766947db2da39ad534a040b770b51153,1,0xf4411c22766947db2da39ad534a040b770b51153,Deployed,"Deployed(address,address,address)",0xc95935a66d15e0da5e412aca0ad27ae891d20b2fb91cf3994b6a3bf2b8178082,false,,address address address,proxy token impl,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,AnyGoodDollar,0xd17652350cfd2a37ba2f947c910987a3b1a1c60d,1,0xd17652350cfd2a37ba2f947c910987a3b1a1c60d,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,AnyGoodDollar,0xd17652350cfd2a37ba2f947c910987a3b1a1c60d,1,0xd17652350cfd2a37ba2f947c910987a3b1a1c60d,LogChangeVault,"LogChangeVault(address,address,uint256)",0x5c364079e7102c27c608f9b237c735a1b7bfa0b67f27c2ad26bad447bf965cac,false,0 1 2,address address uint256,oldVault newVault effectiveTime,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,AnyGoodDollar,0xd17652350cfd2a37ba2f947c910987a3b1a1c60d,1,0xd17652350cfd2a37ba2f947c910987a3b1a1c60d,LogSwapin,"LogSwapin(bytes32,address,uint256)",0x05d0634fe981be85c22e2942a880821b70095d84e152c3ea3c17a4e4250d9d61,false,0 1,bytes32 address uint256,txhash account amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,AnyGoodDollar,0xd17652350cfd2a37ba2f947c910987a3b1a1c60d,1,0xd17652350cfd2a37ba2f947c910987a3b1a1c60d,LogSwapout,"LogSwapout(address,address,uint256)",0x6b616089d04950dc06c45c6dd787d657980543f89651aec47924752c7d16c888,false,0 1,address address uint256,account bindaddr amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,AnyGoodDollar,0xd17652350cfd2a37ba2f947c910987a3b1a1c60d,1,0xd17652350cfd2a37ba2f947c910987a3b1a1c60d,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Avatar,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,1,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,ExternalTokenApproval,"ExternalTokenApproval(address,address,uint256)",0x3a48a4d6253b30fd10e57a347c1f9bcb0604946481fae0b2fdad6e74f2a9cbb3,false,0,address address uint256,_externalToken _spender _value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Avatar,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,1,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,ExternalTokenTransfer,"ExternalTokenTransfer(address,address,uint256)",0x49dc2a60d2599a7b6932d78fb694c30dfc596fe4e0282b5d0fd184b52472c04d,false,0 1,address address uint256,_externalToken _to _value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Avatar,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,1,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,ExternalTokenTransferFrom,"ExternalTokenTransferFrom(address,address,address,uint256)",0x179c15de44aa7ab84896301974328eb40b5b40fe01cfe0fee2924ea712c3e843,false,0,address address address uint256,_externalToken _from _to _value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Avatar,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,1,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,GenericCall,"GenericCall(address,bytes,uint256,bool)",0x534b52c783549f909f9e743120524d0b7154058e4a54cdc895c2c0b587a1c7e0,false,0,address bytes uint256 bool,_contract _data _value _success,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Avatar,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,1,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,MetaData,MetaData(string),0xf9deba4938ba20070ec5a45ddf59bccba49cf83124215228ec1232182ef0ba2b,false,,string,_metaData,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Avatar,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,1,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Avatar,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,1,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,ReceiveEther,"ReceiveEther(address,uint256)",0xf32a9f77675fd5917534c7746608fd3e309eac68fbdcbf5925e24ca97a704396,false,0,address uint256,_sender _value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Avatar,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,1,0x1ecfd1afb601c406ff0e13c3485f2d75699b6817,SendEther,"SendEther(uint256,address)",0x22fca66666089f39bc900dd6605b489df4aae6260cc8ea8257594cfb8c84926c,false,1,uint256 address,_amountInWei _to,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,cDAI,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,1,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,AccrueInterest,"AccrueInterest(uint256,uint256,uint256,uint256)",0x4dec04e750ca11537cabcd8a9eab06494de08da3735bc8871cd41250e190bc04,false,,uint256 uint256 uint256 uint256,cashPrior interestAccumulated borrowIndex totalBorrows,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,cDAI,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,1,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,cDAI,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,1,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,Borrow,"Borrow(address,uint256,uint256,uint256)",0x13ed6866d4e1ee6da46f845c46d7e54120883d75c5ea9a2dacc1c4ca8984ab80,false,,address uint256 uint256 uint256,borrower borrowAmount accountBorrows totalBorrows,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,cDAI,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,1,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,Failure,"Failure(uint256,uint256,uint256)",0x45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0,false,,uint256 uint256 uint256,error info detail,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,cDAI,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,1,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,LiquidateBorrow,"LiquidateBorrow(address,address,uint256,address,uint256)",0x298637f684da70674f26509b10f07ec2fbc77a335ab1e7d6215a4b2484d8bb52,false,,address address uint256 address uint256,liquidator borrower repayAmount cTokenCollateral seizeTokens,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,cDAI,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,1,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,Mint,"Mint(address,uint256,uint256)",0x4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f,false,,address uint256 uint256,minter mintAmount mintTokens,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,cDAI,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,1,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,NewAdmin,"NewAdmin(address,address)",0xf9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc,false,,address address,oldAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,cDAI,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,1,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,NewComptroller,"NewComptroller(address,address)",0x7ac369dbd14fa5ea3f473ed67cc9d598964a77501540ba6751eb0b3decf5870d,false,,address address,oldComptroller newComptroller,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,cDAI,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,1,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,NewImplementation,"NewImplementation(address,address)",0xd604de94d45953f9138079ec1b82d533cb2160c906d1076d1f7ed54befbca97a,false,,address address,oldImplementation newImplementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,cDAI,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,1,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,NewMarketInterestRateModel,"NewMarketInterestRateModel(address,address)",0xedffc32e068c7c95dfd4bdfd5c4d939a084d6b11c4199eac8436ed234d72f926,false,,address address,oldInterestRateModel newInterestRateModel,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,cDAI,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,1,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,NewPendingAdmin,"NewPendingAdmin(address,address)",0xca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a9,false,,address address,oldPendingAdmin newPendingAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,cDAI,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,1,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,NewReserveFactor,"NewReserveFactor(uint256,uint256)",0xaaa68312e2ea9d50e16af5068410ab56e1a1fd06037b1a35664812c30f821460,false,,uint256 uint256,oldReserveFactorMantissa newReserveFactorMantissa,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,cDAI,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,1,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,Redeem,"Redeem(address,uint256,uint256)",0xe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4ec31a929,false,,address uint256 uint256,redeemer redeemAmount redeemTokens,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,cDAI,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,1,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,RepayBorrow,"RepayBorrow(address,address,uint256,uint256,uint256)",0x1a2a22cb034d26d1854bdc6666a5b91fe25efbbb5dcad3b0355478d6f5c362a1,false,,address address uint256 uint256 uint256,payer borrower repayAmount accountBorrows totalBorrows,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,cDAI,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,1,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,ReservesAdded,"ReservesAdded(address,uint256,uint256)",0xa91e67c5ea634cd43a12c5a482724b03de01e85ca68702a53d0c2f45cb7c1dc5,false,,address uint256 uint256,benefactor addAmount newTotalReserves,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,cDAI,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,1,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,ReservesReduced,"ReservesReduced(address,uint256,uint256)",0x3bad0c59cf2f06e7314077049f48a93578cd16f5ef92329f1dab1420a99c177e,false,,address uint256 uint256,admin reduceAmount newTotalReserves,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,cDAI,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,1,0x5d3a536e4d6dbd6114cc1ead35777bab948e3643,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,COMP,0xc00e94cb662c3520282e6f5717214004a7f26888,1,0xc00e94cb662c3520282e6f5717214004a7f26888,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,COMP,0xc00e94cb662c3520282e6f5717214004a7f26888,1,0xc00e94cb662c3520282e6f5717214004a7f26888,DelegateChanged,"DelegateChanged(address,address,address)",0x3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f,false,0 1 2,address address address,delegator fromDelegate toDelegate,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,COMP,0xc00e94cb662c3520282e6f5717214004a7f26888,1,0xc00e94cb662c3520282e6f5717214004a7f26888,DelegateVotesChanged,"DelegateVotesChanged(address,uint256,uint256)",0xdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724,false,0,address uint256 uint256,delegate previousBalance newBalance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,COMP,0xc00e94cb662c3520282e6f5717214004a7f26888,1,0xc00e94cb662c3520282e6f5717214004a7f26888,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundStakingFactory,0x78cc5ab2f0990b5fe58f95baebf8f37879534aeb,1,0x78cc5ab2f0990b5fe58f95baebf8f37879534aeb,Deployed,"Deployed(address,address,address)",0xc95935a66d15e0da5e412aca0ad27ae891d20b2fb91cf3994b6a3bf2b8178082,false,,address address address,proxy cToken impl,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0x92af163505c05d63a4f7478c01b9af9be369c143,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0x92af163505c05d63a4f7478c01b9af9be369c143,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0x92af163505c05d63a4f7478c01b9af9be369c143,GuardianSet,GuardianSet(address),0xe6c09ffe4572dc9ceaa5ddde4ae41befa655d6fdfe8052077af0970f700e942e,false,,address,newGuardian,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0x92af163505c05d63a4f7478c01b9af9be369c143,ParametersSet,ParametersSet(uint256[9]),0x51472f0134408629271bc25caae248dd940cd836aa7bbc3974aa1ec2978059b5,false,,uint256[9],params,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0x92af163505c05d63a4f7478c01b9af9be369c143,ProposalBridge,"ProposalBridge(uint256,uint256)",0x93f05b7f92e65fef7a2a62683de78a4230ca5ec425170818561a02b6afcff28b,false,1,uint256 uint256,id forBlockchain,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0x92af163505c05d63a4f7478c01b9af9be369c143,ProposalCanceled,ProposalCanceled(uint256),0x789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c,false,,uint256,id,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0x92af163505c05d63a4f7478c01b9af9be369c143,ProposalCreated,"ProposalCreated(uint256,address,address[],uint256[],string[],bytes[],uint256,uint256,string)",0x7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e0,false,,uint256 address address[] uint256[] string[] bytes[] uint256 uint256 string,id proposer targets values signatures calldatas startBlock endBlock description,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0x92af163505c05d63a4f7478c01b9af9be369c143,ProposalExecuted,ProposalExecuted(uint256),0x712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f,false,,uint256,id,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0x92af163505c05d63a4f7478c01b9af9be369c143,ProposalExecutionResult,"ProposalExecutionResult(uint256,uint256,bool,bytes)",0x7ee6f70307f5df49af1cdc334b322bc2ff99ae186134a468bf77618a2ce2ff04,false,,uint256 uint256 bool bytes,id index ok result,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0x92af163505c05d63a4f7478c01b9af9be369c143,ProposalQueued,"ProposalQueued(uint256,uint256)",0x9a2e42fd6722813d69113e7d0079d3d940171428df7373df9c7f7617cfda2892,false,,uint256 uint256,id eta,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0x92af163505c05d63a4f7478c01b9af9be369c143,ProposalSucceeded,"ProposalSucceeded(uint256,address,address[],uint256[],string[],bytes[],uint256,uint256,uint256,uint256,uint256,uint256)",0xa5369bfba6e8a577af7ee34ae49c68529b2c8914a2561282f16e3a706cb4333c,false,,uint256 address address[] uint256[] string[] bytes[] uint256 uint256 uint256 uint256 uint256 uint256,id proposer targets values signatures calldatas startBlock endBlock forBlockchain eta forVotes againstVotes,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0x92af163505c05d63a4f7478c01b9af9be369c143,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0x92af163505c05d63a4f7478c01b9af9be369c143,VoteCast,"VoteCast(address,uint256,bool,uint256)",0x877856338e13f63d0c36822ff0ef736b80934cd90574a3a5bc9262c39d217c46,false,,address uint256 bool uint256,voter proposalId support votes,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x807d0066d60a0a8312b6d191f60a6938a527e971,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x807d0066d60a0a8312b6d191f60a6938a527e971,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x807d0066d60a0a8312b6d191f60a6938a527e971,GuardianSet,GuardianSet(address),0xe6c09ffe4572dc9ceaa5ddde4ae41befa655d6fdfe8052077af0970f700e942e,false,,address,newGuardian,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x807d0066d60a0a8312b6d191f60a6938a527e971,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,22165594,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 2 of 2 +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x807d0066d60a0a8312b6d191f60a6938a527e971,ParametersSet,ParametersSet(uint256[9]),0x51472f0134408629271bc25caae248dd940cd836aa7bbc3974aa1ec2978059b5,false,,uint256[9],params,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x807d0066d60a0a8312b6d191f60a6938a527e971,ProposalBridge,"ProposalBridge(uint256,uint256)",0x93f05b7f92e65fef7a2a62683de78a4230ca5ec425170818561a02b6afcff28b,false,1,uint256 uint256,id forBlockchain,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x807d0066d60a0a8312b6d191f60a6938a527e971,ProposalCanceled,ProposalCanceled(uint256),0x789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c,false,,uint256,id,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x807d0066d60a0a8312b6d191f60a6938a527e971,ProposalCreated,"ProposalCreated(uint256,address,address[],uint256[],string[],bytes[],uint256,uint256,string)",0x7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e0,false,,uint256 address address[] uint256[] string[] bytes[] uint256 uint256 string,id proposer targets values signatures calldatas startBlock endBlock description,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x807d0066d60a0a8312b6d191f60a6938a527e971,ProposalExecuted,ProposalExecuted(uint256),0x712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f,false,,uint256,id,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x807d0066d60a0a8312b6d191f60a6938a527e971,ProposalExecutionResult,"ProposalExecutionResult(uint256,uint256,bool,bytes)",0x7ee6f70307f5df49af1cdc334b322bc2ff99ae186134a468bf77618a2ce2ff04,false,,uint256 uint256 bool bytes,id index ok result,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x807d0066d60a0a8312b6d191f60a6938a527e971,ProposalQueued,"ProposalQueued(uint256,uint256)",0x9a2e42fd6722813d69113e7d0079d3d940171428df7373df9c7f7617cfda2892,false,,uint256 uint256,id eta,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x807d0066d60a0a8312b6d191f60a6938a527e971,ProposalSucceeded,"ProposalSucceeded(uint256,address,address[],uint256[],string[],bytes[],uint256,uint256,uint256,uint256,uint256,uint256)",0xa5369bfba6e8a577af7ee34ae49c68529b2c8914a2561282f16e3a706cb4333c,false,,uint256 address address[] uint256[] string[] bytes[] uint256 uint256 uint256 uint256 uint256 uint256,id proposer targets values signatures calldatas startBlock endBlock forBlockchain eta forVotes againstVotes,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x807d0066d60a0a8312b6d191f60a6938a527e971,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x807d0066d60a0a8312b6d191f60a6938a527e971,VoteCast,"VoteCast(address,uint256,bool,uint256)",0x877856338e13f63d0c36822ff0ef736b80934cd90574a3a5bc9262c39d217c46,false,,address uint256 bool uint256,voter proposalId support votes,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Contribution,0x8eec64bb6807c0178f96277cce6a334b4e565e5c,1,0x8eec64bb6807c0178f96277cce6a334b4e565e5c,SellContributionRatioUpdated,"SellContributionRatioUpdated(address,uint256,uint256)",0x039f8bf61b98a6e6b60eefc7000bbe99e429118add8275a51b89a68efdf76728,false,0,address uint256 uint256,caller nom denom,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Controller,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,1,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,AddGlobalConstraint,"AddGlobalConstraint(address,bytes32,uint8)",0x78800d7333b8d0174a0845569e3913b7ce4a3c03ca444dd9904172fc14f2fdad,false,0,address bytes32 uint8,_globalConstraint _params _when,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Controller,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,1,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,BurnReputation,"BurnReputation(address,address,uint256)",0x186d8887e1b22f9d9b16849c36baa748950d09d9c9b67a4a6ea140eaad00c21c,false,0 1,address address uint256,_sender _from _amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Controller,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,1,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,MintReputation,"MintReputation(address,address,uint256)",0x837f2931e3df0592458212be4e470025f197feb7a8e39deb5b7f1f1d42e6f262,false,0 1,address address uint256,_sender _to _amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Controller,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,1,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,MintTokens,"MintTokens(address,address,uint256)",0x21f9c9a1a1f9a311a50f15fec5c1faa9e21fc9edf964f0fdecba5bd490484c5e,false,0 1,address address uint256,_sender _beneficiary _amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Controller,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,1,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,RegisterScheme,"RegisterScheme(address,address)",0x546816e99403df442acb68ef69562682a50762c20a3fb6b472f7af9923736cfc,false,0 1,address address,_sender _scheme,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Controller,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,1,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,RemoveGlobalConstraint,"RemoveGlobalConstraint(address,uint256,bool)",0xcdf1a50ea6b7de555bd409f8a4a53ea43c6dc6b4caa961889da9e005f21bbaa9,false,0,address uint256 bool,_globalConstraint _index _isPre,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Controller,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,1,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,UnregisterScheme,"UnregisterScheme(address,address)",0x10bb2cf04cb8b902a8e736d494f1a51003be6d4b16ef6fb95ce62c38445023bf,false,0 1,address address,_sender _scheme,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Controller,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,1,0x95c0d9dcea1e243ed696f34cac5e6559c3c128a3,UpgradeController,"UpgradeController(address,address)",0xdb7cbacf8df312d794506c0cc9af07f64d29ca075796ea2e950a3832cc9a63dd,false,0,address address,_oldController _newController,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DAI,0x6b175474e89094c44da98b954eedeac495271d0f,1,0x6b175474e89094c44da98b954eedeac495271d0f,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,src guy wad,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DAI,0x6b175474e89094c44da98b954eedeac495271d0f,1,0x6b175474e89094c44da98b954eedeac495271d0f,LogNote,"LogNote(bytes4,address,bytes32,bytes32,bytes)",,true,0 1 2 3,bytes4 address bytes32 bytes32 bytes,sig usr arg1 arg2 data,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DAI,0x6b175474e89094c44da98b954eedeac495271d0f,1,0x6b175474e89094c44da98b954eedeac495271d0f,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,src dst wad,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DAI_ETH_ORACLE,0x773616e4d11a78f511299002da57a0a94577f1f4,1,0x773616e4d11a78f511299002da57a0a94577f1f4,AnswerUpdated,"AnswerUpdated(int256,uint256,uint256)",0x0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f,false,0 1,int256 uint256 uint256,current roundId updatedAt,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DAI_ETH_ORACLE,0x773616e4d11a78f511299002da57a0a94577f1f4,1,0x773616e4d11a78f511299002da57a0a94577f1f4,NewRound,"NewRound(uint256,address,uint256)",0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271,false,0 1,uint256 address uint256,roundId startedBy startedAt,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DAI_ETH_ORACLE,0x773616e4d11a78f511299002da57a0a94577f1f4,1,0x773616e4d11a78f511299002da57a0a94577f1f4,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,from to,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DAI_ETH_ORACLE,0x773616e4d11a78f511299002da57a0a94577f1f4,1,0x773616e4d11a78f511299002da57a0a94577f1f4,OwnershipTransferRequested,"OwnershipTransferRequested(address,address)",0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278,false,0 1,address address,from to,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,1,0x42cda1bd60cc66ab2e2411e8c93db436c8a27060,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,1,0x42cda1bd60cc66ab2e2411e8c93db436c8a27060,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,1,0x42cda1bd60cc66ab2e2411e8c93db436c8a27060,Distribution,"Distribution(uint256,uint256,uint256,(uint32,uint32,address,uint8)[])",0x1a1e3e6e1822c78a68db5a0be6136fecf7718cccae9f6b92d2115aa0ffc9213f,false,,"uint256 uint256 uint256 (uint32,uint32,address,uint8)[]",distributed startingBalance incomingAmount distributionRecipients,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,1,0x42cda1bd60cc66ab2e2411e8c93db436c8a27060,RecipientAdded,"RecipientAdded((uint32,uint32,address,uint8),uint256)",0x2e65f65347b2e76218df0b7b6b594a3862c81e85706795e700237093c47a3957,false,,"(uint32,uint32,address,uint8) uint256",recipient index,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,1,0x42cda1bd60cc66ab2e2411e8c93db436c8a27060,RecipientUpdated,"RecipientUpdated((uint32,uint32,address,uint8),uint256)",0xd26d9de175cfca2c3e0cad9d09c85f0ce6c7fa5257382d00dc26dc5fb25cd8df,false,,"(uint32,uint32,address,uint8) uint256",recipient index,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,1,0x42cda1bd60cc66ab2e2411e8c93db436c8a27060,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,1,0x42cda1bd60cc66ab2e2411e8c93db436c8a27060,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,1,0x42cda1bd60cc66ab2e2411e8c93db436c8a27060,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,1,0x42cda1bd60cc66ab2e2411e8c93db436c8a27060,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,2,0x16171d113d9592b77cec52b8cc4bdd6f5810daef,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,2,0x16171d113d9592b77cec52b8cc4bdd6f5810daef,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,2,0x16171d113d9592b77cec52b8cc4bdd6f5810daef,Distribution,"Distribution(uint256,uint256,uint256,(uint32,uint32,address,uint8)[])",0x1a1e3e6e1822c78a68db5a0be6136fecf7718cccae9f6b92d2115aa0ffc9213f,false,,"uint256 uint256 uint256 (uint32,uint32,address,uint8)[]",distributed startingBalance incomingAmount distributionRecipients,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,2,0x16171d113d9592b77cec52b8cc4bdd6f5810daef,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,17661435,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,2,0x16171d113d9592b77cec52b8cc4bdd6f5810daef,RecipientAdded,"RecipientAdded((uint32,uint32,address,uint8),uint256)",0x2e65f65347b2e76218df0b7b6b594a3862c81e85706795e700237093c47a3957,false,,"(uint32,uint32,address,uint8) uint256",recipient index,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,2,0x16171d113d9592b77cec52b8cc4bdd6f5810daef,RecipientUpdated,"RecipientUpdated((uint32,uint32,address,uint8),uint256)",0xd26d9de175cfca2c3e0cad9d09c85f0ce6c7fa5257382d00dc26dc5fb25cd8df,false,,"(uint32,uint32,address,uint8) uint256",recipient index,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,2,0x16171d113d9592b77cec52b8cc4bdd6f5810daef,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,2,0x16171d113d9592b77cec52b8cc4bdd6f5810daef,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,2,0x16171d113d9592b77cec52b8cc4bdd6f5810daef,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,2,0x16171d113d9592b77cec52b8cc4bdd6f5810daef,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,3,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,3,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,3,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,Distribution,"Distribution(uint256,uint256,uint256,(uint32,uint32,address,uint8)[])",0x1a1e3e6e1822c78a68db5a0be6136fecf7718cccae9f6b92d2115aa0ffc9213f,false,,"uint256 uint256 uint256 (uint32,uint32,address,uint8)[]",distributed startingBalance incomingAmount distributionRecipients,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,3,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,17661435,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,3,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,RecipientAdded,"RecipientAdded((uint32,uint32,address,uint8),uint256)",0x2e65f65347b2e76218df0b7b6b594a3862c81e85706795e700237093c47a3957,false,,"(uint32,uint32,address,uint8) uint256",recipient index,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,3,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,RecipientUpdated,"RecipientUpdated((uint32,uint32,address,uint8),uint256)",0xd26d9de175cfca2c3e0cad9d09c85f0ce6c7fa5257382d00dc26dc5fb25cd8df,false,,"(uint32,uint32,address,uint8) uint256",recipient index,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,3,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,3,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,3,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,3,0x80fbdcf20af77d7dcb21d7104faddbc5d8bd83eb,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,4,0xa339b7f4e95a93d2c6569cb139ad034c3b9caa77,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,4,0xa339b7f4e95a93d2c6569cb139ad034c3b9caa77,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,4,0xa339b7f4e95a93d2c6569cb139ad034c3b9caa77,Distribution,"Distribution(uint256,uint256,uint256,(uint32,uint32,address,uint8)[])",0x1a1e3e6e1822c78a68db5a0be6136fecf7718cccae9f6b92d2115aa0ffc9213f,false,,"uint256 uint256 uint256 (uint32,uint32,address,uint8)[]",distributed startingBalance incomingAmount distributionRecipients,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,4,0xa339b7f4e95a93d2c6569cb139ad034c3b9caa77,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,17661435,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,4,0xa339b7f4e95a93d2c6569cb139ad034c3b9caa77,RecipientAdded,"RecipientAdded((uint32,uint32,address,uint8),uint256)",0x2e65f65347b2e76218df0b7b6b594a3862c81e85706795e700237093c47a3957,false,,"(uint32,uint32,address,uint8) uint256",recipient index,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,4,0xa339b7f4e95a93d2c6569cb139ad034c3b9caa77,RecipientUpdated,"RecipientUpdated((uint32,uint32,address,uint8),uint256)",0xd26d9de175cfca2c3e0cad9d09c85f0ce6c7fa5257382d00dc26dc5fb25cd8df,false,,"(uint32,uint32,address,uint8) uint256",recipient index,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,4,0xa339b7f4e95a93d2c6569cb139ad034c3b9caa77,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,4,0xa339b7f4e95a93d2c6569cb139ad034c3b9caa77,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,4,0xa339b7f4e95a93d2c6569cb139ad034c3b9caa77,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,4,0xa339b7f4e95a93d2c6569cb139ad034c3b9caa77,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,5,0xae2cd2a9513215961d344a2581dcab678598eedf,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,5,0xae2cd2a9513215961d344a2581dcab678598eedf,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,5,0xae2cd2a9513215961d344a2581dcab678598eedf,Distribution,"Distribution(uint256,uint256,uint256,(uint32,uint32,address,uint8)[])",0x1a1e3e6e1822c78a68db5a0be6136fecf7718cccae9f6b92d2115aa0ffc9213f,false,,"uint256 uint256 uint256 (uint32,uint32,address,uint8)[]",distributed startingBalance incomingAmount distributionRecipients,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,5,0xae2cd2a9513215961d344a2581dcab678598eedf,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,17661435,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,5,0xae2cd2a9513215961d344a2581dcab678598eedf,RecipientAdded,"RecipientAdded((uint32,uint32,address,uint8),uint256)",0x2e65f65347b2e76218df0b7b6b594a3862c81e85706795e700237093c47a3957,false,,"(uint32,uint32,address,uint8) uint256",recipient index,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,5,0xae2cd2a9513215961d344a2581dcab678598eedf,RecipientUpdated,"RecipientUpdated((uint32,uint32,address,uint8),uint256)",0xd26d9de175cfca2c3e0cad9d09c85f0ce6c7fa5257382d00dc26dc5fb25cd8df,false,,"(uint32,uint32,address,uint8) uint256",recipient index,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,5,0xae2cd2a9513215961d344a2581dcab678598eedf,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,5,0xae2cd2a9513215961d344a2581dcab678598eedf,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,5,0xae2cd2a9513215961d344a2581dcab678598eedf,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,DistributionHelper,0xacada0c9795fdbb6921ae96c4d7db2f8b8c52fd0,5,0xae2cd2a9513215961d344a2581dcab678598eedf,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,ETH_USD_ORACLE,0x5f4ec3df9cbd43714fe2740f5e3616155c5b8419,1,0x5f4ec3df9cbd43714fe2740f5e3616155c5b8419,AnswerUpdated,"AnswerUpdated(int256,uint256,uint256)",0x0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f,false,0 1,int256 uint256 uint256,current roundId updatedAt,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,ETH_USD_ORACLE,0x5f4ec3df9cbd43714fe2740f5e3616155c5b8419,1,0x5f4ec3df9cbd43714fe2740f5e3616155c5b8419,NewRound,"NewRound(uint256,address,uint256)",0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271,false,0 1,uint256 address uint256,roundId startedBy startedAt,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,ETH_USD_ORACLE,0x5f4ec3df9cbd43714fe2740f5e3616155c5b8419,1,0x5f4ec3df9cbd43714fe2740f5e3616155c5b8419,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,from to,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,ETH_USD_ORACLE,0x5f4ec3df9cbd43714fe2740f5e3616155c5b8419,1,0x5f4ec3df9cbd43714fe2740f5e3616155c5b8419,OwnershipTransferRequested,"OwnershipTransferRequested(address,address)",0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278,false,0 1,address address,from to,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,ExchangeHelper,0x98fa532dd5c3a6b66fbf370813803192de4e0abd,1,0xbebbd9538d594619d36d48666e12d8c9f8372736,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,ExchangeHelper,0x98fa532dd5c3a6b66fbf370813803192de4e0abd,1,0xbebbd9538d594619d36d48666e12d8c9f8372736,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,ExchangeHelper,0x98fa532dd5c3a6b66fbf370813803192de4e0abd,1,0xbebbd9538d594619d36d48666e12d8c9f8372736,TokenPurchased,"TokenPurchased(address,address,uint256,uint256,address)",0xcace70a03cbf3e4fa942b0ab9f70aa3834cfab0a31aa75bc4895262063444e12,false,0 1 4,address address uint256 uint256 address,caller inputToken inputAmount actualReturn receiverAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,ExchangeHelper,0x98fa532dd5c3a6b66fbf370813803192de4e0abd,1,0xbebbd9538d594619d36d48666e12d8c9f8372736,TokenSold,"TokenSold(address,address,uint256,uint256,uint256,address)",0x067ad67f3f4d17211f9f929d19036c2395bbc9b201d517e46e81f9ceae86032e,false,0 1 5,address address uint256 uint256 uint256 address,caller outputToken gdAmount contributionAmount actualReturn receiverAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,ExchangeHelper,0x98fa532dd5c3a6b66fbf370813803192de4e0abd,1,0xbebbd9538d594619d36d48666e12d8c9f8372736,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,ExchangeHelper,0x98fa532dd5c3a6b66fbf370813803192de4e0abd,2,0x24614ad257f4d09fccaec024c65c40c060e73e9d,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,ExchangeHelper,0x98fa532dd5c3a6b66fbf370813803192de4e0abd,2,0x24614ad257f4d09fccaec024c65c40c060e73e9d,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,ExchangeHelper,0x98fa532dd5c3a6b66fbf370813803192de4e0abd,2,0x24614ad257f4d09fccaec024c65c40c060e73e9d,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,22165594,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 2 of 2 +ETHEREUM,1,ExchangeHelper,0x98fa532dd5c3a6b66fbf370813803192de4e0abd,2,0x24614ad257f4d09fccaec024c65c40c060e73e9d,TokenPurchased,"TokenPurchased(address,address,uint256,uint256,address)",0xcace70a03cbf3e4fa942b0ab9f70aa3834cfab0a31aa75bc4895262063444e12,false,0 1 4,address address uint256 uint256 address,caller inputToken inputAmount actualReturn receiverAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,ExchangeHelper,0x98fa532dd5c3a6b66fbf370813803192de4e0abd,2,0x24614ad257f4d09fccaec024c65c40c060e73e9d,TokenSold,"TokenSold(address,address,uint256,uint256,uint256,address)",0x067ad67f3f4d17211f9f929d19036c2395bbc9b201d517e46e81f9ceae86032e,false,0 1 5,address address uint256 uint256 uint256 address,caller outputToken gdAmount contributionAmount actualReturn receiverAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,ExchangeHelper,0x98fa532dd5c3a6b66fbf370813803192de4e0abd,2,0x24614ad257f4d09fccaec024c65c40c060e73e9d,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,ForeignBridge,0xd5d11ee582c8931f336fbcd135e98cee4db8ccb0,1,0xd5d11ee582c8931f336fbcd135e98cee4db8ccb0,ProxyOwnershipTransferred,"ProxyOwnershipTransferred(address,address)",0x5a3e66efaa1e445ebd894728a69d6959842ea1e97bd79b892797106e270efcd9,false,,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,ForeignBridge,0xd5d11ee582c8931f336fbcd135e98cee4db8ccb0,1,0xd5d11ee582c8931f336fbcd135e98cee4db8ccb0,Upgraded,"Upgraded(uint256,address)",0x4289d6195cf3c2d2174adf98d0e19d4d2d08887995b99cb7b100e7ffe795820e,false,1,uint256 address,version implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GAS_PRICE_ORACLE,0x169e633a2d1e6c10dd91238ba11c4a708dfef37c,1,0x169e633a2d1e6c10dd91238ba11c4a708dfef37c,AnswerUpdated,"AnswerUpdated(int256,uint256,uint256)",0x0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f,false,0 1,int256 uint256 uint256,current roundId updatedAt,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GAS_PRICE_ORACLE,0x169e633a2d1e6c10dd91238ba11c4a708dfef37c,1,0x169e633a2d1e6c10dd91238ba11c4a708dfef37c,NewRound,"NewRound(uint256,address,uint256)",0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271,false,0 1,uint256 address uint256,roundId startedBy startedAt,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GAS_PRICE_ORACLE,0x169e633a2d1e6c10dd91238ba11c4a708dfef37c,1,0x169e633a2d1e6c10dd91238ba11c4a708dfef37c,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,from to,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GAS_PRICE_ORACLE,0x169e633a2d1e6c10dd91238ba11c4a708dfef37c,1,0x169e633a2d1e6c10dd91238ba11c4a708dfef37c,OwnershipTransferRequested,"OwnershipTransferRequested(address,address)",0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278,false,0 1,address address,from to,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodDollar,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,1,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodDollar,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,1,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,MinterAdded,MinterAdded(address),0x6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f6,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodDollar,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,1,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,MinterRemoved,MinterRemoved(address),0xe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb66692,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodDollar,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,1,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodDollar,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,1,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodDollar,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,1,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,PauserAdded,PauserAdded(address),0x6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f8,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodDollar,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,1,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,PauserRemoved,PauserRemoved(address),0xcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodDollar,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,1,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodDollar,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,1,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,Transfer,"Transfer(address,address,uint256,bytes)",0xe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16,false,0 1,address address uint256 bytes,from to value data,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodDollar,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,1,0x67c5870b4a41d4ebef24d2456547a03f1f3e094b,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,1,0x4a10354b8e1928c38cc6a738cd2748fa1c818cea,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,1,0x4a10354b8e1928c38cc6a738cd2748fa1c818cea,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,1,0x4a10354b8e1928c38cc6a738cd2748fa1c818cea,CollectInterestTimeThresholdSet,CollectInterestTimeThresholdSet(uint256),0x28b3b60d9fa0f6edab793c2422ff4784f9381ff9d2062481d1254f732452bfbf,false,,uint256,newCollectInterestTimeThreshold,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,1,0x4a10354b8e1928c38cc6a738cd2748fa1c818cea,FundsTransferred,"FundsTransferred(address,address,address[],uint256,uint256,uint256)",0xa152fd34a7e4c4c82eb0c0b0319d3913dc9189d62ae2fe75aef590f0e391a928,false,0,address address address[] uint256 uint256 uint256,caller reserve stakings cDAIinterestEarned gdUBI gdReward,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,1,0x4a10354b8e1928c38cc6a738cd2748fa1c818cea,GasCostExceptInterestCollectSet,GasCostExceptInterestCollectSet(uint256),0xcc09a90bef37a706a00b53dd3f515f9326b029e41271b4bb87777773962cbc60,false,,uint256,newGasCostExceptInterestCollect,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,1,0x4a10354b8e1928c38cc6a738cd2748fa1c818cea,GasCostSet,GasCostSet(uint256),0x08deabc2cb3286b159d9350bf977350e1f31e39ae44075269082a800e9ee59de,false,,uint256,newGasCost,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,1,0x4a10354b8e1928c38cc6a738cd2748fa1c818cea,InterestMultiplierSet,InterestMultiplierSet(uint8),0xceef3bba37867319344ac9cc91b1d2318daa822bae8d15118d84aedc1fbba330,false,,uint8,newInterestMultiplier,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,1,0x4a10354b8e1928c38cc6a738cd2748fa1c818cea,StakingRewardMinted,"StakingRewardMinted(address,address,uint256)",0x5c4a97f844ad1dc8cad420327f32da9b4bd075bab26efa2ae5bd66f84d1fce07,false,,address address uint256,stakingContract staker gdReward,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,1,0x4a10354b8e1928c38cc6a738cd2748fa1c818cea,StakingRewardSet,"StakingRewardSet(uint32,address,uint32,uint32,bool)",0xcfeece178cde5fc0c509d31ec15ec2d996342bec5d9820be8aabbda11a21205b,false,,uint32 address uint32 uint32 bool,_rewardsPerBlock _stakingAddress _blockStart _blockEnd _isBlackListed,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,1,0x4a10354b8e1928c38cc6a738cd2748fa1c818cea,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,2,0x53b3c6b18a03a9a0c3487cf1230eea1eb9a38a0a,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,2,0x53b3c6b18a03a9a0c3487cf1230eea1eb9a38a0a,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,2,0x53b3c6b18a03a9a0c3487cf1230eea1eb9a38a0a,CollectInterestTimeThresholdSet,CollectInterestTimeThresholdSet(uint256),0x28b3b60d9fa0f6edab793c2422ff4784f9381ff9d2062481d1254f732452bfbf,false,,uint256,newCollectInterestTimeThreshold,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,2,0x53b3c6b18a03a9a0c3487cf1230eea1eb9a38a0a,FundsTransferred,"FundsTransferred(address,address,address[],uint256,uint256,uint256)",0xa152fd34a7e4c4c82eb0c0b0319d3913dc9189d62ae2fe75aef590f0e391a928,false,0,address address address[] uint256 uint256 uint256,caller reserve stakings cDAIinterestEarned gdUBI gdReward,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,2,0x53b3c6b18a03a9a0c3487cf1230eea1eb9a38a0a,GasCostExceptInterestCollectSet,GasCostExceptInterestCollectSet(uint256),0xcc09a90bef37a706a00b53dd3f515f9326b029e41271b4bb87777773962cbc60,false,,uint256,newGasCostExceptInterestCollect,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,2,0x53b3c6b18a03a9a0c3487cf1230eea1eb9a38a0a,GasCostSet,GasCostSet(uint256),0x08deabc2cb3286b159d9350bf977350e1f31e39ae44075269082a800e9ee59de,false,,uint256,newGasCost,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,2,0x53b3c6b18a03a9a0c3487cf1230eea1eb9a38a0a,InterestMultiplierSet,InterestMultiplierSet(uint8),0xceef3bba37867319344ac9cc91b1d2318daa822bae8d15118d84aedc1fbba330,false,,uint8,newInterestMultiplier,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,2,0x53b3c6b18a03a9a0c3487cf1230eea1eb9a38a0a,StakingRewardMinted,"StakingRewardMinted(address,address,uint256)",0x5c4a97f844ad1dc8cad420327f32da9b4bd075bab26efa2ae5bd66f84d1fce07,false,,address address uint256,stakingContract staker gdReward,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,2,0x53b3c6b18a03a9a0c3487cf1230eea1eb9a38a0a,StakingRewardSet,"StakingRewardSet(uint32,address,uint32,uint32,bool)",0xcfeece178cde5fc0c509d31ec15ec2d996342bec5d9820be8aabbda11a21205b,false,,uint32 address uint32 uint32 bool,_rewardsPerBlock _stakingAddress _blockStart _blockEnd _isBlackListed,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,2,0x53b3c6b18a03a9a0c3487cf1230eea1eb9a38a0a,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,3,0x4a37a8d7cdb43d89b4dbd7ecfaeaf9bd39e24929,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,3,0x4a37a8d7cdb43d89b4dbd7ecfaeaf9bd39e24929,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,3,0x4a37a8d7cdb43d89b4dbd7ecfaeaf9bd39e24929,CollectInterestTimeThresholdSet,CollectInterestTimeThresholdSet(uint256),0x28b3b60d9fa0f6edab793c2422ff4784f9381ff9d2062481d1254f732452bfbf,false,,uint256,newCollectInterestTimeThreshold,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,3,0x4a37a8d7cdb43d89b4dbd7ecfaeaf9bd39e24929,FundsTransferred,"FundsTransferred(address,address,address[],uint256,uint256,uint256)",0xa152fd34a7e4c4c82eb0c0b0319d3913dc9189d62ae2fe75aef590f0e391a928,false,0,address address address[] uint256 uint256 uint256,caller reserve stakings cDAIinterestEarned gdUBI gdReward,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,3,0x4a37a8d7cdb43d89b4dbd7ecfaeaf9bd39e24929,GasCostExceptInterestCollectSet,GasCostExceptInterestCollectSet(uint256),0xcc09a90bef37a706a00b53dd3f515f9326b029e41271b4bb87777773962cbc60,false,,uint256,newGasCostExceptInterestCollect,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,3,0x4a37a8d7cdb43d89b4dbd7ecfaeaf9bd39e24929,GasCostSet,GasCostSet(uint256),0x08deabc2cb3286b159d9350bf977350e1f31e39ae44075269082a800e9ee59de,false,,uint256,newGasCost,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,3,0x4a37a8d7cdb43d89b4dbd7ecfaeaf9bd39e24929,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,18190480,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 3,4 of 4" +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,3,0x4a37a8d7cdb43d89b4dbd7ecfaeaf9bd39e24929,InterestMultiplierSet,InterestMultiplierSet(uint8),0xceef3bba37867319344ac9cc91b1d2318daa822bae8d15118d84aedc1fbba330,false,,uint8,newInterestMultiplier,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,3,0x4a37a8d7cdb43d89b4dbd7ecfaeaf9bd39e24929,StakingRewardMinted,"StakingRewardMinted(address,address,uint256)",0x5c4a97f844ad1dc8cad420327f32da9b4bd075bab26efa2ae5bd66f84d1fce07,false,,address address uint256,stakingContract staker gdReward,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,3,0x4a37a8d7cdb43d89b4dbd7ecfaeaf9bd39e24929,StakingRewardSet,"StakingRewardSet(uint32,address,uint32,uint32,bool)",0xcfeece178cde5fc0c509d31ec15ec2d996342bec5d9820be8aabbda11a21205b,false,,uint32 address uint32 uint32 bool,_rewardsPerBlock _stakingAddress _blockStart _blockEnd _isBlackListed,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,3,0x4a37a8d7cdb43d89b4dbd7ecfaeaf9bd39e24929,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,4,0xaacbaab8571cbeceb46ba85b5981efdb8928545e,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,4,0xaacbaab8571cbeceb46ba85b5981efdb8928545e,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,4,0xaacbaab8571cbeceb46ba85b5981efdb8928545e,CollectInterestTimeThresholdSet,CollectInterestTimeThresholdSet(uint256),0x28b3b60d9fa0f6edab793c2422ff4784f9381ff9d2062481d1254f732452bfbf,false,,uint256,newCollectInterestTimeThreshold,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,4,0xaacbaab8571cbeceb46ba85b5981efdb8928545e,FundsTransferred,"FundsTransferred(address,address,address[],uint256,uint256,uint256)",0xa152fd34a7e4c4c82eb0c0b0319d3913dc9189d62ae2fe75aef590f0e391a928,false,0,address address address[] uint256 uint256 uint256,caller reserve stakings cDAIinterestEarned gdUBI gdReward,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,4,0xaacbaab8571cbeceb46ba85b5981efdb8928545e,GasCostExceptInterestCollectSet,GasCostExceptInterestCollectSet(uint256),0xcc09a90bef37a706a00b53dd3f515f9326b029e41271b4bb87777773962cbc60,false,,uint256,newGasCostExceptInterestCollect,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,4,0xaacbaab8571cbeceb46ba85b5981efdb8928545e,GasCostSet,GasCostSet(uint256),0x08deabc2cb3286b159d9350bf977350e1f31e39ae44075269082a800e9ee59de,false,,uint256,newGasCost,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,4,0xaacbaab8571cbeceb46ba85b5981efdb8928545e,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,18190480,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 3,4 of 4" +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,4,0xaacbaab8571cbeceb46ba85b5981efdb8928545e,InterestMultiplierSet,InterestMultiplierSet(uint8),0xceef3bba37867319344ac9cc91b1d2318daa822bae8d15118d84aedc1fbba330,false,,uint8,newInterestMultiplier,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,4,0xaacbaab8571cbeceb46ba85b5981efdb8928545e,StakingRewardMinted,"StakingRewardMinted(address,address,uint256)",0x5c4a97f844ad1dc8cad420327f32da9b4bd075bab26efa2ae5bd66f84d1fce07,false,,address address uint256,stakingContract staker gdReward,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,4,0xaacbaab8571cbeceb46ba85b5981efdb8928545e,StakingRewardSet,"StakingRewardSet(uint32,address,uint32,uint32,bool)",0xcfeece178cde5fc0c509d31ec15ec2d996342bec5d9820be8aabbda11a21205b,false,,uint32 address uint32 uint32 bool,_rewardsPerBlock _stakingAddress _blockStart _blockEnd _isBlackListed,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodFundManager,0x0c6c80d2061afa35e160f3799411d83bdeea0a5a,4,0xaacbaab8571cbeceb46ba85b5981efdb8928545e,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodMarketMaker,0xdac6a0c973ba7cf3526de456affa43ab421f659f,1,0xb3ff03c8a42506ba58b1127cd4b5928c7ed70a03,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodMarketMaker,0xdac6a0c973ba7cf3526de456affa43ab421f659f,1,0xb3ff03c8a42506ba58b1127cd4b5928c7ed70a03,BalancesUpdated,"BalancesUpdated(address,address,uint256,uint256,uint256,uint256)",0xed639966d5b0a89f5ac16d6359c7707785de6e51a00f07dd3197e5fbf0a30374,false,0 1,address address uint256 uint256 uint256 uint256,caller reserveToken amount returnAmount totalSupply reserveBalance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodMarketMaker,0xdac6a0c973ba7cf3526de456affa43ab421f659f,1,0xb3ff03c8a42506ba58b1127cd4b5928c7ed70a03,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodMarketMaker,0xdac6a0c973ba7cf3526de456affa43ab421f659f,1,0xb3ff03c8a42506ba58b1127cd4b5928c7ed70a03,ReserveRatioUpdated,"ReserveRatioUpdated(address,uint256,uint256)",0xcd3db955892df8543ef392cb55c3f36e13ad4c38e151c8315101b3006ef105df,false,0,address uint256 uint256,caller nom denom,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodMarketMaker,0xdac6a0c973ba7cf3526de456affa43ab421f659f,1,0xb3ff03c8a42506ba58b1127cd4b5928c7ed70a03,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodMarketMaker,0xdac6a0c973ba7cf3526de456affa43ab421f659f,2,0x8520633e40574e9550f6a0436b0f8d56f3b99bd0,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodMarketMaker,0xdac6a0c973ba7cf3526de456affa43ab421f659f,2,0x8520633e40574e9550f6a0436b0f8d56f3b99bd0,BalancesUpdated,"BalancesUpdated(address,address,uint256,uint256,uint256,uint256)",0xed639966d5b0a89f5ac16d6359c7707785de6e51a00f07dd3197e5fbf0a30374,false,0 1,address address uint256 uint256 uint256 uint256,caller reserveToken amount returnAmount totalSupply reserveBalance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodMarketMaker,0xdac6a0c973ba7cf3526de456affa43ab421f659f,2,0x8520633e40574e9550f6a0436b0f8d56f3b99bd0,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodMarketMaker,0xdac6a0c973ba7cf3526de456affa43ab421f659f,2,0x8520633e40574e9550f6a0436b0f8d56f3b99bd0,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,22165594,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 2 of 2 +ETHEREUM,1,GoodMarketMaker,0xdac6a0c973ba7cf3526de456affa43ab421f659f,2,0x8520633e40574e9550f6a0436b0f8d56f3b99bd0,ReserveRatioUpdated,"ReserveRatioUpdated(address,uint256,uint256)",0xcd3db955892df8543ef392cb55c3f36e13ad4c38e151c8315101b3006ef105df,false,0,address uint256 uint256,caller nom denom,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodMarketMaker,0xdac6a0c973ba7cf3526de456affa43ab421f659f,2,0x8520633e40574e9550f6a0436b0f8d56f3b99bd0,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,1,0x865193da25c4fe135421fca78d2bd061b6efd744,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,1,0x865193da25c4fe135421fca78d2bd061b6efd744,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,1,0x865193da25c4fe135421fca78d2bd061b6efd744,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,1,0x865193da25c4fe135421fca78d2bd061b6efd744,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,1,0x865193da25c4fe135421fca78d2bd061b6efd744,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,1,0x865193da25c4fe135421fca78d2bd061b6efd744,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,1,0x865193da25c4fe135421fca78d2bd061b6efd744,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,1,0x865193da25c4fe135421fca78d2bd061b6efd744,TokenPurchased,"TokenPurchased(address,address,uint256,uint256,address)",0xcace70a03cbf3e4fa942b0ab9f70aa3834cfab0a31aa75bc4895262063444e12,false,0 1 4,address address uint256 uint256 address,caller inputToken inputAmount actualReturn receiverAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,1,0x865193da25c4fe135421fca78d2bd061b6efd744,TokenSold,"TokenSold(address,address,uint256,uint256,uint256,address)",0x067ad67f3f4d17211f9f929d19036c2395bbc9b201d517e46e81f9ceae86032e,false,0 1 5,address address uint256 uint256 uint256 address,caller outputToken gdAmount contributionAmount actualReturn receiverAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,1,0x865193da25c4fe135421fca78d2bd061b6efd744,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,1,0x865193da25c4fe135421fca78d2bd061b6efd744,UBIMinted,"UBIMinted(uint256,address,uint256,uint256,uint256,uint256)",0x1a962236b7c7b3d7b9f6b56036cbce44ab2f93a22b0827d2f2a92a8f055552b9,false,0 1,uint256 address uint256 uint256 uint256 uint256,day interestToken interestReceived gdInterestMinted gdExpansionMinted gdUbiTransferred,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,1,0x865193da25c4fe135421fca78d2bd061b6efd744,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,1,0x865193da25c4fe135421fca78d2bd061b6efd744,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,2,0x6e1c3f516ffd14852f9b25f21af13b6ce98dace5,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,2,0x6e1c3f516ffd14852f9b25f21af13b6ce98dace5,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,2,0x6e1c3f516ffd14852f9b25f21af13b6ce98dace5,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,2,0x6e1c3f516ffd14852f9b25f21af13b6ce98dace5,DistributionHelperSet,"DistributionHelperSet(address,uint32)",0x0fa8d325f44a93da78a029607ba0c95db6a44fa32278f04de5396797a4306ead,false,,address uint32,distributionHelper bps,true,16174339,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,2,0x6e1c3f516ffd14852f9b25f21af13b6ce98dace5,NonUBIMinted,"NonUBIMinted(address,uint256,bool)",0xb56fc50d7b662a8276d9ebb04cd6f2d9f7d6a443f80bf0a969387aaf56dbb535,false,,address uint256 bool,distributionHelper amountMinted distributionSucceeded,true,16174339,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,2,0x6e1c3f516ffd14852f9b25f21af13b6ce98dace5,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,2,0x6e1c3f516ffd14852f9b25f21af13b6ce98dace5,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,2,0x6e1c3f516ffd14852f9b25f21af13b6ce98dace5,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,2,0x6e1c3f516ffd14852f9b25f21af13b6ce98dace5,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,2,0x6e1c3f516ffd14852f9b25f21af13b6ce98dace5,TokenPurchased,"TokenPurchased(address,address,uint256,uint256,address)",0xcace70a03cbf3e4fa942b0ab9f70aa3834cfab0a31aa75bc4895262063444e12,false,0 1 4,address address uint256 uint256 address,caller inputToken inputAmount actualReturn receiverAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,2,0x6e1c3f516ffd14852f9b25f21af13b6ce98dace5,TokenSold,"TokenSold(address,address,uint256,uint256,uint256,address)",0x067ad67f3f4d17211f9f929d19036c2395bbc9b201d517e46e81f9ceae86032e,false,0 1 5,address address uint256 uint256 uint256 address,caller outputToken gdAmount contributionAmount actualReturn receiverAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,2,0x6e1c3f516ffd14852f9b25f21af13b6ce98dace5,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,2,0x6e1c3f516ffd14852f9b25f21af13b6ce98dace5,UBIMinted,"UBIMinted(uint256,address,uint256,uint256,uint256,uint256)",0x1a962236b7c7b3d7b9f6b56036cbce44ab2f93a22b0827d2f2a92a8f055552b9,false,0 1,uint256 address uint256 uint256 uint256 uint256,day interestToken interestReceived gdInterestMinted gdExpansionMinted gdUbiTransferred,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,2,0x6e1c3f516ffd14852f9b25f21af13b6ce98dace5,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,2,0x6e1c3f516ffd14852f9b25f21af13b6ce98dace5,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,3,0x2793a5887f53b025f49f7a9249d66f4671bce29b,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,3,0x2793a5887f53b025f49f7a9249d66f4671bce29b,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,3,0x2793a5887f53b025f49f7a9249d66f4671bce29b,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,3,0x2793a5887f53b025f49f7a9249d66f4671bce29b,DistributionHelperSet,"DistributionHelperSet(address,uint32)",0x0fa8d325f44a93da78a029607ba0c95db6a44fa32278f04de5396797a4306ead,false,,address uint32,distributionHelper bps,true,16174339,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,3,0x2793a5887f53b025f49f7a9249d66f4671bce29b,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,18190480,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 3,4 of 4" +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,3,0x2793a5887f53b025f49f7a9249d66f4671bce29b,NonUBIMinted,"NonUBIMinted(address,uint256,bool)",0xb56fc50d7b662a8276d9ebb04cd6f2d9f7d6a443f80bf0a969387aaf56dbb535,false,,address uint256 bool,distributionHelper amountMinted distributionSucceeded,true,16174339,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,3,0x2793a5887f53b025f49f7a9249d66f4671bce29b,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,3,0x2793a5887f53b025f49f7a9249d66f4671bce29b,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,3,0x2793a5887f53b025f49f7a9249d66f4671bce29b,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,3,0x2793a5887f53b025f49f7a9249d66f4671bce29b,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,3,0x2793a5887f53b025f49f7a9249d66f4671bce29b,TokenPurchased,"TokenPurchased(address,address,uint256,uint256,address)",0xcace70a03cbf3e4fa942b0ab9f70aa3834cfab0a31aa75bc4895262063444e12,false,0 1 4,address address uint256 uint256 address,caller inputToken inputAmount actualReturn receiverAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,3,0x2793a5887f53b025f49f7a9249d66f4671bce29b,TokenSold,"TokenSold(address,address,uint256,uint256,uint256,address)",0x067ad67f3f4d17211f9f929d19036c2395bbc9b201d517e46e81f9ceae86032e,false,0 1 5,address address uint256 uint256 uint256 address,caller outputToken gdAmount contributionAmount actualReturn receiverAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,3,0x2793a5887f53b025f49f7a9249d66f4671bce29b,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,3,0x2793a5887f53b025f49f7a9249d66f4671bce29b,UBIMinted,"UBIMinted(uint256,address,uint256,uint256,uint256,uint256)",0x1a962236b7c7b3d7b9f6b56036cbce44ab2f93a22b0827d2f2a92a8f055552b9,false,0 1,uint256 address uint256 uint256 uint256 uint256,day interestToken interestReceived gdInterestMinted gdExpansionMinted gdUbiTransferred,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,3,0x2793a5887f53b025f49f7a9249d66f4671bce29b,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,3,0x2793a5887f53b025f49f7a9249d66f4671bce29b,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,4,0x18bcdf79a724648bf34eb06701be81bd072a2384,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,4,0x18bcdf79a724648bf34eb06701be81bd072a2384,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,4,0x18bcdf79a724648bf34eb06701be81bd072a2384,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,4,0x18bcdf79a724648bf34eb06701be81bd072a2384,DistributionHelperSet,"DistributionHelperSet(address,uint32)",0x0fa8d325f44a93da78a029607ba0c95db6a44fa32278f04de5396797a4306ead,false,,address uint32,distributionHelper bps,true,16174339,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,4,0x18bcdf79a724648bf34eb06701be81bd072a2384,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,18190480,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 3,4 of 4" +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,4,0x18bcdf79a724648bf34eb06701be81bd072a2384,NonUBIMinted,"NonUBIMinted(address,uint256,bool)",0xb56fc50d7b662a8276d9ebb04cd6f2d9f7d6a443f80bf0a969387aaf56dbb535,false,,address uint256 bool,distributionHelper amountMinted distributionSucceeded,true,16174339,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,4,0x18bcdf79a724648bf34eb06701be81bd072a2384,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,4,0x18bcdf79a724648bf34eb06701be81bd072a2384,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,4,0x18bcdf79a724648bf34eb06701be81bd072a2384,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,4,0x18bcdf79a724648bf34eb06701be81bd072a2384,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,4,0x18bcdf79a724648bf34eb06701be81bd072a2384,TokenPurchased,"TokenPurchased(address,address,uint256,uint256,address)",0xcace70a03cbf3e4fa942b0ab9f70aa3834cfab0a31aa75bc4895262063444e12,false,0 1 4,address address uint256 uint256 address,caller inputToken inputAmount actualReturn receiverAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,4,0x18bcdf79a724648bf34eb06701be81bd072a2384,TokenSold,"TokenSold(address,address,uint256,uint256,uint256,address)",0x067ad67f3f4d17211f9f929d19036c2395bbc9b201d517e46e81f9ceae86032e,false,0 1 5,address address uint256 uint256 uint256 address,caller outputToken gdAmount contributionAmount actualReturn receiverAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,4,0x18bcdf79a724648bf34eb06701be81bd072a2384,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,4,0x18bcdf79a724648bf34eb06701be81bd072a2384,UBIMinted,"UBIMinted(uint256,address,uint256,uint256,uint256,uint256)",0x1a962236b7c7b3d7b9f6b56036cbce44ab2f93a22b0827d2f2a92a8f055552b9,false,0 1,uint256 address uint256 uint256 uint256 uint256,day interestToken interestReceived gdInterestMinted gdExpansionMinted gdUbiTransferred,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,4,0x18bcdf79a724648bf34eb06701be81bd072a2384,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GoodReserveCDai,0xa150a825d425b36329d8294eef8bd0fe68f8f6e0,4,0x18bcdf79a724648bf34eb06701be81bd072a2384,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0x0a5dcf330ba39434dbda59b982a3dd09759cc788,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0x0a5dcf330ba39434dbda59b982a3dd09759cc788,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0x0a5dcf330ba39434dbda59b982a3dd09759cc788,Burn,"Burn(address,uint256)",0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5,false,0,address uint256,_from _amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0x0a5dcf330ba39434dbda59b982a3dd09759cc788,DelegateVotesChanged,"DelegateVotesChanged(address,address,uint256,uint256)",0x8553411b8bbb348336351063649aa1f4fa74c4935f5c4386469a017df33a1f66,false,0 1,address address uint256 uint256,delegate delegator previousBalance newBalance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0x0a5dcf330ba39434dbda59b982a3dd09759cc788,Mint,"Mint(address,uint256)",0x0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885,false,0,address uint256,_to _amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0x0a5dcf330ba39434dbda59b982a3dd09759cc788,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0x0a5dcf330ba39434dbda59b982a3dd09759cc788,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0x0a5dcf330ba39434dbda59b982a3dd09759cc788,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0x0a5dcf330ba39434dbda59b982a3dd09759cc788,StateHash,"StateHash(string,bytes32,uint256)",0x5298f094d368dc1c18dca22952c4ea2cb8b115d7c70a18269735b0f4ed0f4913,false,,string bytes32 uint256,blockchain merkleRoot totalSupply,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0x0a5dcf330ba39434dbda59b982a3dd09759cc788,StateHashProof,"StateHashProof(string,address,uint256)",0x1c708de3afb744b96b84aa0fbf440e683fac3130cce82a8f01eb94b5e67610a0,false,,string address uint256,blockchain user repBalance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0x0a5dcf330ba39434dbda59b982a3dd09759cc788,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x438eb12a081041b525731c34086de3ed31658dee,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x438eb12a081041b525731c34086de3ed31658dee,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x438eb12a081041b525731c34086de3ed31658dee,Burn,"Burn(address,uint256)",0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5,false,0,address uint256,_from _amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x438eb12a081041b525731c34086de3ed31658dee,DelegateVotesChanged,"DelegateVotesChanged(address,address,uint256,uint256)",0x8553411b8bbb348336351063649aa1f4fa74c4935f5c4386469a017df33a1f66,false,0 1,address address uint256 uint256,delegate delegator previousBalance newBalance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x438eb12a081041b525731c34086de3ed31658dee,Mint,"Mint(address,uint256)",0x0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885,false,0,address uint256,_to _amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x438eb12a081041b525731c34086de3ed31658dee,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x438eb12a081041b525731c34086de3ed31658dee,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x438eb12a081041b525731c34086de3ed31658dee,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x438eb12a081041b525731c34086de3ed31658dee,StateHash,"StateHash(string,bytes32,uint256)",0x5298f094d368dc1c18dca22952c4ea2cb8b115d7c70a18269735b0f4ed0f4913,false,,string bytes32 uint256,blockchain merkleRoot totalSupply,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x438eb12a081041b525731c34086de3ed31658dee,StateHashProof,"StateHashProof(string,address,uint256)",0x1c708de3afb744b96b84aa0fbf440e683fac3130cce82a8f01eb94b5e67610a0,false,1,string address uint256,blockchain user repBalance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x438eb12a081041b525731c34086de3ed31658dee,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x634e25b6ffde325d5beb8c6c2d8af6d543b6ff7f,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x634e25b6ffde325d5beb8c6c2d8af6d543b6ff7f,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x634e25b6ffde325d5beb8c6c2d8af6d543b6ff7f,Burn,"Burn(address,uint256)",0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5,false,0,address uint256,_from _amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x634e25b6ffde325d5beb8c6c2d8af6d543b6ff7f,DelegateVotesChanged,"DelegateVotesChanged(address,address,uint256,uint256)",0x8553411b8bbb348336351063649aa1f4fa74c4935f5c4386469a017df33a1f66,false,0 1,address address uint256 uint256,delegate delegator previousBalance newBalance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x634e25b6ffde325d5beb8c6c2d8af6d543b6ff7f,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,16885600,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 3 of 3 +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x634e25b6ffde325d5beb8c6c2d8af6d543b6ff7f,Mint,"Mint(address,uint256)",0x0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885,false,0,address uint256,_to _amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x634e25b6ffde325d5beb8c6c2d8af6d543b6ff7f,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x634e25b6ffde325d5beb8c6c2d8af6d543b6ff7f,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x634e25b6ffde325d5beb8c6c2d8af6d543b6ff7f,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x634e25b6ffde325d5beb8c6c2d8af6d543b6ff7f,StateHash,"StateHash(string,bytes32,uint256)",0x5298f094d368dc1c18dca22952c4ea2cb8b115d7c70a18269735b0f4ed0f4913,false,,string bytes32 uint256,blockchain merkleRoot totalSupply,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x634e25b6ffde325d5beb8c6c2d8af6d543b6ff7f,StateHashProof,"StateHashProof(string,address,uint256)",0x1c708de3afb744b96b84aa0fbf440e683fac3130cce82a8f01eb94b5e67610a0,false,1,string address uint256,blockchain user repBalance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x634e25b6ffde325d5beb8c6c2d8af6d543b6ff7f,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Identity,0x76e76e10ac308a1d54a00f9df27edce4801f288b,1,0x76e76e10ac308a1d54a00f9df27edce4801f288b,BlacklistAdded,BlacklistAdded(address),0x44d5fe68b00f68950fb9c1ff0a61ef7f747b1a36359a7e3a7f3324db4b878967,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Identity,0x76e76e10ac308a1d54a00f9df27edce4801f288b,1,0x76e76e10ac308a1d54a00f9df27edce4801f288b,BlacklistRemoved,BlacklistRemoved(address),0x1747ca720b1a174a464b6513ace29b1d3190b5f632b9f34147017c81425bfde8,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Identity,0x76e76e10ac308a1d54a00f9df27edce4801f288b,1,0x76e76e10ac308a1d54a00f9df27edce4801f288b,ContractAdded,ContractAdded(address),0x89c66952b48f3e96bf1d8ba1b63189520fd988a6979b8b740bd5c5d8dc53e205,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Identity,0x76e76e10ac308a1d54a00f9df27edce4801f288b,1,0x76e76e10ac308a1d54a00f9df27edce4801f288b,ContractRemoved,ContractRemoved(address),0x8d30d41865a0b811b9545d879520d2dde9f4cc49e4241f486ad9752bc904b565,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Identity,0x76e76e10ac308a1d54a00f9df27edce4801f288b,1,0x76e76e10ac308a1d54a00f9df27edce4801f288b,IdentityAdminAdded,IdentityAdminAdded(address),0x3505858ac30c166c603cb64de4a970615e36a4ed8fea37ba93bc5f11a38dd309,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Identity,0x76e76e10ac308a1d54a00f9df27edce4801f288b,1,0x76e76e10ac308a1d54a00f9df27edce4801f288b,IdentityAdminRemoved,IdentityAdminRemoved(address),0x869f6a5b4767d57c58d57f1ddf82e1516487f35944a19bf30a4a21bd35f6ad05,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Identity,0x76e76e10ac308a1d54a00f9df27edce4801f288b,1,0x76e76e10ac308a1d54a00f9df27edce4801f288b,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Identity,0x76e76e10ac308a1d54a00f9df27edce4801f288b,1,0x76e76e10ac308a1d54a00f9df27edce4801f288b,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Identity,0x76e76e10ac308a1d54a00f9df27edce4801f288b,1,0x76e76e10ac308a1d54a00f9df27edce4801f288b,PauserAdded,PauserAdded(address),0x6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f8,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Identity,0x76e76e10ac308a1d54a00f9df27edce4801f288b,1,0x76e76e10ac308a1d54a00f9df27edce4801f288b,PauserRemoved,PauserRemoved(address),0xcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Identity,0x76e76e10ac308a1d54a00f9df27edce4801f288b,1,0x76e76e10ac308a1d54a00f9df27edce4801f288b,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Identity,0x76e76e10ac308a1d54a00f9df27edce4801f288b,1,0x76e76e10ac308a1d54a00f9df27edce4801f288b,WhitelistedAdded,WhitelistedAdded(address),0xee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,Identity,0x76e76e10ac308a1d54a00f9df27edce4801f288b,1,0x76e76e10ac308a1d54a00f9df27edce4801f288b,WhitelistedRemoved,WhitelistedRemoved(address),0x270d9b30cf5b0793bbfd54c9d5b94aeb49462b8148399000265144a8722da6b6,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,1,0x0000000000000000000000000000000000000000,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,1,0x0000000000000000000000000000000000000000,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,1,0x0000000000000000000000000000000000000000,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xf19fb90fa4ddb67c330b41ad4d64ef75b9d8cd33,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xf19fb90fa4ddb67c330b41ad4d64ef75b9d8cd33,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xf19fb90fa4ddb67c330b41ad4d64ef75b9d8cd33,BridgeRequest,"BridgeRequest(address,address,uint256,uint256,uint256,uint8,uint256)",0xabeeb7182c7294cd8efcd40e9ff952c1b759c2165b3634aac589429de5d55ad0,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to targetChainId normalizedAmount timestamp bridge id,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xf19fb90fa4ddb67c330b41ad4d64ef75b9d8cd33,ExecutedTransfer,"ExecutedTransfer(address,address,uint256,uint256,uint256,uint8,uint256)",0x6cf712ce908185c8c38a073b7315f79687e7440fb057d9d1ca76a2509a1282ee,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to normalizedAmount fee sourceChainId bridge id,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xf19fb90fa4ddb67c330b41ad4d64ef75b9d8cd33,FalseSender,"FalseSender(uint256,address)",0x1eafb58197ea0dc76b9278ccad47f61a239f00b017d89a19081a89321cce213d,false,,uint256 address,sourceChainId sourceAddress,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xf19fb90fa4ddb67c330b41ad4d64ef75b9d8cd33,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xf19fb90fa4ddb67c330b41ad4d64ef75b9d8cd33,MessageFailed,"MessageFailed(uint16,bytes,uint64,bytes,bytes)",0xe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c,false,,uint16 bytes uint64 bytes bytes,_srcChainId _srcAddress _nonce _payload _reason,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xf19fb90fa4ddb67c330b41ad4d64ef75b9d8cd33,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xf19fb90fa4ddb67c330b41ad4d64ef75b9d8cd33,RetryMessageSuccess,"RetryMessageSuccess(uint16,bytes,uint64,bytes32)",0xc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e5,false,,uint16 bytes uint64 bytes32,_srcChainId _srcAddress _nonce _payloadHash,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xf19fb90fa4ddb67c330b41ad4d64ef75b9d8cd33,SetMinDstGas,"SetMinDstGas(uint16,uint16,uint256)",0x9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0,false,,uint16 uint16 uint256,_dstChainId _type _minDstGas,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xf19fb90fa4ddb67c330b41ad4d64ef75b9d8cd33,SetPrecrime,SetPrecrime(address),0x5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b,false,,address,precrime,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xf19fb90fa4ddb67c330b41ad4d64ef75b9d8cd33,SetTrustedRemote,"SetTrustedRemote(uint16,bytes)",0xfa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab,false,,uint16 bytes,_remoteChainId _path,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xf19fb90fa4ddb67c330b41ad4d64ef75b9d8cd33,SetTrustedRemoteAddress,"SetTrustedRemoteAddress(uint16,bytes)",0x8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce,false,,uint16 bytes,_remoteChainId _remoteAddress,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xf19fb90fa4ddb67c330b41ad4d64ef75b9d8cd33,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x618fae127b803eabf72f9e86a88a7505eebf218a,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x618fae127b803eabf72f9e86a88a7505eebf218a,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x618fae127b803eabf72f9e86a88a7505eebf218a,BridgeRequest,"BridgeRequest(address,address,uint256,uint256,uint256,uint8,uint256)",0xabeeb7182c7294cd8efcd40e9ff952c1b759c2165b3634aac589429de5d55ad0,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to targetChainId normalizedAmount timestamp bridge id,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x618fae127b803eabf72f9e86a88a7505eebf218a,ExecutedTransfer,"ExecutedTransfer(address,address,uint256,uint256,uint256,uint8,uint256)",0x6cf712ce908185c8c38a073b7315f79687e7440fb057d9d1ca76a2509a1282ee,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to normalizedAmount fee sourceChainId bridge id,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x618fae127b803eabf72f9e86a88a7505eebf218a,FalseSender,"FalseSender(uint256,address)",0x1eafb58197ea0dc76b9278ccad47f61a239f00b017d89a19081a89321cce213d,false,,uint256 address,sourceChainId sourceAddress,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x618fae127b803eabf72f9e86a88a7505eebf218a,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x618fae127b803eabf72f9e86a88a7505eebf218a,MessageFailed,"MessageFailed(uint16,bytes,uint64,bytes,bytes)",0xe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c,false,,uint16 bytes uint64 bytes bytes,_srcChainId _srcAddress _nonce _payload _reason,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x618fae127b803eabf72f9e86a88a7505eebf218a,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x618fae127b803eabf72f9e86a88a7505eebf218a,RetryMessageSuccess,"RetryMessageSuccess(uint16,bytes,uint64,bytes32)",0xc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e5,false,,uint16 bytes uint64 bytes32,_srcChainId _srcAddress _nonce _payloadHash,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x618fae127b803eabf72f9e86a88a7505eebf218a,SetMinDstGas,"SetMinDstGas(uint16,uint16,uint256)",0x9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0,false,,uint16 uint16 uint256,_dstChainId _type _minDstGas,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x618fae127b803eabf72f9e86a88a7505eebf218a,SetPrecrime,SetPrecrime(address),0x5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b,false,,address,precrime,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x618fae127b803eabf72f9e86a88a7505eebf218a,SetTrustedRemote,"SetTrustedRemote(uint16,bytes)",0xfa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab,false,,uint16 bytes,_remoteChainId _path,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x618fae127b803eabf72f9e86a88a7505eebf218a,SetTrustedRemoteAddress,"SetTrustedRemoteAddress(uint16,bytes)",0x8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce,false,,uint16 bytes,_remoteChainId _remoteAddress,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0x618fae127b803eabf72f9e86a88a7505eebf218a,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x12ab702f015d3302f3cc0c4aba0626a127d06a07,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x12ab702f015d3302f3cc0c4aba0626a127d06a07,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x12ab702f015d3302f3cc0c4aba0626a127d06a07,BridgeRequest,"BridgeRequest(address,address,uint256,uint256,uint256,uint8,uint256)",0xabeeb7182c7294cd8efcd40e9ff952c1b759c2165b3634aac589429de5d55ad0,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to targetChainId normalizedAmount timestamp bridge id,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x12ab702f015d3302f3cc0c4aba0626a127d06a07,ExecutedTransfer,"ExecutedTransfer(address,address,uint256,uint256,uint256,uint8,uint256)",0x6cf712ce908185c8c38a073b7315f79687e7440fb057d9d1ca76a2509a1282ee,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to normalizedAmount fee sourceChainId bridge id,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x12ab702f015d3302f3cc0c4aba0626a127d06a07,FalseSender,"FalseSender(uint256,address)",0x1eafb58197ea0dc76b9278ccad47f61a239f00b017d89a19081a89321cce213d,false,,uint256 address,sourceChainId sourceAddress,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x12ab702f015d3302f3cc0c4aba0626a127d06a07,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x12ab702f015d3302f3cc0c4aba0626a127d06a07,MessageFailed,"MessageFailed(uint16,bytes,uint64,bytes,bytes)",0xe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c,false,,uint16 bytes uint64 bytes bytes,_srcChainId _srcAddress _nonce _payload _reason,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x12ab702f015d3302f3cc0c4aba0626a127d06a07,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x12ab702f015d3302f3cc0c4aba0626a127d06a07,RetryMessageSuccess,"RetryMessageSuccess(uint16,bytes,uint64,bytes32)",0xc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e5,false,,uint16 bytes uint64 bytes32,_srcChainId _srcAddress _nonce _payloadHash,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x12ab702f015d3302f3cc0c4aba0626a127d06a07,SetMinDstGas,"SetMinDstGas(uint16,uint16,uint256)",0x9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0,false,,uint16 uint16 uint256,_dstChainId _type _minDstGas,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x12ab702f015d3302f3cc0c4aba0626a127d06a07,SetPrecrime,SetPrecrime(address),0x5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b,false,,address,precrime,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x12ab702f015d3302f3cc0c4aba0626a127d06a07,SetTrustedRemote,"SetTrustedRemote(uint16,bytes)",0xfa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab,false,,uint16 bytes,_remoteChainId _path,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x12ab702f015d3302f3cc0c4aba0626a127d06a07,SetTrustedRemoteAddress,"SetTrustedRemoteAddress(uint16,bytes)",0x8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce,false,,uint16 bytes,_remoteChainId _remoteAddress,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x12ab702f015d3302f3cc0c4aba0626a127d06a07,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x3a2d0a9ef558b42af5ff8d27fe438b466fa7692f,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x3a2d0a9ef558b42af5ff8d27fe438b466fa7692f,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x3a2d0a9ef558b42af5ff8d27fe438b466fa7692f,BridgeRequest,"BridgeRequest(address,address,uint256,uint256,uint256,uint8,uint256)",0xabeeb7182c7294cd8efcd40e9ff952c1b759c2165b3634aac589429de5d55ad0,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to targetChainId normalizedAmount timestamp bridge id,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x3a2d0a9ef558b42af5ff8d27fe438b466fa7692f,ExecutedTransfer,"ExecutedTransfer(address,address,uint256,uint256,uint256,uint8,uint256)",0x6cf712ce908185c8c38a073b7315f79687e7440fb057d9d1ca76a2509a1282ee,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to normalizedAmount fee sourceChainId bridge id,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x3a2d0a9ef558b42af5ff8d27fe438b466fa7692f,FalseSender,"FalseSender(uint256,address)",0x1eafb58197ea0dc76b9278ccad47f61a239f00b017d89a19081a89321cce213d,false,,uint256 address,sourceChainId sourceAddress,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x3a2d0a9ef558b42af5ff8d27fe438b466fa7692f,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x3a2d0a9ef558b42af5ff8d27fe438b466fa7692f,MessageFailed,"MessageFailed(uint16,bytes,uint64,bytes,bytes)",0xe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c,false,,uint16 bytes uint64 bytes bytes,_srcChainId _srcAddress _nonce _payload _reason,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x3a2d0a9ef558b42af5ff8d27fe438b466fa7692f,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x3a2d0a9ef558b42af5ff8d27fe438b466fa7692f,RetryMessageSuccess,"RetryMessageSuccess(uint16,bytes,uint64,bytes32)",0xc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e5,false,,uint16 bytes uint64 bytes32,_srcChainId _srcAddress _nonce _payloadHash,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x3a2d0a9ef558b42af5ff8d27fe438b466fa7692f,SetMinDstGas,"SetMinDstGas(uint16,uint16,uint256)",0x9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0,false,,uint16 uint16 uint256,_dstChainId _type _minDstGas,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x3a2d0a9ef558b42af5ff8d27fe438b466fa7692f,SetPrecrime,SetPrecrime(address),0x5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b,false,,address,precrime,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x3a2d0a9ef558b42af5ff8d27fe438b466fa7692f,SetTrustedRemote,"SetTrustedRemote(uint16,bytes)",0xfa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab,false,,uint16 bytes,_remoteChainId _path,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x3a2d0a9ef558b42af5ff8d27fe438b466fa7692f,SetTrustedRemoteAddress,"SetTrustedRemoteAddress(uint16,bytes)",0x8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce,false,,uint16 bytes,_remoteChainId _remoteAddress,true,18162562,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5 of 5" +ETHEREUM,1,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0x3a2d0a9ef558b42af5ff8d27fe438b466fa7692f,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,MultichainRouter,0x765277eebeca2e31912c9946eae1021199b39c61,1,0x765277eebeca2e31912c9946eae1021199b39c61,LogAnySwapIn,"LogAnySwapIn(bytes32,address,address,uint256,uint256,uint256)",0xaac9ce45fe3adf5143598c4f18a369591a20a3384aedaf1b525d29127e1fcd55,false,0 1 2,bytes32 address address uint256 uint256 uint256,txhash token to amount fromChainID toChainID,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,MultichainRouter,0x765277eebeca2e31912c9946eae1021199b39c61,1,0x765277eebeca2e31912c9946eae1021199b39c61,LogAnySwapOut,"LogAnySwapOut(address,address,address,uint256,uint256,uint256)",0x97116cf6cd4f6412bb47914d6db18da9e16ab2142f543b86e207c24fbd16b23a,false,0 1 2,address address address uint256 uint256 uint256,token from to amount fromChainID toChainID,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,MultichainRouter,0x765277eebeca2e31912c9946eae1021199b39c61,1,0x765277eebeca2e31912c9946eae1021199b39c61,LogAnySwapTradeTokensForNative,"LogAnySwapTradeTokensForNative(address[],address,address,uint256,uint256,uint256,uint256)",0x278277e0209c347189add7bd92411973b5f6b8644f7ac62ea1be984ce993f8f4,false,1 2,address[] address address uint256 uint256 uint256 uint256,path from to amountIn amountOutMin fromChainID toChainID,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,MultichainRouter,0x765277eebeca2e31912c9946eae1021199b39c61,1,0x765277eebeca2e31912c9946eae1021199b39c61,LogAnySwapTradeTokensForTokens,"LogAnySwapTradeTokensForTokens(address[],address,address,uint256,uint256,uint256,uint256)",0xfea6abdf4fd32f20966dff7619354cd82cd43dc78a3bee479f04c74dbfc585b3,false,1 2,address[] address address uint256 uint256 uint256 uint256,path from to amountIn amountOutMin fromChainID toChainID,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,MultichainRouter,0x765277eebeca2e31912c9946eae1021199b39c61,1,0x765277eebeca2e31912c9946eae1021199b39c61,LogChangeMPC,"LogChangeMPC(address,address,uint256,uint256)",0xcda32bc39904597666dfa9f9c845714756e1ffffad55b52e0d344673a2198121,false,0 1 2,address address uint256 uint256,oldMPC newMPC effectiveTime chainID,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,MultichainRouter,0x765277eebeca2e31912c9946eae1021199b39c61,1,0x765277eebeca2e31912c9946eae1021199b39c61,LogChangeRouter,"LogChangeRouter(address,address,uint256)",0x7eefe162042d50d604dca716bef4ff4c5e318a056f712c0195d016f78089955a,false,0 1,address address uint256,oldRouter newRouter chainID,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,NameService,0xec6dce387b1616a0c44ff2e4fa9e90e53cf14eb0,1,0xeb151e175d3d53032c2c185052e48c8c2d5c245d,AddressChanged,"AddressChanged(string,address)",0x135cf55549d8538a41f19f46cc85625da93e68b63484cca8fcb9aaf19e520137,false,,string address,name addr,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,NameService,0xec6dce387b1616a0c44ff2e4fa9e90e53cf14eb0,1,0xeb151e175d3d53032c2c185052e48c8c2d5c245d,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,NameService,0xec6dce387b1616a0c44ff2e4fa9e90e53cf14eb0,1,0xeb151e175d3d53032c2c185052e48c8c2d5c245d,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,NameService,0xec6dce387b1616a0c44ff2e4fa9e90e53cf14eb0,1,0xeb151e175d3d53032c2c185052e48c8c2d5c245d,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,ProxyAdmin,0xa2db14c68ab35e620fea5bf07d65e9bff84c994c,1,0xa2db14c68ab35e620fea5bf07d65e9bff84c994c,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,ProxyFactory,0xda85fced9bd193526b7667f2ad1fd4a0f900d3a7,1,0xda85fced9bd193526b7667f2ad1fd4a0f900d3a7,ContractCreated,ContractCreated(address),0xcf78cf0d6f3d8371e1075c69c492ab4ec5d8cf23a1a239b6a51a1d00be7ca312,false,,address,addr,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,ProxyFactory,0xda85fced9bd193526b7667f2ad1fd4a0f900d3a7,1,0xda85fced9bd193526b7667f2ad1fd4a0f900d3a7,ProxyCreated,ProxyCreated(address),0x00fffc2da0b561cae30d9826d37709e9421c4725faebc226cbbb7ef5fc5e7349,false,,address,proxy,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakersDistribution,0x5766cf4b2fdb09d986eb1783d276013c224e28c8,1,0x5f78ed3a4fdde9e9d91d3707a847fb4ad820ce26,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakersDistribution,0x5766cf4b2fdb09d986eb1783d276013c224e28c8,1,0x5f78ed3a4fdde9e9d91d3707a847fb4ad820ce26,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakersDistribution,0x5766cf4b2fdb09d986eb1783d276013c224e28c8,1,0x5f78ed3a4fdde9e9d91d3707a847fb4ad820ce26,ReputationEarned,"ReputationEarned(address,address[],uint256)",0xb5bb6cf2a7d73ab2167d87f348feea953c3e405a4ece2a262cd92cdce829f6d2,false,,address address[] uint256,staker stakingContracts reputation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakersDistribution,0x5766cf4b2fdb09d986eb1783d276013c224e28c8,1,0x5f78ed3a4fdde9e9d91d3707a847fb4ad820ce26,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakersDistribution,0x5766cf4b2fdb09d986eb1783d276013c224e28c8,2,0x92c69a12c2ffc54afcfa320be7305ffd0f5782e0,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakersDistribution,0x5766cf4b2fdb09d986eb1783d276013c224e28c8,2,0x92c69a12c2ffc54afcfa320be7305ffd0f5782e0,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakersDistribution,0x5766cf4b2fdb09d986eb1783d276013c224e28c8,2,0x92c69a12c2ffc54afcfa320be7305ffd0f5782e0,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,22165594,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 2 of 2 +ETHEREUM,1,StakersDistribution,0x5766cf4b2fdb09d986eb1783d276013c224e28c8,2,0x92c69a12c2ffc54afcfa320be7305ffd0f5782e0,ReputationEarned,"ReputationEarned(address,address[],uint256)",0xb5bb6cf2a7d73ab2167d87f348feea953c3e405a4ece2a262cd92cdce829f6d2,false,,address address[] uint256,staker stakingContracts reputation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakersDistribution,0x5766cf4b2fdb09d986eb1783d276013c224e28c8,2,0x92c69a12c2ffc54afcfa320be7305ffd0f5782e0,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContracts,0xd33ba17c8a644c585089145e86e282fada6f3bfd,1,0xd33ba17c8a644c585089145e86e282fada6f3bfd,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContracts,0xd33ba17c8a644c585089145e86e282fada6f3bfd,1,0xd33ba17c8a644c585089145e86e282fada6f3bfd,InterestCollected,"InterestCollected(address,uint256,uint256,uint256,uint256,uint256)",0x38c2c21f82a20481909d7aef48247b0743f69728fbb599c274039e2eecf8bb17,false,,address uint256 uint256 uint256 uint256 uint256,recipient iTokenGains tokenGains actualTokenRedeemed actualRewardTokenEarned interestCollectedInDAI,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContracts,0xd33ba17c8a644c585089145e86e282fada6f3bfd,1,0xd33ba17c8a644c585089145e86e282fada6f3bfd,Staked,"Staked(address,address,uint256)",0x5dac0c1b1112564a045ba943c9d50270893e8e826c49be8e7073adc713ab7bd7,false,0,address address uint256,staker token value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContracts,0xd33ba17c8a644c585089145e86e282fada6f3bfd,1,0xd33ba17c8a644c585089145e86e282fada6f3bfd,StakeWithdraw,"StakeWithdraw(address,address,uint256)",0x89b2bca2609b9ce42215fdd646f9162cdfb9c1620c93db1cc6302479489d3f32,false,0,address address uint256,staker token value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContracts,0xd33ba17c8a644c585089145e86e282fada6f3bfd,1,0xd33ba17c8a644c585089145e86e282fada6f3bfd,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContractsV2,0x02416eb83cff1f19163f21010149c3867f3261e1,1,0x02416eb83cff1f19163f21010149c3867f3261e1,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContractsV2,0x02416eb83cff1f19163f21010149c3867f3261e1,1,0x02416eb83cff1f19163f21010149c3867f3261e1,InterestCollected,"InterestCollected(address,uint256,uint256,uint256,uint256,uint256)",0x38c2c21f82a20481909d7aef48247b0743f69728fbb599c274039e2eecf8bb17,false,,address uint256 uint256 uint256 uint256 uint256,recipient iTokenGains tokenGains actualTokenRedeemed actualRewardTokenEarned interestCollectedInDAI,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContractsV2,0x02416eb83cff1f19163f21010149c3867f3261e1,1,0x02416eb83cff1f19163f21010149c3867f3261e1,Staked,"Staked(address,address,uint256)",0x5dac0c1b1112564a045ba943c9d50270893e8e826c49be8e7073adc713ab7bd7,false,0,address address uint256,staker token value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContractsV2,0x02416eb83cff1f19163f21010149c3867f3261e1,1,0x02416eb83cff1f19163f21010149c3867f3261e1,StakeWithdraw,"StakeWithdraw(address,address,uint256)",0x89b2bca2609b9ce42215fdd646f9162cdfb9c1620c93db1cc6302479489d3f32,false,0,address address uint256,staker token value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContractsV2,0x02416eb83cff1f19163f21010149c3867f3261e1,1,0x02416eb83cff1f19163f21010149c3867f3261e1,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContractsV2,0xf4c34bed7dd779485692bb1857acf9c561b45010,1,0xf4c34bed7dd779485692bb1857acf9c561b45010,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContractsV2,0xf4c34bed7dd779485692bb1857acf9c561b45010,1,0xf4c34bed7dd779485692bb1857acf9c561b45010,InterestCollected,"InterestCollected(address,uint256,uint256,uint256,uint256,uint256)",0x38c2c21f82a20481909d7aef48247b0743f69728fbb599c274039e2eecf8bb17,false,,address uint256 uint256 uint256 uint256 uint256,recipient iTokenGains tokenGains actualTokenRedeemed actualRewardTokenEarned interestCollectedInDAI,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContractsV2,0xf4c34bed7dd779485692bb1857acf9c561b45010,1,0xf4c34bed7dd779485692bb1857acf9c561b45010,Staked,"Staked(address,address,uint256)",0x5dac0c1b1112564a045ba943c9d50270893e8e826c49be8e7073adc713ab7bd7,false,0,address address uint256,staker token value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContractsV2,0xf4c34bed7dd779485692bb1857acf9c561b45010,1,0xf4c34bed7dd779485692bb1857acf9c561b45010,StakeWithdraw,"StakeWithdraw(address,address,uint256)",0x89b2bca2609b9ce42215fdd646f9162cdfb9c1620c93db1cc6302479489d3f32,false,0,address address uint256,staker token value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContractsV2,0xf4c34bed7dd779485692bb1857acf9c561b45010,1,0xf4c34bed7dd779485692bb1857acf9c561b45010,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContractsV3,0x3ff2d8eb2573819a9ef7167d2ba6fd6d31b17f4f,1,0x3ff2d8eb2573819a9ef7167d2ba6fd6d31b17f4f,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContractsV3,0x3ff2d8eb2573819a9ef7167d2ba6fd6d31b17f4f,1,0x3ff2d8eb2573819a9ef7167d2ba6fd6d31b17f4f,InterestCollected,"InterestCollected(address,uint256,uint256,uint256,uint256,uint256)",0x38c2c21f82a20481909d7aef48247b0743f69728fbb599c274039e2eecf8bb17,false,,address uint256 uint256 uint256 uint256 uint256,recipient iTokenGains tokenGains actualTokenRedeemed actualRewardTokenEarned interestCollectedInDAI,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContractsV3,0x3ff2d8eb2573819a9ef7167d2ba6fd6d31b17f4f,1,0x3ff2d8eb2573819a9ef7167d2ba6fd6d31b17f4f,Staked,"Staked(address,address,uint256)",0x5dac0c1b1112564a045ba943c9d50270893e8e826c49be8e7073adc713ab7bd7,false,0,address address uint256,staker token value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContractsV3,0x3ff2d8eb2573819a9ef7167d2ba6fd6d31b17f4f,1,0x3ff2d8eb2573819a9ef7167d2ba6fd6d31b17f4f,StakeWithdraw,"StakeWithdraw(address,address,uint256)",0x89b2bca2609b9ce42215fdd646f9162cdfb9c1620c93db1cc6302479489d3f32,false,0,address address uint256,staker token value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContractsV3,0x3ff2d8eb2573819a9ef7167d2ba6fd6d31b17f4f,1,0x3ff2d8eb2573819a9ef7167d2ba6fd6d31b17f4f,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContractsV3,0x7b7246c78e2f900d17646ff0cb2ec47d6ba10754,1,0x7b7246c78e2f900d17646ff0cb2ec47d6ba10754,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContractsV3,0x7b7246c78e2f900d17646ff0cb2ec47d6ba10754,1,0x7b7246c78e2f900d17646ff0cb2ec47d6ba10754,InterestCollected,"InterestCollected(address,uint256,uint256,uint256,uint256,uint256)",0x38c2c21f82a20481909d7aef48247b0743f69728fbb599c274039e2eecf8bb17,false,,address uint256 uint256 uint256 uint256 uint256,recipient iTokenGains tokenGains actualTokenRedeemed actualRewardTokenEarned interestCollectedInDAI,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContractsV3,0x7b7246c78e2f900d17646ff0cb2ec47d6ba10754,1,0x7b7246c78e2f900d17646ff0cb2ec47d6ba10754,Staked,"Staked(address,address,uint256)",0x5dac0c1b1112564a045ba943c9d50270893e8e826c49be8e7073adc713ab7bd7,false,0,address address uint256,staker token value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContractsV3,0x7b7246c78e2f900d17646ff0cb2ec47d6ba10754,1,0x7b7246c78e2f900d17646ff0cb2ec47d6ba10754,StakeWithdraw,"StakeWithdraw(address,address,uint256)",0x89b2bca2609b9ce42215fdd646f9162cdfb9c1620c93db1cc6302479489d3f32,false,0,address address uint256,staker token value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +ETHEREUM,1,StakingContractsV3,0x7b7246c78e2f900d17646ff0cb2ec47d6ba10754,1,0x7b7246c78e2f900d17646ff0cb2ec47d6ba10754,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,1,0x832548c789ea71cae69f562476e9978d77e36c70,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,1,0x832548c789ea71cae69f562476e9978d77e36c70,AdminsAdded,AdminsAdded(address[]),0x45486b220020cc2482ad1a5e0ae4d5f0b5372cea1b48173f6273c616a5047269,false,0,address[],admins,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,1,0x832548c789ea71cae69f562476e9978d77e36c70,AdminsRemoved,AdminsRemoved(address[]),0xd5e6894641b5030a67e637ab2e12da64d8aec689f8bd1328de2b04d6a439c810,false,0,address[],admins,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,1,0x832548c789ea71cae69f562476e9978d77e36c70,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,1,0x832548c789ea71cae69f562476e9978d77e36c70,GenericCall,"GenericCall(address,bytes,uint256,bool)",0x534b52c783549f909f9e743120524d0b7154058e4a54cdc895c2c0b587a1c7e0,false,0,address bytes uint256 bool,_contract _data _value _success,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,1,0x832548c789ea71cae69f562476e9978d77e36c70,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,1,0x832548c789ea71cae69f562476e9978d77e36c70,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,1,0x832548c789ea71cae69f562476e9978d77e36c70,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,1,0x832548c789ea71cae69f562476e9978d77e36c70,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,1,0x832548c789ea71cae69f562476e9978d77e36c70,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,1,0x832548c789ea71cae69f562476e9978d77e36c70,WalletTopped,"WalletTopped(address,uint256)",0xf60e56b8021f6ac77bd50d4acdbed9ad9e85107144d43090774a9ebe5ffed985,false,0,address uint256,user amount,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,2,0xeed7ecf710aa2cf1c15dcdba29de8655a384e299,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,2,0xeed7ecf710aa2cf1c15dcdba29de8655a384e299,AdminsAdded,AdminsAdded(address[]),0x45486b220020cc2482ad1a5e0ae4d5f0b5372cea1b48173f6273c616a5047269,false,0,address[],admins,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,2,0xeed7ecf710aa2cf1c15dcdba29de8655a384e299,AdminsRemoved,AdminsRemoved(address[]),0xd5e6894641b5030a67e637ab2e12da64d8aec689f8bd1328de2b04d6a439c810,false,0,address[],admins,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,2,0xeed7ecf710aa2cf1c15dcdba29de8655a384e299,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,2,0xeed7ecf710aa2cf1c15dcdba29de8655a384e299,GenericCall,"GenericCall(address,bytes,uint256,bool)",0x534b52c783549f909f9e743120524d0b7154058e4a54cdc895c2c0b587a1c7e0,false,0,address bytes uint256 bool,_contract _data _value _success,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,2,0xeed7ecf710aa2cf1c15dcdba29de8655a384e299,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,22038689,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,2,0xeed7ecf710aa2cf1c15dcdba29de8655a384e299,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,2,0xeed7ecf710aa2cf1c15dcdba29de8655a384e299,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,2,0xeed7ecf710aa2cf1c15dcdba29de8655a384e299,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,2,0xeed7ecf710aa2cf1c15dcdba29de8655a384e299,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,2,0xeed7ecf710aa2cf1c15dcdba29de8655a384e299,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,2,0xeed7ecf710aa2cf1c15dcdba29de8655a384e299,WalletTopped,"WalletTopped(address,uint256)",0xf60e56b8021f6ac77bd50d4acdbed9ad9e85107144d43090774a9ebe5ffed985,false,0,address uint256,user amount,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,3,0xdd107728aa2445166942837a7338c157065bd8c8,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,3,0xdd107728aa2445166942837a7338c157065bd8c8,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,3,0xdd107728aa2445166942837a7338c157065bd8c8,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,4,0x44035ca8d61472adbfb9dc6a7fdcc6af9d1f7f0a,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,4,0x44035ca8d61472adbfb9dc6a7fdcc6af9d1f7f0a,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,4,0x44035ca8d61472adbfb9dc6a7fdcc6af9d1f7f0a,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,5,0xa9133a3d11bc39eb4d65e6de44fe9ceac3c71f54,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,5,0xa9133a3d11bc39eb4d65e6de44fe9ceac3c71f54,AdminsAdded,AdminsAdded(address[]),0x45486b220020cc2482ad1a5e0ae4d5f0b5372cea1b48173f6273c616a5047269,false,0,address[],admins,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,5,0xa9133a3d11bc39eb4d65e6de44fe9ceac3c71f54,AdminsRemoved,AdminsRemoved(address[]),0xd5e6894641b5030a67e637ab2e12da64d8aec689f8bd1328de2b04d6a439c810,false,0,address[],admins,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,5,0xa9133a3d11bc39eb4d65e6de44fe9ceac3c71f54,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,5,0xa9133a3d11bc39eb4d65e6de44fe9ceac3c71f54,GenericCall,"GenericCall(address,bytes,uint256,bool)",0x534b52c783549f909f9e743120524d0b7154058e4a54cdc895c2c0b587a1c7e0,false,0,address bytes uint256 bool,_contract _data _value _success,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,5,0xa9133a3d11bc39eb4d65e6de44fe9ceac3c71f54,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,22038689,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,5,0xa9133a3d11bc39eb4d65e6de44fe9ceac3c71f54,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,5,0xa9133a3d11bc39eb4d65e6de44fe9ceac3c71f54,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,5,0xa9133a3d11bc39eb4d65e6de44fe9ceac3c71f54,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,5,0xa9133a3d11bc39eb4d65e6de44fe9ceac3c71f54,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,5,0xa9133a3d11bc39eb4d65e6de44fe9ceac3c71f54,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,5,0xa9133a3d11bc39eb4d65e6de44fe9ceac3c71f54,WalletTopped,"WalletTopped(address,uint256)",0xf60e56b8021f6ac77bd50d4acdbed9ad9e85107144d43090774a9ebe5ffed985,false,0,address uint256,user amount,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,6,0x7ac74c2c00b1e403a2d9972b8fdb237ebeffb901,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,6,0x7ac74c2c00b1e403a2d9972b8fdb237ebeffb901,AdminsAdded,AdminsAdded(address[]),0x45486b220020cc2482ad1a5e0ae4d5f0b5372cea1b48173f6273c616a5047269,false,0,address[],admins,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,6,0x7ac74c2c00b1e403a2d9972b8fdb237ebeffb901,AdminsRemoved,AdminsRemoved(address[]),0xd5e6894641b5030a67e637ab2e12da64d8aec689f8bd1328de2b04d6a439c810,false,0,address[],admins,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,6,0x7ac74c2c00b1e403a2d9972b8fdb237ebeffb901,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,6,0x7ac74c2c00b1e403a2d9972b8fdb237ebeffb901,GenericCall,"GenericCall(address,bytes,uint256,bool)",0x534b52c783549f909f9e743120524d0b7154058e4a54cdc895c2c0b587a1c7e0,false,0,address bytes uint256 bool,_contract _data _value _success,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,6,0x7ac74c2c00b1e403a2d9972b8fdb237ebeffb901,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,22038689,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,6,0x7ac74c2c00b1e403a2d9972b8fdb237ebeffb901,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,6,0x7ac74c2c00b1e403a2d9972b8fdb237ebeffb901,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,6,0x7ac74c2c00b1e403a2d9972b8fdb237ebeffb901,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,6,0x7ac74c2c00b1e403a2d9972b8fdb237ebeffb901,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,6,0x7ac74c2c00b1e403a2d9972b8fdb237ebeffb901,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWallet,0x9a34822112bc73bdc941c62dcc311ca905aef2a3,6,0x7ac74c2c00b1e403a2d9972b8fdb237ebeffb901,WalletTopped,"WalletTopped(address,uint256)",0xf60e56b8021f6ac77bd50d4acdbed9ad9e85107144d43090774a9ebe5ffed985,false,0,address uint256,user amount,true,18838651,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,5,6 of 6. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,AdminWalletOld,0x9f75dacb77419b87f568d417ebc84346e134144e,1,0x9f75dacb77419b87f568d417ebc84346e134144e,AdminsAdded,AdminsAdded(address[]),0x45486b220020cc2482ad1a5e0ae4d5f0b5372cea1b48173f6273c616a5047269,false,0,address[],admins,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWalletOld,0x9f75dacb77419b87f568d417ebc84346e134144e,1,0x9f75dacb77419b87f568d417ebc84346e134144e,AdminsRemoved,AdminsRemoved(address[]),0xd5e6894641b5030a67e637ab2e12da64d8aec689f8bd1328de2b04d6a439c810,false,0,address[],admins,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWalletOld,0x9f75dacb77419b87f568d417ebc84346e134144e,1,0x9f75dacb77419b87f568d417ebc84346e134144e,GenericCall,"GenericCall(address,bytes,uint256,bool)",0x534b52c783549f909f9e743120524d0b7154058e4a54cdc895c2c0b587a1c7e0,false,0,address bytes uint256 bool,_contract _data _value _success,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWalletOld,0x9f75dacb77419b87f568d417ebc84346e134144e,1,0x9f75dacb77419b87f568d417ebc84346e134144e,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,AdminWalletOld,0x9f75dacb77419b87f568d417ebc84346e134144e,1,0x9f75dacb77419b87f568d417ebc84346e134144e,WalletTopped,"WalletTopped(address,uint256)",0xf60e56b8021f6ac77bd50d4acdbed9ad9e85107144d43090774a9ebe5ffed985,false,0,address uint256,user amount,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Avatar,0xf96dadc6d71113f6500e97590760c924da1ef70e,1,0xf96dadc6d71113f6500e97590760c924da1ef70e,ExternalTokenApproval,"ExternalTokenApproval(address,address,uint256)",0x3a48a4d6253b30fd10e57a347c1f9bcb0604946481fae0b2fdad6e74f2a9cbb3,false,0,address address uint256,_externalToken _spender _value,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Avatar,0xf96dadc6d71113f6500e97590760c924da1ef70e,1,0xf96dadc6d71113f6500e97590760c924da1ef70e,ExternalTokenTransfer,"ExternalTokenTransfer(address,address,uint256)",0x49dc2a60d2599a7b6932d78fb694c30dfc596fe4e0282b5d0fd184b52472c04d,false,0 1,address address uint256,_externalToken _to _value,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Avatar,0xf96dadc6d71113f6500e97590760c924da1ef70e,1,0xf96dadc6d71113f6500e97590760c924da1ef70e,ExternalTokenTransferFrom,"ExternalTokenTransferFrom(address,address,address,uint256)",0x179c15de44aa7ab84896301974328eb40b5b40fe01cfe0fee2924ea712c3e843,false,0,address address address uint256,_externalToken _from _to _value,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Avatar,0xf96dadc6d71113f6500e97590760c924da1ef70e,1,0xf96dadc6d71113f6500e97590760c924da1ef70e,GenericCall,"GenericCall(address,bytes,uint256,bool)",0x534b52c783549f909f9e743120524d0b7154058e4a54cdc895c2c0b587a1c7e0,false,0,address bytes uint256 bool,_contract _data _value _success,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Avatar,0xf96dadc6d71113f6500e97590760c924da1ef70e,1,0xf96dadc6d71113f6500e97590760c924da1ef70e,MetaData,MetaData(string),0xf9deba4938ba20070ec5a45ddf59bccba49cf83124215228ec1232182ef0ba2b,false,,string,_metaData,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Avatar,0xf96dadc6d71113f6500e97590760c924da1ef70e,1,0xf96dadc6d71113f6500e97590760c924da1ef70e,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Avatar,0xf96dadc6d71113f6500e97590760c924da1ef70e,1,0xf96dadc6d71113f6500e97590760c924da1ef70e,ReceiveEther,"ReceiveEther(address,uint256)",0xf32a9f77675fd5917534c7746608fd3e309eac68fbdcbf5925e24ca97a704396,false,0,address uint256,_sender _value,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Avatar,0xf96dadc6d71113f6500e97590760c924da1ef70e,1,0xf96dadc6d71113f6500e97590760c924da1ef70e,SendEther,"SendEther(uint256,address)",0x22fca66666089f39bc900dd6605b489df4aae6260cc8ea8257594cfb8c84926c,false,1,uint256 address,_amountInWei _to,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,ClaimersDistribution,0x1ae4929090258a9d5000d98cfb8a27174d345834,1,0x264adea794247a7e4dc216c7ca2f1429e3af54a9,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,ClaimersDistribution,0x1ae4929090258a9d5000d98cfb8a27174d345834,1,0x264adea794247a7e4dc216c7ca2f1429e3af54a9,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,ClaimersDistribution,0x1ae4929090258a9d5000d98cfb8a27174d345834,1,0x264adea794247a7e4dc216c7ca2f1429e3af54a9,MonthlyDistributionSet,MonthlyDistributionSet(uint256),0x237ab53d478ae984b5181944dc85b134c034a24236aac1632aa10236cedd8a99,false,,uint256,reputationAmount,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,ClaimersDistribution,0x1ae4929090258a9d5000d98cfb8a27174d345834,1,0x264adea794247a7e4dc216c7ca2f1429e3af54a9,ReputationEarned,"ReputationEarned(address,uint256,uint256,uint256)",0x6d539aca58a0ce9de5ef660cea9845c2b109a1665b74200cceda7e8f097d0ace,false,,address uint256 uint256 uint256,claimer month claims reputation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,ClaimersDistribution,0x1ae4929090258a9d5000d98cfb8a27174d345834,1,0x264adea794247a7e4dc216c7ca2f1429e3af54a9,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,GuardianSet,GuardianSet(address),0xe6c09ffe4572dc9ceaa5ddde4ae41befa655d6fdfe8052077af0970f700e942e,false,,address,newGuardian,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,ParametersSet,ParametersSet(uint256[9]),0x51472f0134408629271bc25caae248dd940cd836aa7bbc3974aa1ec2978059b5,false,,uint256[9],params,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,ProposalBridge,"ProposalBridge(uint256,uint256)",0x93f05b7f92e65fef7a2a62683de78a4230ca5ec425170818561a02b6afcff28b,false,1,uint256 uint256,id forBlockchain,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,ProposalCanceled,ProposalCanceled(uint256),0x789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c,false,,uint256,id,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,ProposalCreated,"ProposalCreated(uint256,address,address[],uint256[],string[],bytes[],uint256,uint256,string)",0x7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e0,false,,uint256 address address[] uint256[] string[] bytes[] uint256 uint256 string,id proposer targets values signatures calldatas startBlock endBlock description,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,ProposalExecuted,ProposalExecuted(uint256),0x712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f,false,,uint256,id,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,ProposalExecutionResult,"ProposalExecutionResult(uint256,uint256,bool,bytes)",0x7ee6f70307f5df49af1cdc334b322bc2ff99ae186134a468bf77618a2ce2ff04,false,,uint256 uint256 bool bytes,id index ok result,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,ProposalQueued,"ProposalQueued(uint256,uint256)",0x9a2e42fd6722813d69113e7d0079d3d940171428df7373df9c7f7617cfda2892,false,,uint256 uint256,id eta,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,ProposalSucceeded,"ProposalSucceeded(uint256,address,address[],uint256[],string[],bytes[],uint256,uint256,uint256,uint256,uint256,uint256)",0xa5369bfba6e8a577af7ee34ae49c68529b2c8914a2561282f16e3a706cb4333c,false,,uint256 address address[] uint256[] string[] bytes[] uint256 uint256 uint256 uint256 uint256 uint256,id proposer targets values signatures calldatas startBlock endBlock forBlockchain eta forVotes againstVotes,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,1,0xa7fdd8b0e68e09c9e4aee8f03a8443d5827187d1,VoteCast,"VoteCast(address,uint256,bool,uint256)",0x877856338e13f63d0c36822ff0ef736b80934cd90574a3a5bc9262c39d217c46,false,,address uint256 bool uint256,voter proposalId support votes,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x9373046bbc6d381129b49ac3334881390df1cb13,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x9373046bbc6d381129b49ac3334881390df1cb13,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x9373046bbc6d381129b49ac3334881390df1cb13,GuardianSet,GuardianSet(address),0xe6c09ffe4572dc9ceaa5ddde4ae41befa655d6fdfe8052077af0970f700e942e,false,,address,newGuardian,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x9373046bbc6d381129b49ac3334881390df1cb13,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,34980099,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 2 of 2 +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x9373046bbc6d381129b49ac3334881390df1cb13,ParametersSet,ParametersSet(uint256[9]),0x51472f0134408629271bc25caae248dd940cd836aa7bbc3974aa1ec2978059b5,false,,uint256[9],params,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x9373046bbc6d381129b49ac3334881390df1cb13,ProposalBridge,"ProposalBridge(uint256,uint256)",0x93f05b7f92e65fef7a2a62683de78a4230ca5ec425170818561a02b6afcff28b,false,1,uint256 uint256,id forBlockchain,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x9373046bbc6d381129b49ac3334881390df1cb13,ProposalCanceled,ProposalCanceled(uint256),0x789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c,false,,uint256,id,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x9373046bbc6d381129b49ac3334881390df1cb13,ProposalCreated,"ProposalCreated(uint256,address,address[],uint256[],string[],bytes[],uint256,uint256,string)",0x7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e0,false,,uint256 address address[] uint256[] string[] bytes[] uint256 uint256 string,id proposer targets values signatures calldatas startBlock endBlock description,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x9373046bbc6d381129b49ac3334881390df1cb13,ProposalExecuted,ProposalExecuted(uint256),0x712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f,false,,uint256,id,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x9373046bbc6d381129b49ac3334881390df1cb13,ProposalExecutionResult,"ProposalExecutionResult(uint256,uint256,bool,bytes)",0x7ee6f70307f5df49af1cdc334b322bc2ff99ae186134a468bf77618a2ce2ff04,false,,uint256 uint256 bool bytes,id index ok result,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x9373046bbc6d381129b49ac3334881390df1cb13,ProposalQueued,"ProposalQueued(uint256,uint256)",0x9a2e42fd6722813d69113e7d0079d3d940171428df7373df9c7f7617cfda2892,false,,uint256 uint256,id eta,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x9373046bbc6d381129b49ac3334881390df1cb13,ProposalSucceeded,"ProposalSucceeded(uint256,address,address[],uint256[],string[],bytes[],uint256,uint256,uint256,uint256,uint256,uint256)",0xa5369bfba6e8a577af7ee34ae49c68529b2c8914a2561282f16e3a706cb4333c,false,,uint256 address address[] uint256[] string[] bytes[] uint256 uint256 uint256 uint256 uint256 uint256,id proposer targets values signatures calldatas startBlock endBlock forBlockchain eta forVotes againstVotes,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x9373046bbc6d381129b49ac3334881390df1cb13,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,CompoundVotingMachine,0x57ee6ceff51cb30ecb1245934a882c500fbec1e9,2,0x9373046bbc6d381129b49ac3334881390df1cb13,VoteCast,"VoteCast(address,uint256,bool,uint256)",0x877856338e13f63d0c36822ff0ef736b80934cd90574a3a5bc9262c39d217c46,false,,address uint256 bool uint256,voter proposalId support votes,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Controller,0xbce053b99e22158f8b62f4dbfbede1f936b2d4e4,1,0xbce053b99e22158f8b62f4dbfbede1f936b2d4e4,AddGlobalConstraint,"AddGlobalConstraint(address,bytes32,uint8)",0x78800d7333b8d0174a0845569e3913b7ce4a3c03ca444dd9904172fc14f2fdad,false,0,address bytes32 uint8,_globalConstraint _params _when,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Controller,0xbce053b99e22158f8b62f4dbfbede1f936b2d4e4,1,0xbce053b99e22158f8b62f4dbfbede1f936b2d4e4,BurnReputation,"BurnReputation(address,address,uint256)",0x186d8887e1b22f9d9b16849c36baa748950d09d9c9b67a4a6ea140eaad00c21c,false,0 1,address address uint256,_sender _from _amount,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Controller,0xbce053b99e22158f8b62f4dbfbede1f936b2d4e4,1,0xbce053b99e22158f8b62f4dbfbede1f936b2d4e4,MintReputation,"MintReputation(address,address,uint256)",0x837f2931e3df0592458212be4e470025f197feb7a8e39deb5b7f1f1d42e6f262,false,0 1,address address uint256,_sender _to _amount,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Controller,0xbce053b99e22158f8b62f4dbfbede1f936b2d4e4,1,0xbce053b99e22158f8b62f4dbfbede1f936b2d4e4,MintTokens,"MintTokens(address,address,uint256)",0x21f9c9a1a1f9a311a50f15fec5c1faa9e21fc9edf964f0fdecba5bd490484c5e,false,0 1,address address uint256,_sender _beneficiary _amount,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Controller,0xbce053b99e22158f8b62f4dbfbede1f936b2d4e4,1,0xbce053b99e22158f8b62f4dbfbede1f936b2d4e4,RegisterScheme,"RegisterScheme(address,address)",0x546816e99403df442acb68ef69562682a50762c20a3fb6b472f7af9923736cfc,false,0 1,address address,_sender _scheme,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Controller,0xbce053b99e22158f8b62f4dbfbede1f936b2d4e4,1,0xbce053b99e22158f8b62f4dbfbede1f936b2d4e4,RemoveGlobalConstraint,"RemoveGlobalConstraint(address,uint256,bool)",0xcdf1a50ea6b7de555bd409f8a4a53ea43c6dc6b4caa961889da9e005f21bbaa9,false,0,address uint256 bool,_globalConstraint _index _isPre,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Controller,0xbce053b99e22158f8b62f4dbfbede1f936b2d4e4,1,0xbce053b99e22158f8b62f4dbfbede1f936b2d4e4,UnregisterScheme,"UnregisterScheme(address,address)",0x10bb2cf04cb8b902a8e736d494f1a51003be6d4b16ef6fb95ce62c38445023bf,false,0 1,address address,_sender _scheme,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Controller,0xbce053b99e22158f8b62f4dbfbede1f936b2d4e4,1,0xbce053b99e22158f8b62f4dbfbede1f936b2d4e4,UpgradeController,"UpgradeController(address,address)",0xdb7cbacf8df312d794506c0cc9af07f64d29ca075796ea2e950a3832cc9a63dd,false,0,address address,_oldController _newController,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,1,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,1,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,2,0x7a73f1fa2d9d24b6e8b02aae83eb348d51440623,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,2,0x7a73f1fa2d9d24b6e8b02aae83eb348d51440623,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,2,0x7a73f1fa2d9d24b6e8b02aae83eb348d51440623,WalletTopped,"WalletTopped(address,uint256)",0xf60e56b8021f6ac77bd50d4acdbed9ad9e85107144d43090774a9ebe5ffed985,false,0,address uint256,user amount,true,18632009,22038735,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,5,6,7 of 12. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,3,0xbded8cf5629732956d58d85b6cc619d83778a226,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,3,0xbded8cf5629732956d58d85b6cc619d83778a226,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,3,0xbded8cf5629732956d58d85b6cc619d83778a226,WalletTopped,"WalletTopped(address,uint256)",0xf60e56b8021f6ac77bd50d4acdbed9ad9e85107144d43090774a9ebe5ffed985,false,0,address uint256,user amount,true,18632009,22038735,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,5,6,7 of 12. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,4,0xc9f33d360ed722fb8f26209b402b58494ef8f54b,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,4,0xc9f33d360ed722fb8f26209b402b58494ef8f54b,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,5,0xc0753ae7d5e010083035090b405110ed8323d07e,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,5,0xc0753ae7d5e010083035090b405110ed8323d07e,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,5,0xc0753ae7d5e010083035090b405110ed8323d07e,WalletTopped,"WalletTopped(address,uint256)",0xf60e56b8021f6ac77bd50d4acdbed9ad9e85107144d43090774a9ebe5ffed985,false,0,address uint256,user amount,true,18632009,22038735,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,5,6,7 of 12. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,6,0x6c8efc4ab75b834ee9e7f2d9fa96b09724fbf4d3,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,6,0x6c8efc4ab75b834ee9e7f2d9fa96b09724fbf4d3,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,6,0x6c8efc4ab75b834ee9e7f2d9fa96b09724fbf4d3,WalletTopped,"WalletTopped(address,uint256)",0xf60e56b8021f6ac77bd50d4acdbed9ad9e85107144d43090774a9ebe5ffed985,false,0,address uint256,user amount,true,18632009,22038735,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,5,6,7 of 12. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,7,0x06b5b324baa4e7d1c9a8137f0e82ebb780b3570e,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,7,0x06b5b324baa4e7d1c9a8137f0e82ebb780b3570e,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,7,0x06b5b324baa4e7d1c9a8137f0e82ebb780b3570e,WalletTopped,"WalletTopped(address,uint256)",0xf60e56b8021f6ac77bd50d4acdbed9ad9e85107144d43090774a9ebe5ffed985,false,0,address uint256,user amount,true,18632009,22038735,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,5,6,7 of 12. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,8,0x6ba541e6f4e7df758b98d0117c6ccd353eccc728,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,8,0x6ba541e6f4e7df758b98d0117c6ccd353eccc728,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,22038735,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 8,9,10,11,12 of 12" +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,8,0x6ba541e6f4e7df758b98d0117c6ccd353eccc728,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,8,0x6ba541e6f4e7df758b98d0117c6ccd353eccc728,WalletTopped,"WalletTopped(address,uint256,address,address)",0x7872034fbcc87890e73d66eac55389e0ffdba157b89a73bd2011157ebac1d66e,false,0 3,address uint256 address address,account amount whitelistedRoot relayerOrWhitelisted,true,22038735,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 8,9,10,11,12 of 12" +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,9,0xa528531d648cfb3cda91cda71c7ec6a172bcbd04,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,9,0xa528531d648cfb3cda91cda71c7ec6a172bcbd04,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,22038735,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 8,9,10,11,12 of 12" +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,9,0xa528531d648cfb3cda91cda71c7ec6a172bcbd04,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,9,0xa528531d648cfb3cda91cda71c7ec6a172bcbd04,WalletTopped,"WalletTopped(address,uint256,address,address)",0x7872034fbcc87890e73d66eac55389e0ffdba157b89a73bd2011157ebac1d66e,false,0 3,address uint256 address address,account amount whitelistedRoot relayerOrWhitelisted,true,22038735,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 8,9,10,11,12 of 12" +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,10,0x2e4fdb111b46a15987c275d8472d51bfb16597c5,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,10,0x2e4fdb111b46a15987c275d8472d51bfb16597c5,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,22038735,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 8,9,10,11,12 of 12" +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,10,0x2e4fdb111b46a15987c275d8472d51bfb16597c5,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,10,0x2e4fdb111b46a15987c275d8472d51bfb16597c5,WalletTopped,"WalletTopped(address,uint256,address,address)",0x7872034fbcc87890e73d66eac55389e0ffdba157b89a73bd2011157ebac1d66e,false,0 3,address uint256 address address,account amount whitelistedRoot relayerOrWhitelisted,true,22038735,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 8,9,10,11,12 of 12" +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,11,0x49ddbcc575c0a813a453fe4466e5a08449bd533d,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,11,0x49ddbcc575c0a813a453fe4466e5a08449bd533d,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,22038735,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 8,9,10,11,12 of 12" +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,11,0x49ddbcc575c0a813a453fe4466e5a08449bd533d,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,11,0x49ddbcc575c0a813a453fe4466e5a08449bd533d,WalletTopped,"WalletTopped(address,uint256,address,address)",0x7872034fbcc87890e73d66eac55389e0ffdba157b89a73bd2011157ebac1d66e,false,0 3,address uint256 address address,account amount whitelistedRoot relayerOrWhitelisted,true,22038735,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 8,9,10,11,12 of 12" +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,12,0x6b7405c75d461237fc89dac475dcbfbe1459f10f,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,12,0x6b7405c75d461237fc89dac475dcbfbe1459f10f,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,22038735,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 8,9,10,11,12 of 12" +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,12,0x6b7405c75d461237fc89dac475dcbfbe1459f10f,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseFaucet,0x01ab5966c1d742ae0cff7f14cc0f4d85156e83d9,12,0x6b7405c75d461237fc89dac475dcbfbe1459f10f,WalletTopped,"WalletTopped(address,uint256,address,address)",0x7872034fbcc87890e73d66eac55389e0ffdba157b89a73bd2011157ebac1d66e,false,0 3,address uint256 address address,account amount whitelistedRoot relayerOrWhitelisted,true,22038735,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 8,9,10,11,12 of 12" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,1,0xa199f0c353e25adf022378b0c208d600f39a6505,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,1,0xa199f0c353e25adf022378b0c208d600f39a6505,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,2,0x9f9ff3720dba5f0e67e28ecfba5e433b0d271204,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,2,0x9f9ff3720dba5f0e67e28ecfba5e433b0d271204,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,2,0x9f9ff3720dba5f0e67e28ecfba5e433b0d271204,UBICollected,"UBICollected(uint256,uint256,uint256,uint256,uint256,uint256,address,uint256)",0x49a079c90e07ed02ae8283e86eaeb643c637381d30aa7ba06d155e5b744a8543,false,0,uint256 uint256 uint256 uint256 uint256 uint256 address uint256,currentDay ubi communityPool gdBought stakingRewards pendingFuseEarnings keeper keeperGDFee,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,2,0x9f9ff3720dba5f0e67e28ecfba5e433b0d271204,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,3,0x7fca2b3e1047291f65c2c914083d970c027f4290,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,3,0x7fca2b3e1047291f65c2c914083d970c027f4290,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,3,0x7fca2b3e1047291f65c2c914083d970c027f4290,UBICollected,"UBICollected(uint256,uint256,uint256,uint256,uint256,uint256,address,uint256)",0x49a079c90e07ed02ae8283e86eaeb643c637381d30aa7ba06d155e5b744a8543,false,0,uint256 uint256 uint256 uint256 uint256 uint256 address uint256,currentDay ubi communityPool gdBought stakingRewards pendingFuseEarnings keeper keeperGDFee,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,3,0x7fca2b3e1047291f65c2c914083d970c027f4290,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,4,0x1e3a43799b4e68c7d872ebece91a6389c0d8844c,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,4,0x1e3a43799b4e68c7d872ebece91a6389c0d8844c,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,4,0x1e3a43799b4e68c7d872ebece91a6389c0d8844c,UBICollected,"UBICollected(uint256,uint256,uint256,uint256,uint256,uint256,address,uint256)",0x49a079c90e07ed02ae8283e86eaeb643c637381d30aa7ba06d155e5b744a8543,false,0,uint256 uint256 uint256 uint256 uint256 uint256 address uint256,currentDay ubi communityPool gdBought stakingRewards pendingFuseEarnings keeper keeperGDFee,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,4,0x1e3a43799b4e68c7d872ebece91a6389c0d8844c,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,5,0x8141208203c298f07ddcd794b14722e69aa42549,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,5,0x8141208203c298f07ddcd794b14722e69aa42549,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,5,0x8141208203c298f07ddcd794b14722e69aa42549,UBICollected,"UBICollected(uint256,uint256,uint256,uint256,uint256,uint256,address,uint256)",0x49a079c90e07ed02ae8283e86eaeb643c637381d30aa7ba06d155e5b744a8543,false,0,uint256 uint256 uint256 uint256 uint256 uint256 address uint256,currentDay ubi communityPool gdBought stakingRewards pendingFuseEarnings keeper keeperGDFee,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,5,0x8141208203c298f07ddcd794b14722e69aa42549,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,6,0xfda6a8aee1a909e1cc7da28b34f61b32e4e9a74a,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,6,0xfda6a8aee1a909e1cc7da28b34f61b32e4e9a74a,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,6,0xfda6a8aee1a909e1cc7da28b34f61b32e4e9a74a,UBICollected,"UBICollected(uint256,uint256,uint256,uint256,uint256,uint256,address,uint256)",0x49a079c90e07ed02ae8283e86eaeb643c637381d30aa7ba06d155e5b744a8543,false,0,uint256 uint256 uint256 uint256 uint256 uint256 address uint256,currentDay ubi communityPool gdBought stakingRewards pendingFuseEarnings keeper keeperGDFee,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,6,0xfda6a8aee1a909e1cc7da28b34f61b32e4e9a74a,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,7,0xd980a608abd9566c87bb4e60302259858766b996,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,7,0xd980a608abd9566c87bb4e60302259858766b996,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,7,0xd980a608abd9566c87bb4e60302259858766b996,UBICollected,"UBICollected(uint256,uint256,uint256,uint256,uint256,uint256,address,uint256)",0x49a079c90e07ed02ae8283e86eaeb643c637381d30aa7ba06d155e5b744a8543,false,0,uint256 uint256 uint256 uint256 uint256 uint256 address uint256,currentDay ubi communityPool gdBought stakingRewards pendingFuseEarnings keeper keeperGDFee,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,7,0xd980a608abd9566c87bb4e60302259858766b996,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,8,0x53f650758deff504f4e5a327f11f44275a710aa9,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,8,0x53f650758deff504f4e5a327f11f44275a710aa9,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,8,0x53f650758deff504f4e5a327f11f44275a710aa9,UBICollected,"UBICollected(uint256,uint256,uint256,uint256,uint256,uint256,address,uint256)",0x49a079c90e07ed02ae8283e86eaeb643c637381d30aa7ba06d155e5b744a8543,false,0,uint256 uint256 uint256 uint256 uint256 uint256 address uint256,currentDay ubi communityPool gdBought stakingRewards pendingFuseEarnings keeper keeperGDFee,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,8,0x53f650758deff504f4e5a327f11f44275a710aa9,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,9,0xbd1f52ab9f30483796d33fa7a4e7371b043dbbe6,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,9,0xbd1f52ab9f30483796d33fa7a4e7371b043dbbe6,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,10,0x2560f53027fd1800174f842f071abd52521f0807,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,10,0x2560f53027fd1800174f842f071abd52521f0807,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,10,0x2560f53027fd1800174f842f071abd52521f0807,UBICollected,"UBICollected(uint256,uint256,uint256,uint256,uint256,uint256,address,uint256)",0x49a079c90e07ed02ae8283e86eaeb643c637381d30aa7ba06d155e5b744a8543,false,0,uint256 uint256 uint256 uint256 uint256 uint256 address uint256,currentDay ubi communityPool gdBought stakingRewards pendingFuseEarnings keeper keeperGDFee,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,10,0x2560f53027fd1800174f842f071abd52521f0807,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,11,0xf2c42adcc899871f1a8aa1a313702b4e7ebff9f5,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,11,0xf2c42adcc899871f1a8aa1a313702b4e7ebff9f5,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,11,0xf2c42adcc899871f1a8aa1a313702b4e7ebff9f5,UBICollected,"UBICollected(uint256,uint256,uint256,uint256,uint256,uint256,address,uint256)",0x49a079c90e07ed02ae8283e86eaeb643c637381d30aa7ba06d155e5b744a8543,false,0,uint256 uint256 uint256 uint256 uint256 uint256 address uint256,currentDay ubi communityPool gdBought stakingRewards pendingFuseEarnings keeper keeperGDFee,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,11,0xf2c42adcc899871f1a8aa1a313702b4e7ebff9f5,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,12,0x2e15da5e7b0c9861272912454f2382949beca07c,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,12,0x2e15da5e7b0c9861272912454f2382949beca07c,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,12,0x2e15da5e7b0c9861272912454f2382949beca07c,UBICollected,"UBICollected(uint256,uint256,uint256,uint256,uint256,uint256,address,uint256)",0x49a079c90e07ed02ae8283e86eaeb643c637381d30aa7ba06d155e5b744a8543,false,0,uint256 uint256 uint256 uint256 uint256 uint256 address uint256,currentDay ubi communityPool gdBought stakingRewards pendingFuseEarnings keeper keeperGDFee,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,12,0x2e15da5e7b0c9861272912454f2382949beca07c,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,13,0xb51ed83bd8329ab1712a4698864e6d2871c38fc7,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,13,0xb51ed83bd8329ab1712a4698864e6d2871c38fc7,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,13,0xb51ed83bd8329ab1712a4698864e6d2871c38fc7,UBICollected,"UBICollected(uint256,uint256,uint256,uint256,uint256,uint256,address,uint256)",0x49a079c90e07ed02ae8283e86eaeb643c637381d30aa7ba06d155e5b744a8543,false,0,uint256 uint256 uint256 uint256 uint256 uint256 address uint256,currentDay ubi communityPool gdBought stakingRewards pendingFuseEarnings keeper keeperGDFee,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,13,0xb51ed83bd8329ab1712a4698864e6d2871c38fc7,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,14,0x720d18ebeac3326098b96201ffe32b580508d018,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,14,0x720d18ebeac3326098b96201ffe32b580508d018,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,14,0x720d18ebeac3326098b96201ffe32b580508d018,UBICollected,"UBICollected(uint256,uint256,uint256,uint256,uint256,uint256,address,uint256)",0x49a079c90e07ed02ae8283e86eaeb643c637381d30aa7ba06d155e5b744a8543,false,0,uint256 uint256 uint256 uint256 uint256 uint256 address uint256,currentDay ubi communityPool gdBought stakingRewards pendingFuseEarnings keeper keeperGDFee,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,14,0x720d18ebeac3326098b96201ffe32b580508d018,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,15,0xe2491656c5657b87b09e5adea27bd637a8953395,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,15,0xe2491656c5657b87b09e5adea27bd637a8953395,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,24976379,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 15 of 16 +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,15,0xe2491656c5657b87b09e5adea27bd637a8953395,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,15,0xe2491656c5657b87b09e5adea27bd637a8953395,UBICollected,"UBICollected(uint256,uint256,uint256,uint256,uint256,uint256,address,uint256)",0x49a079c90e07ed02ae8283e86eaeb643c637381d30aa7ba06d155e5b744a8543,false,0,uint256 uint256 uint256 uint256 uint256 uint256 address uint256,currentDay ubi communityPool gdBought stakingRewards pendingFuseEarnings keeper keeperGDFee,true,8824926,27047375,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,10,11,12,13,14,15 of 16. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,15,0xe2491656c5657b87b09e5adea27bd637a8953395,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,16,0x7c723bbeb808b74fb63fc1cb09ffa43d66a96390,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,FuseStaking,0xa199f0c353e25adf022378b0c208d600f39a6505,16,0x7c723bbeb808b74fb63fc1cb09ffa43d66a96390,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollar,0x495d133b938596c9984d462f007b676bdc57ecec,1,0x495d133b938596c9984d462f007b676bdc57ecec,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollar,0x495d133b938596c9984d462f007b676bdc57ecec,1,0x495d133b938596c9984d462f007b676bdc57ecec,MinterAdded,MinterAdded(address),0x6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f6,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollar,0x495d133b938596c9984d462f007b676bdc57ecec,1,0x495d133b938596c9984d462f007b676bdc57ecec,MinterRemoved,MinterRemoved(address),0xe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb66692,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollar,0x495d133b938596c9984d462f007b676bdc57ecec,1,0x495d133b938596c9984d462f007b676bdc57ecec,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollar,0x495d133b938596c9984d462f007b676bdc57ecec,1,0x495d133b938596c9984d462f007b676bdc57ecec,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollar,0x495d133b938596c9984d462f007b676bdc57ecec,1,0x495d133b938596c9984d462f007b676bdc57ecec,PauserAdded,PauserAdded(address),0x6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f8,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollar,0x495d133b938596c9984d462f007b676bdc57ecec,1,0x495d133b938596c9984d462f007b676bdc57ecec,PauserRemoved,PauserRemoved(address),0xcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollar,0x495d133b938596c9984d462f007b676bdc57ecec,1,0x495d133b938596c9984d462f007b676bdc57ecec,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollar,0x495d133b938596c9984d462f007b676bdc57ecec,1,0x495d133b938596c9984d462f007b676bdc57ecec,Transfer,"Transfer(address,address,uint256,bytes)",0xe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16,false,0 1,address address uint256 bytes,from to value data,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollar,0x495d133b938596c9984d462f007b676bdc57ecec,1,0x495d133b938596c9984d462f007b676bdc57ecec,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollarMintBurnWrapper,0x031b2b7c7854dd8ee9c4a644d7e54ad17f56e3cb,1,0x716031ae7db1a5c07b24ed3b651d5f57945e1ac3,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollarMintBurnWrapper,0x031b2b7c7854dd8ee9c4a644d7e54ad17f56e3cb,1,0x716031ae7db1a5c07b24ed3b651d5f57945e1ac3,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollarMintBurnWrapper,0x031b2b7c7854dd8ee9c4a644d7e54ad17f56e3cb,1,0x716031ae7db1a5c07b24ed3b651d5f57945e1ac3,Burned,"Burned(address,address,uint256)",0x6ab368f832c266c8eb942b84fbcaa20aedc24a699d2a05fae2568028733b1d09,false,,address address uint256,minter to amount,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollarMintBurnWrapper,0x031b2b7c7854dd8ee9c4a644d7e54ad17f56e3cb,1,0x716031ae7db1a5c07b24ed3b651d5f57945e1ac3,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollarMintBurnWrapper,0x031b2b7c7854dd8ee9c4a644d7e54ad17f56e3cb,1,0x716031ae7db1a5c07b24ed3b651d5f57945e1ac3,Minted,"Minted(address,address,uint256)",0x9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0,false,,address address uint256,minter to amount,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollarMintBurnWrapper,0x031b2b7c7854dd8ee9c4a644d7e54ad17f56e3cb,1,0x716031ae7db1a5c07b24ed3b651d5f57945e1ac3,MinterSet,"MinterSet(address,uint256,uint256,uint32,uint256,uint256,uint32,bool,bool)",0x58c3ceb7d4f068706ddc92911fae8701fac2c91c60bcc1b56ec7a6f56001aa5e,false,,address uint256 uint256 uint32 uint256 uint256 uint32 bool bool,minter totalMintCapIn perTxCapIn bpsIn totalMintCapOut perTxCapOut bpsOut rewardsRole isUpdate,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollarMintBurnWrapper,0x031b2b7c7854dd8ee9c4a644d7e54ad17f56e3cb,1,0x716031ae7db1a5c07b24ed3b651d5f57945e1ac3,Paused,Paused(bytes32),0x0cb09dc71d57eeec2046f6854976717e4874a3cf2d6ddeddde337e5b6de6ba31,false,,bytes32,role,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollarMintBurnWrapper,0x031b2b7c7854dd8ee9c4a644d7e54ad17f56e3cb,1,0x716031ae7db1a5c07b24ed3b651d5f57945e1ac3,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollarMintBurnWrapper,0x031b2b7c7854dd8ee9c4a644d7e54ad17f56e3cb,1,0x716031ae7db1a5c07b24ed3b651d5f57945e1ac3,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollarMintBurnWrapper,0x031b2b7c7854dd8ee9c4a644d7e54ad17f56e3cb,1,0x716031ae7db1a5c07b24ed3b651d5f57945e1ac3,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollarMintBurnWrapper,0x031b2b7c7854dd8ee9c4a644d7e54ad17f56e3cb,1,0x716031ae7db1a5c07b24ed3b651d5f57945e1ac3,SendOrMint,"SendOrMint(address,address,uint256,uint256,uint256,uint256)",0xdea51570922020f525c1f30d8c1c57bd3cffe5632d70d13aaf8f8451388dbd95,false,,address address uint256 uint256 uint256 uint256,rewarder to amount sent minted outstandingMintDebt,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollarMintBurnWrapper,0x031b2b7c7854dd8ee9c4a644d7e54ad17f56e3cb,1,0x716031ae7db1a5c07b24ed3b651d5f57945e1ac3,Unpaused,Unpaused(bytes32),0xd05bfc2250abb0f8fd265a54c53a24359c5484af63cad2e4ce87c78ab751395a,false,,bytes32,role,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollarMintBurnWrapper,0x031b2b7c7854dd8ee9c4a644d7e54ad17f56e3cb,1,0x716031ae7db1a5c07b24ed3b651d5f57945e1ac3,UpdateFrequencySet,UpdateFrequencySet(uint128),0x5497ec04d2873f2e2d376db2bb24e7e57851278c75fc1fcc9aab4db5fb70d223,false,,uint128,newFrequency,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GoodDollarMintBurnWrapper,0x031b2b7c7854dd8ee9c4a644d7e54ad17f56e3cb,1,0x716031ae7db1a5c07b24ed3b651d5f57945e1ac3,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GovernanceStaking,0xfaf457fb4a978be059506f6cd41f9b30fca753b0,1,0xfaf457fb4a978be059506f6cd41f9b30fca753b0,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GovernanceStaking,0xfaf457fb4a978be059506f6cd41f9b30fca753b0,1,0xfaf457fb4a978be059506f6cd41f9b30fca753b0,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GovernanceStaking,0xfaf457fb4a978be059506f6cd41f9b30fca753b0,1,0xfaf457fb4a978be059506f6cd41f9b30fca753b0,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GovernanceStaking,0xfaf457fb4a978be059506f6cd41f9b30fca753b0,1,0xfaf457fb4a978be059506f6cd41f9b30fca753b0,ReputationEarned,"ReputationEarned(address,uint256)",0x43848d0574703c28d68ae8958e0571521618f60c4bcacfb094cff2156eaae0f1,false,0,address uint256,staker value,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GovernanceStaking,0xfaf457fb4a978be059506f6cd41f9b30fca753b0,1,0xfaf457fb4a978be059506f6cd41f9b30fca753b0,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GovernanceStaking,0xfaf457fb4a978be059506f6cd41f9b30fca753b0,1,0xfaf457fb4a978be059506f6cd41f9b30fca753b0,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GovernanceStakingV2,0xb7c3e738224625289c573c54d402e9be46205546,1,0xb7c3e738224625289c573c54d402e9be46205546,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GovernanceStakingV2,0xb7c3e738224625289c573c54d402e9be46205546,1,0xb7c3e738224625289c573c54d402e9be46205546,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GovernanceStakingV2,0xb7c3e738224625289c573c54d402e9be46205546,1,0xb7c3e738224625289c573c54d402e9be46205546,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GovernanceStakingV2,0xb7c3e738224625289c573c54d402e9be46205546,1,0xb7c3e738224625289c573c54d402e9be46205546,ReputationEarned,"ReputationEarned(address,uint256)",0x43848d0574703c28d68ae8958e0571521618f60c4bcacfb094cff2156eaae0f1,false,0,address uint256,staker amount,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GovernanceStakingV2,0xb7c3e738224625289c573c54d402e9be46205546,1,0xb7c3e738224625289c573c54d402e9be46205546,Staked,"Staked(address,uint256)",0x9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d,false,0,address uint256,staker amount,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GovernanceStakingV2,0xb7c3e738224625289c573c54d402e9be46205546,1,0xb7c3e738224625289c573c54d402e9be46205546,StakeWithdraw,"StakeWithdraw(address,uint256)",0x1248d48e2de900a1010c7fce73506969ecec243600bfc08b641b158f26d857cd,false,0,address uint256,staker amount,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GovernanceStakingV2,0xb7c3e738224625289c573c54d402e9be46205546,1,0xb7c3e738224625289c573c54d402e9be46205546,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GovernanceStakingV2,0xb7c3e738224625289c573c54d402e9be46205546,1,0xb7c3e738224625289c573c54d402e9be46205546,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0xdeef7c187a9e254ded7b503ac5703adc7b3b15e6,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0xdeef7c187a9e254ded7b503ac5703adc7b3b15e6,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0xdeef7c187a9e254ded7b503ac5703adc7b3b15e6,Burn,"Burn(address,uint256)",0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5,false,0,address uint256,_from _amount,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0xdeef7c187a9e254ded7b503ac5703adc7b3b15e6,DelegateVotesChanged,"DelegateVotesChanged(address,address,uint256,uint256)",0x8553411b8bbb348336351063649aa1f4fa74c4935f5c4386469a017df33a1f66,false,0 1,address address uint256 uint256,delegate delegator previousBalance newBalance,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0xdeef7c187a9e254ded7b503ac5703adc7b3b15e6,Mint,"Mint(address,uint256)",0x0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885,false,0,address uint256,_to _amount,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0xdeef7c187a9e254ded7b503ac5703adc7b3b15e6,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0xdeef7c187a9e254ded7b503ac5703adc7b3b15e6,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0xdeef7c187a9e254ded7b503ac5703adc7b3b15e6,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0xdeef7c187a9e254ded7b503ac5703adc7b3b15e6,StateHash,"StateHash(string,bytes32,uint256)",0x5298f094d368dc1c18dca22952c4ea2cb8b115d7c70a18269735b0f4ed0f4913,false,,string bytes32 uint256,blockchain merkleRoot totalSupply,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0xdeef7c187a9e254ded7b503ac5703adc7b3b15e6,StateHashProof,"StateHashProof(string,address,uint256)",0x1c708de3afb744b96b84aa0fbf440e683fac3130cce82a8f01eb94b5e67610a0,false,,string address uint256,blockchain user repBalance,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,1,0xdeef7c187a9e254ded7b503ac5703adc7b3b15e6,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x418accc2e62cc3745d67ef6b779c441ff223fc27,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x418accc2e62cc3745d67ef6b779c441ff223fc27,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x418accc2e62cc3745d67ef6b779c441ff223fc27,Burn,"Burn(address,uint256)",0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5,false,0,address uint256,_from _amount,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x418accc2e62cc3745d67ef6b779c441ff223fc27,DelegateVotesChanged,"DelegateVotesChanged(address,address,uint256,uint256)",0x8553411b8bbb348336351063649aa1f4fa74c4935f5c4386469a017df33a1f66,false,0 1,address address uint256 uint256,delegate delegator previousBalance newBalance,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x418accc2e62cc3745d67ef6b779c441ff223fc27,Mint,"Mint(address,uint256)",0x0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885,false,0,address uint256,_to _amount,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x418accc2e62cc3745d67ef6b779c441ff223fc27,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x418accc2e62cc3745d67ef6b779c441ff223fc27,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x418accc2e62cc3745d67ef6b779c441ff223fc27,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x418accc2e62cc3745d67ef6b779c441ff223fc27,StateHash,"StateHash(string,bytes32,uint256)",0x5298f094d368dc1c18dca22952c4ea2cb8b115d7c70a18269735b0f4ed0f4913,false,,string bytes32 uint256,blockchain merkleRoot totalSupply,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x418accc2e62cc3745d67ef6b779c441ff223fc27,StateHashProof,"StateHashProof(string,address,uint256)",0x1c708de3afb744b96b84aa0fbf440e683fac3130cce82a8f01eb94b5e67610a0,false,1,string address uint256,blockchain user repBalance,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,2,0x418accc2e62cc3745d67ef6b779c441ff223fc27,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x2845b2ff94d01355bdf5bab2333a5c173a803c3d,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x2845b2ff94d01355bdf5bab2333a5c173a803c3d,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x2845b2ff94d01355bdf5bab2333a5c173a803c3d,Burn,"Burn(address,uint256)",0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5,false,0,address uint256,_from _amount,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x2845b2ff94d01355bdf5bab2333a5c173a803c3d,DelegateVotesChanged,"DelegateVotesChanged(address,address,uint256,uint256)",0x8553411b8bbb348336351063649aa1f4fa74c4935f5c4386469a017df33a1f66,false,0 1,address address uint256 uint256,delegate delegator previousBalance newBalance,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x2845b2ff94d01355bdf5bab2333a5c173a803c3d,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,22365120,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 3 of 3 +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x2845b2ff94d01355bdf5bab2333a5c173a803c3d,Mint,"Mint(address,uint256)",0x0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885,false,0,address uint256,_to _amount,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x2845b2ff94d01355bdf5bab2333a5c173a803c3d,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x2845b2ff94d01355bdf5bab2333a5c173a803c3d,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x2845b2ff94d01355bdf5bab2333a5c173a803c3d,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x2845b2ff94d01355bdf5bab2333a5c173a803c3d,StateHash,"StateHash(string,bytes32,uint256)",0x5298f094d368dc1c18dca22952c4ea2cb8b115d7c70a18269735b0f4ed0f4913,false,,string bytes32 uint256,blockchain merkleRoot totalSupply,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x2845b2ff94d01355bdf5bab2333a5c173a803c3d,StateHashProof,"StateHashProof(string,address,uint256)",0x1c708de3afb744b96b84aa0fbf440e683fac3130cce82a8f01eb94b5e67610a0,false,1,string address uint256,blockchain user repBalance,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,GReputation,0x603b8c0f110e037b51a381cbcacabb8d6c6e4543,3,0x2845b2ff94d01355bdf5bab2333a5c173a803c3d,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,HomeBridge,0xd39021db018e2caeadb4b2e6717d31550e7918d0,1,0xd39021db018e2caeadb4b2e6717d31550e7918d0,ProxyOwnershipTransferred,"ProxyOwnershipTransferred(address,address)",0x5a3e66efaa1e445ebd894728a69d6959842ea1e97bd79b892797106e270efcd9,false,,address address,previousOwner newOwner,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,HomeBridge,0xd39021db018e2caeadb4b2e6717d31550e7918d0,1,0xd39021db018e2caeadb4b2e6717d31550e7918d0,Upgraded,"Upgraded(uint256,address)",0x4289d6195cf3c2d2174adf98d0e19d4d2d08887995b99cb7b100e7ffe795820e,false,1,uint256 address,version implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,1,0xf36b3394235965aa0605fb09eb319eb3586c9ed1,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,1,0xf36b3394235965aa0605fb09eb319eb3586c9ed1,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,1,0xf36b3394235965aa0605fb09eb319eb3586c9ed1,BlacklistAdded,BlacklistAdded(address),0x44d5fe68b00f68950fb9c1ff0a61ef7f747b1a36359a7e3a7f3324db4b878967,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,1,0xf36b3394235965aa0605fb09eb319eb3586c9ed1,BlacklistRemoved,BlacklistRemoved(address),0x1747ca720b1a174a464b6513ace29b1d3190b5f632b9f34147017c81425bfde8,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,1,0xf36b3394235965aa0605fb09eb319eb3586c9ed1,ContractAdded,ContractAdded(address),0x89c66952b48f3e96bf1d8ba1b63189520fd988a6979b8b740bd5c5d8dc53e205,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,1,0xf36b3394235965aa0605fb09eb319eb3586c9ed1,ContractRemoved,ContractRemoved(address),0x8d30d41865a0b811b9545d879520d2dde9f4cc49e4241f486ad9752bc904b565,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,1,0xf36b3394235965aa0605fb09eb319eb3586c9ed1,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,1,0xf36b3394235965aa0605fb09eb319eb3586c9ed1,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,1,0xf36b3394235965aa0605fb09eb319eb3586c9ed1,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,1,0xf36b3394235965aa0605fb09eb319eb3586c9ed1,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,1,0xf36b3394235965aa0605fb09eb319eb3586c9ed1,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,1,0xf36b3394235965aa0605fb09eb319eb3586c9ed1,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,1,0xf36b3394235965aa0605fb09eb319eb3586c9ed1,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,1,0xf36b3394235965aa0605fb09eb319eb3586c9ed1,WhitelistedAdded,WhitelistedAdded(address),0xee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,1,0xf36b3394235965aa0605fb09eb319eb3586c9ed1,WhitelistedAuthenticated,"WhitelistedAuthenticated(address,uint256)",0xb2a82fce6d8c7a633efe9579f77b4edb96bfdf171a49bfc2ce666dc543a1f500,false,0,address uint256,account timestamp,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,1,0xf36b3394235965aa0605fb09eb319eb3586c9ed1,WhitelistedRemoved,WhitelistedRemoved(address),0x270d9b30cf5b0793bbfd54c9d5b94aeb49462b8148399000265144a8722da6b6,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,2,0xc1956c99fd3209e30c0746dfd4d4f11d03cc0e9a,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,2,0xc1956c99fd3209e30c0746dfd4d4f11d03cc0e9a,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,2,0xc1956c99fd3209e30c0746dfd4d4f11d03cc0e9a,BlacklistAdded,BlacklistAdded(address),0x44d5fe68b00f68950fb9c1ff0a61ef7f747b1a36359a7e3a7f3324db4b878967,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,2,0xc1956c99fd3209e30c0746dfd4d4f11d03cc0e9a,BlacklistRemoved,BlacklistRemoved(address),0x1747ca720b1a174a464b6513ace29b1d3190b5f632b9f34147017c81425bfde8,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,2,0xc1956c99fd3209e30c0746dfd4d4f11d03cc0e9a,ContractAdded,ContractAdded(address),0x89c66952b48f3e96bf1d8ba1b63189520fd988a6979b8b740bd5c5d8dc53e205,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,2,0xc1956c99fd3209e30c0746dfd4d4f11d03cc0e9a,ContractRemoved,ContractRemoved(address),0x8d30d41865a0b811b9545d879520d2dde9f4cc49e4241f486ad9752bc904b565,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,2,0xc1956c99fd3209e30c0746dfd4d4f11d03cc0e9a,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,2,0xc1956c99fd3209e30c0746dfd4d4f11d03cc0e9a,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,2,0xc1956c99fd3209e30c0746dfd4d4f11d03cc0e9a,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,2,0xc1956c99fd3209e30c0746dfd4d4f11d03cc0e9a,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,2,0xc1956c99fd3209e30c0746dfd4d4f11d03cc0e9a,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,2,0xc1956c99fd3209e30c0746dfd4d4f11d03cc0e9a,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,2,0xc1956c99fd3209e30c0746dfd4d4f11d03cc0e9a,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,2,0xc1956c99fd3209e30c0746dfd4d4f11d03cc0e9a,WhitelistedAdded,WhitelistedAdded(address),0xee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,2,0xc1956c99fd3209e30c0746dfd4d4f11d03cc0e9a,WhitelistedAuthenticated,"WhitelistedAuthenticated(address,uint256)",0xb2a82fce6d8c7a633efe9579f77b4edb96bfdf171a49bfc2ce666dc543a1f500,false,0,address uint256,account timestamp,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,2,0xc1956c99fd3209e30c0746dfd4d4f11d03cc0e9a,WhitelistedRemoved,WhitelistedRemoved(address),0x270d9b30cf5b0793bbfd54c9d5b94aeb49462b8148399000265144a8722da6b6,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,3,0x4111a54797e11043def22c4a0240e1605fd7b719,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,3,0x4111a54797e11043def22c4a0240e1605fd7b719,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,3,0x4111a54797e11043def22c4a0240e1605fd7b719,BlacklistAdded,BlacklistAdded(address),0x44d5fe68b00f68950fb9c1ff0a61ef7f747b1a36359a7e3a7f3324db4b878967,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,3,0x4111a54797e11043def22c4a0240e1605fd7b719,BlacklistRemoved,BlacklistRemoved(address),0x1747ca720b1a174a464b6513ace29b1d3190b5f632b9f34147017c81425bfde8,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,3,0x4111a54797e11043def22c4a0240e1605fd7b719,ContractAdded,ContractAdded(address),0x89c66952b48f3e96bf1d8ba1b63189520fd988a6979b8b740bd5c5d8dc53e205,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,3,0x4111a54797e11043def22c4a0240e1605fd7b719,ContractRemoved,ContractRemoved(address),0x8d30d41865a0b811b9545d879520d2dde9f4cc49e4241f486ad9752bc904b565,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,3,0x4111a54797e11043def22c4a0240e1605fd7b719,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,3,0x4111a54797e11043def22c4a0240e1605fd7b719,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,3,0x4111a54797e11043def22c4a0240e1605fd7b719,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,3,0x4111a54797e11043def22c4a0240e1605fd7b719,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,3,0x4111a54797e11043def22c4a0240e1605fd7b719,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,3,0x4111a54797e11043def22c4a0240e1605fd7b719,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,3,0x4111a54797e11043def22c4a0240e1605fd7b719,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,3,0x4111a54797e11043def22c4a0240e1605fd7b719,WhitelistedAdded,WhitelistedAdded(address),0xee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,3,0x4111a54797e11043def22c4a0240e1605fd7b719,WhitelistedAuthenticated,"WhitelistedAuthenticated(address,uint256)",0xb2a82fce6d8c7a633efe9579f77b4edb96bfdf171a49bfc2ce666dc543a1f500,false,0,address uint256,account timestamp,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,3,0x4111a54797e11043def22c4a0240e1605fd7b719,WhitelistedRemoved,WhitelistedRemoved(address),0x270d9b30cf5b0793bbfd54c9d5b94aeb49462b8148399000265144a8722da6b6,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,4,0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d,AccountConnected,"AccountConnected(address,address)",0x18f7736ef54539debd9afd3c9500b106e12ae7c70e685f5a5efd727b1ce1d54c,false,0 1,address address,connected to,true,40887165,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 4 of 4 +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,4,0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d,AccountDisconnected,"AccountDisconnected(address,address)",0x7cdef5f9c5cb8ce728661ede956fef26cb91eb4d7d2180cc041b73f9fef568d2,false,0 1,address address,disconnected from,true,40887165,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 4 of 4 +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,4,0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,4,0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,4,0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d,BlacklistAdded,BlacklistAdded(address),0x44d5fe68b00f68950fb9c1ff0a61ef7f747b1a36359a7e3a7f3324db4b878967,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,4,0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d,BlacklistRemoved,BlacklistRemoved(address),0x1747ca720b1a174a464b6513ace29b1d3190b5f632b9f34147017c81425bfde8,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,4,0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d,ContractAdded,ContractAdded(address),0x89c66952b48f3e96bf1d8ba1b63189520fd988a6979b8b740bd5c5d8dc53e205,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,4,0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d,ContractRemoved,ContractRemoved(address),0x8d30d41865a0b811b9545d879520d2dde9f4cc49e4241f486ad9752bc904b565,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,4,0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,4,0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,4,0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,4,0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,4,0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,4,0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,4,0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,4,0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d,WhitelistedAdded,WhitelistedAdded(address),0xee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,4,0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d,WhitelistedAuthenticated,"WhitelistedAuthenticated(address,uint256)",0xb2a82fce6d8c7a633efe9579f77b4edb96bfdf171a49bfc2ce666dc543a1f500,false,0,address uint256,account timestamp,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Identity,0x2f9c28de9e6d44b71b91b8ba337a5d82e308e7be,4,0xfab5545b17d7e315f5c8b0f69cb81571c6ec436d,WhitelistedRemoved,WhitelistedRemoved(address),0x270d9b30cf5b0793bbfd54c9d5b94aeb49462b8148399000265144a8722da6b6,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,IdentityOld,0xfa8d865a962ca8456df331d78806152d3ac5b84f,1,0xfa8d865a962ca8456df331d78806152d3ac5b84f,BlacklistAdded,BlacklistAdded(address),0x44d5fe68b00f68950fb9c1ff0a61ef7f747b1a36359a7e3a7f3324db4b878967,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,IdentityOld,0xfa8d865a962ca8456df331d78806152d3ac5b84f,1,0xfa8d865a962ca8456df331d78806152d3ac5b84f,BlacklistRemoved,BlacklistRemoved(address),0x1747ca720b1a174a464b6513ace29b1d3190b5f632b9f34147017c81425bfde8,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,IdentityOld,0xfa8d865a962ca8456df331d78806152d3ac5b84f,1,0xfa8d865a962ca8456df331d78806152d3ac5b84f,ContractAdded,ContractAdded(address),0x89c66952b48f3e96bf1d8ba1b63189520fd988a6979b8b740bd5c5d8dc53e205,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,IdentityOld,0xfa8d865a962ca8456df331d78806152d3ac5b84f,1,0xfa8d865a962ca8456df331d78806152d3ac5b84f,ContractRemoved,ContractRemoved(address),0x8d30d41865a0b811b9545d879520d2dde9f4cc49e4241f486ad9752bc904b565,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,IdentityOld,0xfa8d865a962ca8456df331d78806152d3ac5b84f,1,0xfa8d865a962ca8456df331d78806152d3ac5b84f,IdentityAdminAdded,IdentityAdminAdded(address),0x3505858ac30c166c603cb64de4a970615e36a4ed8fea37ba93bc5f11a38dd309,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,IdentityOld,0xfa8d865a962ca8456df331d78806152d3ac5b84f,1,0xfa8d865a962ca8456df331d78806152d3ac5b84f,IdentityAdminRemoved,IdentityAdminRemoved(address),0x869f6a5b4767d57c58d57f1ddf82e1516487f35944a19bf30a4a21bd35f6ad05,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,IdentityOld,0xfa8d865a962ca8456df331d78806152d3ac5b84f,1,0xfa8d865a962ca8456df331d78806152d3ac5b84f,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,IdentityOld,0xfa8d865a962ca8456df331d78806152d3ac5b84f,1,0xfa8d865a962ca8456df331d78806152d3ac5b84f,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,IdentityOld,0xfa8d865a962ca8456df331d78806152d3ac5b84f,1,0xfa8d865a962ca8456df331d78806152d3ac5b84f,PauserAdded,PauserAdded(address),0x6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f8,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,IdentityOld,0xfa8d865a962ca8456df331d78806152d3ac5b84f,1,0xfa8d865a962ca8456df331d78806152d3ac5b84f,PauserRemoved,PauserRemoved(address),0xcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,IdentityOld,0xfa8d865a962ca8456df331d78806152d3ac5b84f,1,0xfa8d865a962ca8456df331d78806152d3ac5b84f,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,IdentityOld,0xfa8d865a962ca8456df331d78806152d3ac5b84f,1,0xfa8d865a962ca8456df331d78806152d3ac5b84f,WhitelistedAdded,WhitelistedAdded(address),0xee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,IdentityOld,0xfa8d865a962ca8456df331d78806152d3ac5b84f,1,0xfa8d865a962ca8456df331d78806152d3ac5b84f,WhitelistedRemoved,WhitelistedRemoved(address),0x270d9b30cf5b0793bbfd54c9d5b94aeb49462b8148399000265144a8722da6b6,false,0,address,account,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,1,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,1,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,2,0x0e9c269afd9ee20a349507c61092f58a636a1ed3,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,2,0x0e9c269afd9ee20a349507c61092f58a636a1ed3,InviteeJoined,"InviteeJoined(address,address)",0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051,false,0 1,address address,inviter invitee,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,2,0x0e9c269afd9ee20a349507c61092f58a636a1ed3,InviterBounty,"InviterBounty(address,address,uint256,uint256,bool)",0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b,false,0 1,address address uint256 uint256 bool,inviter invitee bountyPaid inviterLevel earnedLevel,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,2,0x0e9c269afd9ee20a349507c61092f58a636a1ed3,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,3,0x0c8e02371de8c6ec3a261bd24a419beb19171558,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,3,0x0c8e02371de8c6ec3a261bd24a419beb19171558,InviteeJoined,"InviteeJoined(address,address)",0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051,false,0 1,address address,inviter invitee,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,3,0x0c8e02371de8c6ec3a261bd24a419beb19171558,InviterBounty,"InviterBounty(address,address,uint256,uint256,bool)",0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b,false,0 1,address address uint256 uint256 bool,inviter invitee bountyPaid inviterLevel earnedLevel,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,3,0x0c8e02371de8c6ec3a261bd24a419beb19171558,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,4,0x1394a4658f88e40a6f7673136f533157dfb6ba20,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,4,0x1394a4658f88e40a6f7673136f533157dfb6ba20,InviteeJoined,"InviteeJoined(address,address)",0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051,false,0 1,address address,inviter invitee,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,4,0x1394a4658f88e40a6f7673136f533157dfb6ba20,InviterBounty,"InviterBounty(address,address,uint256,uint256,bool)",0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b,false,0 1,address address uint256 uint256 bool,inviter invitee bountyPaid inviterLevel earnedLevel,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,4,0x1394a4658f88e40a6f7673136f533157dfb6ba20,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,5,0xdd45a44f2e11fb95d1be4ac41501ca0b8cd60de7,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,5,0xdd45a44f2e11fb95d1be4ac41501ca0b8cd60de7,InviteeJoined,"InviteeJoined(address,address)",0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051,false,0 1,address address,inviter invitee,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,5,0xdd45a44f2e11fb95d1be4ac41501ca0b8cd60de7,InviterBounty,"InviterBounty(address,address,uint256,uint256,bool)",0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b,false,0 1,address address uint256 uint256 bool,inviter invitee bountyPaid inviterLevel earnedLevel,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,5,0xdd45a44f2e11fb95d1be4ac41501ca0b8cd60de7,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,6,0xd97ecd0487293e0e2b0b52f37eeb2951d69d43f0,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,6,0xd97ecd0487293e0e2b0b52f37eeb2951d69d43f0,InviteeJoined,"InviteeJoined(address,address)",0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051,false,0 1,address address,inviter invitee,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,6,0xd97ecd0487293e0e2b0b52f37eeb2951d69d43f0,InviterBounty,"InviterBounty(address,address,uint256,uint256,bool)",0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b,false,0 1,address address uint256 uint256 bool,inviter invitee bountyPaid inviterLevel earnedLevel,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,6,0xd97ecd0487293e0e2b0b52f37eeb2951d69d43f0,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,7,0x3ac09cfaa27c830693c55d5454ca39ced7b9cf3a,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,7,0x3ac09cfaa27c830693c55d5454ca39ced7b9cf3a,InviteeJoined,"InviteeJoined(address,address)",0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051,false,0 1,address address,inviter invitee,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,7,0x3ac09cfaa27c830693c55d5454ca39ced7b9cf3a,InviterBounty,"InviterBounty(address,address,uint256,uint256,bool)",0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b,false,0 1,address address uint256 uint256 bool,inviter invitee bountyPaid inviterLevel earnedLevel,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,7,0x3ac09cfaa27c830693c55d5454ca39ced7b9cf3a,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,8,0x4461384c11a73948ab62fd489478f7bbc3166528,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,8,0x4461384c11a73948ab62fd489478f7bbc3166528,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,22038741,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,8,0x4461384c11a73948ab62fd489478f7bbc3166528,InviteeJoined,"InviteeJoined(address,address)",0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051,false,0 1,address address,inviter invitee,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,8,0x4461384c11a73948ab62fd489478f7bbc3166528,InviterBounty,"InviterBounty(address,address,uint256,uint256,bool)",0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b,false,0 1,address address uint256 uint256 bool,inviter invitee bountyPaid inviterLevel earnedLevel,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,8,0x4461384c11a73948ab62fd489478f7bbc3166528,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,9,0xc5a2c8c6dbac1f1c934f9651733758ff3ba06345,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,9,0xc5a2c8c6dbac1f1c934f9651733758ff3ba06345,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,22038741,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,9,0xc5a2c8c6dbac1f1c934f9651733758ff3ba06345,InviteeJoined,"InviteeJoined(address,address)",0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051,false,0 1,address address,inviter invitee,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,9,0xc5a2c8c6dbac1f1c934f9651733758ff3ba06345,InviterBounty,"InviterBounty(address,address,uint256,uint256,bool)",0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b,false,0 1,address address uint256 uint256 bool,inviter invitee bountyPaid inviterLevel earnedLevel,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,9,0xc5a2c8c6dbac1f1c934f9651733758ff3ba06345,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,10,0x618dc4c8f5aa433b6c8e03da1e69d299c6c49ef6,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,10,0x618dc4c8f5aa433b6c8e03da1e69d299c6c49ef6,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,22038741,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,10,0x618dc4c8f5aa433b6c8e03da1e69d299c6c49ef6,InviteeJoined,"InviteeJoined(address,address)",0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051,false,0 1,address address,inviter invitee,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,10,0x618dc4c8f5aa433b6c8e03da1e69d299c6c49ef6,InviterBounty,"InviterBounty(address,address,uint256,uint256,bool)",0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b,false,0 1,address address uint256 uint256 bool,inviter invitee bountyPaid inviterLevel earnedLevel,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,10,0x618dc4c8f5aa433b6c8e03da1e69d299c6c49ef6,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,11,0x4072cb2d7e95def1559f6f72491039fe0534fa37,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,11,0x4072cb2d7e95def1559f6f72491039fe0534fa37,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,22038741,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,11,0x4072cb2d7e95def1559f6f72491039fe0534fa37,InviteeJoined,"InviteeJoined(address,address)",0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051,false,0 1,address address,inviter invitee,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,11,0x4072cb2d7e95def1559f6f72491039fe0534fa37,InviterBounty,"InviterBounty(address,address,uint256,uint256,bool)",0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b,false,0 1,address address uint256 uint256 bool,inviter invitee bountyPaid inviterLevel earnedLevel,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,11,0x4072cb2d7e95def1559f6f72491039fe0534fa37,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,12,0xef577898972e72c7bc03791d22f79c0056917517,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,12,0xef577898972e72c7bc03791d22f79c0056917517,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,13,0x502aa6663621759d299f15bd967d53431daa9503,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,13,0x502aa6663621759d299f15bd967d53431daa9503,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,22038741,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,13,0x502aa6663621759d299f15bd967d53431daa9503,InviteeJoined,"InviteeJoined(address,address)",0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051,false,0 1,address address,inviter invitee,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,13,0x502aa6663621759d299f15bd967d53431daa9503,InviterBounty,"InviterBounty(address,address,uint256,uint256,bool)",0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b,false,0 1,address address uint256 uint256 bool,inviter invitee bountyPaid inviterLevel earnedLevel,true,9117508,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6,7,8,9,10,11,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,Invites,0xca2f09c3ccfd7ad5cb9276918bd1868f2b922ea0,13,0x502aa6663621759d299f15bd967d53431daa9503,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,1,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,1,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,1,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd3b5bfdacb042a89bbabad2376aa1a923b365a14,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd3b5bfdacb042a89bbabad2376aa1a923b365a14,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd3b5bfdacb042a89bbabad2376aa1a923b365a14,BridgeRequest,"BridgeRequest(address,address,uint256,uint256,uint256,uint8,uint256)",0xabeeb7182c7294cd8efcd40e9ff952c1b759c2165b3634aac589429de5d55ad0,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to targetChainId normalizedAmount timestamp bridge id,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd3b5bfdacb042a89bbabad2376aa1a923b365a14,ExecutedTransfer,"ExecutedTransfer(address,address,uint256,uint256,uint256,uint8,uint256)",0x6cf712ce908185c8c38a073b7315f79687e7440fb057d9d1ca76a2509a1282ee,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to normalizedAmount fee sourceChainId bridge id,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd3b5bfdacb042a89bbabad2376aa1a923b365a14,FalseSender,"FalseSender(uint256,address)",0x1eafb58197ea0dc76b9278ccad47f61a239f00b017d89a19081a89321cce213d,false,,uint256 address,sourceChainId sourceAddress,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd3b5bfdacb042a89bbabad2376aa1a923b365a14,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd3b5bfdacb042a89bbabad2376aa1a923b365a14,MessageFailed,"MessageFailed(uint16,bytes,uint64,bytes,bytes)",0xe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c,false,,uint16 bytes uint64 bytes bytes,_srcChainId _srcAddress _nonce _payload _reason,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd3b5bfdacb042a89bbabad2376aa1a923b365a14,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd3b5bfdacb042a89bbabad2376aa1a923b365a14,RetryMessageSuccess,"RetryMessageSuccess(uint16,bytes,uint64,bytes32)",0xc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e5,false,,uint16 bytes uint64 bytes32,_srcChainId _srcAddress _nonce _payloadHash,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd3b5bfdacb042a89bbabad2376aa1a923b365a14,SetMinDstGas,"SetMinDstGas(uint16,uint16,uint256)",0x9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0,false,,uint16 uint16 uint256,_dstChainId _type _minDstGas,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd3b5bfdacb042a89bbabad2376aa1a923b365a14,SetPrecrime,SetPrecrime(address),0x5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b,false,,address,precrime,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd3b5bfdacb042a89bbabad2376aa1a923b365a14,SetTrustedRemote,"SetTrustedRemote(uint16,bytes)",0xfa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab,false,,uint16 bytes,_remoteChainId _path,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd3b5bfdacb042a89bbabad2376aa1a923b365a14,SetTrustedRemoteAddress,"SetTrustedRemoteAddress(uint16,bytes)",0x8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce,false,,uint16 bytes,_remoteChainId _remoteAddress,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xd3b5bfdacb042a89bbabad2376aa1a923b365a14,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xfcd61ccb982ce77192e3d18a5ae3326dce0b6874,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xfcd61ccb982ce77192e3d18a5ae3326dce0b6874,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xfcd61ccb982ce77192e3d18a5ae3326dce0b6874,BridgeRequest,"BridgeRequest(address,address,uint256,uint256,uint256,uint8,uint256)",0xabeeb7182c7294cd8efcd40e9ff952c1b759c2165b3634aac589429de5d55ad0,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to targetChainId normalizedAmount timestamp bridge id,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xfcd61ccb982ce77192e3d18a5ae3326dce0b6874,ExecutedTransfer,"ExecutedTransfer(address,address,uint256,uint256,uint256,uint8,uint256)",0x6cf712ce908185c8c38a073b7315f79687e7440fb057d9d1ca76a2509a1282ee,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to normalizedAmount fee sourceChainId bridge id,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xfcd61ccb982ce77192e3d18a5ae3326dce0b6874,FalseSender,"FalseSender(uint256,address)",0x1eafb58197ea0dc76b9278ccad47f61a239f00b017d89a19081a89321cce213d,false,,uint256 address,sourceChainId sourceAddress,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xfcd61ccb982ce77192e3d18a5ae3326dce0b6874,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xfcd61ccb982ce77192e3d18a5ae3326dce0b6874,MessageFailed,"MessageFailed(uint16,bytes,uint64,bytes,bytes)",0xe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c,false,,uint16 bytes uint64 bytes bytes,_srcChainId _srcAddress _nonce _payload _reason,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xfcd61ccb982ce77192e3d18a5ae3326dce0b6874,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xfcd61ccb982ce77192e3d18a5ae3326dce0b6874,RetryMessageSuccess,"RetryMessageSuccess(uint16,bytes,uint64,bytes32)",0xc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e5,false,,uint16 bytes uint64 bytes32,_srcChainId _srcAddress _nonce _payloadHash,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xfcd61ccb982ce77192e3d18a5ae3326dce0b6874,SetMinDstGas,"SetMinDstGas(uint16,uint16,uint256)",0x9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0,false,,uint16 uint16 uint256,_dstChainId _type _minDstGas,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xfcd61ccb982ce77192e3d18a5ae3326dce0b6874,SetPrecrime,SetPrecrime(address),0x5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b,false,,address,precrime,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xfcd61ccb982ce77192e3d18a5ae3326dce0b6874,SetTrustedRemote,"SetTrustedRemote(uint16,bytes)",0xfa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab,false,,uint16 bytes,_remoteChainId _path,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xfcd61ccb982ce77192e3d18a5ae3326dce0b6874,SetTrustedRemoteAddress,"SetTrustedRemoteAddress(uint16,bytes)",0x8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce,false,,uint16 bytes,_remoteChainId _remoteAddress,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xfcd61ccb982ce77192e3d18a5ae3326dce0b6874,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x6f252280eb53df085ead27bbe55d615741a8268d,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x6f252280eb53df085ead27bbe55d615741a8268d,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x6f252280eb53df085ead27bbe55d615741a8268d,BridgeRequest,"BridgeRequest(address,address,uint256,uint256,uint256,uint8,uint256)",0xabeeb7182c7294cd8efcd40e9ff952c1b759c2165b3634aac589429de5d55ad0,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to targetChainId normalizedAmount timestamp bridge id,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x6f252280eb53df085ead27bbe55d615741a8268d,ExecutedTransfer,"ExecutedTransfer(address,address,uint256,uint256,uint256,uint8,uint256)",0x6cf712ce908185c8c38a073b7315f79687e7440fb057d9d1ca76a2509a1282ee,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to normalizedAmount fee sourceChainId bridge id,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x6f252280eb53df085ead27bbe55d615741a8268d,FalseSender,"FalseSender(uint256,address)",0x1eafb58197ea0dc76b9278ccad47f61a239f00b017d89a19081a89321cce213d,false,,uint256 address,sourceChainId sourceAddress,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x6f252280eb53df085ead27bbe55d615741a8268d,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x6f252280eb53df085ead27bbe55d615741a8268d,MessageFailed,"MessageFailed(uint16,bytes,uint64,bytes,bytes)",0xe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c,false,,uint16 bytes uint64 bytes bytes,_srcChainId _srcAddress _nonce _payload _reason,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x6f252280eb53df085ead27bbe55d615741a8268d,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x6f252280eb53df085ead27bbe55d615741a8268d,RetryMessageSuccess,"RetryMessageSuccess(uint16,bytes,uint64,bytes32)",0xc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e5,false,,uint16 bytes uint64 bytes32,_srcChainId _srcAddress _nonce _payloadHash,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x6f252280eb53df085ead27bbe55d615741a8268d,SetMinDstGas,"SetMinDstGas(uint16,uint16,uint256)",0x9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0,false,,uint16 uint16 uint256,_dstChainId _type _minDstGas,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x6f252280eb53df085ead27bbe55d615741a8268d,SetPrecrime,SetPrecrime(address),0x5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b,false,,address,precrime,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x6f252280eb53df085ead27bbe55d615741a8268d,SetTrustedRemote,"SetTrustedRemote(uint16,bytes)",0xfa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab,false,,uint16 bytes,_remoteChainId _path,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x6f252280eb53df085ead27bbe55d615741a8268d,SetTrustedRemoteAddress,"SetTrustedRemoteAddress(uint16,bytes)",0x8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce,false,,uint16 bytes,_remoteChainId _remoteAddress,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x6f252280eb53df085ead27bbe55d615741a8268d,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0xfb62aa509a7b260b6697b671c969a184d6c39e90,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0xfb62aa509a7b260b6697b671c969a184d6c39e90,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0xfb62aa509a7b260b6697b671c969a184d6c39e90,BridgeRequest,"BridgeRequest(address,address,uint256,uint256,uint256,uint8,uint256)",0xabeeb7182c7294cd8efcd40e9ff952c1b759c2165b3634aac589429de5d55ad0,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to targetChainId normalizedAmount timestamp bridge id,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0xfb62aa509a7b260b6697b671c969a184d6c39e90,ExecutedTransfer,"ExecutedTransfer(address,address,uint256,uint256,uint256,uint8,uint256)",0x6cf712ce908185c8c38a073b7315f79687e7440fb057d9d1ca76a2509a1282ee,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to normalizedAmount fee sourceChainId bridge id,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0xfb62aa509a7b260b6697b671c969a184d6c39e90,FalseSender,"FalseSender(uint256,address)",0x1eafb58197ea0dc76b9278ccad47f61a239f00b017d89a19081a89321cce213d,false,,uint256 address,sourceChainId sourceAddress,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0xfb62aa509a7b260b6697b671c969a184d6c39e90,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0xfb62aa509a7b260b6697b671c969a184d6c39e90,MessageFailed,"MessageFailed(uint16,bytes,uint64,bytes,bytes)",0xe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c,false,,uint16 bytes uint64 bytes bytes,_srcChainId _srcAddress _nonce _payload _reason,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0xfb62aa509a7b260b6697b671c969a184d6c39e90,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0xfb62aa509a7b260b6697b671c969a184d6c39e90,RetryMessageSuccess,"RetryMessageSuccess(uint16,bytes,uint64,bytes32)",0xc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e5,false,,uint16 bytes uint64 bytes32,_srcChainId _srcAddress _nonce _payloadHash,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0xfb62aa509a7b260b6697b671c969a184d6c39e90,SetMinDstGas,"SetMinDstGas(uint16,uint16,uint256)",0x9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0,false,,uint16 uint16 uint256,_dstChainId _type _minDstGas,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0xfb62aa509a7b260b6697b671c969a184d6c39e90,SetPrecrime,SetPrecrime(address),0x5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b,false,,address,precrime,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0xfb62aa509a7b260b6697b671c969a184d6c39e90,SetTrustedRemote,"SetTrustedRemote(uint16,bytes)",0xfa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab,false,,uint16 bytes,_remoteChainId _path,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0xfb62aa509a7b260b6697b671c969a184d6c39e90,SetTrustedRemoteAddress,"SetTrustedRemoteAddress(uint16,bytes)",0x8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce,false,,uint16 bytes,_remoteChainId _remoteAddress,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,5,0xfb62aa509a7b260b6697b671c969a184d6c39e90,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xcac4215c57ef199210e759af92bcad012f61e7a1,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xcac4215c57ef199210e759af92bcad012f61e7a1,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xcac4215c57ef199210e759af92bcad012f61e7a1,BridgeRequest,"BridgeRequest(address,address,uint256,uint256,uint256,uint8,uint256)",0xabeeb7182c7294cd8efcd40e9ff952c1b759c2165b3634aac589429de5d55ad0,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to targetChainId normalizedAmount timestamp bridge id,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xcac4215c57ef199210e759af92bcad012f61e7a1,ExecutedTransfer,"ExecutedTransfer(address,address,uint256,uint256,uint256,uint8,uint256)",0x6cf712ce908185c8c38a073b7315f79687e7440fb057d9d1ca76a2509a1282ee,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to normalizedAmount fee sourceChainId bridge id,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xcac4215c57ef199210e759af92bcad012f61e7a1,FalseSender,"FalseSender(uint256,address)",0x1eafb58197ea0dc76b9278ccad47f61a239f00b017d89a19081a89321cce213d,false,,uint256 address,sourceChainId sourceAddress,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xcac4215c57ef199210e759af92bcad012f61e7a1,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xcac4215c57ef199210e759af92bcad012f61e7a1,MessageFailed,"MessageFailed(uint16,bytes,uint64,bytes,bytes)",0xe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c,false,,uint16 bytes uint64 bytes bytes,_srcChainId _srcAddress _nonce _payload _reason,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xcac4215c57ef199210e759af92bcad012f61e7a1,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xcac4215c57ef199210e759af92bcad012f61e7a1,RetryMessageSuccess,"RetryMessageSuccess(uint16,bytes,uint64,bytes32)",0xc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e5,false,,uint16 bytes uint64 bytes32,_srcChainId _srcAddress _nonce _payloadHash,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xcac4215c57ef199210e759af92bcad012f61e7a1,SetMinDstGas,"SetMinDstGas(uint16,uint16,uint256)",0x9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0,false,,uint16 uint16 uint256,_dstChainId _type _minDstGas,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xcac4215c57ef199210e759af92bcad012f61e7a1,SetPrecrime,SetPrecrime(address),0x5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b,false,,address,precrime,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xcac4215c57ef199210e759af92bcad012f61e7a1,SetTrustedRemote,"SetTrustedRemote(uint16,bytes)",0xfa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab,false,,uint16 bytes,_remoteChainId _path,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xcac4215c57ef199210e759af92bcad012f61e7a1,SetTrustedRemoteAddress,"SetTrustedRemoteAddress(uint16,bytes)",0x8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce,false,,uint16 bytes,_remoteChainId _remoteAddress,true,25464924,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4,5,6 of 6" +FUSE,122,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,6,0xcac4215c57ef199210e759af92bcad012f61e7a1,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MultichainRouter,0x735abe48e8782948a37c7765ecb76b98cde97b0f,1,0x735abe48e8782948a37c7765ecb76b98cde97b0f,LogAnySwapIn,"LogAnySwapIn(bytes32,address,address,uint256,uint256,uint256)",0xaac9ce45fe3adf5143598c4f18a369591a20a3384aedaf1b525d29127e1fcd55,false,0 1 2,bytes32 address address uint256 uint256 uint256,txhash token to amount fromChainID toChainID,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MultichainRouter,0x735abe48e8782948a37c7765ecb76b98cde97b0f,1,0x735abe48e8782948a37c7765ecb76b98cde97b0f,LogAnySwapOut,"LogAnySwapOut(address,address,address,uint256,uint256,uint256)",0x97116cf6cd4f6412bb47914d6db18da9e16ab2142f543b86e207c24fbd16b23a,false,0 1 2,address address address uint256 uint256 uint256,token from to amount fromChainID toChainID,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MultichainRouter,0x735abe48e8782948a37c7765ecb76b98cde97b0f,1,0x735abe48e8782948a37c7765ecb76b98cde97b0f,LogAnySwapOut,"LogAnySwapOut(address,address,string,uint256,uint256,uint256)",0x409e0ad946b19f77602d6cf11d59e1796ddaa4828159a0b4fb7fa2ff6b161b79,false,0 1,address address string uint256 uint256 uint256,token from to amount fromChainID toChainID,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,MultichainRouter,0x735abe48e8782948a37c7765ecb76b98cde97b0f,1,0x735abe48e8782948a37c7765ecb76b98cde97b0f,LogChangeMPC,"LogChangeMPC(address,address,uint256,uint256)",0xcda32bc39904597666dfa9f9c845714756e1ffffad55b52e0d344673a2198121,false,0 1 2,address address uint256 uint256,oldMPC newMPC effectiveTime chainID,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,NameService,0xec6dce387b1616a0c44ff2e4fa9e90e53cf14eb0,1,0xba3f1ba4eb215204385107e76c11894b876ecf40,AddressChanged,"AddressChanged(string,address)",0x135cf55549d8538a41f19f46cc85625da93e68b63484cca8fcb9aaf19e520137,false,,string address,name addr,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,NameService,0xec6dce387b1616a0c44ff2e4fa9e90e53cf14eb0,1,0xba3f1ba4eb215204385107e76c11894b876ecf40,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,NameService,0xec6dce387b1616a0c44ff2e4fa9e90e53cf14eb0,1,0xba3f1ba4eb215204385107e76c11894b876ecf40,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,NameService,0xec6dce387b1616a0c44ff2e4fa9e90e53cf14eb0,1,0xba3f1ba4eb215204385107e76c11894b876ecf40,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,OneTimePayments,0xd9aa86e0ddb932bd78ab8c71c1b98f83cf610bd4,1,0xd9aa86e0ddb932bd78ab8c71c1b98f83cf610bd4,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,OneTimePayments,0xd9aa86e0ddb932bd78ab8c71c1b98f83cf610bd4,1,0xd9aa86e0ddb932bd78ab8c71c1b98f83cf610bd4,PaymentCancel,"PaymentCancel(address,address,uint256)",0xb1f6a8f6b8fb527cfeec0df589160bc2a92ff715097117cb250e823c7106bc2f,false,0,address address uint256,from paymentId amount,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,OneTimePayments,0xd9aa86e0ddb932bd78ab8c71c1b98f83cf610bd4,1,0xd9aa86e0ddb932bd78ab8c71c1b98f83cf610bd4,PaymentDeposit,"PaymentDeposit(address,address,uint256)",0x6c9f23ee41b34196a6e871314d55c3a0cce3399afc5d09755d171ea06547e073,false,0,address address uint256,from paymentId amount,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,OneTimePayments,0xd9aa86e0ddb932bd78ab8c71c1b98f83cf610bd4,1,0xd9aa86e0ddb932bd78ab8c71c1b98f83cf610bd4,PaymentWithdraw,"PaymentWithdraw(address,address,address,uint256)",0x39ca68a9f5d8038e871ef25a6622a56579cda4a6eedf63813574d23652e94048,false,0 1 2,address address address uint256,from to paymentId amount,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,ProxyAdmin,0x57179b2a8eb019157b0c3e761cdb26c82c982a3b,1,0x57179b2a8eb019157b0c3e761cdb26c82c982a3b,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,ProxyFactory,0xda85fced9bd193526b7667f2ad1fd4a0f900d3a7,1,0xda85fced9bd193526b7667f2ad1fd4a0f900d3a7,ContractCreated,ContractCreated(address),0xcf78cf0d6f3d8371e1075c69c492ab4ec5d8cf23a1a239b6a51a1d00be7ca312,false,,address,addr,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,ProxyFactory,0xda85fced9bd193526b7667f2ad1fd4a0f900d3a7,1,0xda85fced9bd193526b7667f2ad1fd4a0f900d3a7,ProxyCreated,ProxyCreated(address),0x00fffc2da0b561cae30d9826d37709e9421c4725faebc226cbbb7ef5fc5e7349,false,,address,proxy,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,1,0xfaa48a6b603985a507f18ad7f453f784f1faa025,ActivatedUser,ActivatedUser(address),0x2f9cfaa2a5c422dfab45f7d0da071f030fc2d3a7a1f0a255c028eff9b6d3d936,false,0,address,account,true,15747401,38729068,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,1,0xfaa48a6b603985a507f18ad7f453f784f1faa025,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,1,0xfaa48a6b603985a507f18ad7f453f784f1faa025,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,1,0xfaa48a6b603985a507f18ad7f453f784f1faa025,CycleLengthSet,CycleLengthSet(uint256),0xa61e6cca2c12e2a0a493683acfe95b034f0f50d793434f4dfe3ba06ea201f344,false,,uint256,newCycleLength,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,1,0xfaa48a6b603985a507f18ad7f453f784f1faa025,DaySet,DaySet(uint256),0x67eb03bd555181f9dd23f546e4331ddfb8b4a7d0c8d261ba44e037f30ce894ea,false,,uint256,newDay,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,1,0xfaa48a6b603985a507f18ad7f453f784f1faa025,InactiveUserFished,"InactiveUserFished(address,address,uint256)",0x3c91d315d82534112f8ce552cb79133a14191077a2d715fd65cabd026fc27c74,false,0 1,address address uint256,caller fished_account claimAmount,true,15747401,38729068,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,1,0xfaa48a6b603985a507f18ad7f453f784f1faa025,ShouldWithdrawFromDAOSet,ShouldWithdrawFromDAOSet(bool),0x6cd9a0fd2e006be39a9918bf56c85cae1d4f4599474483ff18cb93355ebaaf8e,false,,bool,ShouldWithdrawFromDAO,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,1,0xfaa48a6b603985a507f18ad7f453f784f1faa025,TotalFished,TotalFished(uint256),0x72b174db45b7e58932cb0c6bf37a7158f40424a078b07677d823cafdb3db540f,false,,uint256,total,true,15747401,38729068,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,1,0xfaa48a6b603985a507f18ad7f453f784f1faa025,UBICalculated,"UBICalculated(uint256,uint256,uint256)",0x836fa39995340265746dfe9587d9fe5c5de35b7bce778afd9b124ce1cfeafdc4,false,,uint256 uint256 uint256,day dailyUbi blockNumber,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,1,0xfaa48a6b603985a507f18ad7f453f784f1faa025,UBIClaimed,"UBIClaimed(address,uint256)",0x89ed24731df6b066e4c5186901fffdba18cd9a10f07494aff900bdee260d1304,false,0,address uint256,claimer amount,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,1,0xfaa48a6b603985a507f18ad7f453f784f1faa025,UBICycleCalculated,"UBICycleCalculated(uint256,uint256,uint256,uint256)",0x83e0d535b9e84324e0a25922406398d6ff5f96d0c686204ee490e16d7670566f,false,,uint256 uint256 uint256 uint256,day pool cycleLength dailyUBIPool,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,1,0xfaa48a6b603985a507f18ad7f453f784f1faa025,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,1,0xfaa48a6b603985a507f18ad7f453f784f1faa025,WithdrawFromDao,"WithdrawFromDao(uint256,uint256)",0x3107ec7eaa50b775d2486c7a394472235804b6fe1c0d4b7bd1d79b09df60f2ba,false,,uint256 uint256,prevBalance newBalance,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,2,0xf288e44c7e5baa05b2de9d916e53b67c183e46e0,ActivatedUser,ActivatedUser(address),0x2f9cfaa2a5c422dfab45f7d0da071f030fc2d3a7a1f0a255c028eff9b6d3d936,false,0,address,account,true,15747401,38729068,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,2,0xf288e44c7e5baa05b2de9d916e53b67c183e46e0,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,2,0xf288e44c7e5baa05b2de9d916e53b67c183e46e0,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,2,0xf288e44c7e5baa05b2de9d916e53b67c183e46e0,CycleLengthSet,CycleLengthSet(uint256),0xa61e6cca2c12e2a0a493683acfe95b034f0f50d793434f4dfe3ba06ea201f344,false,,uint256,newCycleLength,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,2,0xf288e44c7e5baa05b2de9d916e53b67c183e46e0,DaySet,DaySet(uint256),0x67eb03bd555181f9dd23f546e4331ddfb8b4a7d0c8d261ba44e037f30ce894ea,false,,uint256,newDay,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,2,0xf288e44c7e5baa05b2de9d916e53b67c183e46e0,InactiveUserFished,"InactiveUserFished(address,address,uint256)",0x3c91d315d82534112f8ce552cb79133a14191077a2d715fd65cabd026fc27c74,false,0 1,address address uint256,caller fished_account claimAmount,true,15747401,38729068,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,2,0xf288e44c7e5baa05b2de9d916e53b67c183e46e0,ShouldWithdrawFromDAOSet,ShouldWithdrawFromDAOSet(bool),0x6cd9a0fd2e006be39a9918bf56c85cae1d4f4599474483ff18cb93355ebaaf8e,false,,bool,ShouldWithdrawFromDAO,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,2,0xf288e44c7e5baa05b2de9d916e53b67c183e46e0,TotalFished,TotalFished(uint256),0x72b174db45b7e58932cb0c6bf37a7158f40424a078b07677d823cafdb3db540f,false,,uint256,total,true,15747401,38729068,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,2,0xf288e44c7e5baa05b2de9d916e53b67c183e46e0,UBICalculated,"UBICalculated(uint256,uint256,uint256)",0x836fa39995340265746dfe9587d9fe5c5de35b7bce778afd9b124ce1cfeafdc4,false,,uint256 uint256 uint256,day dailyUbi blockNumber,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,2,0xf288e44c7e5baa05b2de9d916e53b67c183e46e0,UBIClaimed,"UBIClaimed(address,uint256)",0x89ed24731df6b066e4c5186901fffdba18cd9a10f07494aff900bdee260d1304,false,0,address uint256,claimer amount,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,2,0xf288e44c7e5baa05b2de9d916e53b67c183e46e0,UBICycleCalculated,"UBICycleCalculated(uint256,uint256,uint256,uint256)",0x83e0d535b9e84324e0a25922406398d6ff5f96d0c686204ee490e16d7670566f,false,,uint256 uint256 uint256 uint256,day pool cycleLength dailyUBIPool,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,2,0xf288e44c7e5baa05b2de9d916e53b67c183e46e0,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,2,0xf288e44c7e5baa05b2de9d916e53b67c183e46e0,WithdrawFromDao,"WithdrawFromDao(uint256,uint256)",0x3107ec7eaa50b775d2486c7a394472235804b6fe1c0d4b7bd1d79b09df60f2ba,false,,uint256 uint256,prevBalance newBalance,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,3,0x0d7014649e6f5979d2a09a3d3ad2d3ae3eefb42e,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,3,0x0d7014649e6f5979d2a09a3d3ad2d3ae3eefb42e,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,3,0x0d7014649e6f5979d2a09a3d3ad2d3ae3eefb42e,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,4,0x8294378a45b52389d45b623d0191f7285f4f047f,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,4,0x8294378a45b52389d45b623d0191f7285f4f047f,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,4,0x8294378a45b52389d45b623d0191f7285f4f047f,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,5,0xa99ba154223052b8c5fd92b3f5df9eb08b72d5fc,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,5,0xa99ba154223052b8c5fd92b3f5df9eb08b72d5fc,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,5,0xa99ba154223052b8c5fd92b3f5df9eb08b72d5fc,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,6,0x8294378a45b52389d45b623d0191f7285f4f047f,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,6,0x8294378a45b52389d45b623d0191f7285f4f047f,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,6,0x8294378a45b52389d45b623d0191f7285f4f047f,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,7,0x76eb96616514adac35152155bbc614272f0601b3,ActivatedUser,ActivatedUser(address),0x2f9cfaa2a5c422dfab45f7d0da071f030fc2d3a7a1f0a255c028eff9b6d3d936,false,0,address,account,true,15747401,38729068,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,7,0x76eb96616514adac35152155bbc614272f0601b3,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,7,0x76eb96616514adac35152155bbc614272f0601b3,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,7,0x76eb96616514adac35152155bbc614272f0601b3,CycleLengthSet,CycleLengthSet(uint256),0xa61e6cca2c12e2a0a493683acfe95b034f0f50d793434f4dfe3ba06ea201f344,false,,uint256,newCycleLength,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,7,0x76eb96616514adac35152155bbc614272f0601b3,DaySet,DaySet(uint256),0x67eb03bd555181f9dd23f546e4331ddfb8b4a7d0c8d261ba44e037f30ce894ea,false,,uint256,newDay,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,7,0x76eb96616514adac35152155bbc614272f0601b3,InactiveUserFished,"InactiveUserFished(address,address,uint256)",0x3c91d315d82534112f8ce552cb79133a14191077a2d715fd65cabd026fc27c74,false,0 1,address address uint256,caller fished_account claimAmount,true,15747401,38729068,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,7,0x76eb96616514adac35152155bbc614272f0601b3,ShouldWithdrawFromDAOSet,ShouldWithdrawFromDAOSet(bool),0x6cd9a0fd2e006be39a9918bf56c85cae1d4f4599474483ff18cb93355ebaaf8e,false,,bool,ShouldWithdrawFromDAO,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,7,0x76eb96616514adac35152155bbc614272f0601b3,TotalFished,TotalFished(uint256),0x72b174db45b7e58932cb0c6bf37a7158f40424a078b07677d823cafdb3db540f,false,,uint256,total,true,15747401,38729068,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,7,0x76eb96616514adac35152155bbc614272f0601b3,UBICalculated,"UBICalculated(uint256,uint256,uint256)",0x836fa39995340265746dfe9587d9fe5c5de35b7bce778afd9b124ce1cfeafdc4,false,,uint256 uint256 uint256,day dailyUbi blockNumber,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,7,0x76eb96616514adac35152155bbc614272f0601b3,UBIClaimed,"UBIClaimed(address,uint256)",0x89ed24731df6b066e4c5186901fffdba18cd9a10f07494aff900bdee260d1304,false,0,address uint256,claimer amount,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,7,0x76eb96616514adac35152155bbc614272f0601b3,UBICycleCalculated,"UBICycleCalculated(uint256,uint256,uint256,uint256)",0x83e0d535b9e84324e0a25922406398d6ff5f96d0c686204ee490e16d7670566f,false,,uint256 uint256 uint256 uint256,day pool cycleLength dailyUBIPool,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,7,0x76eb96616514adac35152155bbc614272f0601b3,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,7,0x76eb96616514adac35152155bbc614272f0601b3,WithdrawFromDao,"WithdrawFromDao(uint256,uint256)",0x3107ec7eaa50b775d2486c7a394472235804b6fe1c0d4b7bd1d79b09df60f2ba,false,,uint256 uint256,prevBalance newBalance,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,8,0x11f077ae87952948de96b975a805ebaa20eada12,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,8,0x11f077ae87952948de96b975a805ebaa20eada12,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,8,0x11f077ae87952948de96b975a805ebaa20eada12,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,9,0x306cd90bfefb7e409f089a1bde1aa77bbc4cb660,ActivatedUser,ActivatedUser(address),0x2f9cfaa2a5c422dfab45f7d0da071f030fc2d3a7a1f0a255c028eff9b6d3d936,false,0,address,account,true,15747401,38729068,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,9,0x306cd90bfefb7e409f089a1bde1aa77bbc4cb660,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,9,0x306cd90bfefb7e409f089a1bde1aa77bbc4cb660,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,9,0x306cd90bfefb7e409f089a1bde1aa77bbc4cb660,CycleLengthSet,CycleLengthSet(uint256),0xa61e6cca2c12e2a0a493683acfe95b034f0f50d793434f4dfe3ba06ea201f344,false,,uint256,newCycleLength,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,9,0x306cd90bfefb7e409f089a1bde1aa77bbc4cb660,DaySet,DaySet(uint256),0x67eb03bd555181f9dd23f546e4331ddfb8b4a7d0c8d261ba44e037f30ce894ea,false,,uint256,newDay,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,9,0x306cd90bfefb7e409f089a1bde1aa77bbc4cb660,InactiveUserFished,"InactiveUserFished(address,address,uint256)",0x3c91d315d82534112f8ce552cb79133a14191077a2d715fd65cabd026fc27c74,false,0 1,address address uint256,caller fished_account claimAmount,true,15747401,38729068,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,9,0x306cd90bfefb7e409f089a1bde1aa77bbc4cb660,ShouldWithdrawFromDAOSet,ShouldWithdrawFromDAOSet(bool),0x6cd9a0fd2e006be39a9918bf56c85cae1d4f4599474483ff18cb93355ebaaf8e,false,,bool,ShouldWithdrawFromDAO,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,9,0x306cd90bfefb7e409f089a1bde1aa77bbc4cb660,TotalFished,TotalFished(uint256),0x72b174db45b7e58932cb0c6bf37a7158f40424a078b07677d823cafdb3db540f,false,,uint256,total,true,15747401,38729068,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,9,0x306cd90bfefb7e409f089a1bde1aa77bbc4cb660,UBICalculated,"UBICalculated(uint256,uint256,uint256)",0x836fa39995340265746dfe9587d9fe5c5de35b7bce778afd9b124ce1cfeafdc4,false,,uint256 uint256 uint256,day dailyUbi blockNumber,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,9,0x306cd90bfefb7e409f089a1bde1aa77bbc4cb660,UBIClaimed,"UBIClaimed(address,uint256)",0x89ed24731df6b066e4c5186901fffdba18cd9a10f07494aff900bdee260d1304,false,0,address uint256,claimer amount,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,9,0x306cd90bfefb7e409f089a1bde1aa77bbc4cb660,UBICycleCalculated,"UBICycleCalculated(uint256,uint256,uint256,uint256)",0x83e0d535b9e84324e0a25922406398d6ff5f96d0c686204ee490e16d7670566f,false,,uint256 uint256 uint256 uint256,day pool cycleLength dailyUBIPool,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,9,0x306cd90bfefb7e409f089a1bde1aa77bbc4cb660,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,9,0x306cd90bfefb7e409f089a1bde1aa77bbc4cb660,WithdrawFromDao,"WithdrawFromDao(uint256,uint256)",0x3107ec7eaa50b775d2486c7a394472235804b6fe1c0d4b7bd1d79b09df60f2ba,false,,uint256 uint256,prevBalance newBalance,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,10,0xb22764dce0960b61c5a8d688f075857632917a93,ActivatedUser,ActivatedUser(address),0x2f9cfaa2a5c422dfab45f7d0da071f030fc2d3a7a1f0a255c028eff9b6d3d936,false,0,address,account,true,15747401,38729068,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,10,0xb22764dce0960b61c5a8d688f075857632917a93,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,10,0xb22764dce0960b61c5a8d688f075857632917a93,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,10,0xb22764dce0960b61c5a8d688f075857632917a93,CycleLengthSet,CycleLengthSet(uint256),0xa61e6cca2c12e2a0a493683acfe95b034f0f50d793434f4dfe3ba06ea201f344,false,,uint256,newCycleLength,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,10,0xb22764dce0960b61c5a8d688f075857632917a93,DaySet,DaySet(uint256),0x67eb03bd555181f9dd23f546e4331ddfb8b4a7d0c8d261ba44e037f30ce894ea,false,,uint256,newDay,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,10,0xb22764dce0960b61c5a8d688f075857632917a93,InactiveUserFished,"InactiveUserFished(address,address,uint256)",0x3c91d315d82534112f8ce552cb79133a14191077a2d715fd65cabd026fc27c74,false,0 1,address address uint256,caller fished_account claimAmount,true,15747401,38729068,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,10,0xb22764dce0960b61c5a8d688f075857632917a93,ShouldWithdrawFromDAOSet,ShouldWithdrawFromDAOSet(bool),0x6cd9a0fd2e006be39a9918bf56c85cae1d4f4599474483ff18cb93355ebaaf8e,false,,bool,ShouldWithdrawFromDAO,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,10,0xb22764dce0960b61c5a8d688f075857632917a93,TotalFished,TotalFished(uint256),0x72b174db45b7e58932cb0c6bf37a7158f40424a078b07677d823cafdb3db540f,false,,uint256,total,true,15747401,38729068,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,10,0xb22764dce0960b61c5a8d688f075857632917a93,UBICalculated,"UBICalculated(uint256,uint256,uint256)",0x836fa39995340265746dfe9587d9fe5c5de35b7bce778afd9b124ce1cfeafdc4,false,,uint256 uint256 uint256,day dailyUbi blockNumber,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,10,0xb22764dce0960b61c5a8d688f075857632917a93,UBIClaimed,"UBIClaimed(address,uint256)",0x89ed24731df6b066e4c5186901fffdba18cd9a10f07494aff900bdee260d1304,false,0,address uint256,claimer amount,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,10,0xb22764dce0960b61c5a8d688f075857632917a93,UBICycleCalculated,"UBICycleCalculated(uint256,uint256,uint256,uint256)",0x83e0d535b9e84324e0a25922406398d6ff5f96d0c686204ee490e16d7670566f,false,,uint256 uint256 uint256 uint256,day pool cycleLength dailyUBIPool,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,10,0xb22764dce0960b61c5a8d688f075857632917a93,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,10,0xb22764dce0960b61c5a8d688f075857632917a93,WithdrawFromDao,"WithdrawFromDao(uint256,uint256)",0x3107ec7eaa50b775d2486c7a394472235804b6fe1c0d4b7bd1d79b09df60f2ba,false,,uint256 uint256,prevBalance newBalance,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,11,0xbb6dff610ecbea25a6c57b086ef92c6724306a76,ActivatedUser,ActivatedUser(address),0x2f9cfaa2a5c422dfab45f7d0da071f030fc2d3a7a1f0a255c028eff9b6d3d936,false,0,address,account,true,15747401,38729068,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,11,0xbb6dff610ecbea25a6c57b086ef92c6724306a76,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,11,0xbb6dff610ecbea25a6c57b086ef92c6724306a76,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,11,0xbb6dff610ecbea25a6c57b086ef92c6724306a76,CycleLengthSet,CycleLengthSet(uint256),0xa61e6cca2c12e2a0a493683acfe95b034f0f50d793434f4dfe3ba06ea201f344,false,,uint256,newCycleLength,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,11,0xbb6dff610ecbea25a6c57b086ef92c6724306a76,DaySet,DaySet(uint256),0x67eb03bd555181f9dd23f546e4331ddfb8b4a7d0c8d261ba44e037f30ce894ea,false,,uint256,newDay,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,11,0xbb6dff610ecbea25a6c57b086ef92c6724306a76,InactiveUserFished,"InactiveUserFished(address,address,uint256)",0x3c91d315d82534112f8ce552cb79133a14191077a2d715fd65cabd026fc27c74,false,0 1,address address uint256,caller fished_account claimAmount,true,15747401,38729068,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,11,0xbb6dff610ecbea25a6c57b086ef92c6724306a76,ShouldWithdrawFromDAOSet,ShouldWithdrawFromDAOSet(bool),0x6cd9a0fd2e006be39a9918bf56c85cae1d4f4599474483ff18cb93355ebaaf8e,false,,bool,ShouldWithdrawFromDAO,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,11,0xbb6dff610ecbea25a6c57b086ef92c6724306a76,TotalFished,TotalFished(uint256),0x72b174db45b7e58932cb0c6bf37a7158f40424a078b07677d823cafdb3db540f,false,,uint256,total,true,15747401,38729068,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,11,0xbb6dff610ecbea25a6c57b086ef92c6724306a76,UBICalculated,"UBICalculated(uint256,uint256,uint256)",0x836fa39995340265746dfe9587d9fe5c5de35b7bce778afd9b124ce1cfeafdc4,false,,uint256 uint256 uint256,day dailyUbi blockNumber,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,11,0xbb6dff610ecbea25a6c57b086ef92c6724306a76,UBIClaimed,"UBIClaimed(address,uint256)",0x89ed24731df6b066e4c5186901fffdba18cd9a10f07494aff900bdee260d1304,false,0,address uint256,claimer amount,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,11,0xbb6dff610ecbea25a6c57b086ef92c6724306a76,UBICycleCalculated,"UBICycleCalculated(uint256,uint256,uint256,uint256)",0x83e0d535b9e84324e0a25922406398d6ff5f96d0c686204ee490e16d7670566f,false,,uint256 uint256 uint256 uint256,day pool cycleLength dailyUBIPool,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,11,0xbb6dff610ecbea25a6c57b086ef92c6724306a76,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,11,0xbb6dff610ecbea25a6c57b086ef92c6724306a76,WithdrawFromDao,"WithdrawFromDao(uint256,uint256)",0x3107ec7eaa50b775d2486c7a394472235804b6fe1c0d4b7bd1d79b09df60f2ba,false,,uint256 uint256,prevBalance newBalance,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,12,0x1c90f733e1724bd1db47f84cde4f9e83087cfb6d,ActivatedUser,ActivatedUser(address),0x2f9cfaa2a5c422dfab45f7d0da071f030fc2d3a7a1f0a255c028eff9b6d3d936,false,0,address,account,true,15747401,38729068,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,12,0x1c90f733e1724bd1db47f84cde4f9e83087cfb6d,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,12,0x1c90f733e1724bd1db47f84cde4f9e83087cfb6d,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,12,0x1c90f733e1724bd1db47f84cde4f9e83087cfb6d,CycleLengthSet,CycleLengthSet(uint256),0xa61e6cca2c12e2a0a493683acfe95b034f0f50d793434f4dfe3ba06ea201f344,false,,uint256,newCycleLength,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,12,0x1c90f733e1724bd1db47f84cde4f9e83087cfb6d,DaySet,DaySet(uint256),0x67eb03bd555181f9dd23f546e4331ddfb8b4a7d0c8d261ba44e037f30ce894ea,false,,uint256,newDay,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,12,0x1c90f733e1724bd1db47f84cde4f9e83087cfb6d,InactiveUserFished,"InactiveUserFished(address,address,uint256)",0x3c91d315d82534112f8ce552cb79133a14191077a2d715fd65cabd026fc27c74,false,0 1,address address uint256,caller fished_account claimAmount,true,15747401,38729068,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,12,0x1c90f733e1724bd1db47f84cde4f9e83087cfb6d,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,25635053,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 12,13 of 13" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,12,0x1c90f733e1724bd1db47f84cde4f9e83087cfb6d,ShouldWithdrawFromDAOSet,ShouldWithdrawFromDAOSet(bool),0x6cd9a0fd2e006be39a9918bf56c85cae1d4f4599474483ff18cb93355ebaaf8e,false,,bool,ShouldWithdrawFromDAO,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,12,0x1c90f733e1724bd1db47f84cde4f9e83087cfb6d,TotalFished,TotalFished(uint256),0x72b174db45b7e58932cb0c6bf37a7158f40424a078b07677d823cafdb3db540f,false,,uint256,total,true,15747401,38729068,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,12,0x1c90f733e1724bd1db47f84cde4f9e83087cfb6d,UBICalculated,"UBICalculated(uint256,uint256,uint256)",0x836fa39995340265746dfe9587d9fe5c5de35b7bce778afd9b124ce1cfeafdc4,false,,uint256 uint256 uint256,day dailyUbi blockNumber,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,12,0x1c90f733e1724bd1db47f84cde4f9e83087cfb6d,UBIClaimed,"UBIClaimed(address,uint256)",0x89ed24731df6b066e4c5186901fffdba18cd9a10f07494aff900bdee260d1304,false,0,address uint256,claimer amount,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,12,0x1c90f733e1724bd1db47f84cde4f9e83087cfb6d,UBICycleCalculated,"UBICycleCalculated(uint256,uint256,uint256,uint256)",0x83e0d535b9e84324e0a25922406398d6ff5f96d0c686204ee490e16d7670566f,false,,uint256 uint256 uint256 uint256,day pool cycleLength dailyUBIPool,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,12,0x1c90f733e1724bd1db47f84cde4f9e83087cfb6d,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,12,0x1c90f733e1724bd1db47f84cde4f9e83087cfb6d,WithdrawFromDao,"WithdrawFromDao(uint256,uint256)",0x3107ec7eaa50b775d2486c7a394472235804b6fe1c0d4b7bd1d79b09df60f2ba,false,,uint256 uint256,prevBalance newBalance,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,13,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,13,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,13,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,CycleLengthSet,CycleLengthSet(uint256),0xa61e6cca2c12e2a0a493683acfe95b034f0f50d793434f4dfe3ba06ea201f344,false,,uint256,newCycleLength,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,13,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,DaySet,DaySet(uint256),0x67eb03bd555181f9dd23f546e4331ddfb8b4a7d0c8d261ba44e037f30ce894ea,false,,uint256,newDay,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,13,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,25635053,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 12,13 of 13" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,13,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,ShouldWithdrawFromDAOSet,ShouldWithdrawFromDAOSet(bool),0x6cd9a0fd2e006be39a9918bf56c85cae1d4f4599474483ff18cb93355ebaaf8e,false,,bool,ShouldWithdrawFromDAO,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,13,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,UBICalculated,"UBICalculated(uint256,uint256,uint256)",0x836fa39995340265746dfe9587d9fe5c5de35b7bce778afd9b124ce1cfeafdc4,false,,uint256 uint256 uint256,day dailyUbi blockNumber,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,13,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,UBIClaimed,"UBIClaimed(address,uint256)",0x89ed24731df6b066e4c5186901fffdba18cd9a10f07494aff900bdee260d1304,false,0,address uint256,claimer amount,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,13,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,UBICycleCalculated,"UBICycleCalculated(uint256,uint256,uint256,uint256)",0x83e0d535b9e84324e0a25922406398d6ff5f96d0c686204ee490e16d7670566f,false,,uint256 uint256 uint256 uint256,day pool cycleLength dailyUBIPool,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,13,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +FUSE,122,UBIScheme,0xd253a5203817225e9768c05e5996d642fb96ba86,13,0xc41d596a21965c8a28c1ae43ee8a0d2e66c4d961,WithdrawFromDao,"WithdrawFromDao(uint256,uint256)",0x3107ec7eaa50b775d2486c7a394472235804b6fe1c0d4b7bd1d79b09df60f2ba,false,,uint256 uint256,prevBalance newBalance,true,15747401,9223372036854775807,blockscout_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 1,2,7,9,10,11,12,13 of 13. NOT CONTIGUOUS: Removed and later restored" +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,1,0xa7f4717bf6e7d27d7c855d5f4a869e96bd16d873,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,1,0xa7f4717bf6e7d27d7c855d5f4a869e96bd16d873,AdminsAdded,AdminsAdded(address[]),0x45486b220020cc2482ad1a5e0ae4d5f0b5372cea1b48173f6273c616a5047269,false,0,address[],admins,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,1,0xa7f4717bf6e7d27d7c855d5f4a869e96bd16d873,AdminsRemoved,AdminsRemoved(address[]),0xd5e6894641b5030a67e637ab2e12da64d8aec689f8bd1328de2b04d6a439c810,false,0,address[],admins,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,1,0xa7f4717bf6e7d27d7c855d5f4a869e96bd16d873,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,1,0xa7f4717bf6e7d27d7c855d5f4a869e96bd16d873,GenericCall,"GenericCall(address,bytes,uint256,bool)",0x534b52c783549f909f9e743120524d0b7154058e4a54cdc895c2c0b587a1c7e0,false,0,address bytes uint256 bool,_contract _data _value _success,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,1,0xa7f4717bf6e7d27d7c855d5f4a869e96bd16d873,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,1,0xa7f4717bf6e7d27d7c855d5f4a869e96bd16d873,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,1,0xa7f4717bf6e7d27d7c855d5f4a869e96bd16d873,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,1,0xa7f4717bf6e7d27d7c855d5f4a869e96bd16d873,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,1,0xa7f4717bf6e7d27d7c855d5f4a869e96bd16d873,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,1,0xa7f4717bf6e7d27d7c855d5f4a869e96bd16d873,WalletTopped,"WalletTopped(address,uint256)",0xf60e56b8021f6ac77bd50d4acdbed9ad9e85107144d43090774a9ebe5ffed985,false,0,address uint256,user amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,2,0x68dbe795ee2219437299bb23d70311e3b7c69f9a,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,2,0x68dbe795ee2219437299bb23d70311e3b7c69f9a,AdminsAdded,AdminsAdded(address[]),0x45486b220020cc2482ad1a5e0ae4d5f0b5372cea1b48173f6273c616a5047269,false,0,address[],admins,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,2,0x68dbe795ee2219437299bb23d70311e3b7c69f9a,AdminsRemoved,AdminsRemoved(address[]),0xd5e6894641b5030a67e637ab2e12da64d8aec689f8bd1328de2b04d6a439c810,false,0,address[],admins,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,2,0x68dbe795ee2219437299bb23d70311e3b7c69f9a,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,2,0x68dbe795ee2219437299bb23d70311e3b7c69f9a,GenericCall,"GenericCall(address,bytes,uint256,bool)",0x534b52c783549f909f9e743120524d0b7154058e4a54cdc895c2c0b587a1c7e0,false,0,address bytes uint256 bool,_contract _data _value _success,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,2,0x68dbe795ee2219437299bb23d70311e3b7c69f9a,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,2,0x68dbe795ee2219437299bb23d70311e3b7c69f9a,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,2,0x68dbe795ee2219437299bb23d70311e3b7c69f9a,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,2,0x68dbe795ee2219437299bb23d70311e3b7c69f9a,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,2,0x68dbe795ee2219437299bb23d70311e3b7c69f9a,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,AdminWallet,0x66fc1be551f752706130b6f54d84141f8c2ae8bb,2,0x68dbe795ee2219437299bb23d70311e3b7c69f9a,WalletTopped,"WalletTopped(address,uint256)",0xf60e56b8021f6ac77bd50d4acdbed9ad9e85107144d43090774a9ebe5ffed985,false,0,address uint256,user amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Avatar,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,1,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,ExternalTokenApproval,"ExternalTokenApproval(address,address,uint256)",0x3a48a4d6253b30fd10e57a347c1f9bcb0604946481fae0b2fdad6e74f2a9cbb3,false,0,address address uint256,_externalToken _spender _value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Avatar,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,1,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,ExternalTokenTransfer,"ExternalTokenTransfer(address,address,uint256)",0x49dc2a60d2599a7b6932d78fb694c30dfc596fe4e0282b5d0fd184b52472c04d,false,0 1,address address uint256,_externalToken _to _value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Avatar,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,1,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,ExternalTokenTransferFrom,"ExternalTokenTransferFrom(address,address,address,uint256)",0x179c15de44aa7ab84896301974328eb40b5b40fe01cfe0fee2924ea712c3e843,false,0,address address address uint256,_externalToken _from _to _value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Avatar,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,1,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,GenericCall,"GenericCall(address,bytes,uint256,bool)",0x534b52c783549f909f9e743120524d0b7154058e4a54cdc895c2c0b587a1c7e0,false,0,address bytes uint256 bool,_contract _data _value _success,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Avatar,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,1,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,MetaData,MetaData(string),0xf9deba4938ba20070ec5a45ddf59bccba49cf83124215228ec1232182ef0ba2b,false,,string,_metaData,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Avatar,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,1,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Avatar,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,1,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,ReceiveEther,"ReceiveEther(address,uint256)",0xf32a9f77675fd5917534c7746608fd3e309eac68fbdcbf5925e24ca97a704396,false,0,address uint256,_sender _value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Avatar,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,1,0x21eac3fe218307bee0463f77ebca3b50f452c0ce,SendEther,"SendEther(uint256,address)",0x22fca66666089f39bc900dd6605b489df4aae6260cc8ea8257594cfb8c84926c,false,1,uint256 address,_amountInWei _to,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Controller,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,1,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,AddGlobalConstraint,"AddGlobalConstraint(address,bytes32,uint8)",0x78800d7333b8d0174a0845569e3913b7ce4a3c03ca444dd9904172fc14f2fdad,false,0,address bytes32 uint8,_globalConstraint _params _when,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Controller,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,1,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,BurnReputation,"BurnReputation(address,address,uint256)",0x186d8887e1b22f9d9b16849c36baa748950d09d9c9b67a4a6ea140eaad00c21c,false,0 1,address address uint256,_sender _from _amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Controller,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,1,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,MintReputation,"MintReputation(address,address,uint256)",0x837f2931e3df0592458212be4e470025f197feb7a8e39deb5b7f1f1d42e6f262,false,0 1,address address uint256,_sender _to _amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Controller,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,1,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,MintTokens,"MintTokens(address,address,uint256)",0x21f9c9a1a1f9a311a50f15fec5c1faa9e21fc9edf964f0fdecba5bd490484c5e,false,0 1,address address uint256,_sender _beneficiary _amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Controller,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,1,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,RegisterScheme,"RegisterScheme(address,address)",0x546816e99403df442acb68ef69562682a50762c20a3fb6b472f7af9923736cfc,false,0 1,address address,_sender _scheme,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Controller,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,1,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,RemoveGlobalConstraint,"RemoveGlobalConstraint(address,uint256,bool)",0xcdf1a50ea6b7de555bd409f8a4a53ea43c6dc6b4caa961889da9e005f21bbaa9,false,0,address uint256 bool,_globalConstraint _index _isPre,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Controller,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,1,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,UnregisterScheme,"UnregisterScheme(address,address)",0x10bb2cf04cb8b902a8e736d494f1a51003be6d4b16ef6fb95ce62c38445023bf,false,0 1,address address,_sender _scheme,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Controller,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,1,0x75a8be0c2deaded8fc9eceb5f01ad0b979b7ad03,UpgradeController,"UpgradeController(address,address)",0xdb7cbacf8df312d794506c0cc9af07f64d29ca075796ea2e950a3832cc9a63dd,false,0,address address,_oldController _newController,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,CUSD,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,1,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,CUSD,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,1,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,CUSD,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,1,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,AuthorizationCanceled,"AuthorizationCanceled(address,bytes32)",0x1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d81,false,0 1,address bytes32,authorizer nonce,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,CUSD,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,1,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,AuthorizationUsed,"AuthorizationUsed(address,bytes32)",0x98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a5,false,0 1,address bytes32,authorizer nonce,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,CUSD,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,1,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,Blacklisted,Blacklisted(address),0xffa4e6181777692565cf28528fc88fd1516ea86b56da075235fa575af6a4b855,false,0,address,_account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,CUSD,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,1,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,BlacklisterChanged,BlacklisterChanged(address),0xc67398012c111ce95ecb7429b933096c977380ee6c421175a71a4a4c6c88c06e,false,0,address,newBlacklister,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,CUSD,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,1,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,Burn,"Burn(address,uint256)",0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5,false,0,address uint256,burner amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,CUSD,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,1,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,MasterMinterChanged,MasterMinterChanged(address),0xdb66dfa9c6b8f5226fe9aac7e51897ae8ee94ac31dc70bb6c9900b2574b707e6,false,0,address,newMasterMinter,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,CUSD,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,1,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,Mint,"Mint(address,address,uint256)",0xab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f8,false,0 1,address address uint256,minter to amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,CUSD,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,1,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,MinterConfigured,"MinterConfigured(address,uint256)",0x46980fca912ef9bcdbd36877427b6b90e860769f604e89c0e67720cece530d20,false,0,address uint256,minter minterAllowedAmount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,CUSD,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,1,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,MinterRemoved,MinterRemoved(address),0xe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb66692,false,0,address,oldMinter,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,CUSD,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,1,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,CUSD,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,1,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,Pause,Pause(),0x6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff625,false,,,,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,CUSD,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,1,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,PauserChanged,PauserChanged(address),0xb80482a293ca2e013eda8683c9bd7fc8347cfdaeea5ede58cba46df502c2a604,false,0,address,newAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,CUSD,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,1,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,RescuerChanged,RescuerChanged(address),0xe475e580d85111348e40d8ca33cfdd74c30fe1655c2d8537a13abc10065ffa5a,false,0,address,newRescuer,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,CUSD,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,1,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,CUSD,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,1,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,UnBlacklisted,UnBlacklisted(address),0x117e3210bb9aa7d9baff172026820255c6f6c30ba8999d1c2fd88e2848137c4e,false,0,address,_account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,CUSD,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,1,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,Unpause,Unpause(),0x7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b33,false,,,,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,CUSD,0xfa2958cb79b0491cc627c1557f441ef849ca8eb1,1,0x9ddb959f04b7075aaccd28e2e5c5c113469c534b,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,DistributionHelper,0xb8a0d4b97327a0b6dd0705dc290ae26aa38a7d2b,1,0x971fdacd201cdaa741db06d580eb634b02307926,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,DistributionHelper,0xb8a0d4b97327a0b6dd0705dc290ae26aa38a7d2b,1,0x971fdacd201cdaa741db06d580eb634b02307926,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,DistributionHelper,0xb8a0d4b97327a0b6dd0705dc290ae26aa38a7d2b,1,0x971fdacd201cdaa741db06d580eb634b02307926,BuyNativeFailed,"BuyNativeFailed(string,uint256,uint256)",0x1c337a8467703b7dbf7a278074870cb1a1f993ef69d022192ba360567703098f,false,,string uint256 uint256,reason amountToSell amountOutMinimum,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,DistributionHelper,0xb8a0d4b97327a0b6dd0705dc290ae26aa38a7d2b,1,0x971fdacd201cdaa741db06d580eb634b02307926,Distribution,"Distribution(uint256,uint256,uint256,(uint32,uint32,address,uint8)[],uint256,uint256)",0xdbd53b67dd15f9594eee6de294654de25af4c2a14d79d76e47d08d83c8025f5d,false,,"uint256 uint256 uint256 (uint32,uint32,address,uint8)[] uint256 uint256",distributed startingBalance incomingAmount distributionRecipients gdSoldForGas nativeBoughtForGas,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,DistributionHelper,0xb8a0d4b97327a0b6dd0705dc290ae26aa38a7d2b,1,0x971fdacd201cdaa741db06d580eb634b02307926,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,DistributionHelper,0xb8a0d4b97327a0b6dd0705dc290ae26aa38a7d2b,1,0x971fdacd201cdaa741db06d580eb634b02307926,RecipientAdded,"RecipientAdded((uint32,uint32,address,uint8),uint256)",0x2e65f65347b2e76218df0b7b6b594a3862c81e85706795e700237093c47a3957,false,,"(uint32,uint32,address,uint8) uint256",recipient index,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,DistributionHelper,0xb8a0d4b97327a0b6dd0705dc290ae26aa38a7d2b,1,0x971fdacd201cdaa741db06d580eb634b02307926,RecipientUpdated,"RecipientUpdated((uint32,uint32,address,uint8),uint256)",0xd26d9de175cfca2c3e0cad9d09c85f0ce6c7fa5257382d00dc26dc5fb25cd8df,false,,"(uint32,uint32,address,uint8) uint256",recipient index,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,DistributionHelper,0xb8a0d4b97327a0b6dd0705dc290ae26aa38a7d2b,1,0x971fdacd201cdaa741db06d580eb634b02307926,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,DistributionHelper,0xb8a0d4b97327a0b6dd0705dc290ae26aa38a7d2b,1,0x971fdacd201cdaa741db06d580eb634b02307926,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,DistributionHelper,0xb8a0d4b97327a0b6dd0705dc290ae26aa38a7d2b,1,0x971fdacd201cdaa741db06d580eb634b02307926,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,DistributionHelper,0xb8a0d4b97327a0b6dd0705dc290ae26aa38a7d2b,1,0x971fdacd201cdaa741db06d580eb634b02307926,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,1,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,1,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,1,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,1,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,1,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,1,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,1,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,1,0x9fc57c2aa7230ff041a39c64c67e3d38c3c6621a,WalletTopped,"WalletTopped(address,uint256,address,address)",0x7872034fbcc87890e73d66eac55389e0ffdba157b89a73bd2011157ebac1d66e,false,0 3,address uint256 address address,account amount whitelistedRoot relayerOrWhitelisted,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,2,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,2,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,2,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,2,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,2,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,2,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,2,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,2,0xb6739a9dd61b0deff7cfb24cad220d70f948dbee,WalletTopped,"WalletTopped(address,uint256,address,address)",0x7872034fbcc87890e73d66eac55389e0ffdba157b89a73bd2011157ebac1d66e,false,0 3,address uint256 address address,account amount whitelistedRoot relayerOrWhitelisted,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,3,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,3,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,3,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,3,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,3,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,3,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,3,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Faucet,0x7344da1be296f03fbb8082adac5696058b5a9bd9,3,0x1c3e0cfb6c316188789ad7f4c1e2fd56dd902214,WalletTopped,"WalletTopped(address,uint256,address,address)",0x7872034fbcc87890e73d66eac55389e0ffdba157b89a73bd2011157ebac1d66e,false,0 3,address uint256 address address,account amount whitelistedRoot relayerOrWhitelisted,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,FeeFormula,0xf4e9af892a09f04b7408266777198206e7f80d46,1,0xf4e9af892a09f04b7408266777198206e7f80d46,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,AgreementCreated,"AgreementCreated(address,bytes32,bytes32[])",0x770ea40a13a4644573ed785e5c7116890709947918747febc5add46feb531e2d,false,0,address bytes32 bytes32[],agreementClass id data,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,AgreementLiquidated,"AgreementLiquidated(address,bytes32,address,address,uint256)",0x8505c3d8f1f184f032cf0bc4cd80ee61c8b9d94f8907c3281bf0101a2610fe80,false,0 2 3,address bytes32 address address uint256,agreementClass id penaltyAccount rewardAccount rewardAmount,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,AgreementLiquidatedBy,"AgreementLiquidatedBy(address,address,bytes32,address,address,uint256,uint256)",0x5f22b60e58b1d6de858bc27c48d5a4653e052da99e083c1d88bb8c58e1abc8ef,false,1 3 4,address address bytes32 address address uint256 uint256,liquidatorAccount agreementClass id penaltyAccount bondAccount rewardAmount bailoutAmount,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,AgreementLiquidatedV2,"AgreementLiquidatedV2(address,bytes32,address,address,address,uint256,int256,bytes)",0xb8381a3ce157650e06186e3e8f4dd4dc29236f2688b6eed1893d0a60d7c6386f,false,0 2 3,address bytes32 address address address uint256 int256 bytes,agreementClass id liquidatorAccount targetAccount rewardAmountReceiver rewardAmount targetAccountBalanceDelta liquidationTypeData,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,AgreementStateUpdated,"AgreementStateUpdated(address,address,uint256)",0x30f416fa68fca014a0f334464c64b000ba53e99b6d2afdea9d5ca756372d5985,false,0 1,address address uint256,agreementClass account slotId,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,AgreementTerminated,"AgreementTerminated(address,bytes32)",0x71a63dc095de07aa5512ad57a7596a39516317e316981a1cd71000057be1537b,false,0,address bytes32,agreementClass id,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,AgreementUpdated,"AgreementUpdated(address,bytes32,bytes32[])",0x0c4c547b3a4fcaa5be8353b3111472b124155bccc86de811d4a481c9e6e9faca,false,0,address bytes32 bytes32[],agreementClass id data,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,AuthorizedOperator,"AuthorizedOperator(address,address)",0xf4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f9,false,0 1,address address,operator tokenHolder,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,Bailout,"Bailout(address,uint256)",0xd6c9a04afc81e8c614310bbee6c9e84f5abe15b82038bf8347014ce0852e6ffd,false,0,address uint256,bailoutAccount bailoutAmount,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,Burned,"Burned(address,address,uint256,bytes,bytes)",0xa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098,false,0 1,address address uint256 bytes bytes,operator from amount data operatorData,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,Minted,"Minted(address,address,uint256,bytes,bytes)",0x2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d,false,0 1,address address uint256 bytes bytes,operator to amount data operatorData,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,RevokedOperator,"RevokedOperator(address,address)",0x50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa1,false,0 1,address address,operator tokenHolder,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,Sent,"Sent(address,address,address,uint256,bytes,bytes)",0x06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987,false,0 1 2,address address address uint256 bytes bytes,operator from to amount data operatorData,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,Transfer,"Transfer(address,address,uint256,bytes)",0xe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16,false,0 1,address address uint256 bytes,from to value data,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,TransferFee,"TransferFee(address,address,uint256,uint256,bool)",0x3eba86eb3c0ea121e35980d4acae6eb9f1cdf0bf7c0c08443798cfd6e5299de3,false,,address address uint256 uint256 bool,from to amount fee senderPays,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,2,0x6936441113610483cc5b6a7adec4b45303b297a9,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,AgreementCreated,"AgreementCreated(address,bytes32,bytes32[])",0x770ea40a13a4644573ed785e5c7116890709947918747febc5add46feb531e2d,false,0,address bytes32 bytes32[],agreementClass id data,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,AgreementLiquidated,"AgreementLiquidated(address,bytes32,address,address,uint256)",0x8505c3d8f1f184f032cf0bc4cd80ee61c8b9d94f8907c3281bf0101a2610fe80,false,0 2 3,address bytes32 address address uint256,agreementClass id penaltyAccount rewardAccount rewardAmount,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,AgreementLiquidatedBy,"AgreementLiquidatedBy(address,address,bytes32,address,address,uint256,uint256)",0x5f22b60e58b1d6de858bc27c48d5a4653e052da99e083c1d88bb8c58e1abc8ef,false,1 3 4,address address bytes32 address address uint256 uint256,liquidatorAccount agreementClass id penaltyAccount bondAccount rewardAmount bailoutAmount,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,AgreementLiquidatedV2,"AgreementLiquidatedV2(address,bytes32,address,address,address,uint256,int256,bytes)",0xb8381a3ce157650e06186e3e8f4dd4dc29236f2688b6eed1893d0a60d7c6386f,false,0 2 3,address bytes32 address address address uint256 int256 bytes,agreementClass id liquidatorAccount targetAccount rewardAmountReceiver rewardAmount targetAccountBalanceDelta liquidationTypeData,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,AgreementStateUpdated,"AgreementStateUpdated(address,address,uint256)",0x30f416fa68fca014a0f334464c64b000ba53e99b6d2afdea9d5ca756372d5985,false,0 1,address address uint256,agreementClass account slotId,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,AgreementTerminated,"AgreementTerminated(address,bytes32)",0x71a63dc095de07aa5512ad57a7596a39516317e316981a1cd71000057be1537b,false,0,address bytes32,agreementClass id,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,AgreementUpdated,"AgreementUpdated(address,bytes32,bytes32[])",0x0c4c547b3a4fcaa5be8353b3111472b124155bccc86de811d4a481c9e6e9faca,false,0,address bytes32 bytes32[],agreementClass id data,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,owner spender value,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,AuthorizedOperator,"AuthorizedOperator(address,address)",0xf4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f9,false,0 1,address address,operator tokenHolder,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,Bailout,"Bailout(address,uint256)",0xd6c9a04afc81e8c614310bbee6c9e84f5abe15b82038bf8347014ce0852e6ffd,false,0,address uint256,bailoutAccount bailoutAmount,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,Burned,"Burned(address,address,uint256,bytes,bytes)",0xa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098,false,0 1,address address uint256 bytes bytes,operator from amount data operatorData,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,CodeUpdated,"CodeUpdated(bytes32,address)",0xe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc,false,,bytes32 address,uuid codeAddress,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,Minted,"Minted(address,address,uint256,bytes,bytes)",0x2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d,false,0 1,address address uint256 bytes bytes,operator to amount data operatorData,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,RevokedOperator,"RevokedOperator(address,address)",0x50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa1,false,0 1,address address,operator tokenHolder,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,Sent,"Sent(address,address,address,uint256,bytes,bytes)",0x06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987,false,0 1 2,address address address uint256 bytes bytes,operator from to amount data operatorData,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,Transfer,"Transfer(address,address,uint256,bytes)",0xe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16,false,0 1,address address uint256 bytes,from to value data,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,from to value,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,TransferFee,"TransferFee(address,address,uint256,uint256,bool)",0x3eba86eb3c0ea121e35980d4acae6eb9f1cdf0bf7c0c08443798cfd6e5299de3,false,,address address uint256 uint256 bool,from to amount fee senderPays,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,GoodDollar,0xec2136843a983885aebf2feb3931f73a8ebee50c,3,0x1db2f592014a9394604bf6381f025754579547ec,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,true,95143245,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3 of 3" +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,BlacklistAdded,BlacklistAdded(address),0x44d5fe68b00f68950fb9c1ff0a61ef7f747b1a36359a7e3a7f3324db4b878967,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,BlacklistRemoved,BlacklistRemoved(address),0x1747ca720b1a174a464b6513ace29b1d3190b5f632b9f34147017c81425bfde8,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,ContractAdded,ContractAdded(address),0x89c66952b48f3e96bf1d8ba1b63189520fd988a6979b8b740bd5c5d8dc53e205,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,ContractRemoved,ContractRemoved(address),0x8d30d41865a0b811b9545d879520d2dde9f4cc49e4241f486ad9752bc904b565,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,WhitelistedAdded,WhitelistedAdded(address),0xee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,WhitelistedAuthenticated,"WhitelistedAuthenticated(address,uint256)",0xb2a82fce6d8c7a633efe9579f77b4edb96bfdf171a49bfc2ce666dc543a1f500,false,0,address uint256,account timestamp,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,1,0x284a775f971c58c93cc5ee2a09a5f3496af9b11d,WhitelistedRemoved,WhitelistedRemoved(address),0x270d9b30cf5b0793bbfd54c9d5b94aeb49462b8148399000265144a8722da6b6,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,2,0x28830934ad2146e7a273fd394f706571c2d09373,AccountConnected,"AccountConnected(address,address)",0x18f7736ef54539debd9afd3c9500b106e12ae7c70e685f5a5efd727b1ce1d54c,false,0 1,address address,connected to,true,100340676,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 2 of 2 +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,2,0x28830934ad2146e7a273fd394f706571c2d09373,AccountDisconnected,"AccountDisconnected(address,address)",0x7cdef5f9c5cb8ce728661ede956fef26cb91eb4d7d2180cc041b73f9fef568d2,false,0 1,address address,disconnected from,true,100340676,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 2 of 2 +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,2,0x28830934ad2146e7a273fd394f706571c2d09373,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,2,0x28830934ad2146e7a273fd394f706571c2d09373,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,2,0x28830934ad2146e7a273fd394f706571c2d09373,BlacklistAdded,BlacklistAdded(address),0x44d5fe68b00f68950fb9c1ff0a61ef7f747b1a36359a7e3a7f3324db4b878967,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,2,0x28830934ad2146e7a273fd394f706571c2d09373,BlacklistRemoved,BlacklistRemoved(address),0x1747ca720b1a174a464b6513ace29b1d3190b5f632b9f34147017c81425bfde8,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,2,0x28830934ad2146e7a273fd394f706571c2d09373,ContractAdded,ContractAdded(address),0x89c66952b48f3e96bf1d8ba1b63189520fd988a6979b8b740bd5c5d8dc53e205,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,2,0x28830934ad2146e7a273fd394f706571c2d09373,ContractRemoved,ContractRemoved(address),0x8d30d41865a0b811b9545d879520d2dde9f4cc49e4241f486ad9752bc904b565,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,2,0x28830934ad2146e7a273fd394f706571c2d09373,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,2,0x28830934ad2146e7a273fd394f706571c2d09373,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,2,0x28830934ad2146e7a273fd394f706571c2d09373,RoleAdminChanged,"RoleAdminChanged(bytes32,bytes32,bytes32)",0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff,false,0 1 2,bytes32 bytes32 bytes32,role previousAdminRole newAdminRole,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,2,0x28830934ad2146e7a273fd394f706571c2d09373,RoleGranted,"RoleGranted(bytes32,address,address)",0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,2,0x28830934ad2146e7a273fd394f706571c2d09373,RoleRevoked,"RoleRevoked(bytes32,address,address)",0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b,false,0 1 2,bytes32 address address,role account sender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,2,0x28830934ad2146e7a273fd394f706571c2d09373,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,2,0x28830934ad2146e7a273fd394f706571c2d09373,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,2,0x28830934ad2146e7a273fd394f706571c2d09373,WhitelistedAdded,WhitelistedAdded(address),0xee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,2,0x28830934ad2146e7a273fd394f706571c2d09373,WhitelistedAuthenticated,"WhitelistedAuthenticated(address,uint256)",0xb2a82fce6d8c7a633efe9579f77b4edb96bfdf171a49bfc2ce666dc543a1f500,false,0,address uint256,account timestamp,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Identity,0x27a4a02c9ed591e1a86e2e5d05870292c34622c9,2,0x28830934ad2146e7a273fd394f706571c2d09373,WhitelistedRemoved,WhitelistedRemoved(address),0x270d9b30cf5b0793bbfd54c9d5b94aeb49462b8148399000265144a8722da6b6,false,0,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Invites,0x6bd698566632bf2e81e2278f1656cb24aaf06d2e,1,0xb22bb27d920a4efdafaa03a51e8a4c41e4cc4217,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Invites,0x6bd698566632bf2e81e2278f1656cb24aaf06d2e,1,0xb22bb27d920a4efdafaa03a51e8a4c41e4cc4217,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Invites,0x6bd698566632bf2e81e2278f1656cb24aaf06d2e,1,0xb22bb27d920a4efdafaa03a51e8a4c41e4cc4217,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Invites,0x6bd698566632bf2e81e2278f1656cb24aaf06d2e,1,0xb22bb27d920a4efdafaa03a51e8a4c41e4cc4217,InviteeJoined,"InviteeJoined(address,address)",0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051,false,0 1,address address,inviter invitee,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Invites,0x6bd698566632bf2e81e2278f1656cb24aaf06d2e,1,0xb22bb27d920a4efdafaa03a51e8a4c41e4cc4217,InviterBounty,"InviterBounty(address,address,uint256,uint256,bool)",0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b,false,0 1,address address uint256 uint256 bool,inviter invitee bountyPaid inviterLevel earnedLevel,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Invites,0x6bd698566632bf2e81e2278f1656cb24aaf06d2e,1,0xb22bb27d920a4efdafaa03a51e8a4c41e4cc4217,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Invites,0x6bd698566632bf2e81e2278f1656cb24aaf06d2e,2,0x783548481a6ca92b6589365161b31e3ed64d0c3c,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Invites,0x6bd698566632bf2e81e2278f1656cb24aaf06d2e,2,0x783548481a6ca92b6589365161b31e3ed64d0c3c,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Invites,0x6bd698566632bf2e81e2278f1656cb24aaf06d2e,2,0x783548481a6ca92b6589365161b31e3ed64d0c3c,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Invites,0x6bd698566632bf2e81e2278f1656cb24aaf06d2e,2,0x783548481a6ca92b6589365161b31e3ed64d0c3c,InviteeJoined,"InviteeJoined(address,address)",0xd8c638d8979e2ba5dba1f0d66246ee4b1c54b838f0e0a2b601365345eb23b051,false,0 1,address address,inviter invitee,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Invites,0x6bd698566632bf2e81e2278f1656cb24aaf06d2e,2,0x783548481a6ca92b6589365161b31e3ed64d0c3c,InviterBounty,"InviterBounty(address,address,uint256,uint256,bool)",0x6081787cd1bd02ab1576c52f03e8710d792d460e7881c3155d77d23893f3768b,false,0 1,address address uint256 uint256 bool,inviter invitee bountyPaid inviterLevel earnedLevel,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,Invites,0x6bd698566632bf2e81e2278f1656cb24aaf06d2e,2,0x783548481a6ca92b6589365161b31e3ed64d0c3c,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,1,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,bytecode_equality_with_celo_0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,1,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,bytecode_equality_with_celo_0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,1,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,ExchangeProviderAdded,ExchangeProviderAdded(address),0x2ee2cb0721ec60b86190cae5c48e25064b69b35abad32452a4ec99d232033de2,false,0,address,exchangeProvider,false,,,bytecode_equality_with_celo_0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,1,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,ExchangeProviderRemoved,ExchangeProviderRemoved(address),0x29e92ab2e30f4f74283034c28c451b6faac986b554f1808101eb6418bdba19d4,false,0,address,exchangeProvider,false,,,bytecode_equality_with_celo_0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,1,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,bytecode_equality_with_celo_0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,1,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,ReserveSet,"ReserveSet(address,address)",0xb69e1c416d8be92ac92c8e97e77c4626fba5e6ab50161099f659ea3303479e50,false,0 1,address address,newAddress prevAddress,false,,,bytecode_equality_with_celo_0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,1,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,Swap,"Swap(address,bytes32,address,address,address,uint256,uint256)",0xe7b046415cac9de47940c3087e06db13a0e058ccf53ac5f0edd49ebb4c2c3a6f,false,1 2 3,address bytes32 address address address uint256 uint256,exchangeProvider exchangeId trader tokenIn tokenOut amountIn amountOut,false,,,bytecode_equality_with_celo_0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,1,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,TradingLimitConfigured,"TradingLimitConfigured(bytes32,address,(uint32,uint32,int48,int48,int48,uint8))",0x1a082a1efaf1549c18917ddcb1f759680c29371609e24f4b946e93acf4ce5ad2,false,,"bytes32 address (uint32,uint32,int48,int48,int48,uint8)",exchangeId token config,true,100091095,100340676,bytecode_equality_with_celo_0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 1 of 2 +XDC,50,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,1,0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,bytecode_equality_with_celo_0xc22505d3a6ae087c0bd4715a56c38b7a029477b2,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,2,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,2,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,2,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,ExchangeProviderAdded,ExchangeProviderAdded(address),0x2ee2cb0721ec60b86190cae5c48e25064b69b35abad32452a4ec99d232033de2,false,0,address,exchangeProvider,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,2,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,ExchangeProviderRemoved,ExchangeProviderRemoved(address),0x29e92ab2e30f4f74283034c28c451b6faac986b554f1808101eb6418bdba19d4,false,0,address,exchangeProvider,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,2,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,2,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,ReserveSet,"ReserveSet(address,address)",0xb69e1c416d8be92ac92c8e97e77c4626fba5e6ab50161099f659ea3303479e50,false,0 1,address address,newAddress prevAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,2,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,Swap,"Swap(address,bytes32,address,address,address,uint256,uint256)",0xe7b046415cac9de47940c3087e06db13a0e058ccf53ac5f0edd49ebb4c2c3a6f,false,1 2 3,address bytes32 address address address uint256 uint256,exchangeProvider exchangeId trader tokenIn tokenOut amountIn amountOut,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,2,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,TradingLimitConfigured,"TradingLimitConfigured(bytes32,address,(uint32,uint32,int48,int48,int48,int48,int48,uint8))",0x3ed50aa123e1e547aa90fcf88624ef8278d253e252bb1feac75eda93e1905bb6,false,,"bytes32 address (uint32,uint32,int48,int48,int48,int48,int48,uint8)",exchangeId token config,true,100340676,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 2 of 2 +XDC,50,MentoBroker,0x88de45906d4f5a57315c133620cfa484cb297541,2,0xc69ae3550e25c7ab28301b9bf75f20f5af47b7d2,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,AvatarUpdated,AvatarUpdated(address),0x67b34afe551279f03ead7ef1a0ecd16bec18f83ab1a9834c7fda2627374aae9a,false,0,address,AVATAR,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,BrokerUpdated,BrokerUpdated(address),0x865dab7821134b6eb27cba259b40e33bbc1b898e970a535a18a83147f380a51f,false,0,address,newBroker,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,ExchangeCreated,"ExchangeCreated(bytes32,address,address)",0xef64f1477da1dc2a681adfafd64ea6aea317bc2b4b289d3cb83ed28e06a0eca7,false,0 1 2,bytes32 address address,exchangeId reserveAsset tokenAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,ExchangeDestroyed,"ExchangeDestroyed(bytes32,address,address)",0x72508491fc70b128eac87e7e09c111008dbf1a965572c407dc568853bfffb4c3,false,0 1 2,bytes32 address address,exchangeId reserveAsset tokenAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,ExitContributionSet,"ExitContributionSet(bytes32,uint256)",0x1af751293d0291cca774a2d8152b5eaf650ff3b8243976f64402e7b70344c936,false,0,bytes32 uint256,exchangeId exitContribution,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,ExpansionControllerUpdated,ExpansionControllerUpdated(address),0x6791df7c014d19acfc9b7e3a5d48588a876b014fdd3321f193fef6b0ae785c24,false,0,address,expansionController,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,ReserveRatioUpdated,"ReserveRatioUpdated(bytes32,uint32)",0x79f5414ef686d317caad619bee58ae93a7a214651f1d0819d4ce5cb1dde57e9a,false,0,bytes32 uint32,exchangeId reserveRatio,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,ReserveUpdated,ReserveUpdated(address),0x0b248ab246a87e452fbedee8dc12dfc53e3f3bfdc6920999062c56dea4ab522a,false,0,address,newReserve,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,1,0xd9ce916d711977d5b27697a13964556b4fb8af1d,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,AvatarUpdated,AvatarUpdated(address),0x67b34afe551279f03ead7ef1a0ecd16bec18f83ab1a9834c7fda2627374aae9a,false,0,address,AVATAR,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,BrokerUpdated,BrokerUpdated(address),0x865dab7821134b6eb27cba259b40e33bbc1b898e970a535a18a83147f380a51f,false,0,address,newBroker,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,ExchangeCreated,"ExchangeCreated(bytes32,address,address)",0xef64f1477da1dc2a681adfafd64ea6aea317bc2b4b289d3cb83ed28e06a0eca7,false,0 1 2,bytes32 address address,exchangeId reserveAsset tokenAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,ExchangeDestroyed,"ExchangeDestroyed(bytes32,address,address)",0x72508491fc70b128eac87e7e09c111008dbf1a965572c407dc568853bfffb4c3,false,0 1 2,bytes32 address address,exchangeId reserveAsset tokenAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,ExchangeUpdated,"ExchangeUpdated(bytes32,address,address)",0x795d5a71e23aab4c26a0763c6014c82fd9eae5c5e22fa2540301d2e9ee21f974,false,0 1 2,bytes32 address address,exchangeId reserveAsset tokenAddress,true,100340676,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,present in eras 2 of 2 +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,ExitContributionSet,"ExitContributionSet(bytes32,uint256)",0x1af751293d0291cca774a2d8152b5eaf650ff3b8243976f64402e7b70344c936,false,0,bytes32 uint256,exchangeId exitContribution,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,ExpansionControllerUpdated,ExpansionControllerUpdated(address),0x6791df7c014d19acfc9b7e3a5d48588a876b014fdd3321f193fef6b0ae785c24,false,0,address,expansionController,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,Paused,Paused(address),0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,ReserveRatioUpdated,"ReserveRatioUpdated(bytes32,uint32)",0x79f5414ef686d317caad619bee58ae93a7a214651f1d0819d4ce5cb1dde57e9a,false,0,bytes32 uint32,exchangeId reserveRatio,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,ReserveUpdated,ReserveUpdated(address),0x0b248ab246a87e452fbedee8dc12dfc53e3f3bfdc6920999062c56dea4ab522a,false,0,address,newReserve,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,Unpaused,Unpaused(address),0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa,false,,address,account,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExchangeProvider,0x2ffbb49055d487ddbbb0c052cd7c2a02a7971e41,2,0xe930cde20f60d0a4fc9487874861ae259f5bed48,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,AvatarUpdated,AvatarUpdated(address),0x67b34afe551279f03ead7ef1a0ecd16bec18f83ab1a9834c7fda2627374aae9a,false,0,address,avatar,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,DistributionHelperUpdated,DistributionHelperUpdated(address),0x37bb6eaf6f31a018c4328eb0343706d73df678b663b21b972351d2528f755af5,false,0,address,distributionHelper,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,ExpansionConfigSet,"ExpansionConfigSet(bytes32,uint64,uint32)",0xec7bd652042d4e7ac612fa1ad2901ce09f76d87ddf816a2c139dd24e3485e3ae,false,0,bytes32 uint64 uint32,exchangeId expansionRate expansionFrequency,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,ExpansionUBIMinted,"ExpansionUBIMinted(bytes32,uint256)",0x0781f173380ed4227560d90be8abf115523ae75bb917c0de637ce6cfbde0011b,false,0,bytes32 uint256,exchangeId amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,GoodDollarExchangeProviderUpdated,GoodDollarExchangeProviderUpdated(address),0xbbee0329d0a3c6241c11b82178f5039a54f654d789f3d9cbb471bf12f0c77e8f,false,0,address,exchangeProvider,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,InterestUBIMinted,"InterestUBIMinted(bytes32,uint256)",0x16414a884759b367b2c78dab8035003a0b744b3b41128d432aa29045743d0116,false,0,bytes32 uint256,exchangeId amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,ReserveUpdated,ReserveUpdated(address),0x0b248ab246a87e452fbedee8dc12dfc53e3f3bfdc6920999062c56dea4ab522a,false,0,address,reserve,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,RewardMinted,"RewardMinted(bytes32,address,uint256)",0x45a9b25eb22877783b22873a81ab6e03cff8a14dbe2013660999213bdc4067b1,false,0 1,bytes32 address uint256,exchangeId to amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoExpansionController,0x5557e9def86ad6564462741a7a3f3679c1223f5d,1,0x7288d592e1b9013c668801f722be650993d2925a,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoProxyAdmin,0x8471406c3bff67cc6538481c8550364bda6ca691,1,0x8471406c3bff67cc6538481c8550364bda6ca691,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,AssetAllocationSet,"AssetAllocationSet(bytes32[],uint256[])",0x55b488abd19ae7621712324d3d42c2ef7a9575f64f5503103286a1161fb40855,false,,bytes32[] uint256[],symbols weights,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,CollateralAssetAdded,CollateralAssetAdded(address),0x0c7515883121475b5d9289febf21a9de4ad53f18349a856d90c7acd6e099600b,false,,address,collateralAsset,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,CollateralAssetRemoved,CollateralAssetRemoved(address),0x4336391ada1af9dcb966fed43ebafa4404719b6d8e42c765ab28e3abc9a24e7a,false,,address,collateralAsset,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,DailySpendingRatioForCollateralAssetSet,"DailySpendingRatioForCollateralAssetSet(address,uint256)",0x15ff5079dfbf448e4bb45ac83498c2ecb0833ad35916946bb683ccb49f8013a3,false,,address uint256,collateralAsset collateralAssetDailySpendingRatios,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,DailySpendingRatioSet,DailySpendingRatioSet(uint256),0xb08f0607338ad77f5b08ccf831e533cefcc2d373c173e87a8f61144f1d82be1e,false,,uint256,ratio,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,ExchangeSpenderAdded,ExchangeSpenderAdded(address),0x71bccdb89fff4d914e3d2e472b327e3debaf4c4d6f1dfe528f430447e4cbcf5f,false,0,address,exchangeSpender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,ExchangeSpenderRemoved,ExchangeSpenderRemoved(address),0x20aaa18caa668680a42b328a15fd50d580bac65d8bd346e104355473c6373ff3,false,0,address,exchangeSpender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,OtherReserveAddressAdded,OtherReserveAddressAdded(address),0xd78793225285ecf9cf5f0f84b1cdc335c2cb4d6810ff0b9fd156ad6026c89cea,false,0,address,otherReserveAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,OtherReserveAddressRemoved,"OtherReserveAddressRemoved(address,uint256)",0x89b4ee5cecfdfb246ede373c10283b5038afe56a531fc1d2f3ed8c5507a52fcb,false,0,address uint256,otherReserveAddress index,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,RegistrySet,RegistrySet(address),0x27fe5f0c1c3b1ed427cc63d0f05759ffdecf9aec9e18d31ef366fc8a6cb5dc3b,false,0,address,registryAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,ReserveCollateralAssetsTransferred,"ReserveCollateralAssetsTransferred(address,address,uint256,address)",0xc171b15fb47a5beb3e11b1951d4518544f699edd6acd893d8695c91703922b60,false,0 1,address address uint256 address,spender to value token,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,ReserveGoldTransferred,"ReserveGoldTransferred(address,address,uint256)",0x4dd1abe16ad3d4f829372dc77766ca2cce34e205af9b10f8cc1fab370425864f,false,0 1,address address uint256,spender to value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,SpenderAdded,SpenderAdded(address),0x3139419c41cdd7abca84fa19dd21118cd285d3e2ce1a9444e8161ce9fa62fdcd,false,0,address,spender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,SpenderRemoved,SpenderRemoved(address),0xab8cff50266d80b9c9d9703af934ca455b9218286bf4fcaa05653a564c499e4b,false,0,address,spender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,TobinTaxReserveRatioSet,TobinTaxReserveRatioSet(uint256),0x4da8e8b2223fbbb897200fb9dfb6b986c1b4188621114d407ee8ec363569fc37,false,,uint256,value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,TobinTaxSet,TobinTaxSet(uint256),0xfe69856ffb1b1d6cb00c1d8151726e6e95032b1666282eeb293ecadd58b29a6e,false,,uint256,value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,TobinTaxStalenessThresholdSet,TobinTaxStalenessThresholdSet(uint256),0x7bfe94ca3147f135fcd6d94ebf61d33fa34fbe904f933ccae66911b9548544f2,false,,uint256,value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,TokenAdded,TokenAdded(address),0x784c8f4dbf0ffedd6e72c76501c545a70f8b203b30a26ce542bf92ba87c248a4,false,0,address,token,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,TokenRemoved,"TokenRemoved(address,uint256)",0xbe9bb4bdca0a094babd75e3a98b1d2e2390633430d0a2f6e2b9970e2ee03fb2e,false,0,address uint256,token index,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,1,0xf036896e9441ecaeb1b6d2fc1b982021eed2b439,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,AssetAllocationSet,"AssetAllocationSet(bytes32[],uint256[])",0x55b488abd19ae7621712324d3d42c2ef7a9575f64f5503103286a1161fb40855,false,,bytes32[] uint256[],symbols weights,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,CollateralAssetAdded,CollateralAssetAdded(address),0x0c7515883121475b5d9289febf21a9de4ad53f18349a856d90c7acd6e099600b,false,,address,collateralAsset,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,CollateralAssetRemoved,CollateralAssetRemoved(address),0x4336391ada1af9dcb966fed43ebafa4404719b6d8e42c765ab28e3abc9a24e7a,false,,address,collateralAsset,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,DailySpendingRatioForCollateralAssetSet,"DailySpendingRatioForCollateralAssetSet(address,uint256)",0x15ff5079dfbf448e4bb45ac83498c2ecb0833ad35916946bb683ccb49f8013a3,false,,address uint256,collateralAsset collateralAssetDailySpendingRatios,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,DailySpendingRatioSet,DailySpendingRatioSet(uint256),0xb08f0607338ad77f5b08ccf831e533cefcc2d373c173e87a8f61144f1d82be1e,false,,uint256,ratio,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,ExchangeSpenderAdded,ExchangeSpenderAdded(address),0x71bccdb89fff4d914e3d2e472b327e3debaf4c4d6f1dfe528f430447e4cbcf5f,false,0,address,exchangeSpender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,ExchangeSpenderRemoved,ExchangeSpenderRemoved(address),0x20aaa18caa668680a42b328a15fd50d580bac65d8bd346e104355473c6373ff3,false,0,address,exchangeSpender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,OtherReserveAddressAdded,OtherReserveAddressAdded(address),0xd78793225285ecf9cf5f0f84b1cdc335c2cb4d6810ff0b9fd156ad6026c89cea,false,0,address,otherReserveAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,OtherReserveAddressRemoved,"OtherReserveAddressRemoved(address,uint256)",0x89b4ee5cecfdfb246ede373c10283b5038afe56a531fc1d2f3ed8c5507a52fcb,false,0,address uint256,otherReserveAddress index,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,RegistrySet,RegistrySet(address),0x27fe5f0c1c3b1ed427cc63d0f05759ffdecf9aec9e18d31ef366fc8a6cb5dc3b,false,0,address,registryAddress,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,ReserveCollateralAssetsTransferred,"ReserveCollateralAssetsTransferred(address,address,uint256,address)",0xc171b15fb47a5beb3e11b1951d4518544f699edd6acd893d8695c91703922b60,false,0 1,address address uint256 address,spender to value token,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,ReserveGoldTransferred,"ReserveGoldTransferred(address,address,uint256)",0x4dd1abe16ad3d4f829372dc77766ca2cce34e205af9b10f8cc1fab370425864f,false,0 1,address address uint256,spender to value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,SpenderAdded,SpenderAdded(address),0x3139419c41cdd7abca84fa19dd21118cd285d3e2ce1a9444e8161ce9fa62fdcd,false,0,address,spender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,SpenderRemoved,SpenderRemoved(address),0xab8cff50266d80b9c9d9703af934ca455b9218286bf4fcaa05653a564c499e4b,false,0,address,spender,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,TobinTaxReserveRatioSet,TobinTaxReserveRatioSet(uint256),0x4da8e8b2223fbbb897200fb9dfb6b986c1b4188621114d407ee8ec363569fc37,false,,uint256,value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,TobinTaxSet,TobinTaxSet(uint256),0xfe69856ffb1b1d6cb00c1d8151726e6e95032b1666282eeb293ecadd58b29a6e,false,,uint256,value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,TobinTaxStalenessThresholdSet,TobinTaxStalenessThresholdSet(uint256),0x7bfe94ca3147f135fcd6d94ebf61d33fa34fbe904f933ccae66911b9548544f2,false,,uint256,value,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,TokenAdded,TokenAdded(address),0x784c8f4dbf0ffedd6e72c76501c545a70f8b203b30a26ce542bf92ba87c248a4,false,0,address,token,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,TokenRemoved,"TokenRemoved(address,uint256)",0xbe9bb4bdca0a094babd75e3a98b1d2e2390633430d0a2f6e2b9970e2ee03fb2e,false,0,address uint256,token index,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MentoReserve,0x94a3240f484a04f5e3d524f528d02694c109463b,2,0xbdaa65e8175875340365d76a660bb2a7a4efe909,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,1,0x0000000000000000000000000000000000000000,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,1,0x0000000000000000000000000000000000000000,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,1,0x0000000000000000000000000000000000000000,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xa7bfc0d36300b5978cfa18301446cad3e855ae06,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xa7bfc0d36300b5978cfa18301446cad3e855ae06,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xa7bfc0d36300b5978cfa18301446cad3e855ae06,BridgeRequest,"BridgeRequest(address,address,uint256,uint256,uint256,uint8,uint256)",0xabeeb7182c7294cd8efcd40e9ff952c1b759c2165b3634aac589429de5d55ad0,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to targetChainId normalizedAmount timestamp bridge id,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xa7bfc0d36300b5978cfa18301446cad3e855ae06,ExecutedTransfer,"ExecutedTransfer(address,address,uint256,uint256,uint256,uint8,uint256)",0x6cf712ce908185c8c38a073b7315f79687e7440fb057d9d1ca76a2509a1282ee,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to normalizedAmount fee sourceChainId bridge id,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xa7bfc0d36300b5978cfa18301446cad3e855ae06,FalseSender,"FalseSender(uint256,address)",0x1eafb58197ea0dc76b9278ccad47f61a239f00b017d89a19081a89321cce213d,false,,uint256 address,sourceChainId sourceAddress,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xa7bfc0d36300b5978cfa18301446cad3e855ae06,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xa7bfc0d36300b5978cfa18301446cad3e855ae06,MessageFailed,"MessageFailed(uint16,bytes,uint64,bytes,bytes)",0xe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c,false,,uint16 bytes uint64 bytes bytes,_srcChainId _srcAddress _nonce _payload _reason,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xa7bfc0d36300b5978cfa18301446cad3e855ae06,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xa7bfc0d36300b5978cfa18301446cad3e855ae06,RetryMessageSuccess,"RetryMessageSuccess(uint16,bytes,uint64,bytes32)",0xc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e5,false,,uint16 bytes uint64 bytes32,_srcChainId _srcAddress _nonce _payloadHash,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xa7bfc0d36300b5978cfa18301446cad3e855ae06,SetMinDstGas,"SetMinDstGas(uint16,uint16,uint256)",0x9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0,false,,uint16 uint16 uint256,_dstChainId _type _minDstGas,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xa7bfc0d36300b5978cfa18301446cad3e855ae06,SetPrecrime,SetPrecrime(address),0x5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b,false,,address,precrime,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xa7bfc0d36300b5978cfa18301446cad3e855ae06,SetTrustedRemote,"SetTrustedRemote(uint16,bytes)",0xfa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab,false,,uint16 bytes,_remoteChainId _path,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xa7bfc0d36300b5978cfa18301446cad3e855ae06,SetTrustedRemoteAddress,"SetTrustedRemoteAddress(uint16,bytes)",0x8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce,false,,uint16 bytes,_remoteChainId _remoteAddress,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,2,0xa7bfc0d36300b5978cfa18301446cad3e855ae06,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xe4cfa18a3d0a7d77faa42961ee943c9221d61937,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xe4cfa18a3d0a7d77faa42961ee943c9221d61937,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xe4cfa18a3d0a7d77faa42961ee943c9221d61937,BridgeRequest,"BridgeRequest(address,address,uint256,uint256,uint256,uint8,uint256)",0xabeeb7182c7294cd8efcd40e9ff952c1b759c2165b3634aac589429de5d55ad0,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to targetChainId normalizedAmount timestamp bridge id,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xe4cfa18a3d0a7d77faa42961ee943c9221d61937,ExecutedTransfer,"ExecutedTransfer(address,address,uint256,uint256,uint256,uint8,uint256)",0x6cf712ce908185c8c38a073b7315f79687e7440fb057d9d1ca76a2509a1282ee,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to normalizedAmount fee sourceChainId bridge id,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xe4cfa18a3d0a7d77faa42961ee943c9221d61937,FalseSender,"FalseSender(uint256,address)",0x1eafb58197ea0dc76b9278ccad47f61a239f00b017d89a19081a89321cce213d,false,,uint256 address,sourceChainId sourceAddress,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xe4cfa18a3d0a7d77faa42961ee943c9221d61937,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xe4cfa18a3d0a7d77faa42961ee943c9221d61937,MessageFailed,"MessageFailed(uint16,bytes,uint64,bytes,bytes)",0xe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c,false,,uint16 bytes uint64 bytes bytes,_srcChainId _srcAddress _nonce _payload _reason,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xe4cfa18a3d0a7d77faa42961ee943c9221d61937,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xe4cfa18a3d0a7d77faa42961ee943c9221d61937,RetryMessageSuccess,"RetryMessageSuccess(uint16,bytes,uint64,bytes32)",0xc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e5,false,,uint16 bytes uint64 bytes32,_srcChainId _srcAddress _nonce _payloadHash,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xe4cfa18a3d0a7d77faa42961ee943c9221d61937,SetMinDstGas,"SetMinDstGas(uint16,uint16,uint256)",0x9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0,false,,uint16 uint16 uint256,_dstChainId _type _minDstGas,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xe4cfa18a3d0a7d77faa42961ee943c9221d61937,SetPrecrime,SetPrecrime(address),0x5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b,false,,address,precrime,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xe4cfa18a3d0a7d77faa42961ee943c9221d61937,SetTrustedRemote,"SetTrustedRemote(uint16,bytes)",0xfa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab,false,,uint16 bytes,_remoteChainId _path,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xe4cfa18a3d0a7d77faa42961ee943c9221d61937,SetTrustedRemoteAddress,"SetTrustedRemoteAddress(uint16,bytes)",0x8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce,false,,uint16 bytes,_remoteChainId _remoteAddress,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,3,0xe4cfa18a3d0a7d77faa42961ee943c9221d61937,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x00f7f61080ef40d3832c8c06e8a2af757839e1f7,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x00f7f61080ef40d3832c8c06e8a2af757839e1f7,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x00f7f61080ef40d3832c8c06e8a2af757839e1f7,BridgeRequest,"BridgeRequest(address,address,uint256,uint256,uint256,uint8,uint256)",0xabeeb7182c7294cd8efcd40e9ff952c1b759c2165b3634aac589429de5d55ad0,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to targetChainId normalizedAmount timestamp bridge id,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x00f7f61080ef40d3832c8c06e8a2af757839e1f7,ExecutedTransfer,"ExecutedTransfer(address,address,uint256,uint256,uint256,uint8,uint256)",0x6cf712ce908185c8c38a073b7315f79687e7440fb057d9d1ca76a2509a1282ee,false,0 1 6,address address uint256 uint256 uint256 uint8 uint256,from to normalizedAmount fee sourceChainId bridge id,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x00f7f61080ef40d3832c8c06e8a2af757839e1f7,FalseSender,"FalseSender(uint256,address)",0x1eafb58197ea0dc76b9278ccad47f61a239f00b017d89a19081a89321cce213d,false,,uint256 address,sourceChainId sourceAddress,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x00f7f61080ef40d3832c8c06e8a2af757839e1f7,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x00f7f61080ef40d3832c8c06e8a2af757839e1f7,MessageFailed,"MessageFailed(uint16,bytes,uint64,bytes,bytes)",0xe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c,false,,uint16 bytes uint64 bytes bytes,_srcChainId _srcAddress _nonce _payload _reason,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x00f7f61080ef40d3832c8c06e8a2af757839e1f7,OwnershipTransferred,"OwnershipTransferred(address,address)",0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0,false,0 1,address address,previousOwner newOwner,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x00f7f61080ef40d3832c8c06e8a2af757839e1f7,RetryMessageSuccess,"RetryMessageSuccess(uint16,bytes,uint64,bytes32)",0xc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e5,false,,uint16 bytes uint64 bytes32,_srcChainId _srcAddress _nonce _payloadHash,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x00f7f61080ef40d3832c8c06e8a2af757839e1f7,SetMinDstGas,"SetMinDstGas(uint16,uint16,uint256)",0x9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0,false,,uint16 uint16 uint256,_dstChainId _type _minDstGas,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x00f7f61080ef40d3832c8c06e8a2af757839e1f7,SetPrecrime,SetPrecrime(address),0x5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b,false,,address,precrime,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x00f7f61080ef40d3832c8c06e8a2af757839e1f7,SetTrustedRemote,"SetTrustedRemote(uint16,bytes)",0xfa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab,false,,uint16 bytes,_remoteChainId _path,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x00f7f61080ef40d3832c8c06e8a2af757839e1f7,SetTrustedRemoteAddress,"SetTrustedRemoteAddress(uint16,bytes)",0x8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce,false,,uint16 bytes,_remoteChainId _remoteAddress,true,95254421,9223372036854775807,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index,"present in eras 2,3,4 of 4" +XDC,50,MpbBridge,0xa3247276dbcc76dd7705273f766eb3e8a5ecf4a5,4,0x00f7f61080ef40d3832c8c06e8a2af757839e1f7,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,NameService,0x1e5154bf5e31ff56051bbd45958b879fb7a290fe,1,0x653c67be5b3739708e84b61641253822405d78d8,AddressChanged,"AddressChanged(string,address)",0x135cf55549d8538a41f19f46cc85625da93e68b63484cca8fcb9aaf19e520137,false,,string address,name addr,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,NameService,0x1e5154bf5e31ff56051bbd45958b879fb7a290fe,1,0x653c67be5b3739708e84b61641253822405d78d8,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,NameService,0x1e5154bf5e31ff56051bbd45958b879fb7a290fe,1,0x653c67be5b3739708e84b61641253822405d78d8,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,NameService,0x1e5154bf5e31ff56051bbd45958b879fb7a290fe,1,0x653c67be5b3739708e84b61641253822405d78d8,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,NameService,0x1e5154bf5e31ff56051bbd45958b879fb7a290fe,1,0x653c67be5b3739708e84b61641253822405d78d8,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,ProxyFactory,0x5be34022c26fa03a8d6926314a42414c7ca2df51,1,0x5be34022c26fa03a8d6926314a42414c7ca2df51,ContractCreated,ContractCreated(address),0xcf78cf0d6f3d8371e1075c69c492ab4ec5d8cf23a1a239b6a51a1d00be7ca312,false,,address,addr,false,,,bytecode_equality_with_celo_0xd86cd6bb3c2a576b2c2cef4e047b1a7adc5be62d,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,ProxyFactory,0x5be34022c26fa03a8d6926314a42414c7ca2df51,1,0x5be34022c26fa03a8d6926314a42414c7ca2df51,ProxyCreated,ProxyCreated(address),0x00fffc2da0b561cae30d9826d37709e9421c4725faebc226cbbb7ef5fc5e7349,false,,address,proxy,false,,,bytecode_equality_with_celo_0xd86cd6bb3c2a576b2c2cef4e047b1a7adc5be62d,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,StaticOracle,0x725244458f011551dde1104c9728746eebea19f9,1,0x725244458f011551dde1104c9728746eebea19f9,OracleCreated,OracleCreated(address),0x5dba83b2e4f5ef7ead6ae8f4902f5335ce28561a5207952f0b0a9d9f3a01a1b7,false,,address,oracle,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,UBIScheme,0x22867567e2d80f2049200e25c6f31cb6ec2f0faf,1,0xea12bb3917cf6ae2fde97ce4756177703426d41f,AdminChanged,"AdminChanged(address,address)",0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f,false,,address address,previousAdmin newAdmin,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,UBIScheme,0x22867567e2d80f2049200e25c6f31cb6ec2f0faf,1,0xea12bb3917cf6ae2fde97ce4756177703426d41f,BeaconUpgraded,BeaconUpgraded(address),0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e,false,0,address,beacon,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,UBIScheme,0x22867567e2d80f2049200e25c6f31cb6ec2f0faf,1,0xea12bb3917cf6ae2fde97ce4756177703426d41f,CycleLengthSet,CycleLengthSet(uint256),0xa61e6cca2c12e2a0a493683acfe95b034f0f50d793434f4dfe3ba06ea201f344,false,,uint256,newCycleLength,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,UBIScheme,0x22867567e2d80f2049200e25c6f31cb6ec2f0faf,1,0xea12bb3917cf6ae2fde97ce4756177703426d41f,DaySet,DaySet(uint256),0x67eb03bd555181f9dd23f546e4331ddfb8b4a7d0c8d261ba44e037f30ce894ea,false,,uint256,newDay,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,UBIScheme,0x22867567e2d80f2049200e25c6f31cb6ec2f0faf,1,0xea12bb3917cf6ae2fde97ce4756177703426d41f,Initialized,Initialized(uint8),0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498,false,,uint8,version,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,UBIScheme,0x22867567e2d80f2049200e25c6f31cb6ec2f0faf,1,0xea12bb3917cf6ae2fde97ce4756177703426d41f,ShouldWithdrawFromDAOSet,ShouldWithdrawFromDAOSet(bool),0x6cd9a0fd2e006be39a9918bf56c85cae1d4f4599474483ff18cb93355ebaaf8e,false,,bool,ShouldWithdrawFromDAO,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,UBIScheme,0x22867567e2d80f2049200e25c6f31cb6ec2f0faf,1,0xea12bb3917cf6ae2fde97ce4756177703426d41f,UBICalculated,"UBICalculated(uint256,uint256,uint256)",0x836fa39995340265746dfe9587d9fe5c5de35b7bce778afd9b124ce1cfeafdc4,false,,uint256 uint256 uint256,day dailyUbi blockNumber,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,UBIScheme,0x22867567e2d80f2049200e25c6f31cb6ec2f0faf,1,0xea12bb3917cf6ae2fde97ce4756177703426d41f,UBIClaimed,"UBIClaimed(address,uint256)",0x89ed24731df6b066e4c5186901fffdba18cd9a10f07494aff900bdee260d1304,false,0,address uint256,claimer amount,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,UBIScheme,0x22867567e2d80f2049200e25c6f31cb6ec2f0faf,1,0xea12bb3917cf6ae2fde97ce4756177703426d41f,UBICycleCalculated,"UBICycleCalculated(uint256,uint256,uint256,uint256)",0x83e0d535b9e84324e0a25922406398d6ff5f96d0c686204ee490e16d7670566f,false,,uint256 uint256 uint256 uint256,day pool cycleLength dailyUBIPool,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,UBIScheme,0x22867567e2d80f2049200e25c6f31cb6ec2f0faf,1,0xea12bb3917cf6ae2fde97ce4756177703426d41f,Upgraded,Upgraded(address),0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b,false,0,address,implementation,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,UBIScheme,0x22867567e2d80f2049200e25c6f31cb6ec2f0faf,1,0xea12bb3917cf6ae2fde97ce4756177703426d41f,WithdrawFromDao,"WithdrawFromDao(uint256,uint256)",0x3107ec7eaa50b775d2486c7a394472235804b6fe1c0d4b7bd1d79b09df60f2ba,false,,uint256 uint256,prevBalance newBalance,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,WXDC,0x951857744785e80e2de051c32ee7b25f9c458c42,1,0x951857744785e80e2de051c32ee7b25f9c458c42,Approval,"Approval(address,address,uint256)",0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,false,0 1,address address uint256,src guy wad,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,WXDC,0x951857744785e80e2de051c32ee7b25f9c458c42,1,0x951857744785e80e2de051c32ee7b25f9c458c42,Deposit,"Deposit(address,uint256)",0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c,false,0,address uint256,dst wad,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,WXDC,0x951857744785e80e2de051c32ee7b25f9c458c42,1,0x951857744785e80e2de051c32ee7b25f9c458c42,Transfer,"Transfer(address,address,uint256)",0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,false,0 1,address address uint256,src dst wad,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, +XDC,50,WXDC,0x951857744785e80e2de051c32ee7b25f9c458c42,1,0x951857744785e80e2de051c32ee7b25f9c458c42,Withdrawal,"Withdrawal(address,uint256)",0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65,false,0,address uint256,src wad,false,,,etherscan_v2_verified_source,measured_2026_09_24_union_of_published_artifact_onchain_registry_and_chain_index, diff --git a/projects/onchain-analytics/gd_dbt/tests/assert_claim_amount_is_plausible.sql b/projects/onchain-analytics/gd_dbt/tests/assert_claim_amount_is_plausible.sql index c883dbe..3bc338b 100644 --- a/projects/onchain-analytics/gd_dbt/tests/assert_claim_amount_is_plausible.sql +++ b/projects/onchain-analytics/gd_dbt/tests/assert_claim_amount_is_plausible.sql @@ -11,6 +11,13 @@ -- say why in the commit. -- -- Returns a row (i.e. fails) for any claim outside the band. +-- +-- STRENGTHENED 2026-09-28 with a raw lower bound, because the band above catches a wrong SCALE and +-- was blind to a wrong LAYOUT. A decoder reading an event against the wrong indexed layout returns +-- a word from the wrong offset, and those arrive as tiny integers -- 4, for instance, being the +-- byte length of the string "celo" read as a uint256. That is 4e-18 GD, comfortably inside +-- "greater than zero", so the original band would have passed it. It is the exact value a reversed +-- union ABI produces, which makes it the one value this test most needs to catch. SELECT network, @@ -21,4 +28,4 @@ SELECT token_decimals FROM {{ ref('claim_events') }} WHERE claim_amount IS NOT NULL - AND (claim_amount <= 0 OR claim_amount > 100000) + AND (claim_amount <= 0 OR claim_amount > 100000 OR claim_amount < 0.000001) diff --git a/projects/onchain-analytics/gd_dbt/tests/assert_era_intervals_do_not_overlap.sql b/projects/onchain-analytics/gd_dbt/tests/assert_era_intervals_do_not_overlap.sql new file mode 100644 index 0000000..0945793 --- /dev/null +++ b/projects/onchain-analytics/gd_dbt/tests/assert_era_intervals_do_not_overlap.sql @@ -0,0 +1,41 @@ +-- Era intervals must not overlap, per (chain, contract). +-- +-- An era is a Type-2 validity interval: exactly one implementation is behind a proxy at any block. +-- Two overlapping intervals mean the "which ABI was in force at block N" question has two answers, +-- and a topic0-keyed decoder would take whichever the join happened to return -- silently, and +-- differently between runs. +-- +-- Intervals are HALF-OPEN, [valid_from_block, valid_to_block), which is the convention the era +-- lookup in the pipeline already implements. Two intervals therefore overlap when one starts +-- strictly before the other ends AND ends strictly after the other starts. Touching intervals +-- (a.valid_to = b.valid_from) are correct and must not be flagged. +-- +-- Returns a row (i.e. fails) for each overlapping pair. + +WITH intervals AS ( + SELECT + chain, + chain_id, + proxy_address, + era_index, + CAST(valid_from_block AS INT64) AS valid_from_block, + CAST(valid_to_block AS INT64) AS valid_to_block + FROM {{ ref('era_intervals') }} +) + +SELECT + a.chain, + a.proxy_address, + a.era_index AS era_a, + b.era_index AS era_b, + a.valid_from_block AS a_from, + a.valid_to_block AS a_to, + b.valid_from_block AS b_from, + b.valid_to_block AS b_to +FROM intervals a +JOIN intervals b + ON a.chain_id = b.chain_id + AND a.proxy_address = b.proxy_address + AND a.era_index < b.era_index +WHERE a.valid_from_block < b.valid_to_block + AND a.valid_to_block > b.valid_from_block diff --git a/projects/onchain-analytics/gd_dbt/tests/assert_era_intervals_have_no_gaps.sql b/projects/onchain-analytics/gd_dbt/tests/assert_era_intervals_have_no_gaps.sql new file mode 100644 index 0000000..8fab76c --- /dev/null +++ b/projects/onchain-analytics/gd_dbt/tests/assert_era_intervals_have_no_gaps.sql @@ -0,0 +1,93 @@ +-- Era intervals must leave no gap between a contract's deployment and its head. +-- +-- A gap is worse than an overlap. An overlap gives two answers to "which ABI was in force at block +-- N"; a gap gives NONE, and a left join against a missing interval returns null rather than +-- raising, so every log in the gap decodes to nothing and is indistinguishable from a block range +-- that produced no logs at all. +-- +-- Intervals are half-open, so "no gap" is an exact equality: era N's valid_to_block must equal +-- era N+1's valid_from_block. The first era must start at the contract's creation block, and the +-- last must be open ended (the INT64 sentinel) when the contract is live. +-- +-- Returns a row (i.e. fails) for each break in the chain. + +WITH intervals AS ( + SELECT + chain, + chain_id, + proxy_address, + contract_name, + CAST(era_index AS INT64) AS era_index, + CAST(valid_from_block AS INT64) AS valid_from_block, + CAST(valid_to_block AS INT64) AS valid_to_block, + is_live + FROM {{ ref('era_intervals') }} +), + +deployment AS ( + SELECT + chain_id, + proxy_address, + CAST(era_index AS INT64) AS era_index, + CAST(creation_block AS INT64) AS creation_block + FROM {{ ref('contract_deployments') }} + WHERE era_method != 'no_code_deployed' + AND era_index = '1' +), + +-- 1. A break between one era and the next. +interior AS ( + SELECT + a.chain, + a.proxy_address, + a.contract_name, + 'era_boundary_not_contiguous' AS failure, + a.era_index AS era_index, + a.valid_to_block AS expected_next_from, + b.valid_from_block AS actual_next_from + FROM intervals a + JOIN intervals b + ON a.chain_id = b.chain_id + AND a.proxy_address = b.proxy_address + AND b.era_index = a.era_index + 1 + WHERE a.valid_to_block != b.valid_from_block +), + +-- 2. The first era must open where the contract was created. +left_edge AS ( + SELECT + i.chain, + i.proxy_address, + i.contract_name, + 'first_era_does_not_start_at_creation' AS failure, + i.era_index, + d.creation_block AS expected_next_from, + i.valid_from_block AS actual_next_from + FROM intervals i + JOIN deployment d + ON i.chain_id = d.chain_id + AND i.proxy_address = d.proxy_address + WHERE i.era_index = 1 + AND i.valid_from_block != d.creation_block +), + +-- 3. A live contract's last era must reach the head, i.e. carry the open-ended sentinel. +right_edge AS ( + SELECT + chain, + proxy_address, + contract_name, + 'live_contract_last_era_is_not_open_ended' AS failure, + era_index, + 9223372036854775807 AS expected_next_from, + valid_to_block AS actual_next_from + FROM intervals + WHERE is_live = 'true' + AND valid_to_block != 9223372036854775807 +) + +SELECT * FROM interior +UNION ALL +SELECT * FROM left_edge +UNION ALL +SELECT * FROM right_edge diff --git a/projects/onchain-analytics/gd_dbt/tests/assert_event_surface_binds_to_a_real_era.sql b/projects/onchain-analytics/gd_dbt/tests/assert_event_surface_binds_to_a_real_era.sql new file mode 100644 index 0000000..7cf1aad --- /dev/null +++ b/projects/onchain-analytics/gd_dbt/tests/assert_event_surface_binds_to_a_real_era.sql @@ -0,0 +1,31 @@ +-- Every event_surface row must name a (chain, proxy_address, era_index) that exists in +-- contract_deployments. +-- +-- WHY THIS IS A SINGULAR TEST AND NOT A relationships TEST. The seed's own documentation states +-- the binding rule as "bind on (chain, proxy_address, era_index), not on a contract name". dbt's +-- built-in relationships test takes one column, so the declared version checked proxy_address +-- alone. Measured against the delivered seed on 2026-09-24: an era_index corrupted to one past +-- that contract's real maximum passes the single-column test on 2,824 of 2,824 rows. It constrains +-- nothing about the era, which is the half of the key that actually varies. +-- +-- WHAT THIS TEST DOES NOT CATCH, stated because a test trusted beyond its reach is worse than no +-- test. Re-derived on the delivered seed, not inherited: +-- era_index wrong 2,824 rows corrupted, 2,824 caught. Complete. +-- chain wrong 742 rows corruptible, 156 caught, which is 21 percent. +-- The residue is 14 addresses deployed at the identical address with the identical era index on +-- two chains, so a flipped chain still resolves to a real row. That is invisible to any foreign +-- key and needs a different check, most likely comparing the runtime code hash per chain. +-- +-- On the seed as delivered, zero rows fail either version. This is a missing guard, not an active +-- defect. +SELECT + s.chain, + s.proxy_address, + s.era_index, + s.event_signature +FROM {{ ref('event_surface') }} s +LEFT JOIN {{ ref('contract_deployments') }} d + ON d.chain = s.chain + AND d.proxy_address = s.proxy_address + AND d.era_index = s.era_index +WHERE d.proxy_address IS NULL diff --git a/projects/onchain-analytics/gd_dbt/tests/assert_exactly_one_era_covers_a_queried_block.sql b/projects/onchain-analytics/gd_dbt/tests/assert_exactly_one_era_covers_a_queried_block.sql new file mode 100644 index 0000000..eb94a6b --- /dev/null +++ b/projects/onchain-analytics/gd_dbt/tests/assert_exactly_one_era_covers_a_queried_block.sql @@ -0,0 +1,62 @@ +-- Exactly one era interval must cover any block that is actually queried. +-- +-- The overlap and gap tests check the interval chain's SHAPE. This one checks the property a +-- reader depends on: resolve a real block against the table and get exactly one answer. It is the +-- as-of temporal join the decode layer performs, run as an assertion. +-- +-- The probe blocks are taken from the intervals themselves rather than invented, so the test +-- exercises every real boundary: each era's first block, its last block, and the block one before +-- its opening. A boundary-off-by-one is the failure this shape is built to find, because a +-- half-open interval that is written closed produces exactly two covering rows at every join. +-- +-- Returns a row (i.e. fails) for any probe block covered by a number of intervals other than one. + +WITH intervals AS ( + SELECT + chain, + chain_id, + proxy_address, + contract_name, + CAST(era_index AS INT64) AS era_index, + CAST(valid_from_block AS INT64) AS valid_from_block, + CAST(valid_to_block AS INT64) AS valid_to_block + FROM {{ ref('era_intervals') }} +), + +probes AS ( + SELECT chain_id, proxy_address, valid_from_block AS probe_block, 'era_first_block' AS probe_kind + FROM intervals + UNION ALL + -- The last block an era actually covers, under the half-open convention. Skipped on the + -- open-ended sentinel, where "last block" is not a real block. + SELECT chain_id, proxy_address, valid_to_block - 1, 'era_last_block' + FROM intervals + WHERE valid_to_block != 9223372036854775807 +), + +coverage AS ( + SELECT + p.chain_id, + p.proxy_address, + p.probe_block, + p.probe_kind, + COUNT(i.era_index) AS covering_intervals, + STRING_AGG(CAST(i.era_index AS STRING), ',' ORDER BY i.era_index) AS covering_eras + FROM probes p + LEFT JOIN intervals i + ON i.chain_id = p.chain_id + AND i.proxy_address = p.proxy_address + AND p.probe_block >= i.valid_from_block + AND p.probe_block < i.valid_to_block + GROUP BY 1, 2, 3, 4 +) + +SELECT + chain_id, + proxy_address, + probe_block, + probe_kind, + covering_intervals, + covering_eras +FROM coverage +WHERE covering_intervals != 1 diff --git a/projects/onchain-analytics/gd_dbt/tests/assert_invite_bounty_is_plausible.sql b/projects/onchain-analytics/gd_dbt/tests/assert_invite_bounty_is_plausible.sql new file mode 100644 index 0000000..64c0e6e --- /dev/null +++ b/projects/onchain-analytics/gd_dbt/tests/assert_invite_bounty_is_plausible.sql @@ -0,0 +1,35 @@ +-- The invite bounty decimals tripwire. +-- +-- The sibling of `assert_claim_amount_is_plausible`, for the other consumed amount field. The need +-- is the same and it is not hypothetical: a wrong scale factor produces a plausible-looking number +-- off by a power of ten, and every grain, referential and domain test passes on it happily. +-- +-- `bounty_paid` is the inviter's own portion, a uint256 in 18-decimal token units. Measured at +-- 1000 GD on all 939 rows in the warehouse, and the contract's levels array supports a level-based +-- bonus above that, so the upper bound leaves room for a protocol change without leaving room for +-- a factor error. +-- +-- The LOWER bound is the one that catches a wrong-layout decode rather than a wrong scale. A +-- decoder reading an event against the wrong indexed layout returns a word from the wrong offset, +-- and those come back as tiny integers -- 4, for instance, being the byte length of a string read +-- as a uint256. A real bounty is never a few raw units of an 18-decimal token. +-- +-- Returns a row (i.e. fails) for any payout outside the band. + +SELECT + network, + tx_hash, + log_index, + payout_origin, + inviter_amount_g, + total_amount_g +FROM {{ ref('invite_payouts') }} +WHERE inviter_amount_g IS NOT NULL + AND ( + -- above any plausible bounty: the divide is missing, or the factor is too small + inviter_amount_g > 100000 + -- at or below zero: a referral payout is never free + OR inviter_amount_g <= 0 + -- below a millionth of one token: the signature of a wrong-layout decode, not a small payout + OR inviter_amount_g < 0.000001 + ) diff --git a/projects/onchain-analytics/gd_dbt/tests/assert_inviter_level_is_plausible.sql b/projects/onchain-analytics/gd_dbt/tests/assert_inviter_level_is_plausible.sql new file mode 100644 index 0000000..9901255 --- /dev/null +++ b/projects/onchain-analytics/gd_dbt/tests/assert_inviter_level_is_plausible.sql @@ -0,0 +1,22 @@ +-- The inviter-level tripwire. +-- +-- `inviter_level` is an INDEX into the contract's levels array, not a token amount, so it is not +-- decimals-scaled and its plausible range is tiny. That makes it the cheapest tripwire in the +-- system and one of the most discriminating: a decoder reading one word out of step returns an +-- address-shaped or 1e18-shaped integer here, and either is caught immediately. +-- +-- Measured at 0 on every InviterBounty row in the warehouse, so the level-based variation the +-- model supports has never actually occurred on this chain. The bound is set well above that +-- rather than at it, because the test exists to catch a decode error and not to freeze the +-- protocol's current configuration. +-- +-- Returns a row (i.e. fails) for any level outside the band. + +SELECT + network, + tx_hash, + log_index, + inviter_level +FROM {{ ref('invite_payouts') }} +WHERE inviter_level IS NOT NULL + AND (inviter_level < 0 OR inviter_level > 100) diff --git a/projects/onchain-analytics/pipeline-v5/README.md b/projects/onchain-analytics/pipeline-v5/README.md index b354598..9c39bbf 100644 --- a/projects/onchain-analytics/pipeline-v5/README.md +++ b/projects/onchain-analytics/pipeline-v5/README.md @@ -91,6 +91,48 @@ The BigQuery tables are created by the DDL in `../warehouse/L1/`, not by the pip live table does not have, and checks at startup that the bookkeeping tables carry the columns it is about to write, rather than failing part way into a backfill. +### Two datasets, and why staging is not one of them + +The pipeline needs **two** BigQuery datasets and will refuse to compose a staging table name if +they are configured to the same value. + +| Variable | Default | Holds | +| - | - | - | +| `DATASET_ID` | `BlockchainEvents` | The production tables. Written by MERGE, never dropped | +| `STAGING_DATASET_ID` | `BlockchainEvents_Staging` | One short-lived table per run, created and dropped | + +**This is a permission boundary, not a naming preference.** Every write stages its rows into a +temporary table and merges from it, then drops it. Wherever that table lives, the writer identity +needs permission to DELETE tables -- and while staging lived inside the production dataset, that +meant holding delete permission on the raw layer this warehouse is built on. + +The ordering makes it worse than a standing grant. Staging cleanup happens AFTER the MERGE, so a +run without that permission fails having already written production rows, and the quickest way out +in that moment is to grant delete on production. Separating the datasets moves the destructive +permission onto a dataset that holds nothing anyone would miss. + +Grant the writer, on `STAGING_DATASET_ID`: create, delete, `getData` and `updateData`. On +`DATASET_ID`: `tables.create`, `tables.get`, `tables.getData` and `tables.updateData`, and **no** +`tables.delete` and **no** `datasets.delete`. + +### Cost ceiling + +Every query and DML statement the pipeline submits carries `maximumBytesBilled`, set by +`MAX_BYTES_BILLED_PER_JOB` and defaulting to 10 GiB. BigQuery refuses a job whose estimate exceeds +it before running it, so an over-ceiling statement costs nothing rather than raising an alarm +after the money is spent. Load jobs are outside it -- they bill storage, and the API rejects the +setting on a load configuration -- as are queries a dashboard submits on its own behalf, which +never pass through this process and are bounded instead by the size of the tables exposed to them. + +### One writer at a time + +A cross-process lease excludes a second writer on the same host from merging into the same table. +Two concurrent captures of one range previously produced two rows per key while both processes +exited zero and both recorded the range as completely captured. A writer that cannot take the +lease within `WRITE_LOCK_WAIT_MS` is refused, exits nonzero, and records the range as incomplete +so the next run reads it again. A lease whose holder is no longer running is reclaimed at once; +one from another host expires after `WRITE_LOCK_STALE_MS`. + --- ## The seven modes diff --git a/projects/onchain-analytics/pipeline-v5/eslint.config.mjs b/projects/onchain-analytics/pipeline-v5/eslint.config.mjs new file mode 100644 index 0000000..ebc5dc1 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/eslint.config.mjs @@ -0,0 +1,48 @@ +// @ts-check +import js from "@eslint/js"; +import tseslint from "typescript-eslint"; + +/** + * Lint configuration. + * + * DELIBERATELY NARROW. This phase is forbidden from changing production behaviour, so a rule set + * that demands edits to existing code would force exactly the change it is not allowed to make. + * What is enabled is the set that catches the defect SHAPES this project has actually shipped: + * a promise whose rejection nobody handles, a condition that is always true, a variable used + * before it is defined. Style is not linted; that is what review is for. + * + * Type-aware rules are off on purpose. They need a second full type-check pass, and the strict + * `tsc --noEmit` in `npm run typecheck` already runs one. + */ +export default tseslint.config( + { + ignores: ["dist/**", "node_modules/**", "coverage/**", "**/*.d.ts"], + }, + js.configs.recommended, + ...tseslint.configs.recommended, + { + files: ["**/*.ts"], + rules: { + // `any` is used throughout for BigQuery rows and JSON-RPC results, both of which are + // genuinely unshaped at the boundary. Flagging every one would be noise, not signal. + "@typescript-eslint/no-explicit-any": "off", + // Caught by tsc with `strict`, and the ESLint version double-reports it. + "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_", varsIgnorePattern: "^_" }], + "no-constant-condition": ["error", { checkLoops: false }], + "no-empty": ["error", { allowEmptyCatch: true }], + }, + }, + { + files: ["**/*.mjs"], + languageOptions: { + globals: { process: "readonly", console: "readonly", URL: "readonly", fetch: "readonly" }, + }, + }, + { + // Test doubles impersonate third-party clients, so they carry looser shapes by necessity. + files: ["test/**/*.ts"], + rules: { + "@typescript-eslint/no-unused-expressions": "off", + }, + }, +); diff --git a/projects/onchain-analytics/pipeline-v5/package-lock.json b/projects/onchain-analytics/pipeline-v5/package-lock.json index 805e733..d4b0293 100644 --- a/projects/onchain-analytics/pipeline-v5/package-lock.json +++ b/projects/onchain-analytics/pipeline-v5/package-lock.json @@ -10,12 +10,18 @@ "dependencies": { "@envio-dev/hypersync-client": "^0.6.3", "@google-cloud/bigquery": "^7.9.1", + "csv-parse": "7.0.3", "dotenv": "^16.4.7", "viem": "^2.21.0" }, "devDependencies": { + "@eslint/js": "^9.39.5", + "@vitest/coverage-v8": "^3.2.7", + "eslint": "^9.39.5", "tsx": "^4.19.2", - "typescript": "^5.7.2" + "typescript": "^5.7.2", + "typescript-eslint": "^8.70.1", + "vitest": "^3.2.7" } }, "node_modules/@adraffy/ens-normalize": { @@ -24,6 +30,80 @@ "integrity": "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==", "license": "MIT" }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.9.tgz", + "integrity": "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.8" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/@envio-dev/hypersync-client": { "version": "0.6.7", "resolved": "https://registry.npmjs.org/@envio-dev/hypersync-client/-/hypersync-client-0.6.7.tgz", @@ -588,6 +668,212 @@ "node": ">=18" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", + "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.5" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz", + "integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.7.tgz", + "integrity": "sha512-F42g89Qd5oAWtp0k0nnSrjziAKza7w8SVT4mStc18LZMaRb4J1HQAHLCalEtDCxrTuksx7NU9qsmeLwpOfPqWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.3.2", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz", + "integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", + "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@google-cloud/bigquery": { "version": "7.9.4", "resolved": "https://registry.npmjs.org/@google-cloud/bigquery/-/bigquery-7.9.4.tgz", @@ -670,6 +956,159 @@ "node": ">=14" } }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", + "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/lzma-linux-x64-gnu": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", + "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, "node_modules/@noble/ciphers": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz", @@ -709,29 +1148,429 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@scure/base": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", - "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" + "optional": true, + "engines": { + "node": ">=14" } }, - "node_modules/@scure/bip32": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", - "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.63.5.tgz", + "integrity": "sha512-J25QJU+B78T4FhhBsNpLJyVWOi31mwtpcMwywHmOKH65Q9IWGA81gPj+dnwlhU8wktVriYE+tFAaQgrnJRzAZg==", + "cpu": [ + "arm" + ], + "dev": true, "license": "MIT", - "dependencies": { - "@noble/curves": "~1.9.0", - "@noble/hashes": "~1.8.0", - "@scure/base": "~1.2.5" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.63.5.tgz", + "integrity": "sha512-LDopB3zuZM5Ux9TT2luNEBJW/tYbGU2g1d+VpKk6I+gSKDb+/7sYE6M225gRQt4RbMX6MSwMsVR/phdjVUgRLg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.63.5.tgz", + "integrity": "sha512-wlJEERGfeuHeBavCL2qVnNacOK43NDoZM4sjkeRPymd04OAE9T1zBqDJgmZ+CIsPTYKwdzpUC8vmOw84dwY4Tg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.63.5.tgz", + "integrity": "sha512-4nJJGg5jbo2wwPP4JP+LfEBA3bvP8rU9CLuhp7jWvq9sxEyhjQFTFdrqi+/dHEin/pd8jpT0vcehIpnZtmEdcQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.63.5.tgz", + "integrity": "sha512-DrZbyCDF1hneuO6jRbvZ2D7+PIBM6yIwYnJpg2vIk58T+wuFpiaGZrfUr59lDWw45bg+IrpTGLPiNi/Fk4w3Cg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.63.5.tgz", + "integrity": "sha512-gqfUVMJMB3mehqywxp6hTBFfgtMQykZY19+cfiaYP0toIJLb/1DZRJHVkQQGP13W4TAwfZDWeg1qBcheTRioXQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.63.5.tgz", + "integrity": "sha512-CFmhpvAwzSaWMlN3VN7UtmoTihlZNzoP0juQib5TQRnYUyDV8dXeWOp29sobWAT6gXl/hQgAClLlEiYozQG3OQ==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.63.5.tgz", + "integrity": "sha512-Uc9H8eXCOayV6JLTH5bXKMId6qbhNHa818/BgYjm4jrlq3vZquC9cqyvHBw17xy5Mnj5f+I3gFK5JcEf3hSqrw==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.63.5.tgz", + "integrity": "sha512-VcPr/szv/1BFw112Kt//fxulXt/JPqzzidU84iW68L2DdjnOO8QFUv2zTSYBEPHD6movBD4z+bbr5y60GYM7Jw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.63.5.tgz", + "integrity": "sha512-BnxtJ5/91BrIHYIkGrmjz/lbMhqEHt1dPFqIxIFR+jPn0xVc/oUSCtIT089zfp5ufwGDlYz2UC+Fe1SRBpYFbQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.63.5.tgz", + "integrity": "sha512-LrYcHZwF+fAMNKHYTOQ5osWM4AZF7YF6D+XtsjDyEvljtt11twc+zHVXBLNEjxVSUnKYsOhvVz4Z213eW02COQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.63.5.tgz", + "integrity": "sha512-nj7QKQePAAUpCpJHtg0pR0W/b92A9NO17JS3BAQmHDn/yhmkir2p8llrKY9TOhleKIaSzy1JhxS3T9FVld6coA==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.63.5.tgz", + "integrity": "sha512-5ylkX6dWMeBKge9nTU+Rxfb+ZfaCIJ9lRqIFaK0eAMcWp7OJbYnLveLgXmm0VrvuLKb8qIK+mHyH0qu88RM+iA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.63.5.tgz", + "integrity": "sha512-oHK4ZHYFDKjZviK34I+NwgfbGxgI7ztrNxj2hPTSSNFgeq1a/lEd7dHV2fdGAuTH4Iym3RHJg+vAbWaWG4B7Zg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.63.5.tgz", + "integrity": "sha512-UcetmHZ6XOXuUByiKZyQmb55ZPr0LABr3Ec/HB9wKZn6CEAFWZkE+hsJErJ9hbPBC7nI0dKuELx7CoV6IM7TMg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.63.5.tgz", + "integrity": "sha512-C5CmDPQBtvjVo8cgQsBs+w6WB0JLkiixhgi6hVLV11hERWdn/p0XcPU2OUcZzac9BPOFq7SbaHFa8r3SWEysCQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.63.5.tgz", + "integrity": "sha512-lHVQHJFKsuuxLMi3MQO9XVL8Tje3JR82CzB+QDKC5NWBcsIWuwsn9uIM5e3lBhI+fF1/s63qnyYqsg65+8rV/w==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.63.5.tgz", + "integrity": "sha512-3W9bTFcQNJn71cSJVM9RKIiZOy8DO/XLDii8Uv/Pm6WKqDRj7JV3ZfuXIEfyuy5LXpIzAbB/1M4Ukp9GKNa7nA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.63.5.tgz", + "integrity": "sha512-VDC7rRJlee/scpki96GZ27Omf6yU87s1YXwVTpjE5841faVlDYYT565rgfmoR1U0sqL7z5ivQSDjcsF6VRXyBA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.63.5.tgz", + "integrity": "sha512-z86Ok2p4pTdv5xqCKZsTooO7yBEiaJR/HzU3Wx8RmWsPoLppnMKROhJusQob8B3IE1ghC343kUW9rC2r+Wf3ig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.63.5.tgz", + "integrity": "sha512-IzQmj+xXwQFGhMAMKMQVXkMwMZN3TqkJgAE0nSsqvVwWWciP4AIPMmWRqOQ2GfX7TUDZr+xqGFcBS36CRPGw0g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.63.5.tgz", + "integrity": "sha512-F6qpTaPc9bwBH85kjy0/BLmLSW1uv7AoOXCoRIkg2arlgCYlWYcAbiMkvZuAcaWk9TpCRG//okznLAqLGshkMw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.63.5.tgz", + "integrity": "sha512-igoDsTFhhwECBeGbUuLeIk7t8Y1apa+cs6mDWpx2EZ0ch7oEQgzHbFUXN9euoHekCAQzXdXApAGkV6jznS7tWw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.63.5.tgz", + "integrity": "sha512-U3teMeMbXFmaM5D+OTJpsOXd+wV/qftIeYF9kBKL4v73641qyJmoXFtA28DQLsnmlyayEsTe72xpLHrArq6vHw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.63.5.tgz", + "integrity": "sha512-ypfC34F3RKXvCXBglGqGMsUSMKlgwd1HX9AOAlx9RoZZ6GaI42YHVeKpzg3JG+wpBUJYTG+NNZhqbDWL8tBZkw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@scure/base": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", + "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", + "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.9.0", + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@scure/bip39": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", @@ -754,10 +1593,42 @@ "node": ">= 10" } }, - "node_modules/@types/caseless": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", - "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==", + "node_modules/@types/caseless": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", + "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==", + "license": "MIT" + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, "license": "MIT" }, "node_modules/@types/node": { @@ -787,6 +1658,398 @@ "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", "license": "MIT" }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.70.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.70.1.tgz", + "integrity": "sha512-nDNrUQ/4ruSNYbu749TRY7cfrzPtoLHEXSNBI8aaNY32LlZCajixqRf3FqcKC4p5Cam4VOHYx/t+i5+nKXvrqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.70.1", + "@typescript-eslint/type-utils": "8.70.1", + "@typescript-eslint/utils": "8.70.1", + "@typescript-eslint/visitor-keys": "8.70.1", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.70.1", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.10.tgz", + "integrity": "sha512-HpbUakT7xp5miBUywCHf36ZEuAJNklBJDDsGpUIjMzOSmM8ELSfA9Sa/QDPeNeqeoN31u+UTCkL4klCOVvRm4Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.70.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.70.1.tgz", + "integrity": "sha512-nO974WLllwhSFWQXnMLj6nDGa8f0khKEz1JzpPJ1u7Vm/4X1X6ZHajpoknU4bb41vJyMB0HHVyS2GqdhWfIXZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.70.1", + "@typescript-eslint/types": "8.70.1", + "@typescript-eslint/typescript-estree": "8.70.1", + "@typescript-eslint/visitor-keys": "8.70.1", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.70.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.70.1.tgz", + "integrity": "sha512-62xOgboPfwc3/IgPSX/W6oQR3ZbF04194FPGUGH8HL8iLFHbt/456/8Ph1wLNUgVF+s94FlHoipBsz+v7+LMnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.70.1", + "@typescript-eslint/types": "^8.70.1", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.70.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.70.1.tgz", + "integrity": "sha512-Pa0EeSeAusQc1WbjQMac+YfenewYTBu0KjgYvkUKwhXaHUKbFog23Dm/rp0DX/6tyYOQ3Xl1a+3EcFNZynGHCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.70.1", + "@typescript-eslint/visitor-keys": "8.70.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.70.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.70.1.tgz", + "integrity": "sha512-jumze1fPI+sDOaM2TWGQdn39PDxTr7TZGeuyLkAbNyx2vtMT3uRnVKChN0hfht5V2TugphJzF6bYXvBcE09qqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.70.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.70.1.tgz", + "integrity": "sha512-7zKTnyvaVWqzLZHPFQtX1hVHqgkMC+WebPWakNCSyrQVbIP1AM0L0TlBZtACldIRb6PptI8Odk+jyZ5kP3B1VA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.70.1", + "@typescript-eslint/typescript-estree": "8.70.1", + "@typescript-eslint/utils": "8.70.1", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.70.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.70.1.tgz", + "integrity": "sha512-Dm1ypdhhrGCTyyehxElhgJ6kgk8MVCv5qXdoOVqPr1uqk42jX8KjrZqhROvdShczA8qrDoYiOWn1ykWlx2k81Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.70.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.70.1.tgz", + "integrity": "sha512-TU8PwyGN0PQJUcE96mw8eCQ44SmxGdQlJmlWakHaHQ15eIuuvye5yNtmh/i6oS88jzXVQB71xdNkbkB/fMwL0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.70.1", + "@typescript-eslint/tsconfig-utils": "8.70.1", + "@typescript-eslint/types": "8.70.1", + "@typescript-eslint/visitor-keys": "8.70.1", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.70.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.70.1.tgz", + "integrity": "sha512-Esgul8MsnKnRLdYU2Eb2cRV9bS5HJYtKj1ByJnOzzG2M58DGdSUQ1jUuILxipqcpB2h9WLrbD5GijIWUjX/Tqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.70.1", + "@typescript-eslint/types": "8.70.1", + "@typescript-eslint/typescript-estree": "8.70.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.70.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.70.1.tgz", + "integrity": "sha512-Vwj9lUIW5Xq3wQ9w6gv3R86g1hMK8f2zNOdGTAgeXUMMXFK78G9ruCjjqutHMNJc0+CH7LYRnHeUB9IT8wFmcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.70.1", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@vitest/coverage-v8": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.7.tgz", + "integrity": "sha512-NEGWJS2XNu2PfRLQwOO3CTKj1tTETxNBdk454vDxVBhxJYhPaA/eS0nAI0c+1El1P7a60z8+i+ZrQoGESweGKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "@bcoe/v8-coverage": "^1.0.2", + "ast-v8-to-istanbul": "^0.3.3", + "debug": "^4.4.1", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^5.0.6", + "istanbul-reports": "^3.1.7", + "magic-string": "^0.30.17", + "magicast": "^0.3.5", + "std-env": "^3.9.0", + "test-exclude": "^7.0.1", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "3.2.7", + "vitest": "3.2.7" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + } + }, + "node_modules/@vitest/expect": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.7.tgz", + "integrity": "sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.7", + "@vitest/utils": "3.2.7", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.7.tgz", + "integrity": "sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.2.7", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.7.tgz", + "integrity": "sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.7.tgz", + "integrity": "sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.2.7", + "pathe": "^2.0.3", + "strip-literal": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.7.tgz", + "integrity": "sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.7", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.7.tgz", + "integrity": "sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.7.tgz", + "integrity": "sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.7", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, "node_modules/abitype": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.2.3.tgz", @@ -808,6 +2071,29 @@ } } }, + "node_modules/acorn": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", @@ -817,6 +2103,56 @@ "node": ">= 14" } }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.4.0.tgz", + "integrity": "sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, "node_modules/arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", @@ -826,12 +2162,44 @@ "node": ">=8" } }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-v8-to-istanbul": { + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.12.tgz", + "integrity": "sha512-BRRC8VRZY2R4Z4lFIL35MwNXmwVqBityvOIwETtsCSwvjl0IdgFsy9NhdaA6j74nUdtJJlIypeRhpDam19Wq3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.31", + "estree-walker": "^3.0.3", + "js-tokens": "^10.0.0" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -874,12 +2242,35 @@ "node": "*" } }, + "node_modules/brace-expansion": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz", + "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, "node_modules/buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", "license": "BSD-3-Clause" }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -893,6 +2284,96 @@ "node": ">= 0.4" } }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -905,6 +2386,34 @@ "node": ">= 0.8" } }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csv-parse": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-7.0.3.tgz", + "integrity": "sha512-YFd3QM/yo17vH91L1IOZuvl09zM0zEEtdfTcOCKWcMdM++MNaQSyp09slXyFCLaPXvHstQFx/xC8myiFHSMUvw==", + "license": "MIT" + }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -922,6 +2431,23 @@ } } }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -969,6 +2495,13 @@ "stream-shift": "^1.0.2" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -978,6 +2511,13 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, "node_modules/end-of-stream": { "version": "1.4.5", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", @@ -1005,6 +2545,13 @@ "node": ">= 0.4" } }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, "node_modules/es-object-atoms": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", @@ -1074,17 +2621,343 @@ "@esbuild/win32-x64": "0.28.1" } }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", + "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.6", + "@eslint/js": "9.39.5", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz", + "integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", "license": "MIT" }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "license": "MIT" + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz", + "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==", + "dev": true, + "license": "ISC" + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, "node_modules/form-data": { "version": "2.5.6", @@ -1194,6 +3067,87 @@ "node": ">= 0.4" } }, + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.7.tgz", + "integrity": "sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/google-auth-library": { "version": "9.15.1", "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", @@ -1245,6 +3199,16 @@ "node": ">=14.0.0" } }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", @@ -1300,6 +3264,13 @@ ], "license": "MIT" }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, "node_modules/http-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", @@ -1339,6 +3310,43 @@ "node": ">= 14" } }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -1354,6 +3362,39 @@ "node": ">= 0.4" } }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -1366,6 +3407,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, "node_modules/isows": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.7.tgz", @@ -1381,6 +3429,106 @@ "ws": "*" } }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/js-tokens": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", + "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/json-bigint": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", @@ -1390,6 +3538,27 @@ "bignumber.js": "^9.0.0" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/jwa": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", @@ -1411,6 +3580,105 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/magicast": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", + "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.4", + "@babel/types": "^7.25.4", + "source-map-js": "^1.2.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -1434,17 +3702,69 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.8" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.19", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz", + "integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" }, "engines": { - "node": ">= 0.6" + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, "license": "MIT" }, "node_modules/node-fetch": { @@ -1476,6 +3796,24 @@ "wrappy": "1" } }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/ox": { "version": "0.14.33", "resolved": "https://registry.npmjs.org/ox/-/ox-0.14.33.tgz", @@ -1506,6 +3844,181 @@ } } }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.28", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz", + "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.18", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -1520,6 +4033,16 @@ "node": ">= 6" } }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/retry-request": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", @@ -1534,6 +4057,52 @@ "node": ">=14" } }, + "node_modules/rollup": { + "version": "4.63.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.63.5.tgz", + "integrity": "sha512-KRWwmNLlPw5M7HcdYfm15oBv9n9LPtjzpzCIxS/phwqvPyxHSoKX6Y2YU3pxSPfy0CLquVgsx/j/hBi6OvH1Nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@napi-rs/lzma-linux-x64-gnu": "1.5.1", + "@rollup/rollup-android-arm-eabi": "4.63.5", + "@rollup/rollup-android-arm64": "4.63.5", + "@rollup/rollup-darwin-arm64": "4.63.5", + "@rollup/rollup-darwin-x64": "4.63.5", + "@rollup/rollup-freebsd-arm64": "4.63.5", + "@rollup/rollup-freebsd-x64": "4.63.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.63.5", + "@rollup/rollup-linux-arm-musleabihf": "4.63.5", + "@rollup/rollup-linux-arm64-gnu": "4.63.5", + "@rollup/rollup-linux-arm64-musl": "4.63.5", + "@rollup/rollup-linux-loong64-gnu": "4.63.5", + "@rollup/rollup-linux-loong64-musl": "4.63.5", + "@rollup/rollup-linux-ppc64-gnu": "4.63.5", + "@rollup/rollup-linux-ppc64-musl": "4.63.5", + "@rollup/rollup-linux-riscv64-gnu": "4.63.5", + "@rollup/rollup-linux-riscv64-musl": "4.63.5", + "@rollup/rollup-linux-s390x-gnu": "4.63.5", + "@rollup/rollup-linux-x64-gnu": "4.63.5", + "@rollup/rollup-linux-x64-musl": "4.63.5", + "@rollup/rollup-openbsd-x64": "4.63.5", + "@rollup/rollup-openharmony-arm64": "4.63.5", + "@rollup/rollup-win32-arm64-msvc": "4.63.5", + "@rollup/rollup-win32-ia32-msvc": "4.63.5", + "@rollup/rollup-win32-x64-gnu": "4.63.5", + "@rollup/rollup-win32-x64-msvc": "4.63.5", + "fsevents": "~2.3.2" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -1554,6 +4123,86 @@ ], "license": "MIT" }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, "node_modules/stream-events": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", @@ -1575,15 +4224,165 @@ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "license": "MIT", "dependencies": { - "safe-buffer": "~5.2.0" + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", + "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" } }, + "node_modules/strip-literal/node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, "node_modules/stubs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", "license": "MIT" }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/teeny-request": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", @@ -1625,12 +4424,101 @@ "node": ">= 6" } }, + "node_modules/test-exclude": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.2.tgz", + "integrity": "sha512-u9E6A+ZDYdp7a4WnarkXPZOx8Ilz46+kby6p1yZ8zsGTz9gYa6FIS7lj2oezzNKmtdyyJNNmmXDppga5GB7kSw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^10.4.1", + "minimatch": "^10.2.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.6.tgz", + "integrity": "sha512-u8KszXvGfU68hVcZpRHKG28T0krMuv2G5nDhiHaMLen/gIuFEgIJhaJuO69qjnXg5paSrbPMFfx3brNuN8eVSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, "node_modules/tsx": { "version": "4.23.1", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.1.tgz", @@ -1650,6 +4538,19 @@ "fsevents": "~2.3.3" } }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", @@ -1664,12 +4565,46 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.70.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.70.1.tgz", + "integrity": "sha512-AcWG7KDjZ2THNXsgwttMaGmzVi0VFRlFYfqFHYQRbDpF3owuYbuiL8c7UUrd2k8s3PoSfIQrWfrGXfcElrWLYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.70.1", + "@typescript-eslint/parser": "8.70.1", + "@typescript-eslint/typescript-estree": "8.70.1", + "@typescript-eslint/utils": "8.70.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, "node_modules/undici-types": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", "license": "MIT" }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -1720,6 +4655,177 @@ } } }, + "node_modules/vite": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz", + "integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0 || ^0.28.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.7.tgz", + "integrity": "sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/expect": "3.2.7", + "@vitest/mocker": "3.2.7", + "@vitest/pretty-format": "^3.2.7", + "@vitest/runner": "3.2.7", + "@vitest/snapshot": "3.2.7", + "@vitest/spy": "3.2.7", + "@vitest/utils": "3.2.7", + "chai": "^5.2.0", + "debug": "^4.4.1", + "expect-type": "^1.2.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "std-env": "^3.9.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.14", + "tinypool": "^1.1.1", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", + "vite-node": "3.2.4", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.2.7", + "@vitest/ui": "3.2.7", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -1736,6 +4842,147 @@ "webidl-conversions": "^3.0.0" } }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -1762,6 +5009,19 @@ "optional": true } } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/projects/onchain-analytics/pipeline-v5/package.json b/projects/onchain-analytics/pipeline-v5/package.json index a315e26..7c46b15 100644 --- a/projects/onchain-analytics/pipeline-v5/package.json +++ b/projects/onchain-analytics/pipeline-v5/package.json @@ -6,16 +6,31 @@ "scripts": { "daily": "tsx src/index.ts daily", "backfill": "tsx src/index.ts backfill", - "typecheck": "tsc --noEmit" + "typecheck": "tsc --noEmit", + "lint": "eslint .", + "build:check": "tsx src/control-plane/build-check.ts", + "test": "vitest run", + "test:unit": "vitest run test/unit", + "test:integration": "vitest run test/integration", + "test:coverage": "vitest run --coverage", + "test:known-failures": "vitest run --config vitest.known-failures.config.ts", + "gate:write-safety": "tsx test/integration/two-process-merge.gate.ts", + "verify:local": "npm run lint && npm run typecheck && npm run build:check && npm run test:coverage && npm run test:known-failures" }, "dependencies": { "@envio-dev/hypersync-client": "^0.6.3", "@google-cloud/bigquery": "^7.9.1", + "csv-parse": "7.0.3", "dotenv": "^16.4.7", "viem": "^2.21.0" }, "devDependencies": { + "@eslint/js": "^9.39.5", + "@vitest/coverage-v8": "^3.2.7", + "eslint": "^9.39.5", "tsx": "^4.19.2", - "typescript": "^5.7.2" + "typescript": "^5.7.2", + "typescript-eslint": "^8.70.1", + "vitest": "^3.2.7" } } diff --git a/projects/onchain-analytics/pipeline-v5/src/adapters.ts b/projects/onchain-analytics/pipeline-v5/src/adapters.ts new file mode 100644 index 0000000..d1b03cb --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/src/adapters.ts @@ -0,0 +1,280 @@ +/** + * adapters.ts -- the replaceable edges of this program. + * + * WHY THIS FILE EXISTS. Every defect the readiness audit reproduced sits behind something this + * process cannot do in a test: a BigQuery job, a socket, a wall clock, a second process. Until + * those edges are replaceable, the only way to exercise a defect is to run the real thing against + * real infrastructure, which is how a warehouse gets a production incident during an audit. + * + * WHAT THIS FILE IS NOT. It is not a fix for anything. Every default below is the behaviour the + * program has today, written down rather than changed -- with one exception, now that the write + * lock behind `C1` has been built. `NO_LOCK` is still here and still means "no exclusion at + * all", but it is no longer what production gets: `bq.ts` registers the real lease as a factory + * on import. Keeping `NO_LOCK` exported is what lets a test install the absence deliberately and + * show the difference, which is how the control is proven rather than asserted. + * + * Each adapter is a module-level holder with a setter and a reset, rather than a parameter + * threaded through every call site. That is a deliberate trade: threading would have touched + * every function in the pipeline. A holder changes construction only. + */ + +import type { MergeWindow } from "./types.js"; + +// --------------------------------------------------------------------------- BigQuery + +/** + * The narrow slice of `@google-cloud/bigquery` this pipeline actually uses. Narrow on purpose: + * a test double implements six members instead of the whole client surface, and anything the + * pipeline starts using has to be added here first, where it is visible. + */ +export interface BigQueryTableLike { + load(source: string, metadata: unknown): Promise; + getMetadata(): Promise<[{ schema?: { fields?: { name: string }[] } }, ...unknown[]]>; +} + +export interface BigQueryDatasetLike { + table(tableId: string): BigQueryTableLike; +} + +export interface BigQueryClientLike { + query(request: { + query: string; + params?: Record; + types?: Record; + projectId?: string; + /** The per-job cost ceiling. A string because the REST field is an int64. */ + maximumBytesBilled?: string; + }): Promise<[any[], ...unknown[]]>; + dataset(datasetId: string, options?: { projectId?: string }): BigQueryDatasetLike; +} + +let bigQueryClient: BigQueryClientLike | null = null; +let bigQueryFactory: (() => BigQueryClientLike) | null = null; + +/** + * Register how a real client is built, without building one. + * + * `bq.ts` constructed its client at import time, which means importing any module that + * transitively reaches it resolved credentials as a side effect of an import. A test that only + * wanted to read a pure function paid for a credential lookup, and a machine with no credentials + * could not import the module at all. + */ +export function setBigQueryFactory(factory: () => BigQueryClientLike): void { + bigQueryFactory = factory; +} + +/** Replace the client. Tests use this; nothing in `src/` does. */ +export function setBigQueryClient(client: BigQueryClientLike | null): void { + bigQueryClient = client; +} + +export function getBigQueryClient(): BigQueryClientLike { + if (bigQueryClient) return bigQueryClient; + if (!bigQueryFactory) { + throw new Error( + "BQ_CLIENT_UNSET: no BigQuery client and no factory registered. `bq.ts` registers the real " + + "factory on import; a test must call setBigQueryClient() before any query." + ); + } + bigQueryClient = bigQueryFactory(); + return bigQueryClient; +} + +// --------------------------------------------------------------------------- RPC transport + +/** What `rpc.ts` needs from `fetch`. Kept to exactly this so a recorder is a few lines. */ +export interface RpcTransportResponse { + ok: boolean; + status: number; + text(): Promise; +} + +export type RpcTransport = ( + url: string, + init: { method: string; headers: Record; body: string; signal?: AbortSignal } +) => Promise; + +const REAL_TRANSPORT: RpcTransport = (url, init) => + fetch(url, init) as unknown as Promise; + +let rpcTransport: RpcTransport = REAL_TRANSPORT; + +export function setRpcTransport(transport: RpcTransport | null): void { + rpcTransport = transport ?? REAL_TRANSPORT; +} + +export function getRpcTransport(): RpcTransport { + return rpcTransport; +} + +// --------------------------------------------------------------------------- Clock + +export interface Clock { + now(): Date; +} + +const REAL_CLOCK: Clock = { now: () => new Date() }; + +let clock: Clock = REAL_CLOCK; + +export function setClock(replacement: Clock | null): void { + clock = replacement ?? REAL_CLOCK; +} + +export function now(): Date { + return clock.now(); +} + +/** The form every timestamp column in this warehouse is written in. */ +export function nowIso(): string { + return clock.now().toISOString(); +} + +// --------------------------------------------------------------------------- Write lock + +/** + * The cross-process write lease. + * + * C1: two concurrent captures of the same range each staged their own batch, each measured the + * target before and after their own MERGE, and both exited zero while the table held two rows + * per merge key. The control is now real and lives in `writelock.ts`; `bq.ts` registers it as a + * FACTORY on import, for the same reason the BigQuery client is a factory -- building one at + * import time would make every test that transitively reaches this module touch the filesystem. + * + * `NO_LOCK` remains exported, and it is no longer the production default. It is the absence of + * the control written down, so a test can install it deliberately and show what the write path + * does without exclusion. `acquire` may return null to mean refused, which is what turns a + * losing writer into a nonzero exit rather than a duplicate row. + */ +export interface WriteLockHandle { + release(): Promise; +} + +export interface WriteLock { + /** Null means refused. A handle means the caller may mutate `tableId` over `window`. */ + acquire(tableId: string, window: MergeWindow | null): Promise; +} + +const GRANTED: WriteLockHandle = { release: async () => { /* nothing is held */ } }; + +/** Grants every request instantly and excludes nothing. The absence of a lock, written down. */ +export const NO_LOCK: WriteLock = { acquire: async () => GRANTED }; + +let writeLock: WriteLock | null = null; +let writeLockFactory: (() => WriteLock) | null = null; + +/** Register how the real lock is built, without building one. `bq.ts` calls this on import. */ +export function setWriteLockFactory(factory: () => WriteLock): void { + writeLockFactory = factory; +} + +/** Replace the lock. Tests use this; nothing in `src/` does. */ +export function setWriteLock(replacement: WriteLock | null): void { + writeLock = replacement; +} + +/** + * The lock in force. + * + * Falls back to `NO_LOCK` only when no factory has been registered at all, which means nothing + * has imported `bq.ts` and therefore nothing is about to write. + */ +export function getWriteLock(): WriteLock { + if (writeLock) return writeLock; + if (!writeLockFactory) return NO_LOCK; + writeLock = writeLockFactory(); + return writeLock; +} + +// --------------------------------------------------------------------------- Reader + +/** + * The whole reader, replaceable as one unit. + * + * A chain's reader is either a HyperSync index in a child process or a rotation of JSON-RPC + * endpoints. Neither can run in a test, and neither can be made to return a chosen shape by + * stubbing `fetch` alone: the index path never touches `fetch` at all. So the dispatch point in + * `reader.ts` consults this first. + * + * `null` means "use the real reader", which is what every production path gets. + */ +export type FetchRangeFn = ( + network: unknown, + addresses: string[], + fromBlock: number, + toBlock: number, + onChunk: (chunk: any) => Promise +) => Promise; + +let readerOverride: FetchRangeFn | null = null; + +export function setReaderOverride(replacement: FetchRangeFn | null): void { + readerOverride = replacement; +} + +export function getReaderOverride(): FetchRangeFn | null { + return readerOverride; +} + +// --------------------------------------------------------------------------- HyperSync worker + +/** + * The HyperSync worker call, replaceable. + * + * `setReaderOverride` replaces the WHOLE reader, which is the right seam for a test about the + * pipeline and the wrong one for a test about the index reader itself: everything in + * `hypersync.ts` -- chunk planning, bounded retries, the short-collection refusal, empty-chunk + * tracking and rollback-guard forwarding -- sits BELOW that override and is unreachable through + * it. The only thing underneath is `spawn`, so this is the seam. + * + * It replaces one request/response, not the logic around it, so a test exercises the real + * chunking and the real retry policy against a scripted worker. + */ +export type WorkerRunner = ( + request: Record, + timeoutMs: number +) => Promise>; + +let workerRunner: WorkerRunner | null = null; + +export function setWorkerRunner(replacement: WorkerRunner | null): void { + workerRunner = replacement; +} + +export function getWorkerRunner(): WorkerRunner | null { + return workerRunner; +} + +// --------------------------------------------------------------------------- Notifier + +export interface Notifier { + post(payload: Record): Promise; +} + +let notifier: Notifier | null = null; + +export function setNotifier(replacement: Notifier | null): void { + notifier = replacement; +} + +export function getNotifier(): Notifier | null { + return notifier; +} + +// --------------------------------------------------------------------------- Reset + +/** + * Put every edge back to its real default. + * + * Adapters are module-level, so one test leaking a double into the next would make a suite whose + * result depends on file order. Every test file calls this in `afterEach`. + */ +export function resetAdapters(): void { + bigQueryClient = null; + setRpcTransport(null); + setClock(null); + setWriteLock(null); + setNotifier(null); + setReaderOverride(null); + setWorkerRunner(null); +} diff --git a/projects/onchain-analytics/pipeline-v5/src/batch.ts b/projects/onchain-analytics/pipeline-v5/src/batch.ts new file mode 100644 index 0000000..e365b32 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/src/batch.ts @@ -0,0 +1,139 @@ +/** + * batch.ts -- project one batched capture down to per-target results. + * + * FINDING H2. The readers have always accepted a LIST of addresses; the pipeline only ever handed + * them one. `fetchRange(network, [target.address], ...)` sat inside a loop over targets, so a + * chain with 52 contracts issued 52 separate chunk streams over overlapping block ranges, and the + * cost plan the project is budgeted against assumes one batched address query per chain range. + * The measured multiplier is in this unit's report, re-derived from the shipped seed. + * + * THE PART THAT IS EASY TO GET WRONG, and the reason this is a module with its own tests rather + * than a few lines inside the capture loop: batching changes how a result is ATTRIBUTED. One + * query answering for 52 addresses still has to produce 52 coverage rows, each describing that + * contract's own declared range, and a chunk that failed has to be recorded against exactly the + * contracts whose range it overlaps -- not against all of them, and not against none. Closing H2 + * by simply widening the address list would trade a cost defect for a coverage defect, which is + * the worse of the two: cost is visible on a bill and a wrong coverage row is not visible at all. + * + * So the batched range is the UNION of the group's ranges, and every per-target figure is derived + * by projecting that union back onto the target's own interval. A target is never told about a + * block it did not ask for, and never told a range is clean when the chunk covering it failed. + */ + +import type { ChunkResult, FetchResult } from "./types.js"; + +/** One contract's own declared capture interval inside a batched read. */ +export interface BatchMember { + /** Lowercase contract address. Matching is on the normalised form, never the raw spelling. */ + address: string; + fromBlock: number; + toBlock: number; +} + +/** Inclusive interval overlap. */ +export function overlaps(aFrom: number, aTo: number, bFrom: number, bTo: number): boolean { + return aFrom <= bTo && bFrom <= aTo; +} + +/** The union interval a group of members must be read over, or null for an empty group. */ +export function unionRange(members: BatchMember[]): { fromBlock: number; toBlock: number } | null { + if (members.length === 0) return null; + return { + fromBlock: Math.min(...members.map((m) => m.fromBlock)), + toBlock: Math.max(...members.map((m) => m.toBlock)), + }; +} + +/** + * Narrow one batched chunk to what a single member actually asked for. + * + * TWO filters, and both are load bearing: + * ADDRESS, because the chunk holds every member's logs and a row must be attributed to the + * contract that emitted it. + * BLOCK RANGE, because the batched read spans the union of the group and a member whose + * interval starts later did not ask for the blocks below it. Attributing an early log to a + * member that declares no coverage there would put a row in the table under a capture whose + * coverage row says that range was never read. + * + * Transactions and blocks are narrowed to those the surviving logs actually point at. A batched + * chunk carries the transactions of every member, and copying all of them onto each member would + * make the Transactions table's own definition -- one row per transaction that produced at least + * one CAPTURED log -- false for every member but the one that emitted it. + */ +export function projectChunk(chunk: ChunkResult, member: BatchMember): ChunkResult { + const address = member.address.toLowerCase(); + const logs = (chunk.logs ?? []).filter((l) => { + const bn = Number(l.blockNumber); + return String(l.address).toLowerCase() === address && + Number.isFinite(bn) && bn >= member.fromBlock && bn <= member.toBlock; + }); + + const wantedTx = new Set(logs.map((l) => String(l.transactionHash).toLowerCase())); + const wantedBlocks = new Set(logs.map((l) => Number(l.blockNumber))); + + return { + ...chunk, + // The chunk's own bounds are narrowed to the member's interval so that anything reading the + // projected chunk's range sees what this member was actually read over. + fromBlock: Math.max(chunk.fromBlock, member.fromBlock), + toBlock: Math.min(chunk.toBlock, member.toBlock), + logs, + transactions: (chunk.transactions ?? []).filter((t) => wantedTx.has(String(t.hash).toLowerCase())), + blocks: (chunk.blocks ?? []).filter((b) => wantedBlocks.has(Number(b.number))), + }; +} + +/** + * Project the batched FetchResult onto one member's interval. + * + * WHAT EACH FIELD MEANS AFTER PROJECTION, stated because a plausible-looking wrong answer here is + * invisible downstream: + * + * `chunksPlanned` / `chunksOk` count only the chunks that OVERLAP this member. A member whose + * contract was created late did not have 145,000 chunks planned for it. + * `skipped` keeps only the overlapping failures, CLIPPED to the member's interval, because the + * member's coverage row describes the member's range and a skip recorded outside it would be + * read as a hole in ground the member never claimed. + * `complete` is false when any chunk overlapping this member failed. A failure elsewhere in the + * union does not make this member incomplete, and a failure inside it is not excused by the + * other members' success. + * `emptyChunks` is recomputed by the caller from the projected chunks, never inherited: a + * batched chunk holding another contract's logs is NOT empty for the batch but IS empty for + * this member, and that is a negative this member has to confirm. + * `logsSeen` likewise counts this member's logs, not the batch's. + * `rollbackGuards` are carried whole. A guard is a statement by the reader about the blocks it + * is holding, which is a property of the chain and the moment, not of one address. + */ +export function projectFetchResult( + fetch: FetchResult, + member: BatchMember, + chunkRanges: [number, number][], + perMember: { logsSeen: number; emptyChunks: [number, number][] } +): FetchResult { + const mine = chunkRanges.filter(([a, b]) => overlaps(a, b, member.fromBlock, member.toBlock)); + const skipped = fetch.skipped + .filter(([a, b]) => overlaps(a, b, member.fromBlock, member.toBlock)) + .map(([a, b]) => [Math.max(a, member.fromBlock), Math.min(b, member.toBlock)] as [number, number]); + + // A chunk that failed is reported by range, so an error line is attributed by asking whether + // the range it names overlaps this member. An error carrying no range is kept for everyone, + // because dropping an unattributable error silently is how an error count reaches zero while + // something is still wrong. + const errors = fetch.errors.filter((e) => { + const m = /(\d+)\.\.(\d+)/.exec(e); + return m === null || overlaps(Number(m[1]), Number(m[2]), member.fromBlock, member.toBlock); + }); + + return { + ...fetch, + fromBlock: member.fromBlock, + toBlock: member.toBlock, + chunksPlanned: mine.length, + chunksOk: mine.length - skipped.length, + skipped, + errors, + emptyChunks: perMember.emptyChunks, + logsSeen: perMember.logsSeen, + complete: skipped.length === 0, + }; +} diff --git a/projects/onchain-analytics/pipeline-v5/src/bq.ts b/projects/onchain-analytics/pipeline-v5/src/bq.ts index 60f1c7d..65b6340 100644 --- a/projects/onchain-analytics/pipeline-v5/src/bq.ts +++ b/projects/onchain-analytics/pipeline-v5/src/bq.ts @@ -29,14 +29,72 @@ import { tmpdir } from "os"; import { join } from "path"; import { randomUUID } from "crypto"; import { - CONFIG, fullTableName, stagingTableId, MERGE_KEYS, ALL_HISTORY_VIEWS, RAW_LOGS_TABLE, + CONFIG, fullTableName, stagingTableId, stagingTableName, MERGE_KEYS, ALL_HISTORY_VIEWS, + RAW_LOGS_TABLE, } from "./config.js"; import { log } from "./log.js"; import { windowPredicate, windowForSpan, partitionsSpanned } from "./window.js"; +import { + getBigQueryClient, setBigQueryFactory, getWriteLock, setWriteLockFactory, + type BigQueryClientLike, +} from "./adapters.js"; +import { fileWriteLock } from "./writelock.js"; +import { setDatasetAdminFactory, type DatasetAdmin } from "./sandbox.js"; import type { SchemaField, PipelineRunRecord, CoverageRecord, MergeWindow } from "./types.js"; -export const bigquery = new BigQuery({ projectId: CONFIG.GCP_PROJECT_ID }); -const dataset = bigquery.dataset(CONFIG.DATASET_ID, { projectId: CONFIG.GCP_PROJECT_ID }); +// The real client is registered as a FACTORY rather than constructed here. Constructing it at +// import time resolved credentials as a side effect of importing this module, so any test that +// reached bq.ts transitively needed a credential to run at all. +setBigQueryFactory(() => new BigQuery({ projectId: CONFIG.GCP_PROJECT_ID }) as unknown as BigQueryClientLike); + +// The sandbox guard's administrative client, registered the same way and for the same reason. +// Dataset create, list, get and delete are metadata operations: they submit no query job and bill +// no bytes. The guard's own refusals live in sandbox.ts and this client cannot bypass them, +// because nothing here is reachable except through the exported functions there. +setDatasetAdminFactory((): DatasetAdmin => { + const client = new BigQuery({ projectId: CONFIG.GCP_PROJECT_ID }); + return { + async listDatasets() { + const [datasets] = await client.getDatasets({ all: true }); + return datasets.map((d) => d.id!).filter((id): id is string => typeof id === "string"); + }, + async createDataset(datasetId, options) { + await client.createDataset(datasetId, { + location: options.location, + labels: options.labels, + description: options.description, + defaultTableExpirationMs: String(options.defaultTableExpirationMs), + }); + }, + async labelsOf(datasetId) { + try { + const [metadata] = await client.dataset(datasetId).getMetadata(); + return (metadata.labels ?? {}) as Record; + } catch (e: any) { + if (e?.code === 404) return null; + throw e; + } + }, + async deleteDataset(datasetId, options) { + await client.dataset(datasetId).delete({ force: options.deleteContents }); + }, + }; +}); + +const datasetHandle = () => + getBigQueryClient().dataset(CONFIG.DATASET_ID, { projectId: CONFIG.GCP_PROJECT_ID }); + +// Staging tables are created and dropped, so they live in their own dataset and the handle that +// reaches them is a different one. See `config.ts` on STAGING_DATASET_ID: while the two shared an +// id, a writer identity needed `tables.delete` on the production raw layer, and an ingestion run +// that failed at staging cleanup had already written production rows by the time it failed. +const stagingDatasetHandle = () => + getBigQueryClient().dataset(CONFIG.STAGING_DATASET_ID, { projectId: CONFIG.GCP_PROJECT_ID }); + +// The cross-process write lease, registered as a factory for the same reason the client above is: +// building one at import time would make every test that transitively imports this file touch the +// filesystem. C1's fix; see writelock.ts. +setWriteLockFactory(() => fileWriteLock()); // -- Retry helpers -- @@ -64,6 +122,24 @@ function sleep(ms: number): Promise { /** * Run a query with retries. * + * EVERY STATEMENT THIS PIPELINE SUBMITS GOES THROUGH HERE, and that is what makes the cost + * ceiling below a control rather than a convention. `maximumBytesBilled` is attached at this one + * chokepoint instead of at each call site, so a statement added later carries it without anyone + * remembering to. BigQuery evaluates the ceiling against the job's estimate BEFORE running it and + * refuses the job outright if it is exceeded, which means an over-ceiling query bills nothing -- + * the refusal is the control, not an alarm raised after the money is gone. + * + * A refusal is deliberately NOT retried. It is not a transient fault; the same statement will be + * refused identically every time, and retrying it five times only delays the error. `isRetriable` + * matches on transport failures and does not match this, so the refusal surfaces on the first + * attempt with BigQuery's own message naming the byte counts. + * + * Two job classes cannot carry it, both named rather than left to be discovered. Load jobs bill + * storage rather than query bytes and the jobs API rejects the setting on a load configuration, + * so the two `table.load` calls in this file are outside it by construction. Queries Looker + * Studio submits on its own behalf never reach this process and are bounded instead by the size + * of the tables exposed to them. + * * `types` is not optional decoration. The client infers a parameter's BigQuery type from its * JavaScript value, and a null has no type to infer, so a statement carrying even one nullable * parameter is rejected outright with "Parameter types must be provided for null values". Every @@ -77,8 +153,11 @@ export async function bqQuery( let lastErr: any; for (let attempt = 1; attempt <= CONFIG.BQ_RETRIES; attempt++) { try { - const [rows] = await bigquery.query({ + const [rows] = await getBigQueryClient().query({ query: sql, params, types, projectId: CONFIG.GCP_PROJECT_ID, + // A string, not a number. The REST field is an int64 and the client forwards it verbatim; + // a JavaScript number arrives as a float for large values and the API rejects it. + maximumBytesBilled: String(CONFIG.MAX_BYTES_BILLED_PER_JOB), }); return rows; } catch (e: any) { @@ -161,7 +240,7 @@ export async function countRowsInRange( * path survive the table gaining columns, which it already has once. */ export async function liveColumns(tableId: string): Promise> { - const [metadata] = await dataset.table(tableId).getMetadata(); + const [metadata] = await datasetHandle().table(tableId).getMetadata(); return new Set((metadata.schema?.fields ?? []).map((f: any) => f.name)); } @@ -197,7 +276,33 @@ export async function ensureInfraTables(): Promise { captures_planned INT64, captures_ok INT64, captures_failed INT64, - pipeline_version STRING + pipeline_version STRING, + execution_status STRING, + units_planned INT64, + units_attempted INT64, + units_completed INT64, + units_noop INT64, + units_refused INT64, + units_unsupported INT64, + units_failed INT64, + outcome_counts_by_grain JSON, + release_sha STRING, + plan_hash STRING, + parent_run_id STRING, + child_plan_stage STRING, + child_plan_root_hash STRING, + child_plan_hash STRING, + child_ordinal INT64, + stage_child_ordinal INT64, + stage_child_count INT64, + bigquery_job_ledger JSON, + job_ledger_hash STRING, + work_jobs_terminal BOOL, + terminalizer_job_id STRING, + closure_status STRING, + terminalized_at TIMESTAMP, + terminalized_row_hash STRING, + closure_receipt_uri STRING ) PARTITION BY DATE(started_at) `); @@ -213,7 +318,7 @@ export async function ensureInfraTables(): Promise { table_id STRING, from_block INT64, to_block INT64, - status STRING OPTIONS(description="complete, incomplete, unconfirmed_empty, nothing_to_fetch, refused_budget or capability_gap. Never plain success."), + status STRING OPTIONS(description="complete, incomplete, unconfirmed_empty, rollback_eligible, nothing_to_fetch, refused_budget or capability_gap. Never plain success."), chunks_planned INT64, chunks_ok INT64, skipped_ranges STRING, @@ -274,6 +379,32 @@ export async function ensureInfraTables(): Promise { ]); await assertColumns("PipelineRuns", [ "chains_processed", "captures_planned", "captures_ok", "captures_failed", "pipeline_version", + // Plan Phase 3 task 11. A dataset that predates the outcome migration fails HERE, at startup, + // naming the file to run, rather than at the INSERT after a whole run has already happened. + "execution_status", "units_planned", "units_attempted", "units_completed", "units_noop", + "units_refused", "units_unsupported", "units_failed", "outcome_counts_by_grain", + "release_sha", "plan_hash", + // The job-ledger and closure columns. This pipeline writes none of them; the mutation broker + // and the terminalizer do, in Phases 5 and 14. They are asserted here anyway, because a + // half-applied migration is the state that produces a run which believes it can close itself + // and then cannot. + "parent_run_id", "child_plan_stage", "child_plan_root_hash", "child_plan_hash", + "child_ordinal", "stage_child_ordinal", "stage_child_count", + "bigquery_job_ledger", "job_ledger_hash", "work_jobs_terminal", + "terminalizer_job_id", "closure_status", "terminalized_at", + "terminalized_row_hash", "closure_receipt_uri", + ]); + + // MEASURED: the production copy of this table predates the chain dimension. It carries 14 + // columns with `table_id` where this file declares `chain_id` and `contract_address`, so the + // rows `recordReconciliation` builds would be rejected by it -- and the create-if-absent above + // can never correct that. Without this assertion the run fails at the load step, after a + // reconciliation has already read a year of contract state, and the message names a column + // rather than the migration. + await assertColumns("OracleReconciliation", [ + "run_id", "chain_id", "network", "contract_address", "protocol_day", "oracle_block", + "oracle_count", "oracle_amount_raw", "warehouse_stored", "warehouse_distinct", + "warehouse_amount_raw", "count_gap", "amount_gap_raw", "verdict", "checked_at", ]); } @@ -304,10 +435,14 @@ export async function recordPipelineRun(record: PipelineRunRecord): Promise JSON.stringify(r)).join("\n"); const tmpFile = join(tmpdir(), `bq_staging_${runId}_${randomUUID().slice(0, 8)}.ndjson`); writeFileSync(tmpFile, ndjson); - const tbl = dataset.table(staging); + const tbl = stagingDatasetHandle().table(staging); const metadata = { sourceFormat: "NEWLINE_DELIMITED_JSON" as const, writeDisposition: "WRITE_TRUNCATE" as const, @@ -580,6 +776,7 @@ export async function stageAndMerge( } catch (e: any) { log.warn(`Failed to drop staging table ${staging}`, { error: e.message }); } + await lockHandle.release(); } } @@ -682,6 +879,45 @@ export async function duplicateReport(tableId: string, chainId: number): Promise }; } +/** + * Assert that a table holds exactly one row per merge key, and say so loudly when it does not. + * + * THIS IS THE OTHER HALF OF R-XPART, AND THE HALF THAT IS NOT BOUNDED. The padded MERGE window + * prevents a duplicate for a displacement of up to 31 to 62 days; a row displaced 95 days was + * measured to duplicate anyway. That residue is accepted deliberately -- the general fix is a key + * directory, which is deferred because nothing writes outside a recent window today -- but + * accepting a residue is only defensible if the residue is VISIBLE. Silence is what made every + * duplicate incident in this project expensive: the rows were wrong and every count, grain and + * referential test passed. + * + * So this is a post-condition on the key, not a repair. It reports; `dedupTable` repairs. Run it + * after a capture, or against any table anyone is about to trust. + * + * It reads through the all-history view because that is the only route the guard permits for this + * shape: a GROUP BY over the whole table looking for a repeated key has no window by definition. + * A duplicate created by a non-covering window is, by construction, in a partition the incoming + * window excluded, so a windowed check is the one check guaranteed not to find it. + */ +export async function verifyMergeKeyUniqueness( + tableId: string, + chainId: number +): Promise<{ ok: boolean; report: DuplicateReport }> { + const report = await duplicateReport(tableId, chainId); + if (report.phantomRows > 0) { + log.error( + `MERGE_KEY_NOT_UNIQUE: ${tableId}/chain ${chainId} holds ${report.storedRows} rows over ` + + `${report.distinctKeys} distinct merge keys, so ${report.phantomRows} are phantoms. The ` + + `duplicated keys sit between blocks ${report.minBlock} and ${report.maxBlock} ` + + `(${report.minTs} to ${report.maxTs}). A MERGE whose target window did not cover an ` + + `already-present row inserts a second row under its key; one month of padding bounds that ` + + `to a displacement of 31 to 62 days and a larger one is not covered. Repair with ` + + `dedupTable, which deletes the surplus copies in place.`, + { tableId, chainId, phantomRows: report.phantomRows } + ); + } + return { ok: report.phantomRows === 0, report }; +} + /** * Collapse repeated natural keys to one row each, IN PLACE. * @@ -882,7 +1118,7 @@ export async function warehouseDailyTotals( export async function recordReconciliation(rows: Record[]): Promise { if (rows.length === 0) return; - const tbl = dataset.table("OracleReconciliation"); + const tbl = datasetHandle().table("OracleReconciliation"); const tmpFile = join(tmpdir(), `bq_recon_${randomUUID().slice(0, 8)}.ndjson`); writeFileSync(tmpFile, rows.map((r) => JSON.stringify(r)).join("\n")); try { diff --git a/projects/onchain-analytics/pipeline-v5/src/budget.ts b/projects/onchain-analytics/pipeline-v5/src/budget.ts index 54a9d8e..2814507 100644 --- a/projects/onchain-analytics/pipeline-v5/src/budget.ts +++ b/projects/onchain-analytics/pipeline-v5/src/budget.ts @@ -44,6 +44,38 @@ export const DEFAULT_MAX_CAPTURE_DAYS = 30; /** Default number of contracts one run may attempt. Above this, name them or raise it. */ export const DEFAULT_MAX_CAPTURES = 12; +/** + * Explicit upper bounds on the two override flags. Plan task 8. + * + * WHY A CEILING ON A FLAG WHOSE WHOLE JOB IS TO RAISE A CEILING. A limit that can be set to any + * number is not a limit, it is a formality: `--max-captures=99999999999` disables the guard while + * looking like an adjustment to it, and once the value passes `Number.MAX_SAFE_INTEGER` the + * comparison stops being arithmetic at all. This project has already been bitten by exactly that + * class of defect, where `Number("9223372036854775807")` produced a DIFFERENT integer and 134 + * registry rows silently carried it. So the override has a stated maximum and exceeding it is a + * usage error, not a bigger run. + * + * Both numbers are chosen, not derived, and the reasoning is here so the next agent can argue + * with it rather than inherit it. + */ + +/** + * The control plane holds 148 contracts across the four addressable chains (measured 2026-09-28, + * `contract_deployments` 362 records over 148 contracts). A run cannot legitimately attempt more + * captures than there are contracts to capture, so an order of magnitude above the whole registry + * is already far past any real intention. + */ +export const MAX_CAPTURES_CEILING = 1_000; + +/** + * The deepest chain in the release is XDC, whose head was measured at 107,770,039 on 2026-09-28. + * A single capture spanning more than 100 million blocks is a genuine genesis-to-head backfill, + * which is A5, and plan section 1.1 forbids executing A5 from anywhere in this remediation. An + * explicit `--from` and `--to` still bypasses the span guard entirely, by design, so this bounds + * only the flag that raises the default. + */ +export const MAX_CAPTURE_BLOCKS_CEILING = 100_000_000; + export interface BudgetVerdict { allowed: boolean; /** Null when allowed. Otherwise the full sentence a human needs, including the way through. */ @@ -61,9 +93,16 @@ export function maxCaptureBlocks(network: NetworkConfig, opts: PipelineOpts): nu /** * May this capture run? * - * An explicit range is always allowed. `--from` and `--to` are a person naming a span, which is - * the acknowledgement this guard exists to require, so demanding a second one would only teach - * people to pass the override by reflex. + * An explicit range is allowed up to the absolute ceiling. `--from` and `--to` are a person naming + * a span, which is the acknowledgement this guard exists to require, so demanding a second one + * would only teach people to pass the override by reflex. + * + * THE CEILING IS NOT DECORATION AND IT WAS ADDED FOR A MEASURED REASON. Phase 3 made a bare + * `backfill` a usage error, because plan section 1.1 forbids one. The consequence is that EVERY + * backfill is now explicit, so "an explicit range is always allowed" would have left the span + * guard bounding nothing at all: `--from=0 --to=107000000` is a genesis-to-head run of the + * deepest chain in the release, which is A5, and plan section 1.1 forbids executing A5 from + * anywhere in this remediation. Tightening one control must not quietly disarm another. */ export function checkCaptureSpan( network: NetworkConfig, @@ -75,7 +114,20 @@ export function checkCaptureSpan( const limit = maxCaptureBlocks(network, opts); if (opts.fromBlock !== undefined && opts.toBlock !== undefined) { - return { allowed: true, reason: null, limit, requested }; + if (requested <= MAX_CAPTURE_BLOCKS_CEILING) { + return { allowed: true, reason: null, limit, requested }; + } + return { + allowed: false, + limit: MAX_CAPTURE_BLOCKS_CEILING, + requested, + reason: + `Refusing an explicitly named capture of ${requested.toLocaleString()} blocks on ` + + `${network.name}, blocks ${fromBlock} to ${toBlock}. Naming a range deliberately raises the ` + + `ordinary ${limit.toLocaleString()}-block limit, but not past the absolute ceiling of ` + + `${MAX_CAPTURE_BLOCKS_CEILING.toLocaleString()} blocks. A span this size is a full history ` + + `read, which is A5, and the remediation plan forbids executing A5. Nothing was read.`, + }; } if (requested <= limit) { return { allowed: true, reason: null, limit, requested }; diff --git a/projects/onchain-analytics/pipeline-v5/src/calibrate.ts b/projects/onchain-analytics/pipeline-v5/src/calibrate.ts index 9fc631c..a836e3f 100644 --- a/projects/onchain-analytics/pipeline-v5/src/calibrate.ts +++ b/projects/onchain-analytics/pipeline-v5/src/calibrate.ts @@ -26,7 +26,7 @@ import { CONFIG, selectedNetworks } from "./config.js"; import { log } from "./log.js"; import { fetchRange, readerFor } from "./reader.js"; import { probeLogsPresent } from "./rpc.js"; -import { targetsFor } from "./registry.js"; +import { targetsFor, releaseScopedNetworks } from "./registry.js"; import type { PipelineOpts, NetworkConfig } from "./types.js"; export interface Calibration { @@ -154,7 +154,7 @@ export async function runCalibrate(opts: PipelineOpts): Promise { const repeats = CONFIG.CALIBRATION_REPEATS; const results: Calibration[] = []; - for (const network of selectedNetworks(opts.chains)) { + for (const network of releaseScopedNetworks(selectedNetworks(opts.chains))) { const targets = targetsFor(network, { addresses: opts.addresses }); if (targets.length === 0) continue; // One contract per chain unless the caller names addresses. Calibration measures the SOURCE, @@ -192,3 +192,12 @@ export async function runCalibrate(opts: PipelineOpts): Promise { return results.every((r) => r.answers.length > 0); } + +/** + * Exposed for the test harness only. + * + * `summarise` is the one pure function in this module: it turns a set of pass results into a + * measured miss rate and the pass count that rate would need. Everything else here reaches a + * chain. Exporting it is construction, not behaviour -- nothing in `src/` reads this. + */ +export const __testing = { summarise }; diff --git a/projects/onchain-analytics/pipeline-v5/src/config.ts b/projects/onchain-analytics/pipeline-v5/src/config.ts index fa2054b..4ee410e 100644 --- a/projects/onchain-analytics/pipeline-v5/src/config.ts +++ b/projects/onchain-analytics/pipeline-v5/src/config.ts @@ -39,6 +39,27 @@ function envInt(key: string, fallback: number): number { export const CONFIG = { GCP_PROJECT_ID: env("GCP_PROJECT_ID", "gooddollar"), DATASET_ID: env("DATASET_ID", "BlockchainEvents"), + + /** + * Where per-run staging tables are created and dropped. SEPARATE FROM THE PRODUCTION DATASET, + * and that separation is a safety control rather than tidiness. + * + * The write path creates one staging table per run and drops it afterwards, so a writer + * identity needs `tables.delete` wherever staging lives. While staging lived inside + * `DATASET_ID` that meant granting `tables.delete` on the production raw layer -- one of the + * five permissions whose ABSENCE is the whole point of the current lockdown. And the failure + * ordering made it worse than a stale grant: an ingestion run reaches its staging cleanup only + * AFTER the MERGE has already written production rows, so the run fails having already + * mutated production, and the cheapest-looking remedy in that moment is to grant the very + * permission the lockdown removed. + * + * Splitting the datasets moves the destructive permission onto a dataset that holds nothing + * durable. `assertStagingIsSeparate` below refuses to compose a staging name at all if the two + * ids are ever configured to the same value, so this cannot be undone by an environment + * variable. + */ + STAGING_DATASET_ID: env("STAGING_DATASET_ID", "BlockchainEvents_Staging"), + ENVIO_API_TOKEN: requireEnv("ENVIO_API_TOKEN"), SLACK_WEBHOOK_URL: env("SLACK_WEBHOOK_URL", ""), LOG_FILE: env("LOG_FILE", "pipeline.log"), @@ -46,6 +67,18 @@ export const CONFIG = { /** Written onto every PipelineRuns row, so a defect is attributable to the code that wrote it. */ PIPELINE_VERSION: env("PIPELINE_VERSION", "6.0.0-l0v4"), + /** + * The release this binary was built from, and the remediation plan it is bound to. + * + * Plan section 1.1: every executable writer is bound to an immutable plan hash. Both are NULL + * until a release process sets them, and NULL is the honest value: a hash invented by the + * program it is supposed to bind would bind nothing. Phase 13 sets `RELEASE_SHA` at publish and + * `PLAN_HASH` is the 64-character lowercase hex SHA-256 of the plan file, which is + * 9dcde225459127c4da2beadf9094fd894fe193010f39cb70c0753dd874853e26 today. + */ + RELEASE_SHA: env("RELEASE_SHA", "") || null, + PLAN_HASH: env("PLAN_HASH", "") || null, + /** Rows buffered before a write. Writes are always flushed on a BLOCK boundary regardless. */ CHUNK_SIZE_TARGET: envInt("CHUNK_SIZE_TARGET", 50_000), @@ -61,6 +94,34 @@ export const CONFIG = { */ MERGE_PADDING_MONTHS: envInt("MERGE_PADDING_MONTHS", 1), + /** + * The hard ceiling on bytes a single BigQuery job may bill, in bytes. 10 GiB. + * + * WHY A CEILING AND NOT A BUDGET ALARM. BigQuery refuses a job whose estimate exceeds + * `maximumBytesBilled` BEFORE running it, and a refused job bills nothing. An alarm fires + * after the money is spent. Every statement this pipeline submits goes through `bqQuery`, so + * the ceiling is attached at that one chokepoint and no call site can forget it. + * + * WHAT IT DOES NOT COVER, named rather than left to be discovered. Load jobs bill storage + * rather than query bytes and the jobs API rejects this setting on a load configuration, so + * the two `table.load` calls in `bq.ts` are outside it by construction. Queries that Looker + * Studio submits on its own behalf never pass through this process at all and are bounded + * instead by the size of the tables exposed to it. + */ + MAX_BYTES_BILLED_PER_JOB: envInt("MAX_BYTES_BILLED_PER_JOB", 10 * 1024 * 1024 * 1024), + + /** + * The cross-process write lease. See `writelock.ts` for why a file and not a table. + * + * WAIT_MS is how long a second writer blocks before it is refused rather than queued for ever; + * STALE_MS is how old a lease has to be before it is treated as abandoned by a killed process. + * STALE_MS is deliberately far longer than any single MERGE: reclaiming a lease that is merely + * slow would reintroduce the concurrent write it exists to prevent. + */ + WRITE_LOCK_DIR: env("WRITE_LOCK_DIR", ""), + WRITE_LOCK_WAIT_MS: envInt("WRITE_LOCK_WAIT_MS", 15 * 60_000), + WRITE_LOCK_STALE_MS: envInt("WRITE_LOCK_STALE_MS", 60 * 60_000), + BQ_RETRIES: envInt("BQ_RETRIES", 5), HYPERSYNC_RETRIES: envInt("HYPERSYNC_RETRIES", 5), FRESHNESS_THRESHOLD_HOURS: envInt("FRESHNESS_THRESHOLD_HOURS", 36), @@ -129,6 +190,7 @@ export const NETWORKS: Record = { // agreed on every one of roughly 1,500 calls. rpc.xdcrpc.com serves head and accepts wider // eth_getLogs ranges than the other two. rpcUrls: ["https://rpc.ankr.com/xdc", "https://xdc.public-rpc.com", "https://rpc.xdcrpc.com"], + stateRpcUrls: ["https://rpc.ankr.com/xdc", "https://xdc.public-rpc.com"], archiveRpcUrls: ["https://rpc.ankr.com/xdc", "https://xdc.public-rpc.com"], rpcLogRange: envInt("XDC_RPC_LOG_RANGE", 1_000), rpcLogResultCap: null, @@ -163,7 +225,21 @@ export const NETWORKS: Record = { // range age, with no error on any occasion. It is listed because it answers; it is never // trusted alone, and R7 forbids reading any absence from a log scan regardless. rpcUrls: ["https://forno.celo.org", "https://celo.drpc.org", "https://celo.blockscout.com/api/eth-rpc"], - archiveRpcUrls: ["https://forno.celo.org", "https://celo.drpc.org", "https://celo.blockscout.com/api/eth-rpc"], + // Recent-pin state. MEASURED 2026-09-29 across two separate OS processes: these four all + // serve `eth_call` at a recent pinned block, and all four are free. `celo.drpc.org` is + // absent deliberately -- it served `eth_call` 0 of 6 and `eth_blockNumber` 2 of 6, so it + // contributes errors rather than answers and would only make agreement harder to reach. + stateRpcUrls: [ + "https://forno.celo.org", + "https://celo.blockscout.com/api/eth-rpc", + "https://rpc.ankr.com/celo", + "https://1rpc.io/celo", + ], + // DEEP archive, below the L1-to-L2 migration at block 31,056,500. Genuinely one endpoint, + // and that limitation is left recorded rather than papered over: `rpc.ankr.com/celo` holds + // no state below the migration block, so it qualifies for the recent-pin list above and + // not for this one. Nothing shipped reads below that block today. + archiveRpcUrls: ["https://forno.celo.org"], rpcLogRange: envInt("CELO_RPC_LOG_RANGE", 5_000), rpcLogResultCap: null, hasIndependentConfirmingReader: true, @@ -171,7 +247,22 @@ export const NETWORKS: Record = { "HyperSync answers. forno's false-zero rate is a function of RANGE AGE, not width and not " + "answer size, and was measured at 30 percent one day and 70 percent the next on the " + "identical query. rpc.ankr.com/celo holds no state before block 31,056,500, the L1 to L2 " + - "migration block.", + "migration block. " + + "ARCHIVE QUORUM, MEASURED 2026-09-29, five attempts per question per endpoint: only ONE " + + "of the three previously listed endpoints qualifies for DEEP archive. forno passed " + + "everything, including an eth_getCode tripwire across the UBIScheme's own creation block " + + "(1,446 bytes after, 0 before), which is what proves genuine archive state rather than " + + "latest state answering a historical call. celo.drpc.org answered eth_chainId 5 of 5 and " + + "rejected eth_getBlockByNumber, eth_getCode AND eth_call with -32601 'method does not " + + "exist', so it is not intermittent, it is RESTRICTED, and a liveness probe would score " + + "it 5 of 5 and put it in the quorum. celo.blockscout.com rate-limits with HTTP 429. " + + "THAT MEASUREMENT WAS THEN ASKED THE WRONG QUESTION, and re-measuring the right one " + + "removed a spend request. Nothing shipped reads state below the migration block; every " + + "state read this pipeline performs is an eth_call at a RECENT pin. Re-measured across " + + "two separate OS processes on 2026-09-29, four free endpoints serve that: forno, " + + "blockscout, ankr and 1rpc. So the two needs are now two lists. The deep-archive list is " + + "genuinely one endpoint and that limitation stands -- it is simply not on any path in " + + "use, and it is recorded here rather than resolved by spending.", }, }, @@ -202,6 +293,7 @@ export const NETWORKS: Record = { // The ONLY archive-capable Fuse endpoint in existence that this project has found. It // publishes its own quota in headers at 10 reads per 11.08 minutes, which is about 54 // archive reads an hour, so it is listed for STATE reads and is not used for enumeration. + stateRpcUrls: ["https://explorer.fuse.io/api/eth-rpc"], archiveRpcUrls: ["https://explorer.fuse.io/api/eth-rpc"], rpcLogRange: envInt("FUSE_RPC_LOG_RANGE", 50_000), // MEASURED: both enumerating readers cap at 20,000 logs per RESPONSE and refuse a @@ -238,6 +330,7 @@ export const NETWORKS: Record = { // MEASURED: both serve the full range in one request and agreed exactly. drpc, blastapi and // pokt all cap between 10 and 10,000 blocks on their free tiers. rpcUrls: ["https://eth.blockscout.com/api/eth-rpc", "https://gateway.tenderly.co/public/mainnet"], + stateRpcUrls: ["https://eth.blockscout.com/api/eth-rpc", "https://gateway.tenderly.co/public/mainnet"], archiveRpcUrls: ["https://eth.blockscout.com/api/eth-rpc", "https://gateway.tenderly.co/public/mainnet"], rpcLogRange: envInt("ETH_RPC_LOG_RANGE", 50_000), rpcLogResultCap: null, @@ -393,9 +486,24 @@ export interface OracleConfig { } export const ORACLES: OracleConfig[] = [ + { + network: NETWORKS.CELO, + address: "0x43d72ff17701b2da814620735c39c620ce0ea4a1", + // MEASURED from the contract at a pinned block, three endpoints agreeing, zero errors: + // periodStart() = 1677672000 = 2023-03-01T12:00:00Z. Exactly noon UTC, so a comparison keyed + // on the calendar date of a log's timestamp disagrees with the contract on every claim made + // before noon, and does so quietly. + periodStart: 1_677_672_000, + kind: "ubi_daily", + // Same event as XDC, and the layout is taken from the event surface seed rather than recalled: + // claimer is the only indexed parameter, so amount is word 0 of log_data. + eventSignature: "UBIClaimed(address,uint256)", + amountWordIndex: 0, + }, { network: NETWORKS.XDC, address: "0x22867567e2d80f2049200e25c6f31cb6ec2f0faf", + // MEASURED the same way: periodStart() = 1761393600 = 2025-10-25T12:00:00Z, also noon UTC. periodStart: 1_761_393_600, kind: "ubi_daily", // UBIClaimed(address indexed claimer, uint256 amount): claimer is indexed so it occupies @@ -421,7 +529,14 @@ export function oracleFor(chainId: number, address: string): OracleConfig | unde return ORACLES.find((o) => o.network.chainId === chainId && o.address === a); } -/** Every oracle whose chain is in this run's selection. */ +/** + * Every oracle whose chain is in this run's selection. + * + * Pass networks that have ALREADY been filtered by release scope, through + * `releaseScopedNetworks()`. This function cannot do it itself: the scope module lives in + * `registry.ts`, which imports this file, so calling it from here would be a cycle. The + * obligation is therefore on the caller, and both callers now honour it. + */ export function oraclesFor(networks: NetworkConfig[]): OracleConfig[] { const ids = new Set(networks.map((n) => n.chainId)); return ORACLES.filter((o) => ids.has(o.network.chainId)); @@ -436,3 +551,28 @@ export function fullTableName(tableId: string): string { export function stagingTableId(tableId: string, runId: string): string { return `_staging_${tableId}_${runId.replace(/-/g, "")}`; } + +/** + * Refuse to treat the production dataset as a staging dataset. + * + * The staging dataset is the one place this pipeline needs `tables.delete`. Pointing it back at + * production would silently re-create the requirement to hold that permission on the raw layer, + * which is the exact thing the split exists to remove -- and it would do so through an + * environment variable, leaving the code looking correct. So the refusal lives on the path that + * composes every staging name, where nothing can route around it. + */ +export function assertStagingIsSeparate(): void { + if (CONFIG.STAGING_DATASET_ID.trim().toLowerCase() === CONFIG.DATASET_ID.trim().toLowerCase()) { + throw new Error( + `STAGING_NOT_SEPARATE: STAGING_DATASET_ID and DATASET_ID are both "${CONFIG.DATASET_ID}". ` + + `Staging tables are created and dropped, so this would require tables.delete on the ` + + `production dataset. Point STAGING_DATASET_ID at its own dataset.` + ); + } +} + +/** A staging table's fully qualified name, composed from the STAGING dataset, never production. */ +export function stagingTableName(stagingTableId: string): string { + assertStagingIsSeparate(); + return `\`${CONFIG.GCP_PROJECT_ID}.${CONFIG.STAGING_DATASET_ID}.${stagingTableId}\``; +} diff --git a/projects/onchain-analytics/pipeline-v5/src/control-plane/build-check.ts b/projects/onchain-analytics/pipeline-v5/src/control-plane/build-check.ts new file mode 100644 index 0000000..37bd810 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/src/control-plane/build-check.ts @@ -0,0 +1,144 @@ +/** + * build-check.ts -- the decode layer's build-time gate. + * + * WHY A SEPARATE ENTRY POINT. A control that only exists inside a function nothing calls enforces + * nothing. This file is what makes the decode assertions a BUILD failure rather than a fact + * somebody could look up: it runs on `npm run verify:local`, it exits non-zero, and it can be + * pointed at a fixture so the failure itself is demonstrable rather than merely asserted. + * + * npx tsx src/control-plane/build-check.ts [--chains p] [--registry p] [--event-surface p] + * + * Exit 0 clean, exit 1 on a blocking finding, exit 2 on a usage error. + */ + +import { parseEventSurface } from "./eventSurface.js"; +import { parseRegistry } from "./contractRegistry.js"; +import { SeedParseError } from "./csv.js"; +import { pathToFileURL } from "url"; +import { assertSemanticErasConsumable, RELEASE_SCOPE_FREEZE } from "./releaseScope.js"; +import { parseEraBoundaryEvidence, eraEvidenceKey } from "./eraConfidence.js"; +import { + assertNoUnhandledDecodeAmbiguity, + buildAllUnionAbis, + isNewestFirst, + intervalsWithNoDecodableSurface, + UnhandledDecodeAmbiguityError, + KNOWN_DECODE_AMBIGUITIES, +} from "./decodeSurface.js"; + +interface Options { + registry?: string; + eventSurface?: string; + boundaryEvidence?: string; +} + +export function parseArgs(argv: readonly string[]): Options { + const o: Options = {}; + for (let i = 0; i < argv.length; i += 2) { + const flag = argv[i]; + const value = argv[i + 1]; + if (value === undefined) throw new Error(`build-check: '${flag}' needs a value`); + if (flag === "--registry") o.registry = value; + else if (flag === "--event-surface") o.eventSurface = value; + else if (flag === "--boundary-evidence") o.boundaryEvidence = value; + else throw new Error(`build-check: unknown argument '${flag}'`); + } + return o; +} + +export interface BuildCheckResult { + readonly ok: boolean; + readonly lines: readonly string[]; + readonly ambiguousKeyCount: number; + readonly unionsChecked: number; + readonly unionsOutOfOrder: number; + readonly undecodableIntervals: number; + /** Eras carrying promoted boundary evidence on a release chain -- the measured consumed set. */ + readonly evidencedErasChecked: number; + readonly evidencedErasRefused: number; +} + +/** Runs every decode build check. Returns rather than exits, so a test can drive it. */ +export function runBuildCheck(options: Options = {}): BuildCheckResult { + const lines: string[] = []; + const surface = parseEventSurface(options.eventSurface); + const registry = parseRegistry(options.registry); + + // 1. The ambiguous set. Throws on any key nobody has declared. + const ambiguous = assertNoUnhandledDecodeAmbiguity(surface); + lines.push(`decode ambiguity: ${ambiguous.length} key(s) found, all declared in KNOWN_DECODE_AMBIGUITIES (${KNOWN_DECODE_AMBIGUITIES.length} declared)`); + for (const k of ambiguous) lines.push(` declared: ${k.chain} ${k.address} ${k.signature}`); + + // 2. Union order. A union built oldest-first decodes a later-era log into the wrong columns + // without raising, so the order is checked rather than trusted. + const unions = buildAllUnionAbis(surface); + const outOfOrder = [...unions.values()].filter((u) => !isNewestFirst(u)); + lines.push(`union order: ${unions.size} union(s) built, ${outOfOrder.length} not newest-implementation-first`); + for (const u of outOfOrder) lines.push(` OUT OF ORDER: ${u.chain} ${u.address} eras ${u.eraOrder.join(",")}`); + + // 3. Intervals nothing can decode. Reported, never blocking: raw capture is lossless and an + // interval with no ABI is a known state, not a defect in this seed. + const undecodable = intervalsWithNoDecodableSurface(registry.rows, surface); + const noAbi = undecodable.filter((i) => i.reason === "no_abi_held").length; + lines.push(`decode coverage: ${undecodable.length} interval(s) have no surface entry (${noAbi} hold no ABI at all, ${undecodable.length - noAbi} hold an ABI but catalogue no event)`); + + // 4. The semantic-era policy, on the eras that are actually consumed. + // + // WHY THIS SET AND NOT EVERY ERA. Phase 2B derived the consumed set by walking every semantic + // and mart model down to the raw tables it reads: 41 eras over 6 contracts. Those are exactly + // the eras a boundary manifest was produced for, and they are what the promoted evidence seed + // carries. Running the policy over every era in the registry instead would refuse 247 eras + // nobody consumes and block the build for a reason no reader could act on -- which is + // over-refusal, and over-refusal is its own defect. + const evidence = parseEraBoundaryEvidence(options.boundaryEvidence); + const releaseChains = new Set(RELEASE_SCOPE_FREEZE.releaseChains); + const consumed = registry.rows.filter( + (r) => releaseChains.has(r.chain) && !r.noCodeDeployed && evidence.has(eraEvidenceKey(r.chainId, r.proxyAddress, r.eraIndex)), + ); + const refusals = assertSemanticErasConsumable(consumed, "consumed semantic eras", RELEASE_SCOPE_FREEZE, { boundaryEvidence: evidence }); + lines.push(`semantic era policy: ${consumed.length} consumed era(s) checked, ${refusals.length} refused`); + for (const v of refusals) lines.push(` REFUSED: ${v.subject}: ${v.detail}`); + + return { + ok: outOfOrder.length === 0 && refusals.length === 0, + lines, + ambiguousKeyCount: ambiguous.length, + unionsChecked: unions.size, + unionsOutOfOrder: outOfOrder.length, + undecodableIntervals: undecodable.length, + evidencedErasChecked: consumed.length, + evidencedErasRefused: refusals.length, + }; +} + +function main(argv: readonly string[]): number { + let options: Options; + try { + options = parseArgs(argv); + } catch (e) { + console.error((e as Error).message); + return 2; + } + + try { + const result = runBuildCheck(options); + for (const l of result.lines) console.log(l); + if (!result.ok) { + console.error("BUILD CHECK FAILED: a union ABI is not newest-implementation-first, or a consumed era is refused"); + return 1; + } + console.log("BUILD CHECK CLEAN"); + return 0; + } catch (e) { + if (e instanceof UnhandledDecodeAmbiguityError || e instanceof SeedParseError) { + console.error(`BUILD CHECK FAILED: ${e.message}`); + return 1; + } + throw e; + } +} + +// Only run when invoked directly, so importing this file in a test does not exit the process. +if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) { + process.exit(main(process.argv.slice(2))); +} diff --git a/projects/onchain-analytics/pipeline-v5/src/control-plane/chains.ts b/projects/onchain-analytics/pipeline-v5/src/control-plane/chains.ts new file mode 100644 index 0000000..d56057f --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/src/control-plane/chains.ts @@ -0,0 +1,63 @@ +/** + * chains.ts -- the chain-name/chain-id authority, read from the `chains` seed. + * + * Task 8 exists because a composite foreign key cannot catch this class of error. `event_surface` + * points at `contract_deployments` by (chain, proxy_address, era_index); if a row carries + * chain='FUSE' with chain_id=42220, both seeds agree with each other and every referential test + * passes while the row describes a contract that does not exist. It was measured that 14 addresses + * are deployed at the same address with the same era index on two chains, so a wrong chain is + * exactly the error that survives a composite key. This map is the independent third opinion. + */ + +import { resolve, join, dirname } from "path"; +import { fileURLToPath } from "url"; +import { readStrictCsv, SeedParseError } from "./csv.js"; +import { parseFiniteInt } from "./int64.js"; +import { bool, nonEmpty } from "./fields.js"; + +const HERE = dirname(fileURLToPath(import.meta.url)); +export const SEEDS_DIR = resolve(join(HERE, "..", "..", "..", "gd_dbt", "seeds")); +export const CHAINS_PATH = join(SEEDS_DIR, "chains.csv"); + +export const CHAINS_HEADER = [ + "chain", "chain_id", "chain_name", "native_token_symbol", "explorer_url_template", "is_active", "notes", +] as const; + +export interface ChainRow { + readonly line: number; + readonly chain: string; + readonly chainId: number; + readonly isActive: boolean; +} + +export interface ChainAuthority { + readonly byName: ReadonlyMap; + readonly byId: ReadonlyMap; + readonly rows: readonly ChainRow[]; + readonly path: string; +} + +export function loadChains(path = CHAINS_PATH): ChainAuthority { + const csv = readStrictCsv(path, [CHAINS_HEADER]); + const byName = new Map(); + const byId = new Map(); + const rows: ChainRow[] = []; + + for (let i = 0; i < csv.records.length; i++) { + const r = csv.records[i]; + const line = csv.recordLines[i]; + const ctx = (column: string) => ({ path, line, column }); + const chain = nonEmpty(ctx("chain"), r[0]); + const chainId = parseFiniteInt("chain_id", r[1], { min: 1 }); + const isActive = bool(ctx("is_active"), r[5]); + + if (byName.has(chain)) throw new SeedParseError(path, `duplicate chain '${chain}'`, line); + if (byId.has(chainId)) throw new SeedParseError(path, `duplicate chain_id ${chainId} (already '${byId.get(chainId)}')`, line); + byName.set(chain, chainId); + byId.set(chainId, chain); + rows.push({ line, chain, chainId, isActive }); + } + + if (rows.length === 0) throw new SeedParseError(path, "declares no chains"); + return { byName, byId, rows, path }; +} diff --git a/projects/onchain-analytics/pipeline-v5/src/control-plane/contractRegistry.ts b/projects/onchain-analytics/pipeline-v5/src/control-plane/contractRegistry.ts new file mode 100644 index 0000000..fbf4183 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/src/control-plane/contractRegistry.ts @@ -0,0 +1,352 @@ +/** + * contractRegistry.ts -- schema, parse and cross-row validation for `contract_deployments.csv`. + * + * This seed is the contract universe and the era map. Two properties make it unusually + * unforgiving: + * + * 1. A dropped row silently shrinks what the pipeline covers. Nothing downstream can tell a + * contract that was never ingested apart from a contract that produced no logs. + * 2. `lookupEra` cannot fail by construction, so a wrong or missing era yields a CONFIDENT WRONG + * decode rather than an error. 115 eras announce nothing at all on chain, so there is no + * independent signal to catch it afterwards. + * + * Every check below therefore rejects the whole file rather than the offending row. + * + * ON THE BOUNDARY-EVIDENCE COLUMNS. The plan requires the schema to carry + * `boundary_completeness`, `boundary_evidence_manifest_hash`, `boundary_checked_through_block` and + * the frozen safe head that registry and event surface share. They are declared here as an + * optional trailing block: present, they are validated as a unit; absent, every era is + * `raw_only_unproven`, which is precisely the state the plan assigns to an era with no boundary + * evidence. What is NOT done here is infer `plain_contract` from `era_method`. That verdict rests + * on creation-bytecode identity and a proven absence of any proxy mutation surface; deriving it + * from a field that only records how the era was found would manufacture the evidence. + */ + +import { join } from "path"; +import { readStrictCsv, SeedParseError, type StrictCsv } from "./csv.js"; +import { SEEDS_DIR, type ChainAuthority } from "./chains.js"; +import { parseFiniteInt, parseLowerBound, parseUpperBound, compareBounds, type BlockBound } from "./int64.js"; +import { address, optionalAddress, optionalHex32, bool, nonEmpty, oneOf, violation, type Violation, type FieldContext } from "./fields.js"; + +export const REGISTRY_PATH = join(SEEDS_DIR, "contract_deployments.csv"); + +export const REGISTRY_HEADER_BASE = [ + "chain", "chain_id", "contract_name", "category", "provenance", "proxy_address", + "implementation_address", "implementation_name", "era_index", "era_count", "valid_from_block", + "valid_to_block", "is_live", "creation_block", "creation_method", "era_method", "era_evidence", + "era_announcement_event", "abi_source", "runtime_code_hash", "semantics_note", "source", "notes", +] as const; + +/** The declared boundary-evidence block, appended as a unit when Phase 2 task 16 regenerates. */ +export const REGISTRY_BOUNDARY_COLUMNS = [ + "boundary_completeness", "boundary_evidence_manifest_hash", "boundary_checked_through_block", + "frozen_safe_head", "release_scope", +] as const; + +export const REGISTRY_HEADER_WITH_BOUNDARY = [...REGISTRY_HEADER_BASE, ...REGISTRY_BOUNDARY_COLUMNS] as const; + +export const BOUNDARY_COMPLETENESS = ["complete", "plain_contract", "raw_only_unproven"] as const; +export type BoundaryCompleteness = (typeof BOUNDARY_COMPLETENESS)[number]; + +/** + * Release scope, per row. + * + * `scope_pending` exists so an undecided contract is RECORDED as undecided rather than resolved by + * whichever way the seed happens to fall. The plan is explicit that A5 may neither include nor + * silently exclude such a row, which is only enforceable if the state has a name. + * + * `undeclared` is not a value a seed may carry. It is what this loader reports when the column is + * absent altogether, so "nobody has decided yet" never reads as "everything is in". + */ +export const RELEASE_SCOPE = ["in_release", "out_of_release", "scope_pending"] as const; +export type ReleaseScope = (typeof RELEASE_SCOPE)[number] | "undeclared"; + +/** The exact marker that declares the no-code exception shape. */ +export const NO_CODE_ERA_METHOD = "no_code_deployed"; + +export interface RegistryRow { + readonly line: number; + readonly chain: string; + readonly chainId: number; + readonly contractName: string; + readonly category: string; + readonly provenance: string; + readonly proxyAddress: string; + readonly implementationAddress: string | null; + readonly implementationName: string; + readonly eraIndex: number; + readonly eraCount: number; + /** Null only on a `no_code_deployed` row, which declares no era interval at all. */ + readonly validFrom: BlockBound | null; + readonly validTo: BlockBound | null; + readonly isLive: boolean; + readonly creationBlock: number | null; + readonly creationMethod: string; + readonly eraMethod: string; + readonly eraEvidence: string; + readonly eraAnnouncementEvent: string; + readonly abiSource: string; + readonly runtimeCodeHash: string | null; + readonly semanticsNote: string; + readonly source: string; + readonly notes: string; + readonly noCodeDeployed: boolean; + readonly boundaryCompleteness: BoundaryCompleteness; + readonly boundaryEvidenceManifestHash: string | null; + readonly boundaryCheckedThroughBlock: number | null; + readonly frozenSafeHead: number | null; + readonly releaseScope: ReleaseScope; + /** Original field lexemes, so a regenerated seed reproduces the source byte for byte. */ + readonly raw: readonly string[]; +} + +export interface ParsedRegistry { + readonly rows: readonly RegistryRow[]; + readonly csv: StrictCsv; + readonly hasBoundaryColumns: boolean; +} + +/** Adds file/line/column context to the lexeme-level errors thrown by int64.ts. */ +function at(path: string, line: number, column: string, fn: () => T): T { + try { + return fn(); + } catch (e) { + if (e instanceof SeedParseError) throw e; + throw new SeedParseError(path, `column '${column}': ${(e as Error).message}`, line); + } +} + +export function contractKey(chainId: number, proxyAddress: string): string { + return `${chainId}|${proxyAddress}`; +} + +/** + * Parse every physical row. Throws on the FIRST malformed one; never filters, never skips. + */ +export function parseRegistry(path = REGISTRY_PATH): ParsedRegistry { + const csv = readStrictCsv(path, [REGISTRY_HEADER_BASE, REGISTRY_HEADER_WITH_BOUNDARY]); + const hasBoundaryColumns = csv.header.length === REGISTRY_HEADER_WITH_BOUNDARY.length; + const rows: RegistryRow[] = []; + + for (let i = 0; i < csv.records.length; i++) { + const r = csv.records[i]; + const line = csv.recordLines[i]; + const ctx = (column: string): FieldContext => ({ path, line, column }); + + const chain = nonEmpty(ctx("chain"), r[0]); + const chainId = at(path, line, "chain_id", () => parseFiniteInt("chain_id", r[1], { min: 1 })); + const contractName = nonEmpty(ctx("contract_name"), r[2]); + const category = nonEmpty(ctx("category"), r[3]); + const provenance = nonEmpty(ctx("provenance"), r[4]); + const proxyAddress = address(ctx("proxy_address"), r[5]); + const implementationAddress = optionalAddress(ctx("implementation_address"), r[6]); + const implementationName = nonEmpty(ctx("implementation_name"), r[7]); + const eraIndex = at(path, line, "era_index", () => parseFiniteInt("era_index", r[8], { min: 1 })); + const eraCount = at(path, line, "era_count", () => parseFiniteInt("era_count", r[9], { min: 0 })); + const isLive = bool(ctx("is_live"), r[12]); + const eraMethod = nonEmpty(ctx("era_method"), r[15]); + const noCodeDeployed = eraMethod === NO_CODE_ERA_METHOD; + + let validFrom: BlockBound | null = null; + let validTo: BlockBound | null = null; + let creationBlock: number | null = null; + + if (noCodeDeployed) { + // The declared exception shape, enforced in full so it cannot be used as a hiding place for + // a row that simply failed to resolve its blocks. + if (r[10] !== "" || r[11] !== "" || r[13] !== "") { + throw new SeedParseError(path, `${NO_CODE_ERA_METHOD} row must leave valid_from_block, valid_to_block and creation_block empty, found '${r[10]}' / '${r[11]}' / '${r[13]}'`, line); + } + if (eraIndex !== 1 || eraCount !== 0) { + throw new SeedParseError(path, `${NO_CODE_ERA_METHOD} row must declare era_index=1 and era_count=0, found ${eraIndex} / ${eraCount}`, line); + } + if (isLive) throw new SeedParseError(path, `${NO_CODE_ERA_METHOD} row cannot be is_live=true`, line); + if (implementationAddress !== null) { + throw new SeedParseError(path, `${NO_CODE_ERA_METHOD} row must leave implementation_address empty`, line); + } + } else { + validFrom = at(path, line, "valid_from_block", () => parseLowerBound("valid_from_block", r[10], { min: 0 })); + // The row's own `is_live` flag is the explicit open-ended declaration. The sentinel is + // admissible here and nowhere else, and it never becomes a JavaScript number. + validTo = at(path, line, "valid_to_block", () => parseUpperBound("valid_to_block", r[11], { declaredOpenEnded: isLive, min: 0 })); + creationBlock = at(path, line, "creation_block", () => parseFiniteInt("creation_block", r[13], { min: 0 })); + if (eraCount < 1) { + throw new SeedParseError(path, `era_count must be at least 1 on a deployed contract, found ${eraCount}`, line); + } + } + + let boundaryCompleteness: BoundaryCompleteness = "raw_only_unproven"; + let boundaryEvidenceManifestHash: string | null = null; + let boundaryCheckedThroughBlock: number | null = null; + let frozenSafeHead: number | null = null; + let releaseScope: ReleaseScope = "undeclared"; + + if (hasBoundaryColumns) { + boundaryCompleteness = oneOf(ctx("boundary_completeness"), r[23], BOUNDARY_COMPLETENESS); + boundaryEvidenceManifestHash = optionalHex32(ctx("boundary_evidence_manifest_hash"), r[24]); + boundaryCheckedThroughBlock = r[25] === "" ? null : at(path, line, "boundary_checked_through_block", () => parseFiniteInt("boundary_checked_through_block", r[25], { min: 0 })); + frozenSafeHead = r[26] === "" ? null : at(path, line, "frozen_safe_head", () => parseFiniteInt("frozen_safe_head", r[26], { min: 0 })); + releaseScope = oneOf(ctx("release_scope"), r[27], RELEASE_SCOPE); + + // The block is validated as a unit: a completeness verdict with no reproducible manifest, + // no checked-through block or no frozen head is an assertion, not evidence. + if (boundaryCompleteness !== "raw_only_unproven") { + if (boundaryEvidenceManifestHash === null || boundaryCheckedThroughBlock === null || frozenSafeHead === null) { + throw new SeedParseError(path, `boundary_completeness='${boundaryCompleteness}' requires boundary_evidence_manifest_hash, boundary_checked_through_block and frozen_safe_head to all be present`, line); + } + if (boundaryCheckedThroughBlock > frozenSafeHead) { + throw new SeedParseError(path, `boundary_checked_through_block ${boundaryCheckedThroughBlock} is above frozen_safe_head ${frozenSafeHead}`, line); + } + } + } + + rows.push({ + line, chain, chainId, contractName, category, provenance, proxyAddress, + implementationAddress, implementationName, eraIndex, eraCount, validFrom, validTo, isLive, + creationBlock, creationMethod: nonEmpty(ctx("creation_method"), r[14]), eraMethod, + eraEvidence: nonEmpty(ctx("era_evidence"), r[16]), + eraAnnouncementEvent: nonEmpty(ctx("era_announcement_event"), r[17]), + abiSource: nonEmpty(ctx("abi_source"), r[18]), + runtimeCodeHash: optionalHex32(ctx("runtime_code_hash"), r[19]), + semanticsNote: r[20], source: nonEmpty(ctx("source"), r[21]), notes: r[22], + noCodeDeployed, boundaryCompleteness, boundaryEvidenceManifestHash, + boundaryCheckedThroughBlock, frozenSafeHead, releaseScope, raw: r, + }); + } + + return { rows, csv, hasBoundaryColumns }; +} + +/** + * Cross-row rules. Returned rather than thrown so one run names every violation; the loader + * rejects the registry if the list is non-empty. + * + * Era intervals are half-open, [valid_from_block, valid_to_block), which is the convention the era + * lookup already implements. "No gap" is therefore an exact equality between one era's upper bound + * and the next one's lower bound, not an inequality. + */ +export function validateRegistry(parsed: ParsedRegistry, chains: ChainAuthority): Violation[] { + const v: Violation[] = []; + const byContract = new Map(); + + for (const row of parsed.rows) { + const subject = `${row.chain} ${row.proxyAddress} era ${row.eraIndex}`; + + const expectedId = chains.byName.get(row.chain); + if (expectedId === undefined) { + v.push(violation("chain_known", row.line, subject, `chain '${row.chain}' is not declared in ${chains.path}`)); + } else if (expectedId !== row.chainId) { + v.push(violation("chain_id_consistency", row.line, subject, `chain '${row.chain}' is chain_id ${expectedId} in the chains seed but this row says ${row.chainId}`)); + } + + if (row.isLive && row.validTo !== null && row.validTo.kind !== "open_ended") { + v.push(violation("live_era_not_expired", row.line, subject, `is_live=true but valid_to_block is the finite value ${row.validTo.lexeme}`)); + } + if (!row.isLive && row.validTo !== null && row.validTo.kind === "open_ended") { + v.push(violation("open_ended_requires_live", row.line, subject, "valid_to_block is the open-ended sentinel but is_live=false")); + } + if (row.validFrom !== null && row.validTo !== null && compareBounds(row.validFrom, row.validTo) >= 0) { + v.push(violation("interval_ordering", row.line, subject, `valid_from_block ${row.validFrom.lexeme} is not below valid_to_block ${row.validTo.lexeme}`)); + } + if (row.creationBlock !== null && row.validFrom !== null && row.validFrom.kind === "finite" && row.creationBlock > row.validFrom.value) { + v.push(violation("creation_before_first_era", row.line, subject, `creation_block ${row.creationBlock} is after valid_from_block ${row.validFrom.lexeme}`)); + } + + const key = contractKey(row.chainId, row.proxyAddress); + const list = byContract.get(key); + if (list) list.push(row); + else byContract.set(key, [row]); + } + + for (const [key, rows] of byContract) { + const head = rows[0]; + const subject = `${head.chain} ${head.proxyAddress} (${head.contractName})`; + + if (head.noCodeDeployed) { + if (rows.length !== 1) { + v.push(violation("no_code_single_row", head.line, subject, `${NO_CODE_ERA_METHOD} contract carries ${rows.length} rows; it must carry exactly one`)); + } + continue; + } + + const declaredCounts = new Set(rows.map((r) => r.eraCount)); + if (declaredCounts.size > 1) { + v.push(violation("era_count_agreement", head.line, subject, `rows disagree on era_count: ${[...declaredCounts].join(", ")}`)); + } + if (head.eraCount !== rows.length) { + v.push(violation("era_count_matches_rows", head.line, subject, `era_count=${head.eraCount} but ${rows.length} era row(s) are present`)); + } + + const names = new Set(rows.map((r) => r.contractName)); + if (names.size > 1) { + v.push(violation("contract_name_agreement", head.line, subject, `rows disagree on contract_name: ${[...names].join(", ")}`)); + } + + const indexes = rows.map((r) => r.eraIndex).sort((a, b) => a - b); + for (let i = 0; i < indexes.length; i++) { + if (indexes[i] !== i + 1) { + v.push(violation("era_index_contiguous", head.line, subject, `era indexes are not contiguous from 1: ${indexes.join(", ")}`)); + break; + } + } + + const live = rows.filter((r) => r.isLive); + if (live.length > 1) { + v.push(violation("single_live_era", head.line, subject, `${live.length} eras are marked is_live=true (${live.map((r) => r.eraIndex).join(", ")})`)); + } + + const ordered = [...rows].sort((a, b) => compareBounds(a.validFrom!, b.validFrom!) || a.eraIndex - b.eraIndex); + for (let i = 0; i < ordered.length; i++) { + // The era carrying the highest index must be the one carrying the highest interval, or the + // era map and the declared order describe two different histories. + if (ordered[i].eraIndex !== i + 1) { + v.push(violation("era_order_matches_blocks", ordered[i].line, subject, `era ${ordered[i].eraIndex} sits at block-order position ${i + 1}`)); + } + } + for (let i = 1; i < ordered.length; i++) { + const prev = ordered[i - 1]; + const next = ordered[i]; + const cmp = compareBounds(prev.validTo!, next.validFrom!); + if (cmp > 0) { + v.push(violation("era_overlap", next.line, subject, `era ${prev.eraIndex} ends at ${prev.validTo!.lexeme} which is after era ${next.eraIndex} starts at ${next.validFrom!.lexeme}`)); + } else if (cmp < 0) { + v.push(violation("era_gap", next.line, subject, `undeclared gap: era ${prev.eraIndex} ends at ${prev.validTo!.lexeme} and era ${next.eraIndex} starts at ${next.validFrom!.lexeme}`)); + } + } + + const last = ordered[ordered.length - 1]; + if (last.validTo!.kind === "open_ended" && !last.isLive) { + v.push(violation("open_ended_requires_live", last.line, subject, "the final era is open ended but not marked is_live")); + } + + const duplicateIndex = rows.length !== new Set(rows.map((r) => r.eraIndex)).size; + if (duplicateIndex) { + v.push(violation("era_index_unique", head.line, subject, `duplicate era_index within ${key}`)); + } + } + + return v; +} + +/** + * The check that runs when the release scope is frozen, and only then. + * + * It is separate from `validateRegistry` on purpose. Before scope is frozen, `scope_pending` is + * the CORRECT state for an undecided row and must not fail the build. After the freeze, a + * `scope_pending` or `undeclared` row is exactly the silent inclusion or exclusion the plan + * forbids, so it must fail. + */ +export function assertScopeFrozen(parsed: ParsedRegistry): Violation[] { + const v: Violation[] = []; + for (const row of parsed.rows) { + if (row.releaseScope === "scope_pending" || row.releaseScope === "undeclared") { + v.push(violation( + "no_scope_pending_when_frozen", + row.line, + `${row.chain} ${row.proxyAddress} (${row.contractName})`, + `release_scope is '${row.releaseScope}' but the release scope has been frozen; every row must read in_release or out_of_release`, + )); + } + } + return v; +} diff --git a/projects/onchain-analytics/pipeline-v5/src/control-plane/csv.ts b/projects/onchain-analytics/pipeline-v5/src/control-plane/csv.ts new file mode 100644 index 0000000..7fce05e --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/src/control-plane/csv.ts @@ -0,0 +1,168 @@ +/** + * csv.ts -- strict RFC 4180 reading for the two control seeds. + * + * WHAT REPLACED WHAT. The previous loader hand-rolled a character scanner and ended it with + * `.filter(r => r.length === header.length)`. A row with one extra comma therefore VANISHED: no + * error, no warning, a smaller contract universe, and an ingestion run that silently covers less + * than it claims. That is the failure this module exists to make impossible. + * + * THE CONTRACT. A control seed is not ordinary data. One malformed byte must stop the pipeline + * starting, so every check below is fatal on the FIRST offending physical row and none of them + * can drop, skip, trim or repair anything. + */ + +import { readFileSync } from "fs"; +import { parse } from "csv-parse/sync"; + +export class SeedParseError extends Error { + constructor( + readonly path: string, + readonly detail: string, + readonly line: number | null = null, + ) { + super(`SEED_REJECTED ${path}${line === null ? "" : ` line ${line}`}: ${detail}`); + this.name = "SeedParseError"; + } +} + +export interface StrictCsv { + readonly path: string; + /** Header names in file order. */ + readonly header: readonly string[]; + /** Data records, each already proven to have exactly header.length fields. */ + readonly records: readonly (readonly string[])[]; + /** 1-based physical line number of each record, for error messages that a human can act on. */ + readonly recordLines: readonly number[]; + readonly recordDelimiter: "CRLF" | "LF"; + readonly bytes: number; + /** Physical lines in the file, excluding the single trailing terminator. */ + readonly physicalLines: number; +} + +const PRINTABLE_ASCII = /^[\x20-\x7e]*$/; + +/** + * Read a control seed under RFC 4180 with every relaxation switched off. + * + * `acceptedHeaders` is a list of exact header variants rather than one, because a seed may legally + * grow a declared block of columns (the boundary-evidence block) in a later phase. Matching is + * still exact against whichever variant is present; there is no partial or prefix match. + * + * Rejects, in order: a byte-order mark, mixed or absent line terminators, a non-printable or + * non-ASCII byte, a missing final terminator, any quoting or field-count violation csv-parse can + * detect, an empty file, a duplicate or blank header name, and finally any disagreement between + * the physical line count and the parsed record count. + */ +export function readStrictCsv(path: string, acceptedHeaders: readonly (readonly string[])[]): StrictCsv { + const buf = readFileSync(path); + + if (buf.length === 0) throw new SeedParseError(path, "file is empty"); + if (buf[0] === 0xef && buf[1] === 0xbb && buf[2] === 0xbf) { + throw new SeedParseError(path, "starts with a UTF-8 byte-order mark; a control seed must be plain ASCII"); + } + + const text = buf.toString("utf8"); + + const crlf = (text.match(/\r\n/g) ?? []).length; + const bareLf = (text.match(/(? 0) throw new SeedParseError(path, `${bareCr} bare CR byte(s); line terminators must be uniform CRLF or LF`); + if (crlf > 0 && bareLf > 0) { + throw new SeedParseError(path, `mixed line terminators: ${crlf} CRLF and ${bareLf} bare LF`); + } + if (crlf === 0 && bareLf === 0) throw new SeedParseError(path, "no line terminator found"); + const recordDelimiter: "CRLF" | "LF" = crlf > 0 ? "CRLF" : "LF"; + const terminator = recordDelimiter === "CRLF" ? "\r\n" : "\n"; + + if (!text.endsWith(terminator)) { + throw new SeedParseError(path, "does not end with a line terminator"); + } + if (text.endsWith(terminator + terminator)) { + throw new SeedParseError(path, "ends with a blank line"); + } + + // Line-accurate so a maintainer is told which row to open, not just that the file is bad. + const physicalLineTexts = text.slice(0, -terminator.length).split(terminator); + for (let i = 0; i < physicalLineTexts.length; i++) { + if (!PRINTABLE_ASCII.test(physicalLineTexts[i])) { + const bad = [...physicalLineTexts[i]].filter((c) => !PRINTABLE_ASCII.test(c)).map((c) => `U+${c.codePointAt(0)!.toString(16).toUpperCase().padStart(4, "0")}`); + throw new SeedParseError(path, `non-printable or non-ASCII character(s) ${[...new Set(bad)].join(", ")}`, i + 1); + } + } + + let raw: string[][]; + try { + raw = parse(text, { + bom: false, + delimiter: ",", + quote: '"', + escape: '"', + record_delimiter: terminator, + columns: false, + relax_column_count: false, + relax_quotes: false, + skip_empty_lines: false, + skip_records_with_empty_values: false, + skip_records_with_error: false, + trim: false, + ltrim: false, + rtrim: false, + comment: undefined, + cast: false, + }) as string[][]; + } catch (e) { + const err = e as { message?: string; lines?: number; code?: string }; + throw new SeedParseError(path, `${err.code ?? "CSV_ERROR"}: ${err.message ?? String(e)}`, err.lines ?? null); + } + + if (raw.length === 0) throw new SeedParseError(path, "contains no header row"); + + const header = raw[0]; + const blank = header.findIndex((h) => h.trim() === ""); + if (blank >= 0) throw new SeedParseError(path, `header column ${blank + 1} is blank`, 1); + const dupes = header.filter((h, i) => header.indexOf(h) !== i); + if (dupes.length > 0) throw new SeedParseError(path, `duplicate header column(s): ${[...new Set(dupes)].join(", ")}`, 1); + + const matched = acceptedHeaders.find( + (v) => v.length === header.length && v.every((h, i) => h === header[i]), + ); + if (!matched) { + const expected = acceptedHeaders.map((v) => ` expected (${v.length}): ${v.join(",")}`).join("\n"); + throw new SeedParseError( + path, + `header mismatch.\n${expected}\n found (${header.length}): ${header.join(",")}`, + 1, + ); + } + + const records = raw.slice(1); + for (let i = 0; i < records.length; i++) { + if (records[i].length !== header.length) { + // csv-parse should have thrown already; this is the belt to that braces, because a silent + // field-count drift is the exact defect this module replaces. + throw new SeedParseError(path, `expected ${header.length} fields, found ${records[i].length}`, i + 2); + } + } + + // Task 4. A quoted field may legally contain a record delimiter, which would make records fewer + // than physical lines. A control seed may not use that latitude: one record is one line, so this + // count is an exact equality and any embedded newline is rejected here rather than absorbed. + const physicalLines = physicalLineTexts.length; + if (records.length !== physicalLines - 1) { + throw new SeedParseError( + path, + `physical/parsed row count disagreement: ${physicalLines} physical lines (1 header + ${physicalLines - 1} data) but ${records.length} parsed records. ` + + `A field containing an embedded line terminator is not permitted in a control seed.`, + ); + } + + return { + path, + header, + records, + recordLines: records.map((_, i) => i + 2), + recordDelimiter, + bytes: buf.length, + physicalLines, + }; +} diff --git a/projects/onchain-analytics/pipeline-v5/src/control-plane/decodeSurface.ts b/projects/onchain-analytics/pipeline-v5/src/control-plane/decodeSurface.ts new file mode 100644 index 0000000..fa08396 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/src/control-plane/decodeSurface.ts @@ -0,0 +1,476 @@ +/** + * decodeSurface.ts -- the decode layer: union ABIs, the computed ambiguous set, and the + * undecodable-log counter. + * + * WHY THE UNION IS THE FLOOR. Distinct parameter types produce distinct event hashes, so for all + * but a measured handful of keys a union of every implementation's ABI cannot collide. That makes + * the union provably correct rather than a compromise, and it is what every production indexer + * does -- Ponder merges ABIs by address with no block dimension, Dune resubmits under one contract + * name, Envio imports the current ABI. None of them models when each ABI was valid. + * + * WHY THE ORDER IS A CORRECTNESS DECISION AND NOT A STYLE CHOICE. `topic0` is keccak over the + * canonical signature, which EXCLUDES `indexed` modifiers. Two implementations declaring the same + * event with different indexed flags therefore produce the SAME topic0 and DIFFERENT physical + * layouts, and a topic0-keyed decoder picks the first match in array order. Measured 2026-09-28 + * against viem on the real GReputation case: + * + * era-1 log decoded against an era-2-first union -> THROWS + * era-2 log decoded against an era-1-first union -> DECODES SILENTLY WRONG, balance = 4, + * which is the byte length of the string + * "celo" read as a uint256 + * + * A throw is recoverable. A plausible-looking wrong number is not. So every union here is built + * NEWEST-IMPLEMENTATION-FIRST, which is correct for recent data -- where about 95 percent of the + * questions live -- and raises loudly on old ambiguous data instead of lying about it. + * + * WHAT THIS MODULE DOES NOT BUILD. No era-scoped binding subsystem, no per-era ABI selection at + * query time, no bisection tooling. The ambiguous set inside the ingestion scope is empty, and + * building a resolution subsystem for an empty set is work with no member to serve. The assertion + * below is what keeps that true: a third ambiguity fails the build rather than decoding silently. + */ + +import type { EventSurfaceRow, ParsedEventSurface } from "./eventSurface.js"; +import { contractKey } from "./contractRegistry.js"; + +/** + * Ordinal, not locale-aware. + * + * `localeCompare` resolves through ICU collation, which orders punctuation against digits + * differently depending on the locale data the runtime happens to carry -- so it would make the + * ORDER of a shipped artifact an environment fact. Found by a test that expected one order and + * got the other. Every ordering in this module is a property of the data, so it compares bytes. + */ +function ordinal(a: string, b: string): number { + return a < b ? -1 : a > b ? 1 : 0; +} + +/** One input of a union ABI event, in the shape viem and every ABI consumer expects. */ +export interface UnionAbiInput { + readonly name: string; + readonly type: string; + readonly indexed: boolean; +} + +export interface UnionAbiEvent { + readonly type: "event"; + readonly name: string; + readonly inputs: readonly UnionAbiInput[]; + readonly anonymous: boolean; +} + +/** A union entry with the provenance that put it there, so any ordering claim is checkable. */ +export interface UnionAbiEntry { + readonly event: UnionAbiEvent; + readonly eraIndex: number; + readonly line: number; + readonly signature: string; + readonly topic0: string | null; + /** `formatAbiItem`-equivalent identity: name, parameter types AND indexed flags. */ + readonly identity: string; +} + +export interface UnionAbi { + readonly chain: string; + readonly chainId: number; + readonly address: string; + readonly entries: readonly UnionAbiEntry[]; + /** The array a topic0-keyed decoder consumes, in the order it will try them. */ + readonly abi: readonly UnionAbiEvent[]; + /** Era indices contributing to this union, in the order they were merged. */ + readonly eraOrder: readonly number[]; +} + +/** + * The identity two ABI entries must share to be the same entry. + * + * Ponder dedupes on `formatAbiItem`, which INCLUDES `indexed`, so two entries differing only in an + * indexed flag both survive the merge. That is the right rule and it is deliberately reproduced: + * collapsing them would silently discard one of the two real layouts and make the ambiguous set + * unmeasurable. + */ +export function abiItemIdentity(row: EventSurfaceRow): string { + const flags = row.paramTypes.map((t, i) => `${t}${row.indexedPositions.includes(i) ? " indexed" : ""}`); + return `${row.anonymous ? "anonymous " : ""}event ${row.eventName}(${flags.join(",")})`; +} + +function toEvent(row: EventSurfaceRow): UnionAbiEvent { + return { + type: "event", + name: row.eventName, + inputs: row.paramTypes.map((t, i) => ({ + name: row.paramNames[i] ?? "", + type: t, + indexed: row.indexedPositions.includes(i), + })), + anonymous: row.anonymous, + }; +} + +/** + * Build one contract's union ABI, newest implementation first. + * + * Ordering is by DESCENDING era index, then by ascending seed line inside an era so the result is + * a pure function of the seed. Duplicate identities collapse to the newest occurrence, which is + * what keeps the newest-first guarantee true after deduplication rather than merely before it. + */ +export function buildUnionAbi(rows: readonly EventSurfaceRow[]): UnionAbi { + if (rows.length === 0) throw new Error("buildUnionAbi: no surface rows given"); + const first = rows[0]; + for (const r of rows) { + if (r.chainId !== first.chainId || r.proxyAddress !== first.proxyAddress) { + throw new Error( + `buildUnionAbi: rows span more than one contract -- ${first.chainId}|${first.proxyAddress} and ${r.chainId}|${r.proxyAddress}`, + ); + } + } + + const ordered = [...rows].sort((a, b) => b.eraIndex - a.eraIndex || a.line - b.line); + + const seen = new Set(); + const entries: UnionAbiEntry[] = []; + for (const r of ordered) { + const identity = abiItemIdentity(r); + if (seen.has(identity)) continue; + seen.add(identity); + entries.push({ event: toEvent(r), eraIndex: r.eraIndex, line: r.line, signature: r.eventSignature, topic0: r.topic0, identity }); + } + + return { + chain: first.chain, + chainId: first.chainId, + address: first.proxyAddress, + entries, + abi: entries.map((e) => e.event), + eraOrder: entries.map((e) => e.eraIndex), + }; +} + +/** Every contract's union, keyed by `contractKey(chainId, proxyAddress)`. */ +export function buildAllUnionAbis(surface: ParsedEventSurface): Map { + const byContract = new Map(); + for (const r of surface.rows) { + const k = contractKey(r.chainId, r.proxyAddress); + const list = byContract.get(k); + if (list) list.push(r); + else byContract.set(k, [r]); + } + const out = new Map(); + for (const [k, rows] of byContract) out.set(k, buildUnionAbi(rows)); + return out; +} + +/** + * Is this union ordered newest-implementation-first? + * + * Returned rather than asserted so a caller can report every offender in one pass. A union with + * one entry is trivially ordered; the property that matters is that no entry is preceded by an + * entry from an OLDER era. + */ +export function isNewestFirst(union: UnionAbi): boolean { + for (let i = 1; i < union.eraOrder.length; i++) { + if (union.eraOrder[i] > union.eraOrder[i - 1]) return false; + } + return true; +} + +// --------------------------------------------------------------------------------------------- +// The computed ambiguous set +// --------------------------------------------------------------------------------------------- + +export interface AmbiguousLayout { + /** The indexed positions, joined, or the empty-set marker. This IS the physical layout. */ + readonly indexedPositions: string; + readonly eras: readonly number[]; + readonly lines: readonly number[]; +} + +export interface AmbiguousKey { + readonly chain: string; + readonly chainId: number; + readonly address: string; + readonly topic0: string; + readonly signature: string; + readonly layouts: readonly AmbiguousLayout[]; +} + +/** + * The ambiguous set, computed offline from the seed with zero chain calls. + * + * Group each `(chain_id, proxy_address)` union by `topic0`; a group carrying more than one + * distinct indexed-position layout is ambiguous. That is the complete test: topic0 fixes the event + * name and the parameter TYPES, so two entries sharing a topic0 can differ only in which + * parameters are indexed. + * + * Anonymous rows carry no topic0 and are excluded -- they are selected by position rather than by + * selector, so they are not subject to this failure mode. + */ +export function computeAmbiguousKeys(surface: ParsedEventSurface): AmbiguousKey[] { + const groups = new Map }>(); + + for (const r of surface.rows) { + if (r.anonymous || r.topic0 === null) continue; + const k = `${r.chainId}|${r.proxyAddress}|${r.topic0}`; + let g = groups.get(k); + if (!g) { + g = { row: r, layouts: new Map() }; + groups.set(k, g); + } + const layout = r.indexedPositions.length === 0 ? "" : r.indexedPositions.join(" "); + const l = g.layouts.get(layout); + if (l) { + l.eras.push(r.eraIndex); + l.lines.push(r.line); + } else { + g.layouts.set(layout, { eras: [r.eraIndex], lines: [r.line] }); + } + } + + const out: AmbiguousKey[] = []; + for (const g of groups.values()) { + if (g.layouts.size < 2) continue; + out.push({ + chain: g.row.chain, + chainId: g.row.chainId, + address: g.row.proxyAddress, + topic0: g.row.topic0!, + signature: g.row.eventSignature, + layouts: [...g.layouts] + .map(([indexedPositions, v]) => ({ + indexedPositions, + eras: [...v.eras].sort((a, b) => a - b), + lines: [...v.lines].sort((a, b) => a - b), + })) + .sort((a, b) => ordinal(a.indexedPositions, b.indexedPositions)), + }); + } + return out.sort((a, b) => a.chainId - b.chainId || ordinal(a.address, b.address) || ordinal(a.topic0, b.topic0)); +} + +export interface KnownAmbiguity { + readonly chainId: number; + readonly chain: string; + readonly address: string; + readonly signature: string; + readonly disposition: string; +} + +/** + * The ambiguous keys this system has already looked at and decided about. + * + * MEASURED 2026-09-28 over the shipped `event_surface.csv`: exactly two, both the same contract on + * two chains. Neither is inside the ingestion scope of this slice, which is why no era-scoped + * binding subsystem is built -- it would have no member to serve. + * + * A key that is NOT in this list fails the build. That is the whole point: this declaration is + * what makes a third ambiguity a loud event rather than a silent wrong decode. + */ +export const KNOWN_DECODE_AMBIGUITIES: readonly KnownAmbiguity[] = [ + { + chainId: 1, + chain: "ETHEREUM", + address: "0x603b8c0f110e037b51a381cbcacabb8d6c6e4543", + signature: "StateHashProof(string,address,uint256)", + disposition: + "GReputation. Era 1 declares no indexed parameter; eras 2 and 3 index the address. Ethereum " + + "is in the declared release scope but is NOT ingested by this slice and no shipped model " + + "reads this contract, so the union's newest-first order is the whole mitigation: an era-1 " + + "log throws rather than decoding wrong. Revisit before Ethereum is ingested.", + }, + { + chainId: 122, + chain: "FUSE", + address: "0x603b8c0f110e037b51a381cbcacabb8d6c6e4543", + signature: "StateHashProof(string,address,uint256)", + disposition: + "The same contract and the same layout change on Fuse. Fuse was dropped from the release on " + + "2026-09-28; its rows are retained as a record. No capture path reaches it.", + }, +] as const; + +export class UnhandledDecodeAmbiguityError extends Error { + constructor(readonly keys: readonly AmbiguousKey[]) { + const shown = keys + .map((k) => { + const layouts = k.layouts.map((l) => `indexed[${l.indexedPositions}] in era(s) ${l.eras.join(",")}`).join(" vs "); + return ` ${k.chain} ${k.address} ${k.signature}\n topic0 ${k.topic0}\n ${layouts}`; + }) + .join("\n"); + super( + `DECODE_AMBIGUITY_UNHANDLED: ${keys.length} (chain, address, topic0) key(s) carry more than one ` + + `physical layout and are not declared in KNOWN_DECODE_AMBIGUITIES.\n${shown}\n` + + `A topic0-keyed decoder picks the first match in array order, so one of these layouts would be ` + + `decoded into the wrong columns without raising. Declare each key with its disposition in ` + + `src/control-plane/decodeSurface.ts, or bind the contract's eras to their own ABIs.`, + ); + this.name = "UnhandledDecodeAmbiguityError"; + } +} + +/** + * The build-time assertion. Throws on any ambiguous key that has not been declared. + * + * Deliberately NOT scoped to the ingestion chains. Restricting it to what this slice captures + * would let a new ambiguity on a declared-but-not-yet-ingested chain through in silence, and the + * assertion exists precisely to catch the one nobody is looking for. + */ +export function assertNoUnhandledDecodeAmbiguity(surface: ParsedEventSurface): AmbiguousKey[] { + const found = computeAmbiguousKeys(surface); + const declared = new Set(KNOWN_DECODE_AMBIGUITIES.map((k) => `${k.chainId}|${k.address.toLowerCase()}|${k.signature}`)); + const undeclared = found.filter((k) => !declared.has(`${k.chainId}|${k.address.toLowerCase()}|${k.signature}`)); + if (undeclared.length > 0) throw new UnhandledDecodeAmbiguityError(undeclared); + return found; +} + +// --------------------------------------------------------------------------------------------- +// Decode coverage: the undecodable-log counter +// --------------------------------------------------------------------------------------------- + +/** + * The minimum a captured log must carry for this counter to classify it. Deliberately structural + * rather than the full row type, so the counter can run against a BigQuery result, a fixture or a + * HyperSync response without any of them depending on the others. + */ +export interface DecodeCandidateLog { + readonly chainId: number; + readonly address: string; + readonly topic0: string | null; +} + +export interface UndecodableCount { + readonly chainId: number; + readonly address: string; + readonly rowsConsidered: number; + readonly rowsDecodable: number; + /** Rows whose topic0 matched no entry in this address's surface. */ + readonly rowsUndecodable: number; + /** Distinct unmatched topic0 values, so the answer names what to go and find an ABI for. */ + readonly unmatchedTopic0s: readonly string[]; + /** True when this address has no surface row at all, so nothing it emits can be decoded. */ + readonly addressHasNoSurface: boolean; +} + +export interface UndecodableReport { + readonly byContract: readonly UndecodableCount[]; + readonly rowsConsidered: number; + readonly rowsUndecodable: number; + /** + * Rows this counter could NOT classify, counted separately from the result and never folded + * into `rowsUndecodable`. An absence is a measurement only when its error count is zero, and a + * null topic0 on a non-anonymous log means the ROW is unreadable, not that the event is unknown. + */ + readonly errors: number; + readonly errorDetail: readonly string[]; +} + +/** + * Count, per `(chain, address)`, the rows whose `topic0` matched no entry in that address's + * surface. + * + * WHY THIS EXISTS. Block coverage answers "what did we read". It does not answer "what could we + * read". An undecodable log is indistinguishable from an absent one in every downstream model, + * and the magnitude tripwire catches a wrong value, not a missing row. So the count is reported + * beside block coverage rather than inferred from it. + * + * Owner: Unit 2 builds and proves the counter. Unit 3 reports it alongside block coverage, which + * is where the captured rows are available to feed it. + */ +export function countUndecodableLogs( + logs: readonly DecodeCandidateLog[], + surface: ParsedEventSurface, +): UndecodableReport { + const topicsByContract = new Map>(); + for (const r of surface.rows) { + const k = contractKey(r.chainId, r.proxyAddress); + let s = topicsByContract.get(k); + if (!s) { + s = new Set(); + topicsByContract.set(k, s); + } + if (r.topic0 !== null) s.add(r.topic0.toLowerCase()); + } + + const acc = new Map }>(); + let errors = 0; + const errorDetail: string[] = []; + + for (const log of logs) { + const addr = log.address.toLowerCase(); + const k = contractKey(log.chainId, addr); + let a = acc.get(k); + if (!a) { + a = { chainId: log.chainId, address: addr, considered: 0, decodable: 0, undecodable: 0, unmatched: new Set() }; + acc.set(k, a); + } + + if (log.topic0 === null) { + errors++; + if (errorDetail.length < 25) errorDetail.push(`${k}: a log carried no topic0, so it can be neither matched nor ruled out`); + continue; + } + + a.considered++; + const known = topicsByContract.get(k); + if (known && known.has(log.topic0.toLowerCase())) a.decodable++; + else { + a.undecodable++; + a.unmatched.add(log.topic0.toLowerCase()); + } + } + + const byContract = [...acc.values()] + .map((a) => ({ + chainId: a.chainId, + address: a.address, + rowsConsidered: a.considered, + rowsDecodable: a.decodable, + rowsUndecodable: a.undecodable, + unmatchedTopic0s: [...a.unmatched].sort(ordinal), + addressHasNoSurface: !topicsByContract.has(contractKey(a.chainId, a.address)), + })) + .sort((x, y) => x.chainId - y.chainId || ordinal(x.address, y.address)); + + return { + byContract, + rowsConsidered: byContract.reduce((n, c) => n + c.rowsConsidered, 0), + rowsUndecodable: byContract.reduce((n, c) => n + c.rowsUndecodable, 0), + errors, + errorDetail, + }; +} + +/** + * The structural half of the same question, answerable with no captured rows at all: which + * deployment intervals have no surface entry, so ANY log they emit is undecodable. + * + * This is what can be measured before ingestion has run. It is NOT a substitute for the row count + * above and the unit report keeps the two apart. + */ +export interface UndecodableInterval { + readonly chain: string; + readonly chainId: number; + readonly address: string; + readonly contractName: string; + readonly eraIndex: number; + readonly reason: "no_abi_held" | "no_surface_row"; +} + +export function intervalsWithNoDecodableSurface( + registryRows: readonly { chain: string; chainId: number; proxyAddress: string; contractName: string; eraIndex: number; abiSource: string; noCodeDeployed: boolean }[], + surface: ParsedEventSurface, +): UndecodableInterval[] { + const surfaceKeys = new Set(surface.rows.map((r) => `${r.chainId}|${r.proxyAddress}|${r.eraIndex}`)); + const out: UndecodableInterval[] = []; + for (const r of registryRows) { + if (r.noCodeDeployed) continue; + if (surfaceKeys.has(`${r.chainId}|${r.proxyAddress}|${r.eraIndex}`)) continue; + out.push({ + chain: r.chain, + chainId: r.chainId, + address: r.proxyAddress, + contractName: r.contractName, + eraIndex: r.eraIndex, + reason: r.abiSource === "none" || r.abiSource === "" ? "no_abi_held" : "no_surface_row", + }); + } + return out; +} diff --git a/projects/onchain-analytics/pipeline-v5/src/control-plane/eraConfidence.ts b/projects/onchain-analytics/pipeline-v5/src/control-plane/eraConfidence.ts new file mode 100644 index 0000000..113fcef --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/src/control-plane/eraConfidence.ts @@ -0,0 +1,339 @@ +/** + * eraConfidence.ts -- the confidence grade an era interval carries, and the rule that assigns it. + * + * WHAT A GRADE IS FOR. It answers "how wrong could this interval be", never "may I proceed". + * The shipped control previously refused every `raw_only_unproven` interval, which is all of them, + * because the bar it enforced demanded an invariant EIP-1967 declined to require: upgrade events + * SHOULD be emitted, not MUST, and OpenZeppelin's own `_upgradeToAndCallUUPS` reaches + * `_setImplementation` through a branch that writes the slot and emits nothing. Applying that bar + * honestly produced 0 provable eras out of 41. A standard that cannot discriminate a + * well-understood contract from an unknown one moves no decision; it only hides the difference. + * So the grade propagates and the refusals live elsewhere, on conditions that are actually + * actionable -- no ABI, an undeclared ambiguity, a failed magnitude tripwire. + * + * THE RULE IS PUBLISHED, NOT INFERRED. The field-to-grade mapping implemented here was written + * down and hashed BEFORE a single grade was assigned, so no grade is a post-hoc rationalisation of + * whatever the data happened to look like. A grade nobody can re-derive is not evidence. + * + * TWO SOURCES, DELIBERATELY UNEQUAL. Rule A reads a promoted boundary-evidence row, which carries + * a second reader's verdict. Rule B reads only the registry seed, which does not -- so Rule B is + * CAPPED at `slot_bisected` by construction. A grade claiming two agreeing voices has to be able + * to name both. + */ + +import { join } from "path"; +import { readStrictCsv } from "./csv.js"; +import { SEEDS_DIR } from "./chains.js"; +import type { RegistryRow } from "./contractRegistry.js"; + +export const CONFIDENCE_GRADES = ["corroborated", "slot_bisected", "announced", "inferred"] as const; +export type ConfidenceGrade = (typeof CONFIDENCE_GRADES)[number]; + +/** Strongest first. Used for ordering and for the Rule B cap; never for a refusal. */ +export const GRADE_STRENGTH: Readonly> = { + corroborated: 4, + slot_bisected: 3, + announced: 2, + inferred: 1, +}; + +/** + * One era's promoted boundary evidence -- the flattened Phase 2B manifest, as it ships in + * `gd_dbt/seeds/era_boundary_evidence.csv`. + * + * Every field here is one the published rule names. Fields the rule does NOT read are still + * carried when they let a reader judge the evidence for themselves; `obligatorilyEmits` is the + * clearest case -- it is false on every manifest, so it cannot discriminate between eras, but it + * is the reason no era reaches `complete` and hiding it would make the grades look arbitrary. + */ +export interface EraBoundaryEvidence { + readonly chain: string; + readonly chainId: number; + readonly proxyAddress: string; + readonly eraIndex: number; + readonly implementationAddress: string | null; + readonly validFromBlock: number; + readonly openEnded: boolean; + /** The transition that OPENS this era, from `transitions[]`. Null when none was recorded. */ + readonly openingTransitionKind: string | null; + readonly openingEventImplementation: string | null; + readonly openingBothMeasured: boolean | null; + readonly openingAddressAgrees: boolean | null; + readonly openingOrderAgrees: boolean | null; + /** `architecture.slots.eip1967Implementation`, contract level. */ + readonly slotOutcome: string | null; + readonly slotAddress: string | null; + readonly slotAgreeing: number | null; + readonly slotErrorCount: number | null; + /** `slotCrossCheck`, contract level. */ + readonly crossCheckBlocked: boolean; + readonly checkPointsMeasured: number; + readonly checkPointsDisagreeing: number; + /** `baseline`, contract level. */ + readonly claimedEvents: number; + readonly independentlyConfirmedEvents: number; + readonly baselineSkippedChunks: number; + /** `tail`, contract level. */ + readonly tailComplete: boolean; + readonly tailSkippedChunks: number; + readonly tailErrorChunks: number; + /** Carried for the reader, not read by the rule. See the note above. */ + readonly obligatorilyEmits: boolean; + readonly frozenSafeHead: number; + readonly boundaryCheckedThroughBlock: number; + readonly sourceManifest: string; + readonly manifestSha256: string; +} + +export interface GradeVerdict { + readonly grade: ConfidenceGrade; + /** The clause that decided it: A1-A5 or B1-B4. Named so any grade is re-derivable. */ + readonly clause: string; + readonly reason: string; + readonly source: "boundary_evidence" | "registry_seed"; +} + +/** + * A slot reading is admissible when it is a positive answer agreed by two or more readers. + * + * A ZERO reading is admissible as a measured absence only when its error count is zero, because + * an absence is a measurement only when nothing failed while measuring it. A non-zero error count + * alongside a positive answer that two readers agree on does not void the answer -- it is carried + * into the receipt so a reader can weigh it. + */ +export function slotReadingAdmissible(e: Pick): boolean { + if (e.slotOutcome === "answer") return (e.slotAgreeing ?? 0) >= 2; + if (e.slotOutcome === "zero") return (e.slotAgreeing ?? 0) >= 2 && e.slotErrorCount === 0; + return false; +} + +/** + * Rule A. The grade of an era the Phase 2B manifests cover. + * + * Clauses are evaluated in order and the first match wins. + */ +export function gradeFromBoundaryEvidence(e: EraBoundaryEvidence): GradeVerdict { + const announced = e.openingEventImplementation !== null; + const bisectedHere = e.openingBothMeasured === true && e.openingAddressAgrees === true; + const allEventsConfirmed = e.claimedEvents > 0 && e.independentlyConfirmedEvents === e.claimedEvents; + + // A1. Two structurally different instruments agree: contract state at the boundary, and a second + // reader of the log. Requiring BOTH is what makes the name mean what it says -- either one alone + // is a single voice, which is the tier below. + if (announced && bisectedHere && e.openingOrderAgrees === true && e.checkPointsDisagreeing === 0 && allEventsConfirmed) { + return { + grade: "corroborated", + clause: "A1", + source: "boundary_evidence", + reason: + `the opening transition is announced by ${e.openingEventImplementation}, the EIP-1967 slot was read either ` + + `side of block ${e.validFromBlock} and agrees on both address and order with no disagreeing checkpoint, and all ` + + `${e.claimedEvents} claimed upgrade event(s) were independently re-read`, + }; + } + + // A2. The boundary itself was bisected, but the second voice is missing or only partial. A + // partial event-confirmation count is a CONTRACT-level number and cannot be attributed to one + // era, so it buys nothing here rather than being rounded up. + if (bisectedHere) { + return { + grade: "slot_bisected", + clause: "A2", + source: "boundary_evidence", + reason: + `the EIP-1967 slot was read either side of block ${e.validFromBlock} and agrees on address, but the second ` + + `independent reader does not close: ${e.independentlyConfirmedEvents} of ${e.claimedEvents} claimed event(s) confirmed`, + }; + } + + // A3. The live era only. A head slot read names the implementation currently behind the proxy, + // which binds this interval's right edge. It says nothing about any closed interval, so it is + // deliberately unavailable to them. + if (e.openEnded && slotReadingAdmissible(e) && e.slotAddress !== null && e.implementationAddress !== null + && e.slotAddress.toLowerCase() === e.implementationAddress.toLowerCase()) { + return { + grade: "slot_bisected", + clause: "A3", + source: "boundary_evidence", + reason: + `the live era: the EIP-1967 implementation slot read ${e.slotAddress} with ${e.slotAgreeing} agreeing reader(s), ` + + `matching this era's implementation. The boundary itself was not bisected (${e.checkPointsMeasured} checkpoint(s) measured)`, + }; + } + + // A4. An on-chain record bounds the interval, the record has no known hole, and an independent + // check was at least POSSIBLE. Without that last clause a chain where no second reader can run + // at any level of patience would grade the same as one where the check ran and agreed. + const recordWhole = e.baselineSkippedChunks === 0 && e.tailComplete && e.tailSkippedChunks === 0 && e.tailErrorChunks === 0; + const checkWasPossible = !e.crossCheckBlocked || e.independentlyConfirmedEvents > 0; + if (announced && recordWhole && checkWasPossible) { + return { + grade: "announced", + clause: "A4", + source: "boundary_evidence", + reason: + `an on-chain transition (${e.openingTransitionKind}) bounds the interval at block ${e.validFromBlock}, the ` + + `announcement record has no skipped or errored chunk, and an independent check was available. No state read binds this era`, + }; + } + + return { + grade: "inferred", + clause: "A5", + source: "boundary_evidence", + reason: + `the interval edge rests on a single unchallenged source: ` + + `${announced ? "announced" : "no opening transition recorded"}, ` + + `cross-check ${e.crossCheckBlocked ? "BLOCKED" : "available"}, ` + + `${e.independentlyConfirmedEvents} of ${e.claimedEvents} event(s) independently confirmed, ` + + `record ${recordWhole ? "whole" : "has a hole"}`, + }; +} + +/** The era-evidence vocabulary the registry seed carries. */ +const REGISTRY_BISECTED = new Set(["slot_bisection_and_announcement_log", "slot_bisection_only"]); +const REGISTRY_TWO_VOICE_CREATION = new Set([ + "explorer_index_and_state_read_agree", + "explorer_creation_tx_plus_receipt_two_endpoints_agreeing", +]); + +/** + * Rule B. The grade of an in-scope era with no promoted boundary evidence. + * + * CAPPED AT `slot_bisected`. The registry records how an era was found; it does not carry a second + * reader's verdict, so `corroborated` is unreachable from it and saying so in the code is what + * stops a future edit quietly promoting a whole column. + */ +export function gradeFromRegistryRow(row: RegistryRow): GradeVerdict { + if (REGISTRY_BISECTED.has(row.eraEvidence)) { + return { + grade: "slot_bisected", + clause: "B1", + source: "registry_seed", + reason: `era_evidence is '${row.eraEvidence}': the implementation slot was read and binds this interval, from one voice`, + }; + } + if (row.eraEvidence === "announcement_log_only") { + return { + grade: "announced", + clause: "B2", + source: "registry_seed", + reason: "era_evidence is 'announcement_log_only': an upgrade log bounds the interval and no state read binds it", + }; + } + if (row.eraEvidence === "contract_creation" && REGISTRY_TWO_VOICE_CREATION.has(row.creationMethod)) { + return { + grade: "announced", + clause: "B3", + source: "registry_seed", + reason: `the interval opens at contract creation, established by '${row.creationMethod}', which names two agreeing voices`, + }; + } + return { + grade: "inferred", + clause: "B4", + source: "registry_seed", + reason: `era_evidence '${row.eraEvidence}' with creation_method '${row.creationMethod}' rests on a single unchallenged source`, + }; +} + +/** + * The grade for one registry row, preferring promoted boundary evidence when it exists. + * + * The evidence map is keyed `chainId|proxyAddress|eraIndex`. + */ +export function gradeForEra(row: RegistryRow, evidence: ReadonlyMap): GradeVerdict { + const e = evidence.get(eraEvidenceKey(row.chainId, row.proxyAddress, row.eraIndex)); + return e ? gradeFromBoundaryEvidence(e) : gradeFromRegistryRow(row); +} + +export function eraEvidenceKey(chainId: number, proxyAddress: string, eraIndex: number): string { + return `${chainId}|${proxyAddress.toLowerCase()}|${eraIndex}`; +} + +export const ERA_BOUNDARY_EVIDENCE_PATH = join(SEEDS_DIR, "era_boundary_evidence.csv"); + +export const ERA_BOUNDARY_EVIDENCE_HEADER = [ + "chain", "chain_id", "proxy_address", "era_index", "implementation_address", + "valid_from_block", "valid_to_block", "open_ended", + "opening_transition_kind", "opening_event_implementation", + "opening_both_measured", "opening_address_agrees", "opening_order_agrees", + "slot_outcome", "slot_address", "slot_agreeing", "slot_error_count", + "cross_check_blocked", "check_points_total", "check_points_measured", "check_points_disagreeing", + "claimed_events", "independently_confirmed_events", "baseline_skipped_chunks", + "tail_complete", "tail_skipped_chunks", "tail_error_chunks", + "obligatorily_emits", "frozen_safe_head", "boundary_checked_through_block", + "source_manifest", "manifest_sha256", +] as const; + +/** `"true"` / `"false"` / `""`, where the empty string means the question was never answered. */ +function triBool(raw: string): boolean | null { + if (raw === "true") return true; + if (raw === "false") return false; + return null; +} + +function num(raw: string): number { + return raw === "" ? 0 : Number(raw); +} + +/** + * Read the promoted boundary-evidence seed. + * + * This is the artifact an outside reader opens to re-derive any manifest-backed grade, which is + * the whole reason the Phase 2B manifests were promoted out of a gitignored scratch directory: a + * receipt nobody else can open is not a receipt. + */ +export function parseEraBoundaryEvidence(path = ERA_BOUNDARY_EVIDENCE_PATH): Map { + const csv = readStrictCsv(path, [ERA_BOUNDARY_EVIDENCE_HEADER]); + const out = new Map(); + for (const r of csv.records) { + const [ + chain, chainId, proxyAddress, eraIndex, implementationAddress, + validFromBlock, , openEnded, + openingTransitionKind, openingEventImplementation, + openingBothMeasured, openingAddressAgrees, openingOrderAgrees, + slotOutcome, slotAddress, slotAgreeing, slotErrorCount, + crossCheckBlocked, , checkPointsMeasured, checkPointsDisagreeing, + claimedEvents, independentlyConfirmedEvents, baselineSkippedChunks, + tailComplete, tailSkippedChunks, tailErrorChunks, + obligatorilyEmits, frozenSafeHead, boundaryCheckedThroughBlock, + sourceManifest, manifestSha256, + ] = r; + + const row: EraBoundaryEvidence = { + chain, + chainId: Number(chainId), + proxyAddress, + eraIndex: Number(eraIndex), + implementationAddress: implementationAddress === "" ? null : implementationAddress, + validFromBlock: Number(validFromBlock), + openEnded: openEnded === "true", + openingTransitionKind: openingTransitionKind === "" ? null : openingTransitionKind, + openingEventImplementation: openingEventImplementation === "" ? null : openingEventImplementation, + openingBothMeasured: triBool(openingBothMeasured), + openingAddressAgrees: triBool(openingAddressAgrees), + openingOrderAgrees: triBool(openingOrderAgrees), + slotOutcome: slotOutcome === "" ? null : slotOutcome, + slotAddress: slotAddress === "" ? null : slotAddress, + slotAgreeing: slotAgreeing === "" ? null : Number(slotAgreeing), + slotErrorCount: slotErrorCount === "" ? null : Number(slotErrorCount), + crossCheckBlocked: crossCheckBlocked === "true", + checkPointsMeasured: num(checkPointsMeasured), + checkPointsDisagreeing: num(checkPointsDisagreeing), + claimedEvents: num(claimedEvents), + independentlyConfirmedEvents: num(independentlyConfirmedEvents), + baselineSkippedChunks: num(baselineSkippedChunks), + tailComplete: tailComplete === "true", + tailSkippedChunks: num(tailSkippedChunks), + tailErrorChunks: num(tailErrorChunks), + obligatorilyEmits: obligatorilyEmits === "true", + frozenSafeHead: num(frozenSafeHead), + boundaryCheckedThroughBlock: num(boundaryCheckedThroughBlock), + sourceManifest, + manifestSha256, + }; + out.set(eraEvidenceKey(row.chainId, row.proxyAddress, row.eraIndex), row); + } + return out; +} diff --git a/projects/onchain-analytics/pipeline-v5/src/control-plane/eraIntervals.ts b/projects/onchain-analytics/pipeline-v5/src/control-plane/eraIntervals.ts new file mode 100644 index 0000000..ca2e2be --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/src/control-plane/eraIntervals.ts @@ -0,0 +1,214 @@ +/** + * eraIntervals.ts -- the era validity-interval table, and the three properties it must hold. + * + * AN ERA IS A VALIDITY INTERVAL, so it is tested like one. "Which ABI was in force at block N" is + * an as-of temporal join, which is a solved modelling problem -- not an epistemology problem. The + * rigour belongs in the interval algebra, and that is what this file asserts. + * + * THE THREE PROPERTIES, and what each one costs when it is false: + * + * no overlaps two answers to "which ABI at block N". The decoder takes whichever the join + * returns, silently, and possibly differently between runs. + * no gaps NO answer. A left join against a missing interval returns null rather than + * raising, so every log in the gap decodes to nothing and is indistinguishable + * from a block range that produced no logs. + * one covering the property a reader actually depends on. Resolve a real block, get exactly + * one row. A half-open interval written closed returns two at every boundary. + * + * WHY THESE EXIST TWICE. The shipped versions are dbt tests, which need a warehouse target this + * unit does not have. These are the same three assertions over the same seed, and they RUN. A + * criterion claimed from a test that never ran is not a criterion, so both exist and the unit + * report names which unit runs the SQL. + * + * WHAT THEY DO NOT DETECT, said plainly: weak evidence. An interval chain can be perfectly shaped + * and still rest on a single unchallenged source. That is what the confidence grade is for, and + * saying so is the difference between a test suite and a reassurance. + */ + +import { join } from "path"; +import { readStrictCsv } from "./csv.js"; +import { SEEDS_DIR } from "./chains.js"; +import { INT64_MAX_LEXEME } from "./int64.js"; +import { violation, type Violation } from "./fields.js"; +import { CONFIDENCE_GRADES, type ConfidenceGrade } from "./eraConfidence.js"; + +export const ERA_INTERVALS_PATH = join(SEEDS_DIR, "era_intervals.csv"); + +/** The eight columns plan 5.4 names, plus three that make a failure readable. */ +export const ERA_INTERVALS_HEADER = [ + "chain", "chain_id", "proxy_address", "valid_from_block", "valid_to_block", + "implementation", "abi_id", "confidence_grade", "evidence_receipt_uri", + "contract_name", "era_index", "is_live", +] as const; + +/** The eight the plan requires, named separately so a test can assert the contract itself. */ +export const ERA_INTERVAL_REQUIRED_COLUMNS = [ + "chain_id", "proxy_address", "valid_from_block", "valid_to_block", + "implementation", "abi_id", "confidence_grade", "evidence_receipt_uri", +] as const; + +export interface EraInterval { + readonly line: number; + readonly chain: string; + readonly chainId: number; + readonly proxyAddress: string; + readonly contractName: string; + readonly eraIndex: number; + readonly validFromBlock: bigint; + readonly validToBlock: bigint; + readonly implementation: string; + readonly abiId: string; + readonly confidenceGrade: ConfidenceGrade; + readonly evidenceReceiptUri: string; + readonly isLive: boolean; +} + +export const OPEN_ENDED = BigInt(INT64_MAX_LEXEME); + +export function parseEraIntervals(path = ERA_INTERVALS_PATH): EraInterval[] { + const csv = readStrictCsv(path, [ERA_INTERVALS_HEADER]); + return csv.records.map((r, i) => { + const grade = r[7]; + if (!(CONFIDENCE_GRADES as readonly string[]).includes(grade)) { + throw new Error(`${path}:${csv.recordLines[i]} confidence_grade '${grade}' is not one of ${CONFIDENCE_GRADES.join(", ")}`); + } + return { + line: csv.recordLines[i], + chain: r[0], + chainId: Number(r[1]), + proxyAddress: r[2], + validFromBlock: BigInt(r[3]), + validToBlock: BigInt(r[4]), + implementation: r[5], + abiId: r[6], + confidenceGrade: grade as ConfidenceGrade, + evidenceReceiptUri: r[8], + contractName: r[9], + eraIndex: Number(r[10]), + isLive: r[11] === "true", + }; + }); +} + +function byContract(intervals: readonly EraInterval[]): Map { + const m = new Map(); + for (const i of intervals) { + const k = `${i.chainId}|${i.proxyAddress}`; + const list = m.get(k); + if (list) list.push(i); + else m.set(k, [i]); + } + for (const list of m.values()) list.sort((a, b) => a.eraIndex - b.eraIndex); + return m; +} + +/** + * No two intervals on one contract overlap. + * + * Half-open, `[from, to)`, so two intervals overlap when one starts strictly before the other ends + * AND ends strictly after the other starts. Touching intervals are correct and are not flagged. + */ +export function assertNoOverlappingIntervals(intervals: readonly EraInterval[]): Violation[] { + const v: Violation[] = []; + for (const list of byContract(intervals).values()) { + for (let i = 0; i < list.length; i++) { + for (let j = i + 1; j < list.length; j++) { + const a = list[i]; + const b = list[j]; + if (a.validFromBlock < b.validToBlock && a.validToBlock > b.validFromBlock) { + v.push(violation( + "era_intervals_do_not_overlap", + b.line, + `${a.chain} ${a.proxyAddress} (${a.contractName})`, + `era ${a.eraIndex} [${a.validFromBlock}, ${a.validToBlock}) overlaps era ${b.eraIndex} [${b.validFromBlock}, ${b.validToBlock})`, + )); + } + } + } + } + return v; +} + +/** + * The interval chain is contiguous from the contract's creation to its head. + * + * `creationBlockFor` supplies the left edge, because the era table itself cannot know it: an + * interval chain that is internally perfect but starts 400,000 blocks after the contract was + * deployed loses every log in between and looks entirely healthy from the inside. + */ +export function assertNoIntervalGaps( + intervals: readonly EraInterval[], + creationBlockFor: (chainId: number, proxyAddress: string) => bigint | null, +): Violation[] { + const v: Violation[] = []; + for (const list of byContract(intervals).values()) { + for (let i = 1; i < list.length; i++) { + const prev = list[i - 1]; + const next = list[i]; + if (next.eraIndex !== prev.eraIndex + 1) { + v.push(violation("era_intervals_have_no_gaps", next.line, `${next.chain} ${next.proxyAddress} (${next.contractName})`, + `era index jumps from ${prev.eraIndex} to ${next.eraIndex}; an era is missing from the table entirely`)); + continue; + } + if (prev.validToBlock !== next.validFromBlock) { + v.push(violation("era_intervals_have_no_gaps", next.line, `${next.chain} ${next.proxyAddress} (${next.contractName})`, + `era ${prev.eraIndex} ends at ${prev.validToBlock} but era ${next.eraIndex} starts at ${next.validFromBlock}; the intervals are not contiguous`)); + } + } + + const first = list[0]; + const creation = creationBlockFor(first.chainId, first.proxyAddress); + if (creation !== null && first.validFromBlock !== creation) { + v.push(violation("era_intervals_have_no_gaps", first.line, `${first.chain} ${first.proxyAddress} (${first.contractName})`, + `the first era starts at ${first.validFromBlock} but the contract was created at ${creation}; the blocks in between belong to no era`)); + } + + const last = list[list.length - 1]; + if (last.isLive && last.validToBlock !== OPEN_ENDED) { + v.push(violation("era_intervals_have_no_gaps", last.line, `${last.chain} ${last.proxyAddress} (${last.contractName})`, + `the contract is live but its last era ends at ${last.validToBlock} rather than carrying the open-ended sentinel; every block after it belongs to no era`)); + } + } + return v; +} + +export interface CoverageProbe { + readonly chainId: number; + readonly proxyAddress: string; + readonly block: bigint; + readonly kind: string; +} + +/** Every real boundary, taken from the intervals themselves rather than invented. */ +export function boundaryProbes(intervals: readonly EraInterval[]): CoverageProbe[] { + const probes: CoverageProbe[] = []; + for (const i of intervals) { + probes.push({ chainId: i.chainId, proxyAddress: i.proxyAddress, block: i.validFromBlock, kind: "era_first_block" }); + if (i.validToBlock !== OPEN_ENDED) { + probes.push({ chainId: i.chainId, proxyAddress: i.proxyAddress, block: i.validToBlock - 1n, kind: "era_last_block" }); + } + } + return probes; +} + +/** Exactly one interval covers each probe block. Not one or more -- exactly one. */ +export function assertExactlyOneIntervalCovers( + intervals: readonly EraInterval[], + probes: readonly CoverageProbe[], +): Violation[] { + const grouped = byContract(intervals); + const v: Violation[] = []; + for (const p of probes) { + const list = grouped.get(`${p.chainId}|${p.proxyAddress}`) ?? []; + const covering = list.filter((i) => p.block >= i.validFromBlock && p.block < i.validToBlock); + if (covering.length !== 1) { + v.push(violation( + "exactly_one_era_covers_a_queried_block", + covering[0]?.line ?? null, + `chain ${p.chainId} ${p.proxyAddress} block ${p.block} (${p.kind})`, + `${covering.length} interval(s) cover this block${covering.length > 1 ? `: eras ${covering.map((c) => c.eraIndex).join(", ")}` : ""}`, + )); + } + } + return v; +} diff --git a/projects/onchain-analytics/pipeline-v5/src/control-plane/eventSurface.ts b/projects/onchain-analytics/pipeline-v5/src/control-plane/eventSurface.ts new file mode 100644 index 0000000..9feeabf --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/src/control-plane/eventSurface.ts @@ -0,0 +1,430 @@ +/** + * eventSurface.ts -- schema, parse, topic0 proof and era binding for `event_surface.csv`. + * + * WHAT THIS SEED DECIDES. Which log is which event, per era. Getting it wrong does not produce an + * error: it produces decoded rows whose columns hold the wrong values. Two measured facts make + * that concrete. Five selectors carry two different indexed layouts, and two (chain, address, + * topic0) keys change their indexed layout ACROSS THEIR OWN ERAS -- GReputation's + * `StateHashProof(string,address,uint256)` has no indexed parameter in era 1 and an indexed + * `address` in eras 2 and 3. So era resolution is mandatory, and a surface row that binds to the + * wrong era decodes real logs into the wrong fields silently. + * + * WHY topic0 IS RECOMPUTED RATHER THAN TRUSTED. An indexed flag is not part of the selector. + * A wrong-indexed ABI returns the right row count, throws nothing, and writes fields into the + * wrong columns. Recomputing keccak256 over the canonical signature is the only check that binds + * the stored topic0 to the stored parameter types rather than to itself. + */ + +import { join } from "path"; +import { keccak256, toBytes } from "viem"; +import { readStrictCsv, SeedParseError, type StrictCsv } from "./csv.js"; +import { SEEDS_DIR, type ChainAuthority } from "./chains.js"; +import { parseFiniteInt, parseLowerBound, parseUpperBound, compareBounds, type BlockBound } from "./int64.js"; +import { address, optionalAddress, bool, nonEmpty, hex32, violation, type Violation, type FieldContext } from "./fields.js"; +import { contractKey, type ParsedRegistry, type RegistryRow } from "./contractRegistry.js"; + +export const EVENT_SURFACE_PATH = join(SEEDS_DIR, "event_surface.csv"); + +export const EVENT_SURFACE_HEADER = [ + "chain", "chain_id", "contract_name", "proxy_address", "era_index", "implementation_address", + "event_name", "event_signature", "topic0", "anonymous", "indexed_positions", "param_types", + "param_names", "era_bound", "era_bound_from_block", "era_bound_to_block", "abi_source", + "source", "notes", +] as const; + +/** + * A non-anonymous event spends topic0 on its selector, leaving three indexed slots. An anonymous + * event has no selector and may use all four. Exceeding either is physically impossible on chain, + * so it is a defect in the seed, not a capture limitation. + */ +export const MAX_INDEXED_NON_ANONYMOUS = 3; +export const MAX_INDEXED_ANONYMOUS = 4; + +/** Topic slots the universal RawLogs grain physically carries besides topic0. */ +export const RAWLOGS_INDEXED_SLOTS = 3; + +const SOLIDITY_IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/; + +/** + * An indexed parameter of a non-value type is stored as keccak256 of its encoding, so the value + * itself never reaches the chain and is unrecoverable from any log capture, at any completeness. + * Solidity's rule is "arrays and structs", plus the two dynamic byte types. + */ +export function isHashOnlyWhenIndexed(abiType: string): boolean { + return abiType === "string" || abiType === "bytes" || abiType.includes("[") || abiType.includes("(") || abiType.startsWith("tuple"); +} + +export interface EventSurfaceRow { + readonly line: number; + readonly chain: string; + readonly chainId: number; + readonly contractName: string; + readonly proxyAddress: string; + readonly eraIndex: number; + readonly implementationAddress: string | null; + readonly eventName: string; + readonly eventSignature: string; + readonly topic0: string | null; + readonly anonymous: boolean; + readonly indexedPositions: readonly number[]; + readonly paramTypes: readonly string[]; + readonly paramNames: readonly string[]; + readonly eraBound: boolean; + readonly eraBoundFrom: BlockBound | null; + readonly eraBoundTo: BlockBound | null; + readonly abiSource: string; + readonly source: string; + readonly notes: string; + /** Indexed positions whose declared type reaches the topic as a hash only. */ + readonly hashOnlyIndexedPositions: readonly number[]; + readonly raw: readonly string[]; +} + +export interface ParsedEventSurface { + readonly rows: readonly EventSurfaceRow[]; + readonly csv: StrictCsv; +} + +function at(path: string, line: number, column: string, fn: () => T): T { + try { + return fn(); + } catch (e) { + if (e instanceof SeedParseError) throw e; + throw new SeedParseError(path, `column '${column}': ${(e as Error).message}`, line); + } +} + +/** + * A space-separated list where every element must carry a value. + * + * Split is exact: no trimming and no collapsing, so the element count is a faithful function of + * the field. An empty element here is a defect, because a type and an indexed position are both + * things that cannot be blank. + */ +function requiredList(path: string, line: number, column: string, raw: string): string[] { + if (raw === "") return []; + const parts = raw.split(" "); + if (parts.some((p) => p === "")) { + throw new SeedParseError(path, `column '${column}': '${raw}' has a leading, trailing or repeated space, which would make an element blank`, line); + } + return parts; +} + +/** + * The parameter-name list, where an EMPTY element is legitimate. + * + * Solidity permits an unnamed event parameter and this seed contains one: Uniswap V2's + * `PairCreated(address indexed token0, address indexed token1, address pair, uint)` leaves its + * fourth parameter unnamed, so the field reads `token0 token1 pair ` with a trailing space. An + * exact split is a bijection with the element list -- names are Solidity identifiers and cannot + * contain a space -- so `token0 token1 pair ` is unambiguously three named parameters and one + * unnamed one. Trimming it, or collapsing the space, would silently lose which parameter is the + * unnamed one. + */ +function nameList(path: string, line: number, column: string, raw: string, expectedCount: number): string[] { + if (expectedCount === 0) { + if (raw !== "") throw new SeedParseError(path, `column '${column}': '${raw}' is set but the event declares no parameters`, line); + return []; + } + const parts = raw.split(" "); + for (const p of parts) { + if (p !== "" && !SOLIDITY_IDENTIFIER.test(p)) { + throw new SeedParseError(path, `column '${column}': '${p}' is not a Solidity identifier`, line); + } + } + return parts; +} + +/** keccak256 over the UTF-8 bytes of the canonical signature, lowercase 0x-prefixed. */ +export function topic0For(signature: string): string { + return keccak256(toBytes(signature)); +} + +/** `Name(type1,type2)` built from the stored name and stored parameter types. */ +export function canonicalSignature(eventName: string, paramTypes: readonly string[]): string { + return `${eventName}(${paramTypes.join(",")})`; +} + +export function parseEventSurface(path = EVENT_SURFACE_PATH): ParsedEventSurface { + const csv = readStrictCsv(path, [EVENT_SURFACE_HEADER]); + const rows: EventSurfaceRow[] = []; + + for (let i = 0; i < csv.records.length; i++) { + const r = csv.records[i]; + const line = csv.recordLines[i]; + const ctx = (column: string): FieldContext => ({ path, line, column }); + + const chain = nonEmpty(ctx("chain"), r[0]); + const chainId = at(path, line, "chain_id", () => parseFiniteInt("chain_id", r[1], { min: 1 })); + const contractName = nonEmpty(ctx("contract_name"), r[2]); + const proxyAddress = address(ctx("proxy_address"), r[3]); + const eraIndex = at(path, line, "era_index", () => parseFiniteInt("era_index", r[4], { min: 1 })); + const implementationAddress = optionalAddress(ctx("implementation_address"), r[5]); + const eventName = nonEmpty(ctx("event_name"), r[6]); + if (!SOLIDITY_IDENTIFIER.test(eventName)) { + throw new SeedParseError(path, `column 'event_name': '${eventName}' is not a Solidity identifier`, line); + } + const eventSignature = nonEmpty(ctx("event_signature"), r[7]); + const anonymous = bool(ctx("anonymous"), r[9]); + const topic0 = anonymous ? null : hex32(ctx("topic0"), r[8]); + if (anonymous && r[8] !== "") { + // An anonymous event has no selector. A value in topic0 would be a real indexed parameter + // and treating it as a selector is exactly how an anonymous event gets mis-bound. + throw new SeedParseError(path, `column 'topic0': anonymous event '${eventSignature}' must leave topic0 empty, found '${r[8]}'`, line); + } + + const paramTypes = requiredList(path, line, "param_types", r[11]); + const paramNames = nameList(path, line, "param_names", r[12], paramTypes.length); + const indexedPositions = requiredList(path, line, "indexed_positions", r[10]) + .map((p) => at(path, line, "indexed_positions", () => parseFiniteInt("indexed_positions", p, { min: 0 }))); + + if (paramNames.length !== paramTypes.length) { + throw new SeedParseError(path, `${paramTypes.length} param_types but ${paramNames.length} param_names`, line); + } + for (const p of indexedPositions) { + if (p >= paramTypes.length) { + throw new SeedParseError(path, `indexed position ${p} is outside the ${paramTypes.length} declared parameter(s)`, line); + } + } + if (new Set(indexedPositions).size !== indexedPositions.length) { + throw new SeedParseError(path, `duplicate value in indexed_positions '${r[10]}'`, line); + } + for (let k = 1; k < indexedPositions.length; k++) { + if (indexedPositions[k] <= indexedPositions[k - 1]) { + throw new SeedParseError(path, `indexed_positions '${r[10]}' is not strictly ascending`, line); + } + } + + const eraBound = bool(ctx("era_bound"), r[13]); + let eraBoundFrom: BlockBound | null = null; + let eraBoundTo: BlockBound | null = null; + if (eraBound) { + eraBoundFrom = at(path, line, "era_bound_from_block", () => parseLowerBound("era_bound_from_block", r[14], { min: 0 })); + // `era_bound=true` is this seed's explicit open-ended declaration. Whether the sentinel is + // ACTUALLY admissible is settled against the deployment era in validateEventSurface; it can + // only be admissible at all on a bounded row. + eraBoundTo = at(path, line, "era_bound_to_block", () => parseUpperBound("era_bound_to_block", r[15], { declaredOpenEnded: r[15] === "9223372036854775807", min: 0 })); + } else if (r[14] !== "" || r[15] !== "") { + throw new SeedParseError(path, `era_bound=false but era_bound_from_block='${r[14]}' / era_bound_to_block='${r[15]}' are not both empty`, line); + } + + rows.push({ + line, chain, chainId, contractName, proxyAddress, eraIndex, implementationAddress, + eventName, eventSignature, topic0, anonymous, indexedPositions, paramTypes, paramNames, + eraBound, eraBoundFrom, eraBoundTo, + abiSource: nonEmpty(ctx("abi_source"), r[16]), + source: nonEmpty(ctx("source"), r[17]), + notes: r[18], + hashOnlyIndexedPositions: indexedPositions.filter((p) => isHashOnlyWhenIndexed(paramTypes[p])), + raw: r, + }); + } + + return { rows, csv }; +} + +export interface SurfaceCheckCounts { + /** Rows whose topic0 was recomputed (non-anonymous only). */ + readonly topic0Checked: number; + readonly topic0Matched: number; + /** Rows whose stored signature was rebuilt from stored name + param types. */ + readonly signatureChecked: number; + readonly signatureMatched: number; + readonly anonymousRows: number; + readonly boundRowsChecked: number; + readonly boundGroupsChecked: number; + readonly boundGroupsMatchingEnvelope: number; + readonly bindingChecked: number; + readonly bindingMatched: number; + readonly hashOnlyIndexedRows: number; +} + +/** + * Cross-row and cross-seed rules. Counts are returned alongside violations because "every topic0 + * matched" is only meaningful next to how many were actually recomputed. + */ +export function validateEventSurface( + parsed: ParsedEventSurface, + registry: ParsedRegistry, + chains: ChainAuthority, +): { violations: Violation[]; advisories: Violation[]; counts: SurfaceCheckCounts } { + const v: Violation[] = []; + // Reported, never blocking. An advisory is a true statement about the CAPTURE GRAIN rather than + // a defect in the seed. Blocking on one would refuse to start the pipeline over a row that is + // correctly describing the chain. + const advisories: Violation[] = []; + const counts = { + topic0Checked: 0, topic0Matched: 0, signatureChecked: 0, signatureMatched: 0, + anonymousRows: 0, boundRowsChecked: 0, boundGroupsChecked: 0, boundGroupsMatchingEnvelope: 0, + bindingChecked: 0, bindingMatched: 0, hashOnlyIndexedRows: 0, + }; + + // Exactly one era row per (chain, proxy_address, era_index). Built from the registry so a + // duplicate there surfaces here as an ambiguous bind rather than an arbitrary first match. + const eraByKey = new Map(); + for (const row of registry.rows) { + const k = `${row.chainId}|${row.proxyAddress}|${row.eraIndex}`; + const list = eraByKey.get(k); + if (list) list.push(row); + else eraByKey.set(k, [row]); + } + const contractExists = new Set(registry.rows.map((r) => contractKey(r.chainId, r.proxyAddress))); + + for (const row of parsed.rows) { + const subject = `${row.chain} ${row.proxyAddress} era ${row.eraIndex} ${row.eventSignature}`; + + const expectedId = chains.byName.get(row.chain); + if (expectedId === undefined) { + v.push(violation("chain_known", row.line, subject, `chain '${row.chain}' is not declared in ${chains.path}`)); + } else if (expectedId !== row.chainId) { + v.push(violation("chain_id_consistency", row.line, subject, `chain '${row.chain}' is chain_id ${expectedId} in the chains seed but this row says ${row.chainId}`)); + } + + counts.signatureChecked++; + const canonical = canonicalSignature(row.eventName, row.paramTypes); + if (canonical === row.eventSignature) counts.signatureMatched++; + else v.push(violation("signature_canonical", row.line, subject, `stored event_signature '${row.eventSignature}' does not equal '${canonical}' rebuilt from event_name and param_types`)); + + if (row.anonymous) { + counts.anonymousRows++; + if (row.indexedPositions.length > MAX_INDEXED_ANONYMOUS) { + v.push(violation("anonymous_topic_slots", row.line, subject, `${row.indexedPositions.length} indexed parameters exceed the ${MAX_INDEXED_ANONYMOUS} physical topic slots available to an anonymous event`)); + } + if (row.indexedPositions.length > RAWLOGS_INDEXED_SLOTS) { + // Not a seed defect: the seed is right and the grain is narrower than the chain. Recorded + // so it cannot be discovered later as missing data with no explanation. + advisories.push(violation("anonymous_not_capturable_in_rawlogs", row.line, subject, `anonymous event uses ${row.indexedPositions.length} topic slots but RawLogs reserves topic0 for NULL and carries ${RAWLOGS_INDEXED_SLOTS} indexed slots, so this event is not losslessly capturable in the current grain`)); + } + } else { + counts.topic0Checked++; + const recomputed = topic0For(row.eventSignature); + if (recomputed === row.topic0) counts.topic0Matched++; + else v.push(violation("topic0_recompute", row.line, subject, `stored topic0 ${row.topic0} but keccak256('${row.eventSignature}') = ${recomputed}`)); + + if (row.indexedPositions.length > MAX_INDEXED_NON_ANONYMOUS) { + v.push(violation("indexed_slot_limit", row.line, subject, `${row.indexedPositions.length} indexed parameters, but a non-anonymous event has only ${MAX_INDEXED_NON_ANONYMOUS} topic slots after the selector`)); + } + } + + if (row.hashOnlyIndexedPositions.length > 0) counts.hashOnlyIndexedRows++; + + // Task 7: exactly one binding, and it must be the exact era, not merely the same contract. + counts.bindingChecked++; + const matches = eraByKey.get(`${row.chainId}|${row.proxyAddress}|${row.eraIndex}`) ?? []; + if (matches.length === 1) { + counts.bindingMatched++; + const era = matches[0]; + if (era.noCodeDeployed) { + v.push(violation("surface_binds_to_deployed_era", row.line, subject, `binds to a ${era.eraMethod} registry row, which declares no deployed code`)); + } + if (era.contractName !== row.contractName) { + v.push(violation("contract_name_agreement", row.line, subject, `contract_name '${row.contractName}' but the registry era says '${era.contractName}'`)); + } + if (row.implementationAddress !== null && era.implementationAddress !== null && row.implementationAddress !== era.implementationAddress) { + v.push(violation("implementation_agreement", row.line, subject, `implementation_address ${row.implementationAddress} but the registry era says ${era.implementationAddress}`)); + } + + if (row.eraBound && era.validFrom && era.validTo) { + counts.boundRowsChecked++; + // WHAT era_bound_from/to ACTUALLY MEAN, from the seed's own schema: "First block this + // event can be emitted at" and "Exclusive upper bound", for an event that is NOT present + // in every era of its contract. So the window is the event's PRESENCE ENVELOPE across the + // contract's history, not a sub-range of one era. The era this row is declared on must + // therefore sit INSIDE the window; a row claiming an event is decodable in an era its own + // window excludes is a contradiction. Every comparison is on the discriminated bound, so + // the open-ended sentinel is never coerced to a number. + if (compareBounds(era.validFrom, row.eraBoundFrom!) < 0) { + v.push(violation("surface_era_within_window", row.line, subject, `era ${era.eraIndex} starts at ${era.validFrom.lexeme}, before the event's declared first block ${row.eraBoundFrom!.lexeme}`)); + } + if (compareBounds(era.validTo, row.eraBoundTo!) > 0) { + v.push(violation("surface_era_within_window", row.line, subject, `era ${era.eraIndex} ends at ${era.validTo.lexeme}, after the event's declared exclusive upper bound ${row.eraBoundTo!.lexeme}`)); + } + if (era.validTo.kind === "open_ended" && row.eraBoundTo!.kind !== "open_ended") { + v.push(violation("surface_live_era_needs_open_window", row.line, subject, `registry era ${era.eraIndex} is open ended but the event's window closes at the finite block ${row.eraBoundTo!.lexeme}`)); + } + if (compareBounds(row.eraBoundFrom!, row.eraBoundTo!) >= 0) { + v.push(violation("surface_interval_ordering", row.line, subject, `era_bound_from_block ${row.eraBoundFrom!.lexeme} is not below era_bound_to_block ${row.eraBoundTo!.lexeme}`)); + } + } + } else if (matches.length === 0) { + const detail = contractExists.has(contractKey(row.chainId, row.proxyAddress)) + ? `no era ${row.eraIndex} exists for that contract in the registry` + : `contract ${row.proxyAddress} is not in the registry on chain_id ${row.chainId}`; + v.push(violation("surface_binds_to_one_era", row.line, subject, detail)); + } else { + v.push(violation("surface_binds_to_one_era", row.line, subject, `binds to ${matches.length} registry rows (lines ${matches.map((m) => m.line).join(", ")})`)); + } + } + + // Group-level rules. An event is one (chain, contract, selector) across however many eras carry + // it, and the declared window has to describe exactly those eras -- otherwise a decoder that + // trusts the window covers blocks where the event does not exist, or refuses blocks where it + // does. The seed's own schema warns that 59 combinations are removed in one era and restored in + // a later one, so a first-and-last envelope is the only thing the window can honestly be, and + // the per-era rows remain the precise statement of presence. + const groups = new Map(); + for (const row of parsed.rows) { + const k = `${row.chainId}|${row.proxyAddress}|${row.anonymous ? row.eventSignature : row.topic0}`; + const list = groups.get(k); + if (list) list.push(row); + else groups.set(k, [row]); + } + + const erasByContract = new Map(); + for (const r of registry.rows) { + if (r.noCodeDeployed) continue; + const k = contractKey(r.chainId, r.proxyAddress); + const list = erasByContract.get(k); + if (list) list.push(r); + else erasByContract.set(k, [r]); + } + + for (const [, rows] of groups) { + const head = rows[0]; + const subject = `${head.chain} ${head.proxyAddress} ${head.eventSignature}`; + const contractEras = erasByContract.get(contractKey(head.chainId, head.proxyAddress)) ?? []; + if (contractEras.length === 0) continue; + + const bound = rows.filter((r) => r.eraBound); + if (bound.length > 0 && bound.length !== rows.length) { + v.push(violation("era_bound_flag_agreement", head.line, subject, `${bound.length} of ${rows.length} rows for this event declare era_bound=true; the flag describes the event, not one era`)); + continue; + } + + if (bound.length === 0) { + // era_bound=false asserts the event is present in EVERY era of its contract. + const covered = new Set(rows.map((r) => r.eraIndex)); + const missing = contractEras.filter((e) => !covered.has(e.eraIndex)).map((e) => e.eraIndex); + if (missing.length > 0) { + v.push(violation("unbound_event_covers_all_eras", head.line, subject, `era_bound=false asserts presence in every era, but era(s) ${missing.join(", ")} of ${contractEras.length} carry no row for it`)); + } + continue; + } + + counts.boundGroupsChecked++; + const froms = new Set(rows.map((r) => r.eraBoundFrom!.lexeme)); + const tos = new Set(rows.map((r) => r.eraBoundTo!.lexeme)); + if (froms.size > 1 || tos.size > 1) { + v.push(violation("era_bound_window_agreement", head.line, subject, `rows for this event disagree on its window: from {${[...froms].join(", ")}} to {${[...tos].join(", ")}}`)); + continue; + } + + const present = new Set(rows.map((r) => r.eraIndex)); + const presentEras = contractEras.filter((e) => present.has(e.eraIndex)); + if (presentEras.length === 0) continue; + const envelopeFrom = presentEras.reduce((a, b) => (compareBounds(a.validFrom!, b.validFrom!) <= 0 ? a : b)).validFrom!; + const envelopeTo = presentEras.reduce((a, b) => (compareBounds(a.validTo!, b.validTo!) >= 0 ? a : b)).validTo!; + + const fromExact = head.eraBoundFrom!.lexeme === envelopeFrom.lexeme; + const toExact = head.eraBoundTo!.lexeme === envelopeTo.lexeme; + if (!fromExact) { + v.push(violation("era_bound_window_is_exact_envelope", head.line, subject, `era_bound_from_block is ${head.eraBoundFrom!.lexeme} but the earliest era carrying this event starts at ${envelopeFrom.lexeme}`)); + } + if (!toExact) { + v.push(violation("era_bound_window_is_exact_envelope", head.line, subject, `era_bound_to_block is ${head.eraBoundTo!.lexeme} but the latest era carrying this event ends at ${envelopeTo.lexeme}`)); + } + if (fromExact && toExact) counts.boundGroupsMatchingEnvelope++; + } + + return { violations: v, advisories, counts }; +} diff --git a/projects/onchain-analytics/pipeline-v5/src/control-plane/fields.ts b/projects/onchain-analytics/pipeline-v5/src/control-plane/fields.ts new file mode 100644 index 0000000..3cc6d26 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/src/control-plane/fields.ts @@ -0,0 +1,82 @@ +/** + * fields.ts -- field-level validators shared by both control seeds. + * + * Every one of these throws. None of them coerces, trims, repairs or defaults. A control seed is + * the thing that decides what the pipeline covers, so "nearly right" has to be indistinguishable + * from "wrong" at this layer. + */ + +import { SeedParseError } from "./csv.js"; + +export interface FieldContext { + readonly path: string; + readonly line: number; + readonly column: string; +} + +function fail(ctx: FieldContext, detail: string): never { + throw new SeedParseError(ctx.path, `column '${ctx.column}': ${detail}`, ctx.line); +} + +const LOWER_ADDRESS = /^0x[0-9a-f]{40}$/; +const LOWER_HEX32 = /^0x[0-9a-f]{64}$/; + +/** A 20-byte address, lowercase. Mixed case is rejected rather than normalised: EIP-55 checksum + * casing entering a merge key has already produced duplicate rows in this warehouse. */ +export function address(ctx: FieldContext, raw: string): string { + if (!LOWER_ADDRESS.test(raw)) { + const why = /^0x[0-9a-fA-F]{40}$/.test(raw) + ? "contains uppercase hex; addresses must be stored lowercase" + : "is not a lowercase 20-byte 0x-prefixed address"; + fail(ctx, `'${raw}' ${why}`); + } + return raw; +} + +export function optionalAddress(ctx: FieldContext, raw: string): string | null { + return raw === "" ? null : address(ctx, raw); +} + +export function hex32(ctx: FieldContext, raw: string): string { + if (!LOWER_HEX32.test(raw)) fail(ctx, `'${raw}' is not a lowercase 32-byte 0x-prefixed hex value`); + return raw; +} + +export function optionalHex32(ctx: FieldContext, raw: string): string | null { + return raw === "" ? null : hex32(ctx, raw); +} + +/** Exactly "true" or "false". Not "TRUE", not "1", not "yes", not empty. */ +export function bool(ctx: FieldContext, raw: string): boolean { + if (raw === "true") return true; + if (raw === "false") return false; + fail(ctx, `'${raw}' is not exactly 'true' or 'false'`); +} + +export function nonEmpty(ctx: FieldContext, raw: string): string { + if (raw === "") fail(ctx, "is empty, but a value is required"); + return raw; +} + +export function oneOf(ctx: FieldContext, raw: string, allowed: readonly T[]): T { + if (!(allowed as readonly string[]).includes(raw)) { + fail(ctx, `'${raw}' is not one of: ${allowed.join(", ")}`); + } + return raw as T; +} + +export function mustBeEmpty(ctx: FieldContext, raw: string, because: string): void { + if (raw !== "") fail(ctx, `must be empty because ${because}, found '${raw}'`); +} + +/** A cross-row rule violation. Collected rather than thrown so one run reports every one. */ +export interface Violation { + readonly check: string; + readonly line: number | null; + readonly subject: string; + readonly detail: string; +} + +export function violation(check: string, line: number | null, subject: string, detail: string): Violation { + return { check, line, subject, detail }; +} diff --git a/projects/onchain-analytics/pipeline-v5/src/control-plane/index.ts b/projects/onchain-analytics/pipeline-v5/src/control-plane/index.ts new file mode 100644 index 0000000..465a78f --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/src/control-plane/index.ts @@ -0,0 +1,164 @@ +/** + * registry/index.ts -- the public entry point for the control plane. + * + * `loadControlPlane` is fail-closed: it returns a validated control plane or it throws. There is + * no partial result and no warning path, because the exit condition this module exists to satisfy + * is that one malformed byte in either control seed prevents the pipeline from starting. + * + * `inspectControlPlane` is the same work without the throw, for the validation report. It exists + * so evidence can be generated from the identical code the pipeline runs, rather than from a + * second implementation that could disagree with it. + */ + +import { SeedParseError } from "./csv.js"; +import { loadChains, CHAINS_PATH, type ChainAuthority } from "./chains.js"; +import { parseRegistry, validateRegistry, REGISTRY_PATH, type ParsedRegistry } from "./contractRegistry.js"; +import { assertReleaseScopeFrozen, releaseScopeState, RELEASE_SCOPE_FREEZE, type ReleaseScopeFreeze, type ReleaseScopeState } from "./releaseScope.js"; +import { parseEventSurface, validateEventSurface, EVENT_SURFACE_PATH, type ParsedEventSurface, type SurfaceCheckCounts } from "./eventSurface.js"; +import { computeAmbiguousKeys, KNOWN_DECODE_AMBIGUITIES, type AmbiguousKey } from "./decodeSurface.js"; +import { violation, type Violation } from "./fields.js"; + +export * from "./int64.js"; +export * from "./csv.js"; +export * from "./fields.js"; +export * from "./chains.js"; +export * from "./contractRegistry.js"; +export * from "./releaseScope.js"; +export * from "./eventSurface.js"; +export * from "./decodeSurface.js"; +export * from "./eraConfidence.js"; +export * from "./eraIntervals.js"; +export * from "./magnitude.js"; + +export interface ControlPlanePaths { + readonly chains?: string; + readonly registry?: string; + readonly eventSurface?: string; + /** Overridable so a test can exercise an unfrozen scope without editing the shipped decision. */ + readonly freeze?: ReleaseScopeFreeze; +} + +export interface ControlPlane { + readonly chains: ChainAuthority; + readonly registry: ParsedRegistry; + readonly eventSurface: ParsedEventSurface; + readonly counts: SurfaceCheckCounts; + readonly releaseScopeState: ReleaseScopeState; +} + +export interface ControlPlaneInspection { + readonly ok: boolean; + /** Set when a physical row was malformed. Parsing stops at the first one, by design. */ + readonly parseError: { readonly path: string; readonly line: number | null; readonly message: string } | null; + readonly registryViolations: readonly Violation[]; + readonly surfaceViolations: readonly Violation[]; + /** Violations of the frozen release scope: a pending row, an excluded contract, a new chain. */ + readonly releaseScopeViolations: readonly Violation[]; + /** + * An undeclared decode ambiguity: one `topic0` carrying two physical layouts on one address, + * with nothing recording that anybody has looked at it. Blocking, because the alternative is a + * decoder silently picking one of the two layouts. + */ + readonly decodeViolations: readonly Violation[]; + /** Every ambiguous key found, declared or not. Reported so the count is never inferred. */ + readonly decodeAmbiguities: readonly AmbiguousKey[]; + readonly releaseScopeState: ReleaseScopeState | null; + /** True statements about the capture grain. Reported, never blocking. */ + readonly advisories: readonly Violation[]; + readonly plane: ControlPlane | null; +} + +export class ControlPlaneInvalidError extends Error { + constructor(readonly violations: readonly Violation[]) { + const shown = violations.slice(0, 25) + .map((x) => ` [${x.check}] line ${x.line ?? "-"} ${x.subject}: ${x.detail}`) + .join("\n"); + const more = violations.length > 25 ? `\n ... and ${violations.length - 25} more` : ""; + super(`CONTROL_PLANE_REJECTED: ${violations.length} rule violation(s)\n${shown}${more}`); + this.name = "ControlPlaneInvalidError"; + } +} + +export function inspectControlPlane(paths: ControlPlanePaths = {}): ControlPlaneInspection { + const chainsPath = paths.chains ?? CHAINS_PATH; + const registryPath = paths.registry ?? REGISTRY_PATH; + const surfacePath = paths.eventSurface ?? EVENT_SURFACE_PATH; + + let chains: ChainAuthority; + let registry: ParsedRegistry; + let eventSurface: ParsedEventSurface; + try { + chains = loadChains(chainsPath); + registry = parseRegistry(registryPath); + eventSurface = parseEventSurface(surfacePath); + } catch (e) { + if (e instanceof SeedParseError) { + return { + ok: false, + parseError: { path: e.path, line: e.line, message: e.message }, + registryViolations: [], surfaceViolations: [], releaseScopeViolations: [], + decodeViolations: [], decodeAmbiguities: [], + releaseScopeState: null, advisories: [], plane: null, + }; + } + throw e; + } + + const freeze = paths.freeze ?? RELEASE_SCOPE_FREEZE; + const registryViolations = validateRegistry(registry, chains); + const releaseScopeViolations = assertReleaseScopeFrozen(registry, chains, freeze); + const { violations: surfaceViolations, advisories, counts } = validateEventSurface(eventSurface, registry, chains); + const decodeAmbiguities = computeAmbiguousKeys(eventSurface); + const decodeViolations = undeclaredAmbiguityViolations(decodeAmbiguities); + const state = releaseScopeState(registry); + + return { + ok: registryViolations.length === 0 && surfaceViolations.length === 0 + && releaseScopeViolations.length === 0 && decodeViolations.length === 0, + parseError: null, + registryViolations, + surfaceViolations, + releaseScopeViolations, + decodeViolations, + decodeAmbiguities, + releaseScopeState: state, + advisories, + plane: { chains, registry, eventSurface, counts, releaseScopeState: state }, + }; +} + +/** + * An ambiguous key nobody has declared is a blocking violation; a declared one is not. + * + * The distinction is the whole control. Two implementations of one event that differ only in an + * `indexed` flag share a `topic0`, so a topic0-keyed decoder has two candidates and picks the + * first. Declaring the key records that somebody looked and said what happens; leaving it + * undeclared means nobody has, and that is the case worth failing on. + */ +function undeclaredAmbiguityViolations(found: readonly AmbiguousKey[]): Violation[] { + const declared = new Set(KNOWN_DECODE_AMBIGUITIES.map((k) => `${k.chainId}|${k.address.toLowerCase()}|${k.signature}`)); + return found + .filter((k) => !declared.has(`${k.chainId}|${k.address.toLowerCase()}|${k.signature}`)) + .map((k) => violation( + "decode_ambiguity_declared", + k.layouts[0]?.lines[0] ?? null, + `${k.chain} ${k.address} ${k.signature}`, + `topic0 ${k.topic0} carries ${k.layouts.length} physical layouts (${k.layouts.map((l) => `indexed[${l.indexedPositions}] in era(s) ${l.eras.join(",")}`).join(" vs ")}) and is not declared in KNOWN_DECODE_AMBIGUITIES; a topic0-keyed decoder would pick one of them without raising`, + )); +} + +export function loadControlPlane(paths: ControlPlanePaths = {}): ControlPlane { + const chains = loadChains(paths.chains ?? CHAINS_PATH); + const registry = parseRegistry(paths.registry ?? REGISTRY_PATH); + const eventSurface = parseEventSurface(paths.eventSurface ?? EVENT_SURFACE_PATH); + const freeze = paths.freeze ?? RELEASE_SCOPE_FREEZE; + + const registryViolations = validateRegistry(registry, chains); + const releaseScopeViolations = assertReleaseScopeFrozen(registry, chains, freeze); + const { violations: surfaceViolations, counts } = validateEventSurface(eventSurface, registry, chains); + const decodeViolations = undeclaredAmbiguityViolations(computeAmbiguousKeys(eventSurface)); + const all = [...registryViolations, ...surfaceViolations, ...releaseScopeViolations, ...decodeViolations]; + if (all.length > 0) throw new ControlPlaneInvalidError(all); + + return { chains, registry, eventSurface, counts, releaseScopeState: releaseScopeState(registry) }; +} \ No newline at end of file diff --git a/projects/onchain-analytics/pipeline-v5/src/control-plane/int64.ts b/projects/onchain-analytics/pipeline-v5/src/control-plane/int64.ts new file mode 100644 index 0000000..36344c2 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/src/control-plane/int64.ts @@ -0,0 +1,125 @@ +/** + * int64.ts -- the integer contract for every numeric field in the two control seeds. + * + * WHY THIS EXISTS AS ITS OWN MODULE. BigQuery INT64 spans +/-9,223,372,036,854,775,807. JavaScript + * numbers are exact only to 9,007,199,254,740,991. The seeds use the exact decimal + * 9223372036854775807 as the "no upper bound yet" sentinel on 134 registry rows, and + * `Number("9223372036854775807")` silently yields 9223372036854775808 -- a different integer that + * round-trips back into the seed as a different lexeme. The previous loader did exactly that. + * + * So every integer here is parsed from its ORIGINAL DECIMAL LEXEME, through BigInt, before any + * Number() conversion is permitted, and the sentinel never becomes a number at all: it becomes a + * distinct `open_ended` variant that the interval arithmetic understands directly. + */ + +/** The exact decimal lexeme that means "open ended". Compared as a string, never as a number. */ +export const INT64_MAX_LEXEME = "9223372036854775807"; + +/** Decimal integer, no sign, no leading zeros (except "0" itself), no exponent, no decimal point. */ +const CANONICAL_DECIMAL = /^(0|[1-9][0-9]*)$/; + +const MAX_SAFE = BigInt(Number.MAX_SAFE_INTEGER); + +/** + * A block bound. `open_ended` is a first-class value, not a large number and not null, so that + * ordering, overlap and gap checks can compare bounds without ever rounding one. + */ +export type BlockBound = + | { readonly kind: "finite"; readonly lexeme: string; readonly value: number } + | { readonly kind: "open_ended"; readonly lexeme: string }; + +export class Int64ContractError extends Error { + constructor(readonly field: string, readonly lexeme: string, readonly reason: string) { + super(`INT64_CONTRACT: field '${field}' value '${lexeme}': ${reason}`); + this.name = "Int64ContractError"; + } +} + +function rejectSentinelShape(field: string, lexeme: string): void { + if (lexeme === INT64_MAX_LEXEME) { + throw new Int64ContractError(field, lexeme, "the INT64-max sentinel is permitted only as an open-ended upper bound"); + } +} + +/** + * Parse a finite, non-negative integer that must survive in a JavaScript number exactly. + * + * Rejects: the sentinel, exponent notation, decimal points, signs, leading zeros, whitespace, and + * every integer above Number.MAX_SAFE_INTEGER including the sentinel's immediate neighbours. + */ +export function parseFiniteInt(field: string, raw: string, opts: { min?: number } = {}): number { + const lexeme = raw; + if (lexeme === "") throw new Int64ContractError(field, lexeme, "empty, but a value is required"); + if (!CANONICAL_DECIMAL.test(lexeme)) { + throw new Int64ContractError(field, lexeme, "not a canonical decimal integer (no sign, exponent, point, leading zero or whitespace is allowed)"); + } + rejectSentinelShape(field, lexeme); + + const big = BigInt(lexeme); + if (big > MAX_SAFE) { + throw new Int64ContractError(field, lexeme, `exceeds Number.MAX_SAFE_INTEGER (${Number.MAX_SAFE_INTEGER}), so it cannot be represented exactly`); + } + const value = Number(big); + const min = opts.min ?? 0; + if (value < min) throw new Int64ContractError(field, lexeme, `below the minimum permitted value ${min}`); + return value; +} + +/** + * Parse an upper interval bound. + * + * The sentinel is accepted ONLY when the row has independently declared itself open ended, and it + * never becomes a number. A row that carries the sentinel without that declaration, or declares + * itself open ended while carrying a finite bound, is a contradiction and is rejected -- those are + * the two ways an "is this era still current" question could otherwise be answered two ways. + */ +export function parseUpperBound( + field: string, + raw: string, + opts: { declaredOpenEnded: boolean; min?: number }, +): BlockBound { + const lexeme = raw; + if (lexeme === "") throw new Int64ContractError(field, lexeme, "empty, but an upper bound is required"); + + if (lexeme === INT64_MAX_LEXEME) { + if (!opts.declaredOpenEnded) { + throw new Int64ContractError(field, lexeme, "carries the open-ended sentinel but the row is not declared current/open-ended"); + } + return { kind: "open_ended", lexeme }; + } + + if (opts.declaredOpenEnded) { + throw new Int64ContractError(field, lexeme, `row is declared current/open-ended but carries a finite upper bound; expected the exact lexeme ${INT64_MAX_LEXEME}`); + } + return { kind: "finite", lexeme, value: parseFiniteInt(field, lexeme, { min: opts.min }) }; +} + +/** A lower bound is always finite. The sentinel in a lower bound is rejected by construction. */ +export function parseLowerBound(field: string, raw: string, opts: { min?: number } = {}): BlockBound { + return { kind: "finite", lexeme: raw, value: parseFiniteInt(field, raw, opts) }; +} + +/** Total order over bounds, with `open_ended` strictly above every finite value. */ +export function compareBounds(a: BlockBound, b: BlockBound): number { + if (a.kind === "open_ended") return b.kind === "open_ended" ? 0 : 1; + if (b.kind === "open_ended") return -1; + return a.value - b.value; +} + +export function boundsEqual(a: BlockBound, b: BlockBound): boolean { + return compareBounds(a, b) === 0; +} + +/** The original lexeme, so regenerating the seed reproduces the source file byte for byte. */ +export function boundLexeme(b: BlockBound): string { + return b.lexeme; +} + +/** + * Convert a bound for a pipeline API that genuinely needs a number. Open ended becomes null, never + * Infinity and never a large integer, because a null propagates as "unknown" while a number + * propagates as a block that exists. + */ +export function boundToNullableNumber(b: BlockBound): number | null { + return b.kind === "finite" ? b.value : null; +} diff --git a/projects/onchain-analytics/pipeline-v5/src/control-plane/magnitude.ts b/projects/onchain-analytics/pipeline-v5/src/control-plane/magnitude.ts new file mode 100644 index 0000000..ce66ecf --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/src/control-plane/magnitude.ts @@ -0,0 +1,163 @@ +/** + * magnitude.ts -- plausibility bands for every numeric field a semantic model consumes. + * + * WHY A SEPARATE LINE OF DEFENCE. Grain, referential and uniqueness tests all pass on a silently + * wrong decode, and this warehouse has paid for that twice: a 1e16 decimal factor and a duplicate + * ingestion both survived a fully green suite. A structural test asks "is there exactly one row"; + * a magnitude test asks "is this number a possible quantity of the thing it claims to be". + * + * THE CASE THIS EXISTS FOR, stated exactly. When two implementations of one event differ only in + * their `indexed` flags they share a `topic0`, and a decoder given them in the wrong order decodes + * an era-2 log against the era-1 layout and returns `balance = 4` -- the BYTE LENGTH of the string + * `"celo"` read as a uint256. Nothing throws. Every structural test passes. The only thing that + * catches it is noticing that 4 raw units of an 18-decimal token is 0.000000000000000004 GD, which + * is not a quantity anybody claims. So the lower bound below is expressed in RAW units against the + * token's declared decimals, not in human units, because that is the form the failure takes. + * + * AN HONEST LIMIT, because a control whose reach is overstated is worse than none. A magnitude + * band catches a large factor error always and a small one only when the value is big enough. A + * 1e18 error -- the divide missing entirely -- is always caught. A 1e2 error is caught above about + * 1,000 GD and missed below it. That is a real gap, it is why this is a SECOND line of defence and + * not the first, and it is written here rather than discovered later. + */ + +export interface MagnitudeBand { + /** The field this band guards, as `Event.param`. */ + readonly field: string; + readonly solidityType: string; + /** + * Smallest raw value that is a real quantity, as a power of ten BELOW the token's decimals. + * `6` means "at least 1e(decimals-6)", i.e. a millionth of one token. Null for a field that is + * not a token amount. + */ + readonly rawFloorDecimalsBelow: number | null; + /** Inclusive bounds on the human-scaled value. */ + readonly minHuman: number; + readonly maxHuman: number; + readonly why: string; +} + +/** + * One band per consumed numeric field. + * + * The consumed events are `UBIClaimed`, `InviteeJoined` and `InviterBounty` -- derived in Phase 2B + * by walking every semantic and mart model down to the raw tables it reads. `InviteeJoined` + * carries no numeric parameter at all (two addresses), so three fields need a band, not three + * events' worth. + */ +export const MAGNITUDE_BANDS: readonly MagnitudeBand[] = [ + { + field: "UBIClaimed.amount", + solidityType: "uint256", + rawFloorDecimalsBelow: 6, + minHuman: 0, + maxHuman: 100_000, + why: + "a single UBI claim is a small quantity of GD. The measured Celo daily amount has ranged from " + + "roughly 74 to 333 GD per claim. The upper bound matches the shipped dbt test byte for byte so " + + "the code and the SQL cannot drift apart", + }, + { + field: "InviterBounty.bountyPaid", + solidityType: "uint256", + rawFloorDecimalsBelow: 6, + minHuman: 0, + maxHuman: 100_000, + why: + "the inviter's own portion of an invite bounty. Measured at 1000 GD on all 939 rows in the " + + "warehouse, and the contract's levels array tops out far below this bound, so the band leaves " + + "room for a level-based bonus without leaving room for a factor error", + }, + { + field: "InviterBounty.inviterLevel", + solidityType: "uint256", + rawFloorDecimalsBelow: null, + minHuman: 0, + maxHuman: 100, + why: + "an index into the contract's levels array, not a token amount, so it is NOT decimals-scaled. " + + "Measured at 0 on every row. An address-shaped or 1e18-shaped value here is a decode error, " + + "and a band this tight is affordable precisely because the field is an ordinal", + }, +] as const; + +export type MagnitudeOutcome = "plausible" | "below_raw_floor" | "below_min" | "above_max" | "not_a_number"; + +export interface MagnitudeVerdict { + readonly field: string; + readonly outcome: MagnitudeOutcome; + readonly plausible: boolean; + readonly rawValue: bigint | null; + readonly humanValue: number | null; + readonly detail: string; +} + +export function bandFor(field: string): MagnitudeBand | undefined { + return MAGNITUDE_BANDS.find((b) => b.field === field); +} + +/** + * Check one raw on-chain value against its band. + * + * `decimals` is the TOKEN's declared decimals, which differ per chain in this system -- GD is 18 + * on Celo and XDC and 2 on Fuse and Ethereum. Passing the wrong one is itself the defect this + * guards against, so it is a required argument with no default. + */ +export function checkMagnitude(field: string, rawValue: bigint, decimals: number): MagnitudeVerdict { + const band = bandFor(field); + if (!band) throw new Error(`checkMagnitude: no band declared for '${field}'. Every consumed numeric field needs one`); + if (!Number.isInteger(decimals) || decimals < 0 || decimals > 36) { + throw new Error(`checkMagnitude: implausible token decimals ${decimals} for '${field}'`); + } + + if (band.rawFloorDecimalsBelow === null) { + const v = Number(rawValue); + if (!Number.isFinite(v)) { + return { field, outcome: "not_a_number", plausible: false, rawValue, humanValue: null, detail: `${rawValue} does not survive conversion to a finite number` }; + } + if (v < band.minHuman) return { field, outcome: "below_min", plausible: false, rawValue, humanValue: v, detail: `${v} is below the minimum ${band.minHuman}` }; + if (v > band.maxHuman) return { field, outcome: "above_max", plausible: false, rawValue, humanValue: v, detail: `${v} is above the maximum ${band.maxHuman}` }; + return { field, outcome: "plausible", plausible: true, rawValue, humanValue: v, detail: `${v} is inside [${band.minHuman}, ${band.maxHuman}]` }; + } + + // The raw floor, which is what catches a wrong-layout decode. Computed in bigint so an + // 18-decimal token never passes through a float on the way to the comparison. + const floorExp = BigInt(Math.max(0, decimals - band.rawFloorDecimalsBelow)); + const rawFloor = 10n ** floorExp; + if (rawValue > 0n && rawValue < rawFloor) { + return { + field, + outcome: "below_raw_floor", + plausible: false, + rawValue, + humanValue: Number(rawValue) / 10 ** decimals, + detail: + `raw ${rawValue} is below the raw floor ${rawFloor} for a ${decimals}-decimal token. A value this ` + + `small is not a quantity anybody transacts; it is the signature of a wrong-layout decode`, + }; + } + + const human = Number(rawValue) / 10 ** decimals; + if (!Number.isFinite(human)) { + return { field, outcome: "not_a_number", plausible: false, rawValue, humanValue: null, detail: `raw ${rawValue} does not scale to a finite number at ${decimals} decimals` }; + } + if (human <= band.minHuman) return { field, outcome: "below_min", plausible: false, rawValue, humanValue: human, detail: `${human} is at or below the minimum ${band.minHuman}` }; + if (human > band.maxHuman) { + return { + field, + outcome: "above_max", + plausible: false, + rawValue, + humanValue: human, + detail: `${human} is above the maximum ${band.maxHuman}; at ${decimals} decimals this is what a missing or wrong scale factor looks like`, + }; + } + return { field, outcome: "plausible", plausible: true, rawValue, humanValue: human, detail: `${human} is inside (${band.minHuman}, ${band.maxHuman}] at ${decimals} decimals` }; +} + +/** Every band, run over one decoded row. Returns only the failures, so an empty result is a pass. */ +export function checkRowMagnitudes( + values: readonly { readonly field: string; readonly rawValue: bigint; readonly decimals: number }[], +): MagnitudeVerdict[] { + return values.map((v) => checkMagnitude(v.field, v.rawValue, v.decimals)).filter((v) => !v.plausible); +} diff --git a/projects/onchain-analytics/pipeline-v5/src/control-plane/releaseScope.ts b/projects/onchain-analytics/pipeline-v5/src/control-plane/releaseScope.ts new file mode 100644 index 0000000..f7a1dd4 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/src/control-plane/releaseScope.ts @@ -0,0 +1,438 @@ +/** + * releaseScope.ts -- the frozen release scope, and the checks that keep it frozen. + * + * WHY THIS IS CODE AND NOT A NOTE. The plan forbids A5 from either including or silently + * excluding an undecided contract. A decision recorded only in prose cannot enforce that: the + * next seed regeneration can reintroduce an excluded address and nothing would object. So the + * decision is declared here, next to the loader that reads the seed, and the loader refuses to + * start the pipeline if the seed and the decision disagree. + * + * THE DECISION. Recorded 2026-09-28 by whoever owns release scope, on the evidence summarised in + * `docs/release-scope.md`: all nineteen ambiguous candidates are excluded, and Base and Gnosis + * stay out as a DECISION NOT TO ASSESS rather than as an assessment. Nobody queried either chain. + * That distinction is preserved below because a silence later reads as if somebody had checked. + * + * THE AMENDMENT, the same day. Fuse was DROPPED from the release: its data is disproportionately + * expensive to obtain and it was holding up everything else. The recorded Fuse inventory is + * RETAINED in the seeds rather than deleted -- 1 chain row, 96 deployment rows and 616 event + * surface rows bound to them by a composite foreign key -- because deleting the deployment rows + * orphans the surface rows, and because a deleted row says nothing while a retained row declared + * out of the release says exactly what happened. `chainsDropped` is what keeps retention from + * becoming re-admission. + * + * WHAT EACH STATE MEANS, and why only one of them fails the build. + * + * `scope_pending` A row the seed declares undecided. Correct before the freeze, illegal after + * it. This is the state the plan names, and it fails the build. + * `undeclared` Not a value a seed may carry. It is what the loader reports when the whole + * optional boundary/scope column block is absent, which is the shipped seed + * today. It does not fail the build, because the same absence already forces + * every era to `raw_only_unproven`, which forbids every decoder and every + * user-facing model over every era. That is a STRICTLY STRONGER prohibition + * than `out_of_release`, so nothing can be silently included while it holds. + * `releaseScopeState()` names that condition and a test pins the coupling, so + * the two columns can never be decoupled without the test failing. + * + * WHAT A CHAIN'S STANDING MEANS, which is a different axis from a row's `release_scope`. + * + * `in_release` Named in `releaseChains`. Capture, planning and semantic consumption are + * all permitted, subject to every other rule. + * `dropped` Named in `chainsDropped`. Its recorded rows are legal and stay; every path + * that would act on the chain refuses. See `chainStanding`. + * `undeclared` In neither list. Nobody decided, so it FAILS THE BUILD. This is the case the + * discriminator exists to preserve: without `chainsDropped`, dropping a chain + * would have meant making the check stop firing, which also stops it catching + * a chain that arrived in a seed by accident. + */ + +import type { ChainAuthority } from "./chains.js"; +import { + assertScopeFrozen, + type ParsedRegistry, + type RegistryRow, +} from "./contractRegistry.js"; +import { gradeForEra, type ConfidenceGrade, type EraBoundaryEvidence } from "./eraConfidence.js"; +import { violation, type Violation } from "./fields.js"; + +export interface ExcludedContract { + readonly chainId: number; + readonly chain: string; + readonly contractName: string; + /** Lowercase 20-byte address, as the registry stores it. */ + readonly address: string; +} + +/** A chain deliberately removed from the release, with the day it left and why. */ +export interface DroppedChain { + readonly chain: string; + readonly droppedOn: string; + readonly reason: string; +} + +export interface ReleaseScopeFreeze { + readonly frozen: boolean; + readonly decidedOn: string; + readonly decisionRecord: string; + readonly planSha256: string; + /** + * Plans this decision was made under before the current one, newest first. Carried rather than + * overwritten: an artifact that cites only its latest governing document loses the ability to + * answer "what was this decided under at the time". + */ + readonly supersededPlanSha256: readonly string[]; + readonly releaseChains: readonly string[]; + /** + * Chains removed from the release ON PURPOSE. This is NOT the same as a chain nobody decided + * about, and keeping them apart is the whole reason the field exists: a chain in neither list + * still fails the build. + */ + readonly chainsDropped: readonly DroppedChain[]; + readonly chainsNotAssessed: readonly { readonly chain: string; readonly note: string }[]; + readonly excludedContracts: readonly ExcludedContract[]; + readonly evidence: readonly string[]; +} + +export const RELEASE_SCOPE_FREEZE: ReleaseScopeFreeze = { + frozen: true, + decidedOn: "2026-09-28", + decisionRecord: "docs/release-scope.md", + planSha256: "BAA0005DEE707BA6BF26DCC100194087AC84299084C372AE5DED6569325ECA02", + supersededPlanSha256: ["9DCDE225459127C4DA2BEADF9094FD894FE193010F39CB70C0753DD874853E26"], + releaseChains: ["CELO", "XDC", "ETHEREUM"], + chainsDropped: [ + { + chain: "FUSE", + droppedOn: "2026-09-28", + reason: + "no HyperSync index exists, the only archive-capable endpoint is rate limited to roughly " + + "54 reads per hour, the transaction index is pruned so creation blocks cannot be " + + "established by receipt lookup, and no endpoint serves a finality tag. Serving Fuse to the " + + "same standard as the other chains was holding up the release. Recorded rows are retained; " + + "see docs/release-scope.md", + }, + ], + chainsNotAssessed: [ + { chain: "BASE", note: "decision not to assess; zero queries were made against this chain" }, + { chain: "GNOSIS", note: "decision not to assess; zero queries were made against this chain" }, + ], + // The nineteen A1-R candidates. 140 privilege checks against the production Controller, GD + // token and Identity returned zero grants with two or more endpoints agreeing on every check, + // and eighteen of nineteen hold zero production GD. Addresses are copied from the receipts + // named in `evidence`, never retyped from a document. The six on Fuse are kept after the chain + // was dropped: an exclusion is a finding about an address, and it does not expire because the + // chain left the release. + excludedContracts: [ + { chainId: 122, chain: "FUSE", contractName: "ProxyFactory", address: "0x4659176e962763e7c8a4ef965ecfd0fdf9f52057" }, + { chainId: 122, chain: "FUSE", contractName: "NameService", address: "0xe26867ddd22f9342d9f0d566d182f2c960683971" }, + { chainId: 122, chain: "FUSE", contractName: "GReputation", address: "0x3a9299be789ac3730e4e4c49d6d2ad1b8bc34dff" }, + { chainId: 122, chain: "FUSE", contractName: "CompoundVotingMachine", address: "0xc2ff55b896e3c42f9e1c2f7467c51b93f1c23dfd" }, + { chainId: 122, chain: "FUSE", contractName: "ClaimersDistribution", address: "0xf34552f1583c0b981dbb09611128c3375b47182e" }, + { chainId: 122, chain: "FUSE", contractName: "UBIScheme", address: "0x87d77a30a6819860eb8332d293810ed7b510035a" }, + { chainId: 1, chain: "ETHEREUM", contractName: "ProxyFactory", address: "0x4659176e962763e7c8a4ef965ecfd0fdf9f52057" }, + { chainId: 1, chain: "ETHEREUM", contractName: "NameService", address: "0xe26867ddd22f9342d9f0d566d182f2c960683971" }, + { chainId: 1, chain: "ETHEREUM", contractName: "GReputation", address: "0x3a9299be789ac3730e4e4c49d6d2ad1b8bc34dff" }, + { chainId: 1, chain: "ETHEREUM", contractName: "CompoundVotingMachine", address: "0xc2ff55b896e3c42f9e1c2f7467c51b93f1c23dfd" }, + { chainId: 1, chain: "ETHEREUM", contractName: "GoodMarketMaker", address: "0x30d37b05cf73edd8c59ce8450f093f6c06da9272" }, + { chainId: 1, chain: "ETHEREUM", contractName: "GoodReserveCDai", address: "0x6c35677206ae7ff1bf753877649cf57cc30d1c42" }, + { chainId: 1, chain: "ETHEREUM", contractName: "ExchangeHelper", address: "0x0a8c6bb832801454f6cc21761d0a293caa003296" }, + { chainId: 1, chain: "ETHEREUM", contractName: "GoodFundManager", address: "0x3f55bd3b432edc73bbb704fa5a29cc08dc1adbeb" }, + { chainId: 1, chain: "ETHEREUM", contractName: "StakersDistribution", address: "0x12d15efc3c9661ad68209cd197d416bfd9b145f5" }, + { chainId: 1, chain: "ETHEREUM", contractName: "UniswapV2SwapHelper", address: "0x62305662fa7c4bc442803b940d9192dbdc92d710" }, + { chainId: 1, chain: "ETHEREUM", contractName: "CompoundStakingFactory", address: "0x5f6f25143cd580e2e285210d7cfcb26e59cf9566" }, + { chainId: 1, chain: "ETHEREUM", contractName: "AaveStakingFactory", address: "0xa99ba154223052b8c5fd92b3f5df9eb08b72d5fc" }, + { chainId: 1, chain: "ETHEREUM", contractName: "DonationsStaking", address: "0x06eafc6749723583672fc8f4451c8ec0e59f5798" }, + ], + // PROMOTED 2026-09-28. These three entries used to name files under `specs/_scratch/`, which is + // gitignored and local to one machine -- so a receipt pointing there could not be opened by + // anyone holding only this repository, which makes it an assertion rather than a receipt. The + // decision-relevant substance now ships in the repository at the paths below. The raw probe + // output that produced it stays local by design; it is working material, not a reader-facing + // artifact, and the claim it supports is reproducible from what ships. + evidence: [ + "docs/release-scope.md", + "gd_dbt/seeds/contract_deployments.csv", + ], +} as const; + +/** + * Which of the two legitimate conditions the registry is in. + * + * `pre_freeze_seed` is not a pass. It means the seed predates the freeze and therefore carries no + * boundary or scope columns at all, which forces `raw_only_unproven` everywhere. + */ +export type ReleaseScopeState = "pre_freeze_seed" | "frozen_and_declared"; + +export function releaseScopeState(parsed: ParsedRegistry): ReleaseScopeState { + return parsed.hasBoundaryColumns ? "frozen_and_declared" : "pre_freeze_seed"; +} + +function excludedKey(chainId: number, address: string): string { + return `${chainId}|${address.toLowerCase()}`; +} + +/** Where a chain stands against the frozen release. The three cases are deliberately distinct. */ +export type ChainReleaseStanding = "in_release" | "dropped" | "undeclared"; + +/** + * The single answer to "may this system act on this chain". + * + * Every path that could act on a chain asks this rather than keeping its own list. `dropped` and + * `undeclared` both forbid action; they differ only in whether the absence was a decision, and + * that difference is what the seed checks below report. + */ +export function chainStanding( + chain: string, + freeze: ReleaseScopeFreeze = RELEASE_SCOPE_FREEZE, +): ChainReleaseStanding { + if (freeze.releaseChains.includes(chain)) return "in_release"; + if (freeze.chainsDropped.some((c) => c.chain === chain)) return "dropped"; + return "undeclared"; +} + +/** + * The checks that run because scope is frozen. Returned rather than thrown so one run names every + * violation; `loadControlPlane` rejects the whole control plane if the list is non-empty. + */ +export function assertReleaseScopeFrozen( + parsed: ParsedRegistry, + chains: ChainAuthority, + freeze: ReleaseScopeFreeze = RELEASE_SCOPE_FREEZE, +): Violation[] { + if (!freeze.frozen) return []; + + const v: Violation[] = []; + const release = new Set(freeze.releaseChains); + const dropped = new Map(freeze.chainsDropped.map((c) => [c.chain, c])); + const excluded = new Map(freeze.excludedContracts.map((c) => [excludedKey(c.chainId, c.address), c])); + + // A freeze naming a chain in both lists decides nothing. Caught here rather than letting + // whichever list happens to be read first win the answer. + for (const [chain] of dropped) { + if (release.has(chain)) { + v.push(violation( + "release_scope_declaration_coherent", + null, + chain, + `the freeze names '${chain}' in releaseChains AND in chainsDropped; a chain is in the release or it is dropped, never both`, + )); + } + } + + // A chain the authority declares but the freeze does not is a scope change wearing a seed edit. + // A DROPPED chain is not that: it was decided about, its rows are retained on purpose, and the + // refusals live on the paths that would act on it rather than on the row that records it. + for (const row of chains.rows) { + if (chainStanding(row.chain, freeze) === "undeclared") { + v.push(violation( + "release_chain_frozen", + row.line, + `${row.chain} (chain_id ${row.chainId})`, + `the chains seed declares '${row.chain}' but the frozen release scope is ${[...release].join(", ")} and '${row.chain}' is not recorded as dropped either; a scope change invalidates the frozen seeds and returns the work to Phase 2`, + )); + } + } + + for (const row of parsed.rows) { + const subject = `${row.chain} ${row.proxyAddress} (${row.contractName})`; + const standing = chainStanding(row.chain, freeze); + + if (standing === "undeclared") { + v.push(violation("release_chain_frozen", row.line, subject, `row names chain '${row.chain}', which is neither in the frozen release scope nor recorded as dropped from it`)); + } + + // Retention is a record, not a re-admission. A row on a dropped chain may say anything about + // itself except that it is in the release, because that is the one claim the drop denies. + const drop = dropped.get(row.chain); + if (drop && row.releaseScope === "in_release") { + v.push(violation( + "dropped_chain_not_in_release", + row.line, + subject, + `chain '${row.chain}' was dropped from the release on ${drop.droppedOn} but this row declares release_scope 'in_release'; a retained row is a record of what was measured, not a way back into the release`, + )); + } + + // Exclusion has to be enforced on BOTH address columns and matched on (chain_id, column). A + // substring match over the whole file manufactured a false membership during A1-R by + // colliding with a different chain's implementation_address. + const asProxy = excluded.get(excludedKey(row.chainId, row.proxyAddress)); + if (asProxy) { + v.push(violation( + "excluded_contract_absent", + row.line, + subject, + `proxy_address is ${asProxy.chain} ${asProxy.contractName}, excluded from the release on ${freeze.decidedOn}; see ${freeze.decisionRecord}`, + )); + } + if (row.implementationAddress !== null) { + const asImpl = excluded.get(excludedKey(row.chainId, row.implementationAddress)); + if (asImpl) { + v.push(violation( + "excluded_contract_absent", + row.line, + subject, + `implementation_address is ${asImpl.chain} ${asImpl.contractName}, excluded from the release on ${freeze.decidedOn}; see ${freeze.decisionRecord}`, + )); + } + } + } + + // `scope_pending` is only reachable when the seed carries the column. When it does not, every + // era is already `raw_only_unproven`, so nothing is consumable and nothing can be silently + // included. See the header. + if (releaseScopeState(parsed) === "frozen_and_declared") { + v.push(...assertScopeFrozen(parsed)); + } + + return v; +} + +/** + * Which branch decided. Named so the branch table can be asserted by name rather than by counting + * refusals, and so a future edit that deletes a branch fails a test instead of going quiet. + * + * `boundary_completeness_raw_only_unproven` is ABSENT ON PURPOSE. It was a shipped branch and it + * was removed; leaving the name behind would let a reader believe the rule still exists somewhere. + */ +export const ERA_CONSUMABILITY_BRANCHES = [ + "no_code_deployed", + "release_scope_not_in_release", + "boundary_evidence_incomplete", + "abi_unknown", + "decode_ambiguity_unbound", + "magnitude_tripwire_failed", + "consumable", +] as const; +export type EraConsumabilityBranch = (typeof ERA_CONSUMABILITY_BRANCHES)[number]; + +export interface EraConsumability { + readonly consumable: boolean; + readonly reason: string; + /** The branch that decided, always set, including on the pass. */ + readonly branch: EraConsumabilityBranch; + /** + * The confidence grade, which PROPAGATES rather than gates. Present on a refusal too: "how + * wrong could this be" and "may I proceed" are different questions and this answers the first + * one either way. + */ + readonly confidenceGrade: ConfidenceGrade; + readonly gradeClause: string; +} + +/** + * The facts a decode refusal needs that a registry row does not carry. + * + * All three are optional and an absent one refuses nothing. That is deliberate: a control that + * fires when its input is missing is indistinguishable from a control that fires when its input + * says so, and the second one is the only useful kind. + */ +export interface EraDecodeContext { + /** + * `chainId|address` for contracts carrying a decode ambiguity with no era-scoped binding. + * Computed offline from the event surface; see `decodeSurface.computeAmbiguousKeys`. + */ + readonly unboundAmbiguousContracts?: ReadonlySet; + /** `chainId|address|eraIndex` for rows whose decoded values failed a magnitude tripwire. */ + readonly magnitudeFailures?: ReadonlySet; + /** Promoted boundary evidence, keyed by `eraEvidenceKey`, for the propagating grade. */ + readonly boundaryEvidence?: ReadonlyMap; +} + +/** + * May a semantic model decode this era? + * + * THE REVERSAL, 2026-09-28, and what it is not. This function used to refuse every + * `raw_only_unproven` interval, which is every interval in the release. That rule was written when + * `complete` was believed reachable. It is not: reaching it required every slot-writing path to + * obligatorily emit an upgrade event, and EIP-1967 says SHOULD, not MUST -- OpenZeppelin's own + * reference implementation writes the slot before emitting on the rollback branch. Applying the + * bar honestly produced 0 provable eras out of 41, and a bar that cannot tell a well-understood + * contract from an unknown one is uninformative rather than conservative. + * + * So `raw_only_unproven` stops being a refusal and becomes a propagating grade. The control is + * narrowed in exactly one place and widened in three, each of the three on a condition that is + * actually actionable: + * + * RETAINED no code deployed + * RETAINED the row is not in the release <- this is what keeps dropped chains out + * REMOVED boundary_completeness is raw_only_unproven + * RETAINED boundary evidence incomplete <- stated as its refusal condition + * ADDED the interval's ABI is unknown <- no ABI, no decode + * ADDED an unbound decode ambiguity <- two layouts, one topic0, no binding + * ADDED a failed magnitude tripwire <- the value is not a possible quantity + * + * The two retained refusals are the reason removing the third is safe: an out-of-release row and + * an unevidenced row are both still refused, so nothing is admitted that nobody decided about. + */ +export function eraConsumableBySemanticModel( + row: RegistryRow, + freeze: ReleaseScopeFreeze = RELEASE_SCOPE_FREEZE, + context: EraDecodeContext = {}, +): EraConsumability { + const evidence = context.boundaryEvidence ?? new Map(); + const g = gradeForEra(row, evidence); + const grade = { confidenceGrade: g.grade, gradeClause: g.clause }; + + if (row.noCodeDeployed) { + return { consumable: false, branch: "no_code_deployed", ...grade, reason: "no_code_deployed: the contract has no code and declares no era interval" }; + } + if (freeze.frozen && row.releaseScope !== "in_release") { + return { consumable: false, branch: "release_scope_not_in_release", ...grade, reason: `release_scope is '${row.releaseScope}', not 'in_release'` }; + } + if (row.boundaryEvidenceManifestHash === null || row.boundaryCheckedThroughBlock === null || row.frozenSafeHead === null) { + return { consumable: false, branch: "boundary_evidence_incomplete", ...grade, reason: "boundary evidence is incomplete: manifest hash, checked-through block and frozen safe head must all be present" }; + } + if (row.abiSource === "none" || row.abiSource === "") { + return { + consumable: false, + branch: "abi_unknown", + ...grade, + reason: "abi_source is 'none': no ABI is held for this implementation, so its logs are captured raw and decode is refused for the interval", + }; + } + const contract = `${row.chainId}|${row.proxyAddress}`; + if (context.unboundAmbiguousContracts?.has(contract)) { + return { + consumable: false, + branch: "decode_ambiguity_unbound", + ...grade, + reason: `${contract} carries a topic0 with more than one physical layout and no era-scoped binding, so a decoder would pick one of them without raising`, + }; + } + if (context.magnitudeFailures?.has(`${contract}|${row.eraIndex}`)) { + return { + consumable: false, + branch: "magnitude_tripwire_failed", + ...grade, + reason: "a consumed numeric field on this interval failed its magnitude tripwire, which is what a wrong-layout or wrong-scale decode looks like", + }; + } + return { + consumable: true, + branch: "consumable", + ...grade, + reason: `boundary_completeness='${row.boundaryCompleteness}' through frozen safe head ${row.frozenSafeHead}, confidence '${g.grade}' by rule ${g.clause}`, + }; +} + +/** The policy check a semantic model's era selection must pass. One violation per refused era. */ +export function assertSemanticErasConsumable( + rows: readonly RegistryRow[], + modelName: string, + freeze: ReleaseScopeFreeze = RELEASE_SCOPE_FREEZE, + context: EraDecodeContext = {}, +): Violation[] { + const v: Violation[] = []; + for (const row of rows) { + const verdict = eraConsumableBySemanticModel(row, freeze, context); + if (!verdict.consumable) { + v.push(violation( + "semantic_era_reviewed", + row.line, + `${modelName} -> ${row.chain} ${row.proxyAddress} era ${row.eraIndex}`, + verdict.reason, + )); + } + } + return v; +} diff --git a/projects/onchain-analytics/pipeline-v5/src/control-plane/report.ts b/projects/onchain-analytics/pipeline-v5/src/control-plane/report.ts new file mode 100644 index 0000000..77f1b7d --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/src/control-plane/report.ts @@ -0,0 +1,255 @@ +/** + * report.ts -- run every control-plane check against the shipped seeds and emit the evidence. + * + * This is deliberately the SAME code path the pipeline uses (`inspectControlPlane`), not a second + * implementation. A validation report produced by a parallel implementation proves that the two + * agree, which is not the question; the question is what the thing that gates ingestion decides. + * + * Reads files. Writes one JSON file. No network, no BigQuery. + * + * npx tsx src/control-plane/report.ts + */ + +import { writeFileSync, readFileSync } from "fs"; +import { createHash } from "crypto"; +import { inspectControlPlane } from "./index.js"; +import { CHAINS_PATH } from "./chains.js"; +import { REGISTRY_PATH, REGISTRY_BOUNDARY_COLUMNS } from "./contractRegistry.js"; +import { EVENT_SURFACE_PATH, canonicalSignature, topic0For, RAWLOGS_INDEXED_SLOTS } from "./eventSurface.js"; +import { eraConsumableBySemanticModel } from "./releaseScope.js"; +import { buildAllUnionAbis, isNewestFirst } from "./decodeSurface.js"; +import { INT64_MAX_LEXEME } from "./int64.js"; + +function sha256(path: string): string { + return createHash("sha256").update(readFileSync(path)).digest("hex").toUpperCase(); +} + +function tally(items: readonly T[], key: (t: T) => string): Record { + const m = new Map(); + for (const i of items) { + const k = key(i); + m.set(k, (m.get(k) ?? 0) + 1); + } + return Object.fromEntries([...m].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))); +} + +const outPath = process.argv[2]; +if (!outPath) { + console.error("usage: tsx src/control-plane/report.ts "); + process.exit(2); +} + +const inspection = inspectControlPlane(); + +const report: Record = { + generatedAt: new Date().toISOString(), + inputs: { + chains: { path: CHAINS_PATH, sha256: sha256(CHAINS_PATH) }, + contract_deployments: { path: REGISTRY_PATH, sha256: sha256(REGISTRY_PATH) }, + event_surface: { path: EVENT_SURFACE_PATH, sha256: sha256(EVENT_SURFACE_PATH) }, + }, + ok: inspection.ok, + parseError: inspection.parseError, + advisories: inspection.advisories, +}; + +if (inspection.plane) { + const { chains, registry, eventSurface, counts } = inspection.plane; + const rows = registry.rows; + const surface = eventSurface.rows; + + const deployed = rows.filter((r) => !r.noCodeDeployed); + const noCode = rows.filter((r) => r.noCodeDeployed); + const contracts = new Set(rows.map((r) => `${r.chainId}|${r.proxyAddress}`)); + const sentinelRows = rows.filter((r) => r.validTo?.kind === "open_ended"); + const liveRows = rows.filter((r) => r.isLive); + const unions = buildAllUnionAbis(eventSurface); + + // Task 10. The full list, not a count: an indexed dynamic parameter is unrecoverable from any + // log capture at any completeness, so which ones they are is the deliverable. + const hashOnly = surface + .filter((r) => r.hashOnlyIndexedPositions.length > 0) + .map((r) => ({ + line: r.line, chain: r.chain, contract: r.contractName, proxyAddress: r.proxyAddress, + eraIndex: r.eraIndex, signature: r.eventSignature, topic0: r.topic0, + hashOnlyParams: r.hashOnlyIndexedPositions.map((p) => ({ position: p, type: r.paramTypes[p], name: r.paramNames[p] })), + })); + + // Task 9. Anonymous events, with the physical slot arithmetic stated per row. + const anonymous = surface.filter((r) => r.anonymous).map((r) => ({ + line: r.line, chain: r.chain, contract: r.contractName, proxyAddress: r.proxyAddress, + eraIndex: r.eraIndex, signature: r.eventSignature, + indexedCount: r.indexedPositions.length, + indexedPositions: r.indexedPositions, + paramTypes: r.paramTypes, + topicSlotsNeeded: r.indexedPositions.length, + rawlogsIndexedSlots: RAWLOGS_INDEXED_SLOTS, + losslesslyCapturable: r.indexedPositions.length <= RAWLOGS_INDEXED_SLOTS, + })); + + // Task 6, restated independently of the validator so the report carries its own arithmetic. + let topic0Recomputed = 0, topic0Agreed = 0, sigRebuilt = 0, sigAgreed = 0; + const topic0Mismatches: unknown[] = []; + for (const r of surface) { + const canon = canonicalSignature(r.eventName, r.paramTypes); + sigRebuilt++; + if (canon === r.eventSignature) sigAgreed++; + if (!r.anonymous) { + topic0Recomputed++; + const t = topic0For(r.eventSignature); + if (t === r.topic0) topic0Agreed++; + else topic0Mismatches.push({ line: r.line, signature: r.eventSignature, stored: r.topic0, recomputed: t }); + } + } + + const distinctSelectors = new Set(surface.filter((r) => !r.anonymous).map((r) => r.topic0!)); + const layoutsBySelector = new Map>(); + for (const r of surface) { + if (r.anonymous) continue; + const set = layoutsBySelector.get(r.topic0!) ?? new Set(); + set.add(r.indexedPositions.join(",")); + layoutsBySelector.set(r.topic0!, set); + } + const multiLayoutSelectors = [...layoutsBySelector].filter(([, s]) => s.size > 1); + + const layoutsByEraKey = new Map>(); + for (const r of surface) { + if (r.anonymous) continue; + const k = `${r.chainId}|${r.proxyAddress}|${r.topic0}`; + const set = layoutsByEraKey.get(k) ?? new Set(); + set.add(r.indexedPositions.join(",")); + layoutsByEraKey.set(k, set); + } + const keysChangingLayoutAcrossEras = [...layoutsByEraKey] + .filter(([, s]) => s.size > 1) + .map(([k, s]) => ({ key: k, layouts: [...s] })); + + report.chains = { path: chains.path, rows: chains.rows }; + + report.registry = { + path: registry.csv.path, + recordDelimiter: registry.csv.recordDelimiter, + physicalLines: registry.csv.physicalLines, + parsedRecords: registry.rows.length, + physicalMinusHeaderEqualsParsed: registry.csv.physicalLines - 1 === registry.rows.length, + headerFieldCount: registry.csv.header.length, + hasBoundaryColumns: registry.hasBoundaryColumns, + boundaryColumnsExpectedWhenRegenerated: REGISTRY_BOUNDARY_COLUMNS, + droppedRows: 0, + distinctContracts: contracts.size, + eraRows: deployed.length, + noCodeDeployedRows: noCode.length, + noCodeDeployedList: noCode.map((r) => ({ line: r.line, chain: r.chain, contract: r.contractName, address: r.proxyAddress, notes: r.notes })), + eraRowsByChain: tally(deployed, (r) => r.chain), + contractsByChain: tally([...contracts].map((k) => k.split("|")[0]), (id) => chains.byId.get(Number(id)) ?? `chain_id ${id}`), + openEndedSentinelRows: sentinelRows.length, + isLiveRows: liveRows.length, + sentinelSetEqualsLiveSet: + sentinelRows.length === liveRows.length && sentinelRows.every((r) => r.isLive), + sentinelLexeme: INT64_MAX_LEXEME, + boundaryCompletenessDistribution: tally(rows, (r) => r.boundaryCompleteness), + categoryDistribution: tally(rows, (r) => r.category), + eraMethodDistribution: tally(rows, (r) => r.eraMethod), + eraAnnouncementDistribution: tally(rows, (r) => r.eraAnnouncementEvent), + violations: inspection.registryViolations, + violationsByCheck: tally(inspection.registryViolations, (v) => v.check), + }; + + report.eventSurface = { + path: eventSurface.csv.path, + recordDelimiter: eventSurface.csv.recordDelimiter, + physicalLines: eventSurface.csv.physicalLines, + parsedRecords: surface.length, + physicalMinusHeaderEqualsParsed: eventSurface.csv.physicalLines - 1 === surface.length, + headerFieldCount: eventSurface.csv.header.length, + droppedRows: 0, + rowsByChain: tally(surface, (r) => r.chain), + task6_topic0: { + rowsChecked: topic0Recomputed, + rowsMatched: topic0Agreed, + rowsMismatched: topic0Recomputed - topic0Agreed, + rowsNotCheckedBecauseAnonymous: surface.length - topic0Recomputed, + mismatches: topic0Mismatches, + }, + task6_canonicalSignature: { + rowsChecked: sigRebuilt, + rowsMatched: sigAgreed, + rowsMismatched: sigRebuilt - sigAgreed, + }, + task7_binding: { + rowsChecked: counts.bindingChecked, + rowsBindingToExactlyOneEra: counts.bindingMatched, + rowsFailingToBind: counts.bindingChecked - counts.bindingMatched, + }, + task5_eraBoundRows: { + declaredBound: surface.filter((r) => r.eraBound).length, + comparedAgainstDeploymentEra: counts.boundRowsChecked, + carryingOpenEndedSentinel: surface.filter((r) => r.eraBoundTo?.kind === "open_ended").length, + eventGroupsChecked: counts.boundGroupsChecked, + eventGroupsWhoseWindowIsTheExactEnvelope: counts.boundGroupsMatchingEnvelope, + }, + task9_anonymous: { count: anonymous.length, rows: anonymous }, + task10_hashOnlyIndexed: { + rowCount: hashOnly.length, + paramCount: hashOnly.reduce((n, r) => n + r.hashOnlyParams.length, 0), + distinctSignatures: [...new Set(hashOnly.map((r) => r.signature))], + rows: hashOnly, + }, + layoutRisk: { + distinctSelectors: distinctSelectors.size, + selectorsWithMoreThanOneIndexedLayout: multiLayoutSelectors.length, + selectorsWithMoreThanOneIndexedLayoutList: multiLayoutSelectors.map(([t, s]) => ({ topic0: t, layouts: [...s] })), + chainAddressSelectorKeysChangingLayoutAcrossOwnEras: keysChangingLayoutAcrossEras, + }, + violations: inspection.surfaceViolations, + violationsByCheck: tally(inspection.surfaceViolations, (v) => v.check), + }; + + // The grade is a propagating confidence signal, NOT a gate. REVERSED 2026-09-28, at the same + // time as the branch table in `releaseScope.ts`: changing one carrier and not the other would + // have left the old rule live in whichever path survived, and this file is the second carrier. + // + // What changed: `raw_only_unproven` used to forbid every decoder, every state interpretation + // and every user-facing model over every era, which was all of them. It no longer refuses + // anything. The bar it enforced required every slot-writing path to obligatorily emit an upgrade + // event, and EIP-1967 says SHOULD rather than MUST, so the bar was unreachable by construction + // and produced 0 provable eras out of 41 -- uninformative rather than conservative. + report.boundaryEvidence = { + columnsPresent: registry.hasBoundaryColumns, + erasReadingRawOnlyUnproven: rows.filter((r) => r.boundaryCompleteness === "raw_only_unproven").length, + erasCarryingAManifestHash: rows.filter((r) => r.boundaryEvidenceManifestHash !== null).length, + consumableEras: rows.filter((r) => eraConsumableBySemanticModel(r).consumable).length, + refusalsByBranch: tally( + rows.filter((r) => !eraConsumableBySemanticModel(r).consumable), + (r) => eraConsumableBySemanticModel(r).branch, + ), + confidenceGradeDistribution: tally(rows, (r) => eraConsumableBySemanticModel(r).confidenceGrade), + policy: + "boundary_completeness='raw_only_unproven' is a CONFIDENCE GRADE that propagates to whatever " + + "reads the era; it is not a refusal. An era is refused only when it has no code, is not in " + + "the release, carries no boundary evidence at all, holds no ABI, carries an unbound decode " + + "ambiguity, or fails a magnitude tripwire. Every refusal names its branch above.", + }; + + // The computed ambiguous set, reported rather than inferred, with the two senses of scope kept + // apart because they differ: Ethereum is in the declared release and is not ingested here. + const INGESTION_SCOPE = new Set(["CELO", "XDC"]); + report.decodeAmbiguity = { + keysFound: inspection.decodeAmbiguities.length, + keysInDeclaredReleaseScope: inspection.decodeAmbiguities.filter((k) => ["CELO", "XDC", "ETHEREUM"].includes(k.chain)).length, + keysInIngestionScope: inspection.decodeAmbiguities.filter((k) => INGESTION_SCOPE.has(k.chain)).length, + keys: inspection.decodeAmbiguities, + undeclaredViolations: inspection.decodeViolations, + unionsBuilt: unions.size, + unionsNotNewestFirst: [...unions.values()].filter((u) => !isNewestFirst(u)).map((u) => ({ chain: u.chain, address: u.address, eraOrder: u.eraOrder })), + }; +} + +writeFileSync(outPath, JSON.stringify(report, null, 2), "ascii"); +console.log(`ok=${inspection.ok} parseError=${inspection.parseError ? "YES" : "no"} ` + + `registryViolations=${inspection.registryViolations.length} surfaceViolations=${inspection.surfaceViolations.length} ` + + `advisories=${inspection.advisories.length}`); +if (inspection.parseError) console.log(inspection.parseError.message); +for (const v of [...inspection.registryViolations, ...inspection.surfaceViolations, ...inspection.advisories].slice(0, 40)) { + console.log(` [${v.check}] line ${v.line ?? "-"} ${v.subject}: ${v.detail}`); +} diff --git a/projects/onchain-analytics/pipeline-v5/src/coverage.ts b/projects/onchain-analytics/pipeline-v5/src/coverage.ts index dc82a39..f7551c6 100644 --- a/projects/onchain-analytics/pipeline-v5/src/coverage.ts +++ b/projects/onchain-analytics/pipeline-v5/src/coverage.ts @@ -26,9 +26,10 @@ * checked by running it against a warehouse. */ -import { bqQuery } from "./bq.js"; -import { fullTableName } from "./config.js"; +import { bqQuery, allHistory } from "./bq.js"; +import { fullTableName, RAW_LOGS_TABLE } from "./config.js"; import { log } from "./log.js"; +import { countUndecodableLogs, type DecodeCandidateLog, type ParsedEventSurface } from "./control-plane/index.js"; export interface CaptureInterval { fromBlock: number; @@ -130,11 +131,18 @@ function subtract(iv: [number, number][], holes: [number, number][]): [number, n export interface ResumePoint { resumeAt: number; - /** The last block this contract's coverage actually vouches for, or null when none does. */ + /** + * The last block coverage vouches for CONTIGUOUSLY from the contract's creation block, or null + * when nothing does. Deliberately not "the highest block held": a clean capture above a hole + * vouches for its own range and for nothing between, and reading this field as a frontier is + * what let an internal hole pass for covered ground. + */ coveredUpTo: number | null; reason: string; capturesConsidered: number; capturesClean: number; + /** Every range inside the ledger's own envelope that no clean capture covers. */ + openGaps: [number, number][]; } /** @@ -155,17 +163,24 @@ export interface ResumePoint { * answer beats a cheap one that cannot represent a hole. */ export function computeResumePoint(captures: CaptureInterval[], firstBlock: number): ResumePoint { + const gaps = openGaps(captures); + const gapNote = gaps.length === 0 + ? "" + : `. ${gaps.length} open gap(s) below the newest recorded block: ` + + gaps.map(([a, b]) => `${a}..${b}`).join(", "); + const clean = captures.filter(isClean); if (clean.length === 0) { return { resumeAt: firstBlock, coveredUpTo: null, reason: - captures.length === 0 + (captures.length === 0 ? "no coverage row exists for this contract, so no range has been read into this target" - : `all ${captures.length} coverage row(s) are incomplete, skipped or a capability gap`, + : `all ${captures.length} coverage row(s) are incomplete, skipped or a capability gap`) + gapNote, capturesConsidered: captures.length, capturesClean: 0, + openGaps: gaps, }; } @@ -175,31 +190,56 @@ export function computeResumePoint(captures: CaptureInterval[], firstBlock: numb return { resumeAt: firstBlock, coveredUpTo: null, - reason: `no clean capture covers the contract's creation block ${firstBlock}`, + reason: `no clean capture covers the contract's creation block ${firstBlock}` + gapNote, capturesConsidered: captures.length, capturesClean: clean.length, + openGaps: gaps, }; } return { resumeAt: covering[1], coveredUpTo: covering[1], - reason: `coverage is contiguous and clean from ${firstBlock} to ${covering[1]}`, + reason: `coverage is contiguous and clean from ${firstBlock} to ${covering[1]}` + gapNote, capturesConsidered: captures.length, capturesClean: clean.length, + openGaps: gaps, }; } +/** A row describes a real range only when its end is at or above its start. */ +function describesARange(c: CaptureInterval): boolean { + return c.toBlock >= c.fromBlock; +} + /** - * Every range that was attempted and is not now covered by a clean capture. + * Every range inside the ledger's own envelope that is not covered by a clean capture. * * This is what repair works from, and it is the thing that made the field worth writing. Before * this, `skipped_ranges` was written in three places and read in none, which means the pipeline * recorded its own holes and then had no way to act on them. * - * A range appears here when a capture skipped it, or when a capture's status is anything other - * than complete. It disappears when a LATER clean capture covers it, so a gap that has already - * been repaired is not repaired again. + * THREE REASONS A RANGE APPEARS HERE, AND THE THIRD IS FINDING H3. The first two were here + * already: a capture SKIPPED the range, or a capture's status is anything other than complete. + * Both are holes somebody recorded. The third is the hole nobody recorded -- a range inside the + * span this ledger describes that NO capture row mentions at all. + * + * H3 is exactly that case and it was invisible: clean captures of 100..199 and 300..399 leave + * 200..299 read by nobody, and because no failed capture ever described it, it could not enter a + * candidate list built only from recorded failures. `coverage` printed clean and `repair` had + * nothing to act on. The module's own rule decides it -- L0-8 says a block range with no coverage + * row WAS NEVER SCANNED, so an unmentioned interior range is unknown, and unknown resolves + * downwards. + * + * THE ENVELOPE IS THE BOUND, and it is what keeps this from reporting the whole chain. Blocks + * above the newest recorded block are not a gap: nobody has claimed to read them and the resume + * point is the thing that says where to start. Only the INTERIOR of what the ledger describes is + * ground it has implicitly claimed by stepping over. Rows that describe no range at all -- a + * `nothing_to_fetch` row records `toBlock` below `fromBlock` -- are excluded from the envelope + * entirely, because letting one widen it would manufacture an enormous gap out of an empty read. + * + * A range disappears from this list when a LATER clean capture covers it, so a gap that has + * already been repaired is not repaired again. */ export function openGaps(captures: CaptureInterval[]): [number, number][] { const suspect: [number, number][] = []; @@ -211,8 +251,182 @@ export function openGaps(captures: CaptureInterval[]): [number, number][] { } if (c.status !== "complete") suspect.push([c.fromBlock, c.toBlock]); } + + // H3: the interior of the envelope that no coverage row describes. + const described = captures.filter(describesARange); + if (described.length > 0) { + const envelope: [number, number] = [ + Math.min(...described.map((c) => c.fromBlock)), + Math.max(...described.map((c) => c.toBlock)), + ]; + const covered = mergeIntervals(described.map((c) => [c.fromBlock, c.toBlock] as [number, number])); + suspect.push(...subtract([envelope], covered)); + } + if (suspect.length === 0) return []; const cleanCover = mergeIntervals(captures.filter(isClean).map((c) => [c.fromBlock, c.toBlock] as [number, number])); return subtract(mergeIntervals(suspect), cleanCover); } + +// --------------------------------------------------------------------------- decode coverage + +/** + * DECODE COVERAGE, WHICH IS A DIFFERENT QUESTION FROM BLOCK COVERAGE (plan 5.2.1). + * + * Everything above answers "what did we read". None of it answers "what could we decode". Those + * come apart whenever a log's `topic0` matches no entry in its address's event surface: the row is + * present, correct and raw, and every downstream model that selects on an event name skips it. An + * undecodable log and an absent one are indistinguishable once the query has run, and the + * magnitude tripwire does not help -- it catches a wrong value, not a missing row. + * + * So the count is REPORTED beside block coverage rather than inferred from it. The classifier is + * `countUndecodableLogs` in `control-plane/decodeSurface.ts`; this is the reporting half. + */ + +/** One `(chain, address, topic0)` group and how many rows carry it. */ +export interface DecodeLogGroup { + chainId: number; + address: string; + topic0: string | null; + rows: number; +} + +export interface DecodeCoverageRow { + chainId: number; + address: string; + /** Rows whose topic0 could be compared against the surface at all. */ + rowsConsidered: number; + rowsUndecodable: number; + unmatchedTopic0s: readonly string[]; + addressHasNoSurface: boolean; +} + +export interface DecodeCoverage { + byContract: DecodeCoverageRow[]; + rowsConsidered: number; + rowsUndecodable: number; + /** + * ROWS this report could not classify, counted separately from the result and never folded into + * `rowsUndecodable`. A null `topic0` on a non-anonymous log means the row is unreadable, not + * that its event is unknown. An undecodable count of zero is a measurement only when this is + * zero too. + */ + errors: number; + errorDetail: string[]; +} + +/** + * Turn grouped rows into a decode-coverage report. + * + * WHY THE GROUPS ARE WEIGHTED HERE RATHER THAN EXPANDED. `countUndecodableLogs` takes one entry + * per log, and the warehouse holds hundreds of millions of them against at most a few hundred + * distinct `(chain, address, topic0)` keys. Expanding a GROUP BY back into rows to feed a counter + * that would immediately re-aggregate them is arithmetic for its own sake. So the classifier is + * asked the question it is the authority on -- WHICH topic0 values match no surface entry -- and + * the row weights are applied here, where they came from. The classification is not re-derived. + */ +export function weightDecodeCoverage( + groups: readonly DecodeLogGroup[], + surface: ParsedEventSurface, +): DecodeCoverage { + const candidates: DecodeCandidateLog[] = groups.map((g) => ({ + chainId: g.chainId, address: g.address, topic0: g.topic0, + })); + const classified = countUndecodableLogs(candidates, surface); + + const key = (chainId: number, address: string) => `${chainId}:${address.toLowerCase()}`; + const unmatchedByContract = new Map>(); + for (const c of classified.byContract) { + unmatchedByContract.set(key(c.chainId, c.address), new Set(c.unmatchedTopic0s.map((t) => t.toLowerCase()))); + } + + const byContract: DecodeCoverageRow[] = []; + let rowsConsidered = 0; + let rowsUndecodable = 0; + let errors = 0; + const errorDetail: string[] = []; + + for (const c of classified.byContract) { + const k = key(c.chainId, c.address); + const unmatched = unmatchedByContract.get(k) ?? new Set(); + const mine = groups.filter((g) => key(g.chainId, g.address) === k); + + const considered = mine.filter((g) => g.topic0 !== null).reduce((n, g) => n + g.rows, 0); + const undecodable = mine + .filter((g) => g.topic0 !== null && unmatched.has(g.topic0.toLowerCase())) + .reduce((n, g) => n + g.rows, 0); + const unreadable = mine.filter((g) => g.topic0 === null).reduce((n, g) => n + g.rows, 0); + + rowsConsidered += considered; + rowsUndecodable += undecodable; + errors += unreadable; + if (unreadable > 0) { + errorDetail.push( + `${k}: ${unreadable} row(s) carry no topic0, so they can be neither matched nor ruled out` + ); + } + + byContract.push({ + chainId: c.chainId, + address: c.address, + rowsConsidered: considered, + rowsUndecodable: undecodable, + unmatchedTopic0s: c.unmatchedTopic0s, + addressHasNoSurface: c.addressHasNoSurface, + }); + } + + return { byContract, rowsConsidered, rowsUndecodable, errors, errorDetail }; +} + +/** + * Read the `(chain, address, topic0)` groups one contract's captured logs fall into. + * + * Through the all-history view, because this question has no natural block window and a bare + * GROUP BY straight at a `require_partition_filter` table is refused outright. + */ +export async function loadDecodeLogGroups( + chainId: number, + contractAddress: string, +): Promise { + const rows = await bqQuery( + `SELECT chain_id, contract_address, topic0, COUNT(*) AS rows_held + FROM ${allHistory(RAW_LOGS_TABLE)} + WHERE chain_id = @chainId AND contract_address = @address + GROUP BY chain_id, contract_address, topic0`, + { chainId, address: contractAddress.toLowerCase() } + ); + + return rows.map((r: any) => ({ + chainId: Number(r.chain_id), + address: String(r.contract_address ?? "").toLowerCase(), + topic0: r.topic0 === null || r.topic0 === undefined ? null : String(r.topic0).toLowerCase(), + rows: Number(r.rows_held), + })); +} + +/** + * Decode coverage for one contract, or a stated reason it could not be measured. + * + * A query failure returns an error count rather than an empty report. The distinction is the + * whole point of this module: "zero undecodable rows" and "the question could not be asked" must + * never be the same answer. + */ +export async function loadDecodeCoverage( + chainId: number, + contractAddress: string, + surface: ParsedEventSurface, +): Promise { + try { + return weightDecodeCoverage(await loadDecodeLogGroups(chainId, contractAddress), surface); + } catch (e: any) { + log.error( + `Decode coverage for ${contractAddress} on chain ${chainId} could not be measured: ${e.message}` + ); + return { + byContract: [], rowsConsidered: 0, rowsUndecodable: 0, errors: 1, + errorDetail: [`${chainId}:${contractAddress.toLowerCase()}: query failed: ${e.message}`], + }; + } +} diff --git a/projects/onchain-analytics/pipeline-v5/src/hypersync.ts b/projects/onchain-analytics/pipeline-v5/src/hypersync.ts index 8b1d50f..8b974a2 100644 --- a/projects/onchain-analytics/pipeline-v5/src/hypersync.ts +++ b/projects/onchain-analytics/pipeline-v5/src/hypersync.ts @@ -25,6 +25,7 @@ import { fileURLToPath } from "url"; import { dirname, join } from "path"; import { CONFIG } from "./config.js"; import { log } from "./log.js"; +import { getWorkerRunner } from "./adapters.js"; import { normaliseChunk } from "./normalise.js"; import type { NetworkConfig, ChunkResult, FetchResult, RollbackGuard } from "./types.js"; @@ -80,6 +81,13 @@ interface WorkerResult { /** Run one worker request under a hard wall-clock deadline. Never throws. */ function runWorker(request: Record, timeoutMs: number): Promise { + // A replaced runner takes precedence. Everything this module does ABOVE the worker call -- + // chunk planning, bounded retries, the short-collection refusal, empty-chunk tracking and + // rollback-guard forwarding -- is unreachable through `setReaderOverride`, which replaces the + // whole reader. This is the only seam below it. + const replacement = getWorkerRunner(); + if (replacement) return replacement(request, timeoutMs) as Promise; + return new Promise((resolve) => { const t0 = Date.now(); const child = spawn(process.execPath, [WORKER, JSON.stringify(request)], { diff --git a/projects/onchain-analytics/pipeline-v5/src/index.ts b/projects/onchain-analytics/pipeline-v5/src/index.ts index e28fa61..f82a658 100644 --- a/projects/onchain-analytics/pipeline-v5/src/index.ts +++ b/projects/onchain-analytics/pipeline-v5/src/index.ts @@ -11,7 +11,9 @@ */ import { hostname } from "os"; -import { CONFIG, selectedNetworks } from "./config.js"; +import { fileURLToPath } from "url"; +import { resolve } from "path"; +import { CONFIG, NETWORKS, selectedNetworks } from "./config.js"; import { log, flushLogs, RUN_ID } from "./log.js"; import { runPipeline } from "./pipeline.js"; import { runVerify } from "./reconcile.js"; @@ -20,9 +22,18 @@ import { runCalibrate } from "./calibrate.js"; import { loadRegistry } from "./registry.js"; import { ensureInfraTables, recordPipelineRun } from "./bq.js"; import { alertFailure } from "./slack.js"; +import { buildPlan, renderPlan } from "./plan.js"; +import { MAX_CAPTURES_CEILING, MAX_CAPTURE_BLOCKS_CEILING } from "./budget.js"; +import { + RunSummary, unit, captureExitCodeFor, assertExitAgreesWithSummary, readOnlyExitCode, + executionStatusOf, PARENT_GRAIN, + type ReadOnlyOutcome, type ReadOnlyResult, type UnitOutcome, +} from "./outcome.js"; import type { PipelineOpts } from "./types.js"; -const VALID_MODES = ["daily", "backfill", "verify", "dedup", "repair", "calibrate", "coverage"] as const; +const VALID_MODES = [ + "daily", "backfill", "plan", "verify", "dedup", "repair", "calibrate", "coverage", +] as const; type Mode = (typeof VALID_MODES)[number]; const USAGE = ` @@ -30,7 +41,8 @@ Usage: npx tsx src/index.ts [options] Modes daily Ingest from each contract's coverage frontier to the chain tip. - backfill Ingest a named range, or each contract's whole history from its creation block. + backfill Ingest a named range. --from and --to are both required. + plan Say exactly what a run would do. Reads no chain and writes no BigQuery. verify Reconcile the warehouse against a contract's own ledger. Changes nothing. coverage Report every block range that is not covered by a clean capture. Changes nothing. dedup Collapse repeated natural keys. @@ -40,30 +52,58 @@ Modes Options --chains=A,B Limit to these chains, by name. Default: every configured chain. --addresses=0x.. Limit to these contract addresses. - --from=N --to=N Block range. Applies to backfill and calibrate. + --from=N --to=N Block range. Both or neither; one alone is refused. --days=N,N Protocol days. Applies to verify and repair. --dry-run Report what would change without changing it. Applies to dedup and repair. --max-capture-blocks=N Raise the span one capture may attempt. Default: 30 days of blocks - for that chain. An explicit --from and --to is always allowed. + for that chain. Maximum ${MAX_CAPTURE_BLOCKS_CEILING.toLocaleString()}. + An explicit --from and --to is always allowed. --max-captures=N Raise the number of contracts one run may attempt. Default: 12. + Maximum ${MAX_CAPTURES_CEILING.toLocaleString()}. A run is refused, before it reads anything, when it would attempt more than those limits. With an empty coverage ledger every contract resumes from its creation block, so a bare run is a full historical backfill rather than an increment. The limits make that something you ask for. -contract is a seed change. + +Exit codes + 0 at least one unit completed and nothing was refused, unsupported, incomplete or failed + 1 some units completed and some did not, or a read-only command reported a real finding + 2 nothing completed, the scope was empty, the run was refused, or the arguments were wrong `; -function parseArgs(): PipelineOpts { - const modeArg = (process.argv[2] || "").toLowerCase(); +/** + * An argument the parser rejected, carrying the exit code the CLI owes the shell. + * + * The parser used to call `process.exit` from inside itself. That made it untestable in process: + * exercising a bad argument killed the test runner. Throwing instead moves the decision to the + * one place that is allowed to make it, `main`, and changes no observable CLI behaviour. + */ +export class CliUsageError extends Error { + readonly exitCode: number; + readonly showUsage: boolean; + constructor(message: string, opts: { exitCode?: number; showUsage?: boolean } = {}) { + super(message); + this.name = "CliUsageError"; + this.exitCode = opts.exitCode ?? 2; + this.showUsage = opts.showUsage ?? true; + } +} + +/** + * Parse CLI arguments into options, or throw. + * + * Takes the argument list rather than reading `process.argv`, so a caller can parse a hypothetical + * command line. `argv` is the list AFTER the node executable and script path, i.e. mode first. + */ +export function parseArgs(argv: string[]): PipelineOpts { + const modeArg = (argv[0] || "").toLowerCase(); if (!VALID_MODES.includes(modeArg as Mode)) { - console.error(`Unknown mode: "${modeArg}". Valid: ${VALID_MODES.join(", ")}`); - console.error(USAGE); - process.exit(2); + throw new CliUsageError(`Unknown mode: "${modeArg}". Valid: ${VALID_MODES.join(", ")}`); } const opts: PipelineOpts = { mode: modeArg as Mode }; - for (const arg of process.argv.slice(3)) { + for (const arg of argv.slice(1)) { if (arg.startsWith("--chains=")) { opts.chains = arg.slice("--chains=".length).split(",").map((s) => s.trim()).filter(Boolean); } else if (arg.startsWith("--addresses=")) { @@ -83,41 +123,154 @@ function parseArgs(): PipelineOpts { } else if (arg.startsWith("--max-captures=")) { opts.maxCaptures = parseInt(arg.slice("--max-captures=".length), 10); } else { - console.error(`Unrecognised argument: ${arg}`); - console.error(USAGE); - process.exit(2); + throw new CliUsageError(`Unrecognised argument: ${arg}`); } } if (opts.fromBlock !== undefined && Number.isNaN(opts.fromBlock)) { - console.error("--from is not a number"); - process.exit(2); + throw new CliUsageError("--from is not a number", { showUsage: false }); } if (opts.toBlock !== undefined && Number.isNaN(opts.toBlock)) { - console.error("--to is not a number"); - process.exit(2); + throw new CliUsageError("--to is not a number", { showUsage: false }); } if (opts.fromBlock !== undefined && opts.toBlock !== undefined && opts.toBlock < opts.fromBlock) { - console.error(`--to (${opts.toBlock}) is below --from (${opts.fromBlock})`); - process.exit(2); + throw new CliUsageError(`--to (${opts.toBlock}) is below --from (${opts.fromBlock})`, { showUsage: false }); + } + + // Plan task 7: a ONE-SIDED range is refused. Half a range is not a smaller range, it is a + // different command: `--to` alone silently means "from wherever the ledger happens to resume", + // and `--from` alone means "to wherever the chain happens to be", so the span the guard judges + // is not the span the person typed. Plan section 1.1 requires every live range to carry an + // explicit --from AND --to, which this is the enforcement of. + const sides = [opts.fromBlock !== undefined, opts.toBlock !== undefined]; + if (sides[0] !== sides[1]) { + throw new CliUsageError( + `--${sides[0] ? "from" : "to"} was given without --${sides[0] ? "to" : "from"}. A block range ` + + `is both bounds or neither: one alone leaves the other end to be resolved from the coverage ` + + `ledger or the chain tip, so the span you typed is not the span that runs.`, + { showUsage: false } + ); + } + + // Plan section 1.1: bare `backfill` is forbidden. It resumes every selected contract from its + // creation block, which is A5 wearing the name of a range read. + if (opts.mode === "backfill" && opts.fromBlock === undefined) { + throw new CliUsageError( + "backfill requires an explicit --from and --to. Without them it reads from every selected " + + "contract's creation block to the chain tip, which is a full historical backfill.", + { showUsage: false } + ); } - // A limit that silently became NaN would compare false against every span and disable the guard - // it was passed to raise. That is the shape of defect this project keeps finding, so it exits. - for (const [flag, value] of [["--max-capture-blocks", opts.maxCaptureBlocks], ["--max-captures", opts.maxCaptures]] as const) { - if (value !== undefined && (!Number.isFinite(value) || value < 1)) { - console.error(`${flag} must be a positive whole number`); - process.exit(2); + // Plan task 7: an unknown chain name is rejected rather than silently selecting nothing. + // `selectedNetworks` filters by name, so a typo used to produce an empty network list, which + // ran to completion having done nothing and exited 0. + if (opts.chains) { + const known = new Set(Object.values(NETWORKS).map((n) => n.name)); + const unknown = opts.chains.map((c) => c.toUpperCase()).filter((c) => !known.has(c)); + if (unknown.length > 0) { + throw new CliUsageError( + `Unknown chain(s): ${unknown.join(", ")}. Configured chains are ${[...known].join(", ")}.`, + { showUsage: false } + ); + } + } + + // Plan task 8: a limit is a positive SAFE integer with an explicit upper bound. + // + // Three failure shapes, all of them turning the guard OFF while looking like an adjustment to + // it. NaN compares false against every span. A non-integer like 1.5 compares in ways nobody + // predicted. And a value above `Number.MAX_SAFE_INTEGER` is not the integer that was typed: + // this project measured `Number("9223372036854775807")` producing a DIFFERENT number on 134 + // registry rows, so an unbounded limit is not a theoretical hazard here. + for (const [flag, value, ceiling] of [ + ["--max-capture-blocks", opts.maxCaptureBlocks, MAX_CAPTURE_BLOCKS_CEILING], + ["--max-captures", opts.maxCaptures, MAX_CAPTURES_CEILING], + ] as const) { + if (value === undefined) continue; + if (!Number.isSafeInteger(value) || value < 1) { + throw new CliUsageError(`${flag} must be a positive whole number`, { showUsage: false }); + } + if (value > ceiling) { + throw new CliUsageError( + `${flag}=${value} is above the maximum of ${ceiling.toLocaleString()}. A limit that can be ` + + `set to any number is not a limit. If this run genuinely needs more, it is an A5-shaped ` + + `run and plan section 1.1 forbids executing one from here.`, + { showUsage: false } + ); } } return opts; } +/** + * The exit code a capture run owes the shell. + * + * Re-exported rather than redefined: the mapping lives in `outcome.ts` next to the counters it + * reads, so there is one place where "what does this run's result mean" is decided. `main` uses + * the summary-shaped `captureExitCodeFor`; this two-number form is what the C2 regression tests + * and the audit's receipts were taken against, and it is the same function underneath. + */ +export { captureExitCode } from "./outcome.js"; + +/** The process-level wrapper. The only place in this file allowed to end the process. */ +function parseArgvOrExit(): PipelineOpts { + try { + return parseArgs(process.argv.slice(2)); + } catch (e: any) { + console.error(e.message); + if (e instanceof CliUsageError && e.showUsage) console.error(USAGE); + process.exit(e instanceof CliUsageError ? e.exitCode : 2); + } +} + +/** + * Map a read-only command's result to the read-only matrix. + * + * A command that reports its own outcome is believed. A command that still returns a boolean is + * mapped the only way a boolean can be mapped, and that ambiguity is now confined to the four + * commands that have not been given an outcome type yet: `false` means the command found + * something, which is a REPORT and exits 1, while `true` cannot distinguish "checked everything + * and it was fine" from "checked nothing". + * + * `verify` no longer has that problem. Finding C4 was exactly this ambiguity in `runVerify`, and + * it was fixed where it lived -- in the return type -- so the third state that was named here + * before it could be produced, `nothing_to_check`, now arrives as a real value and exits 2. + */ +function readOnlyOutcomeOf(result: boolean | ReadOnlyResult): ReadOnlyOutcome { + if (typeof result === "boolean") return result ? "clean" : "finding"; + return result.outcome; +} + async function main(): Promise { - const opts = parseArgs(); + const opts = parseArgvOrExit(); const startedAt = new Date().toISOString(); + // ------------------------------------------------------------------ plan mode, before anything + // + // Plan task 9: no chain read, no BigQuery write. So it runs BEFORE the registry log line, before + // `ensureInfraTables`, and it never reaches `recordPipelineRun`. A read-only command does not + // gain warehouse mutation merely to close itself. + if (opts.mode === "plan") { + const plan = buildPlan(opts); + console.log(renderPlan(plan)); + console.log(JSON.stringify({ + outcome: plan.outcome, + exitCode: plan.exitCode, + contractsPlanned: plan.contractsPlanned, + unitsPlanned: plan.unitsPlanned, + counts: plan.summary.totals, + countsByGrain: JSON.parse(plan.summary.countsByGrainJson()), + })); + if (plan.exitCode !== 0) { + await alertFailure(RUN_ID, opts.mode, plan.exitCode, plan.refusals[0] ?? plan.outcome, 0); + } + await flushLogs(); + process.exitCode = plan.exitCode; + return; + } + // The registry is loaded before anything else, so a missing or moved seed stops the run with a // message naming the file rather than producing an ingestion that silently covers no contracts. const registry = loadRegistry(); @@ -142,8 +295,9 @@ async function main(): Promise { let exitCode = 0; let errorMessage: string | undefined; let totalRows = 0; - let succeeded = 0; - let failed = 0; + // Every mode ends with one summary, so the run record is filled from the same object the exit + // code is computed from and the two cannot drift. + let summary = new RunSummary(); try { await ensureInfraTables(); @@ -152,60 +306,81 @@ async function main(): Promise { case "daily": case "backfill": { const result = await runPipeline(opts); - succeeded = result.succeeded; - failed = result.failed; + summary = result.summary; totalRows = result.totalRows; - exitCode = failed === 0 ? 0 : succeeded > 0 ? 1 : 2; - break; - } - case "verify": { - const clean = await runVerify(opts); - succeeded = clean ? 1 : 0; - failed = clean ? 0 : 1; - exitCode = clean ? 0 : 1; - if (!clean) errorMessage = "reconciliation against the contract oracle did not come out clean"; - break; - } - case "coverage": { - const clean = await reportCoverage(opts); - succeeded = clean ? 1 : 0; - failed = clean ? 0 : 1; - exitCode = clean ? 0 : 1; - if (!clean) errorMessage = "at least one contract has a block range no clean capture covers"; - break; - } - case "dedup": { - const clean = await runDedup(opts); - succeeded = clean ? 1 : 0; - failed = clean ? 0 : 1; - exitCode = clean ? 0 : 1; - if (!clean) errorMessage = "repeated natural keys remain"; - break; - } - case "repair": { - const clean = await runRepair(opts); - succeeded = clean ? 1 : 0; - failed = clean ? 0 : 1; - exitCode = clean ? 0 : 1; - if (!clean) errorMessage = "repair did not bring every open coverage gap under a clean capture"; + exitCode = captureExitCodeFor(summary); + if (exitCode !== 0) { + errorMessage = summary.problems.slice(0, 3).map((u) => `[${u.kind}] ${u.detail}`).join(" | "); + } break; } + case "verify": + case "coverage": + case "dedup": + case "repair": case "calibrate": { - const ok = await runCalibrate(opts); - succeeded = ok ? 1 : 0; - failed = ok ? 0 : 1; - exitCode = ok ? 0 : 1; - if (!ok) errorMessage = "at least one source returned no answer on any pass"; + const runner = { + verify: runVerify, + coverage: reportCoverage, + dedup: runDedup, + repair: runRepair, + calibrate: runCalibrate, + }[opts.mode]; + const message = { + verify: "reconciliation against the contract oracle did not come out clean", + coverage: "at least one contract has a block range no clean capture covers", + dedup: "repeated natural keys remain", + repair: "repair did not bring every open coverage gap under a clean capture", + calibrate: "at least one source returned no answer on any pass", + }[opts.mode]; + + const result = await runner(opts); + const outcome = readOnlyOutcomeOf(result); + exitCode = readOnlyExitCode(outcome); + + // The run record has to say which of the three happened, not just that it was not clean. + // `nothing_to_check` is an EMPTY run, not a failed one: nothing went wrong, and nothing + // was learned. Collapsing it into `failed` would hide the distinction C4 exists to make + // one layer further on, in the table a reader actually queries. + const detail = typeof result === "boolean" ? message : result.summary; + const kind: UnitOutcome["kind"] = + outcome === "clean" ? "completed" + : outcome === "nothing_to_check" ? "nothing_to_fetch" + : outcome === "unsupported" ? "unsupported" + : "failed"; + + summary.plan(PARENT_GRAIN, 1); + summary.add(unit( + kind, + PARENT_GRAIN, + outcome === "clean" ? `${opts.mode} found nothing to report` : detail, + )); + if (outcome !== "clean") errorMessage = detail; break; } } } catch (e: any) { exitCode = 2; errorMessage = e.message; + summary.add(unit("failed", PARENT_GRAIN, `${opts.mode} crashed: ${e.message}`)); log.error(`Pipeline crashed: ${e.message}`, { error: e.message, stack: String(e.stack ?? "").slice(0, 1000) }); } + // THE EXIT GATE, CHECKED RATHER THAN PROMISED. Plan Phase 3's exit gate is that no log line may + // say refused, unsupported, incomplete or failed while the process and the run record say + // success. This is that sentence as an assertion, and it runs on every real run. If the mapping + // above is ever wrong, the run turns into a nonzero exit naming the contradiction instead of a + // green no-op, which is the exact defect this phase exists to remove. + try { + assertExitAgreesWithSummary(exitCode, summary); + } catch (e: any) { + log.error(e.message); + errorMessage = e.message; + exitCode = 2; + } + const completedAt = new Date().toISOString(); + const t = summary.totals; try { await recordPipelineRun({ @@ -215,29 +390,56 @@ async function main(): Promise { completedAt, exitCode, totalRowsMerged: totalRows, - contractsProcessed: succeeded, - contractsFailed: failed, + contractsProcessed: t.completed, + contractsFailed: t.refused + t.unsupported + t.incomplete + t.failed, host: hostname(), errorMessage, chainsProcessed: networks.map((n) => n.chainId).join(","), - capturesPlanned: succeeded + failed, - capturesOk: succeeded, + capturesPlanned: t.planned, + capturesOk: t.completed, // A run that finished with failed captures did NOT succeed, whatever its exit code, and this // column is where that is queryable. A count that appears only in console output does not // exist. - capturesFailed: failed, + capturesFailed: t.refused + t.unsupported + t.incomplete + t.failed, pipelineVersion: CONFIG.PIPELINE_VERSION, + // Plan task 11. The run record now carries the same typed outcome the exit code was + // computed from, so `PipelineRuns` reconciles exactly to child outcomes instead of to two + // numbers that were incremented separately from them. + executionStatus: executionStatusOf(exitCode, summary), + unitsPlanned: t.planned, + unitsAttempted: t.attempted, + unitsCompleted: t.completed, + unitsNoop: t.noop, + unitsRefused: t.refused, + unitsUnsupported: t.unsupported, + unitsFailed: t.incomplete + t.failed, + outcomeCountsByGrain: summary.countsByGrainJson(), + releaseSha: CONFIG.RELEASE_SHA, + planHash: CONFIG.PLAN_HASH, }); } catch (e: any) { log.warn(`Failed to record PipelineRun: ${e.message}`); } - // Alert on failure + // Plan task 10, first half: every nonzero exit reaches Slack. A globally refused run used to + // exit 0 and therefore never alerted, which is how a scheduled workflow could turn green while + // ingesting nothing. if (exitCode !== 0) { - await alertFailure(RUN_ID, opts.mode, exitCode, errorMessage ?? `${failed} unit(s) failed`, totalRows); + await alertFailure( + RUN_ID, opts.mode, exitCode, + errorMessage ?? `${t.refused + t.unsupported + t.incomplete + t.failed} unit(s) did not complete`, + totalRows + ); } - log.info(`Pipeline complete: exit ${exitCode}`, { succeeded, failed, totalRows, runId: RUN_ID }); + log.info(`Pipeline complete: exit ${exitCode}`, { + runId: RUN_ID, + planned: t.planned, attempted: t.attempted, completed: t.completed, + noop: t.noop, refused: t.refused, unsupported: t.unsupported, + incomplete: t.incomplete, failed: t.failed, + byGrain: summary.countsByGrainJson(), + totalRows, + }); await flushLogs(); // Setting exitCode and letting the loop drain, rather than calling process.exit, which tears @@ -251,4 +453,10 @@ async function main(): Promise { }, 30_000).unref(); } -main(); +// Run only when this file IS the command, so a test can import `parseArgs` and `captureExitCode` +// without starting an ingestion. `process.argv[1]` is the script node was asked to run. +const invokedDirectly = + process.argv[1] !== undefined && + fileURLToPath(import.meta.url) === resolve(process.argv[1]); + +if (invokedDirectly) main(); diff --git a/projects/onchain-analytics/pipeline-v5/src/oracle.ts b/projects/onchain-analytics/pipeline-v5/src/oracle.ts index eab5ed9..c66f873 100644 --- a/projects/onchain-analytics/pipeline-v5/src/oracle.ts +++ b/projects/onchain-analytics/pipeline-v5/src/oracle.ts @@ -74,8 +74,23 @@ function decWords(hex: string): bigint[] { return out; } -/** The chain head every listed endpoint can already serve, minus a margin. */ -export async function pinBlock(network: NetworkConfig, behind = 5): Promise> { +/** + * The chain head every listed endpoint can already serve, minus the chain's own finality margin. + * + * THE MARGIN IS PER CHAIN AND IS MEASURED. It used to default to 5 blocks for every chain, which + * on Celo pins about 1,925 blocks inside the reorganisation window: A2 sampled the finalized tag + * there 33 times and found it 1,187 to 1,930 blocks behind head. A pin inside that window is not + * reproducible, and that is the whole job of a pin -- the block it names can be replaced, and + * every reading taken at it silently changes meaning while still answering. + * + * `config.ts` already carries the measurement per chain, with its source written beside it, so + * this reads that rather than introducing a second constant that would need its own evidence. + * A caller may still pass a wider margin; a narrower one is refused rather than honoured, + * because pinning nearer the head than the chain's own measurement is the defect itself. + */ +export async function pinBlock(network: NetworkConfig, behind?: number): Promise> { + const measured = network.finality.blocks; + const margin = behind === undefined ? measured : Math.max(behind, measured); const r = await consensusRead(network, "eth_blockNumber", [], 1); const heads: number[] = []; const errors = [...r.errors]; @@ -85,8 +100,18 @@ export async function pinBlock(network: NetworkConfig, behind = 5): Promise a.url) }); + if (behind !== undefined && behind < measured) { + errors.push( + `requested pin margin ${behind} is inside ${network.name}'s measured finality of ${measured} ` + + `block(s), so ${measured} was used instead: ${network.finality.source}` + ); + } + const pin = Math.min(...heads) - margin; + log.info(`Pinned ${network.name} block ${pin}`, { + heads, margin, measuredFinality: measured, + publishesFinalizedTag: network.finality.publishesFinalizedTag, + endpoints: r.answers.map((a) => a.url), + }); return { ok: true, value: pin, block: pin, agreeing: r.answers.map((a) => a.url), errors }; } diff --git a/projects/onchain-analytics/pipeline-v5/src/outcome.ts b/projects/onchain-analytics/pipeline-v5/src/outcome.ts new file mode 100644 index 0000000..01a03b4 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/src/outcome.ts @@ -0,0 +1,308 @@ +/** + * outcome.ts -- what a unit of work did, and what the shell is owed because of it. + * + * WHY THIS IS A TYPE AND NOT AN `if`. Finding C2 is not a missing check. `processTarget` returned + * a row count and `runPipeline` returned `{ succeeded, failed }`, and in that shape a refusal has + * nowhere to go: returning 0 rows means "read nothing because there was nothing" and "declined to + * read" with the same value, so the call site cannot tell them apart no matter what it asks. The + * audit's two runtime receipts are that one fact twice. A bare `daily` planned 142 targets against + * a limit of 12, logged REFUSED, read nothing, persisted nothing and exited 0. An XDC backfill + * requested 12,394,045 blocks against a limit of 1,296,000, wrote one refusal row, counted the + * contract as processed successfully and exited 0. + * + * So the fix is the type. Every unit of work now ends in exactly one `UnitOutcome`, the counters + * are derived from those outcomes rather than incremented by hand at each call site, and the exit + * code is a pure function of the counters. A new outcome cannot be added without the compiler + * demanding that the exit mapping say what it means. + * + * THE ONE INVARIANT THE WHOLE PHASE EXISTS TO ENFORCE, from the plan's exit gate: no log line may + * say refused, unsupported, incomplete or failed while the process and the run record say success. + * `assertExitAgreesWithSummary` is that sentence as an assertion, and it runs on every real run. + */ + +/** + * What one unit of work did. One unit is one (contract, chain, grain) capture, or one read-only + * check, or one planned work item. + * + * `completed` is the only value that is success. Everything else is a reason the run is not clean, + * and each of them means something different to the next run: + * + * `nothing_to_fetch` The range was empty by arithmetic, `toBlock` below `fromBlock`. Nothing + * was declined and nothing was missed. It is a no-op, not work. + * `refused_budget` A guard declined before reading. The range is unread and RECORDED as + * unread, so a later run can pick it up. This is the C2 case. + * `unsupported` This pipeline cannot do the thing asked: no reader for the chain, no + * oracle for the check, a chain outside the frozen release scope, an + * address the control plane does not know. + * `incomplete` Work ran and did not finish its range. Some rows may be written. The + * coverage ledger holds the gap. + * `failed` Work ran and threw. + */ +export type UnitOutcomeKind = + | "completed" + | "nothing_to_fetch" + | "refused_budget" + | "unsupported" + | "incomplete" + | "failed"; + +/** Every kind, in one place, so a test can prove each one is reachable and mapped. */ +export const UNIT_OUTCOME_KINDS: readonly UnitOutcomeKind[] = [ + "completed", "nothing_to_fetch", "refused_budget", "unsupported", "incomplete", "failed", +] as const; + +/** + * The grain a unit targeted. + * + * Plan task 6: a budget refusal is recorded against BOTH RawLogs and Transactions, or against one + * parent whose target set names both. `RawLogs+Transactions` is that parent, and it is a distinct + * value rather than a formatting choice: a consumer filtering `target_table = 'RawLogs'` must not + * see a run-level refusal as a claim about the RawLogs grain, because a run-level refusal covers + * no range at all. + */ +export const PARENT_GRAIN = "RawLogs+Transactions"; + +export interface UnitOutcome { + readonly kind: UnitOutcomeKind; + /** `RawLogs`, `Transactions`, `ContractStateSnapshots`, or `PARENT_GRAIN` for a run-level unit. */ + readonly grain: string; + /** Chain id, or null for a unit that is not bound to one chain. */ + readonly chainId: number | null; + /** Lowercase contract address, or null where the unit covers no single contract. */ + readonly address: string | null; + /** Inclusive block range this unit was about, where it had one. */ + readonly fromBlock: number | null; + readonly toBlock: number | null; + /** Rows merged. Only meaningful for `completed` and `incomplete`. */ + readonly rows: number; + /** One sentence a human can act on. Required for everything that is not `completed`. */ + readonly detail: string; +} + +export function unit( + kind: UnitOutcomeKind, + grain: string, + detail: string, + fields: Partial> = {}, +): UnitOutcome { + return { + kind, + grain, + detail, + chainId: fields.chainId ?? null, + address: fields.address ?? null, + fromBlock: fields.fromBlock ?? null, + toBlock: fields.toBlock ?? null, + rows: fields.rows ?? 0, + }; +} + +/** Plan task 2's counters. `planned` is set by the planner; the rest are derived from outcomes. */ +export interface OutcomeCounters { + planned: number; + attempted: number; + completed: number; + noop: number; + refused: number; + unsupported: number; + incomplete: number; + failed: number; +} + +export function emptyCounters(): OutcomeCounters { + return { + planned: 0, attempted: 0, completed: 0, noop: 0, + refused: 0, unsupported: 0, incomplete: 0, failed: 0, + }; +} + +/** + * Which counter a kind increments, and whether it counts as ATTEMPTED. + * + * `attempted` means the pipeline tried to read. A refusal and an unsupported chain were never + * attempted, which is the distinction that makes `planned - attempted` a real number rather than + * an accounting artefact: it is exactly the work this run declined to do. + */ +const COUNTER_OF: Record = { + completed: { field: "completed", attempted: true }, + nothing_to_fetch: { field: "noop", attempted: false }, + refused_budget: { field: "refused", attempted: false }, + unsupported: { field: "unsupported", attempted: false }, + incomplete: { field: "incomplete", attempted: true }, + failed: { field: "failed", attempted: true }, +}; + +export class RunSummary { + readonly units: UnitOutcome[] = []; + readonly totals: OutcomeCounters = emptyCounters(); + readonly byGrain = new Map(); + + /** + * Declare intended work before doing any of it. + * + * Plan task 4 requires a globally refused run to persist the REAL planned count. That number + * only exists if it is recorded before the refusal, which is why this is separate from `add`. + */ + plan(grain: string, count: number): void { + this.totals.planned += count; + this.grain(grain).planned += count; + } + + add(outcome: UnitOutcome): UnitOutcome { + this.units.push(outcome); + const { field, attempted } = COUNTER_OF[outcome.kind]; + this.totals[field] += 1; + this.grain(outcome.grain)[field] += 1; + if (attempted) { + this.totals.attempted += 1; + this.grain(outcome.grain).attempted += 1; + } + return outcome; + } + + private grain(name: string): OutcomeCounters { + let c = this.byGrain.get(name); + if (!c) { c = emptyCounters(); this.byGrain.set(name, c); } + return c; + } + + /** Units that are neither completed nor a no-op. The list the exit code is really about. */ + get problems(): UnitOutcome[] { + return this.units.filter((u) => u.kind !== "completed" && u.kind !== "nothing_to_fetch"); + } + + /** JSON for `PipelineRuns.outcome_counts_by_grain`. Sorted so the column is diffable. */ + countsByGrainJson(): string { + const out: Record = {}; + for (const key of [...this.byGrain.keys()].sort()) out[key] = this.byGrain.get(key)!; + return JSON.stringify(out); + } +} + +// ------------------------------------------------------------------------------ exit codes + +/** + * The exit code a CAPTURE run owes the shell. Plan task 3, first three bullets, verbatim: + * + * 0 at least one requested unit completed and none refused, failed or remained unsupported + * 1 some completed and some did not + * 2 none completed, or the scope was empty, or the run was globally refused + * + * A no-op is deliberately not a completion. A run whose every unit was `nothing_to_fetch` did no + * work, and gate item 5 says empty work is not success, so it lands in the `none completed` arm + * and exits 2. That is the whole of "a command that does no work exits nonzero". + */ +export function captureExitCodeFor(summary: RunSummary): number { + const t = summary.totals; + const notDone = t.refused + t.unsupported + t.incomplete + t.failed; + if (t.completed === 0) return 2; + return notDone === 0 ? 0 : 1; +} + +/** + * The two-number form, kept because `main` and the C2 regression tests both call it and because + * it is the exact mapping the audit's receipt was taken against. + * + * ONE ARM CHANGES, and it is the defect: `(0, 0)` used to be 0. A run with nothing succeeded and + * nothing failed is a run that did no work, and the only reasons to be in that state are a global + * refusal, an empty scope or an unknown chain. All three are exit 2 under plan task 3. + */ +export function captureExitCode(succeeded: number, failed: number): number { + if (succeeded === 0) return 2; + return failed === 0 ? 0 : 1; +} + +/** + * Read-only commands get their own matrix, because plan task 3 says reporting a real finding may + * exit nonzero BY DESIGN and must never be collapsed into the capture rules. + * + * The distinction that matters here is between "I looked and found a problem" (exit 1, the report + * is the product) and "I could not look" (exit 2, there is no report). A verification that + * compared nothing is the second kind. That was finding C4, and `runVerify` now returns a report + * carrying `outcome` so this mapping receives the real answer instead of inferring one from a + * boolean that cannot carry it. + */ +export type ReadOnlyOutcome = "clean" | "finding" | "nothing_to_check" | "unsupported" | "failed"; + +/** + * What a read-only command returns once it can say which of the five happened. + * + * The minimum a command has to carry for the exit mapping to be a lookup rather than a guess. + * Commands still returning `boolean` are mapped on two of the five and cannot express the rest. + */ +export interface ReadOnlyResult { + outcome: ReadOnlyOutcome; +} + +export function readOnlyExitCode(outcome: ReadOnlyOutcome): number { + switch (outcome) { + case "clean": return 0; + case "finding": return 1; + case "nothing_to_check": return 2; + case "unsupported": return 2; + case "failed": return 2; + } +} + +/** Plan task 3, fourth bullet: `plan` is complete-and-inside-budget, or it is nonzero. */ +export type PlanOutcome = "complete" | "refused" | "unsupported" | "incomplete"; + +export function planExitCode(outcome: PlanOutcome): number { + switch (outcome) { + case "complete": return 0; + case "incomplete": return 1; + case "refused": return 2; + case "unsupported": return 2; + } +} + +// ------------------------------------------------------------------------- the exit gate + +/** + * What `PipelineRuns.execution_status` says. A word, not a number, because `exit_code = 2` does + * not distinguish a refusal from a crash and those need different responses. + * + * `success` is deliberately not one of the values. The coverage ledger already refuses that word + * for the same reason: it is the one term that invites a reader to stop asking. + */ +export type ExecutionStatus = + | "completed" | "partial" | "refused" | "unsupported" | "empty" | "failed"; + +export function executionStatusOf(exitCode: number, summary: RunSummary): ExecutionStatus { + const t = summary.totals; + if (exitCode === 0) return "completed"; + if (t.completed > 0) return "partial"; + if (t.refused > 0) return "refused"; + if (t.failed > 0 || t.incomplete > 0) return "failed"; + if (t.unsupported > 0) return "unsupported"; + return "empty"; +} + +/** + * The plan's Phase 3 exit gate, as an assertion rather than a promise. + * + * "No log line can say refused, unsupported, incomplete or failed while the process and run + * record say success." A comment cannot enforce that and a code review has already missed it + * once, so it is checked on every real run, against the counters that are also what gets + * persisted. If this ever throws, the bug is in the mapping above and the run stops rather than + * reporting a success it cannot evidence. + */ +export function assertExitAgreesWithSummary(exitCode: number, summary: RunSummary): void { + if (exitCode !== 0) return; + const t = summary.totals; + const notDone = t.refused + t.unsupported + t.incomplete + t.failed; + if (notDone > 0) { + throw new Error( + `OUTCOME_CONTRADICTION: exit 0 with ${notDone} unit(s) not completed ` + + `(refused ${t.refused}, unsupported ${t.unsupported}, incomplete ${t.incomplete}, ` + + `failed ${t.failed}). ` + + summary.problems.slice(0, 5).map((u) => `[${u.kind} ${u.grain}] ${u.detail}`).join(" | ") + ); + } + if (t.completed === 0) { + throw new Error( + `OUTCOME_CONTRADICTION: exit 0 with zero completed unit(s) out of ${t.planned} planned. ` + + `Empty work is not success.` + ); + } +} diff --git a/projects/onchain-analytics/pipeline-v5/src/pipeline.ts b/projects/onchain-analytics/pipeline-v5/src/pipeline.ts index 70864ba..451af4f 100644 --- a/projects/onchain-analytics/pipeline-v5/src/pipeline.ts +++ b/projects/onchain-analytics/pipeline-v5/src/pipeline.ts @@ -32,14 +32,15 @@ */ import { - CONFIG, selectedNetworks, RAW_LOGS_TABLE, TRANSACTIONS_TABLE, + CONFIG, NETWORKS, selectedNetworks, RAW_LOGS_TABLE, TRANSACTIONS_TABLE, RAW_LOGS_SCHEMA, TRANSACTIONS_SCHEMA, } from "./config.js"; import { log, RUN_ID } from "./log.js"; import { fetchRange, getChainTip, readerFor, gradeCapture } from "./reader.js"; import { confirmEmptyRange } from "./rpc.js"; -import { targetsFor, eraIndexFor } from "./registry.js"; +import { targetsFor, eraIndexFor, partitionByReleaseScope } from "./registry.js"; import { rawLogRows, transactionRows, missingTransactionCount } from "./rawrow.js"; +import { projectChunk, projectFetchResult, unionRange } from "./batch.js"; import { windowForRows, widen } from "./window.js"; import { ensureInfraTables, stageAndMerge, recordCoverage, getMaxBlockTimestamp, setCaptureAssurance, @@ -47,9 +48,11 @@ import { import { loadCoverage, computeResumePoint } from "./coverage.js"; import { checkCaptureSpan, checkRunSize } from "./budget.js"; import { alertStaleness } from "./slack.js"; +import { nowIso } from "./adapters.js"; +import { RunSummary, unit, PARENT_GRAIN, type UnitOutcome } from "./outcome.js"; import type { PipelineOpts, PipelineResult, CaptureTarget, CoverageRecord, FetchResult, NetworkConfig, - MergeWindow, + MergeWindow, ChunkResult, EraMapEntry, } from "./types.js"; export class IncompleteFetchError extends Error {} @@ -92,7 +95,7 @@ function baseCoverage( confirmationResult: "unavailable", assurance: "C", headAtCapture: null, missRateCalibrated: null, passesRun: null, gainSeries: null, - startedAt, completedAt: new Date().toISOString(), + startedAt, completedAt: nowIso(), errorMessage: "", }; } @@ -105,7 +108,7 @@ function baseCoverage( * is what separates the two, and it claims no coverage while it does so. */ async function recordCapabilityGap(network: NetworkConfig, reason: string): Promise { - const startedAt = new Date().toISOString(); + const startedAt = nowIso(); log.error(`CAPABILITY GAP on ${network.name}: ${reason}. No coverage is claimed for this chain.`); await recordCoverage({ captureId: `${RUN_ID}:${network.chainId}:capability_gap`, @@ -122,7 +125,7 @@ async function recordCapabilityGap(network: NetworkConfig, reason: string): Prom confirmationResult: "unavailable", assurance: "C", headAtCapture: null, missRateCalibrated: null, passesRun: null, gainSeries: null, - startedAt, completedAt: new Date().toISOString(), + startedAt, completedAt: nowIso(), errorMessage: reason.slice(0, 4000), }); } @@ -134,10 +137,34 @@ async function recordCapabilityGap(network: NetworkConfig, reason: string): Prom * Exported because repair drives the SAME code path over a named range. The previous repair * carried its own copy of the fetch, decode and write loop, about sixty-five lines duplicated * almost verbatim, so a fix to one path silently left the other behind. + * + * RETURNS A TYPED OUTCOME, NOT A ROW COUNT. That is the C2 fix and it is the whole of it here. + * The previous signature was `Promise`, and a refusal returned 0, which is the same value + * a clean capture of an empty range returns. Two different facts, one value, and every caller + * downstream inherited the ambiguity: the run loop treated any non-throwing return as a success, + * so a refused contract was counted as processed and the process exited 0. + * + * ONE OUTCOME PER GRAIN, WHICH IS FINDING H5. A capture writes coverage rows for two grains, + * RawLogs and Transactions, and used to return a single outcome describing only the first. The + * transaction grain therefore inherited a completeness judgement made about logs: the reader + * returned two logs pointing at two transactions and produced one, the detector at + * `rawrow.ts` counted the missing one, and the Transactions row was still written `complete` with + * the count relegated to an error message. Both rows now carry their own status and both grains + * now return their own outcome, so a grain that did not finish reaches the counters and the exit + * code instead of stopping at a string nobody reads. + * + * PREPARATION IS SEPARATE FROM READING, and that is what closing H2 needed. Resolving a range and + * declining it against the budget are per contract; the READ is per chain. Splitting them lets + * many prepared targets share one batched read while each still decides its own range and writes + * its own verdict. A target refused here never reaches the read at all, so a declined contract + * costs nothing and still leaves the two coverage rows that say it was declined. */ -export async function processTarget(target: CaptureTarget, opts: PipelineOpts): Promise { +async function prepareTarget( + target: CaptureTarget, + opts: PipelineOpts +): Promise<{ sink: CaptureSink } | { outcomes: UnitOutcome[] }> { const { network } = target; - const startedAt = new Date().toISOString(); + const startedAt = nowIso(); const label = `${target.contractName} ${target.address} on ${network.name}`; // ---------------------------------------------------------------- resolve the block range @@ -188,24 +215,46 @@ export async function processTarget(target: CaptureTarget, opts: PipelineOpts): row.sourceId = readerFor(network).id; await recordCoverage(row); log.warn(`Nothing to fetch for ${label}: toBlock ${toBlock} is below fromBlock ${fromBlock}`); - return 0; + return { outcomes: [unit( + "nothing_to_fetch", RAW_LOGS_TABLE, + `${label}: toBlock ${toBlock} is below fromBlock ${fromBlock}, so there was no range to read`, + { chainId: target.chainId, address: target.address, fromBlock, toBlock }, + )] }; } // The span budget. A refusal is a ROW, not a silence: a range nobody read and nothing recorded // is the one state L0-8 exists to prevent, and a guard that produced it would be trading one // defect for another. + // + // IT IS A ROW PER GRAIN, and that is plan task 6. The previous code returned from this branch + // before it reached the Transactions coverage row, so the transaction grain carried no record + // that its range had been declined. An empty Transactions range with no coverage row reads as + // "no transactions in this range" rather than "nobody looked", which is the single state the + // coverage ledger exists to make impossible. const span = checkCaptureSpan(network, fromBlock, toBlock, opts); if (!span.allowed) { - const row = baseCoverage(target, captureId, fromBlock, toBlock, startedAt); - row.status = "refused_budget"; - row.sourceKind = readerFor(network).kind === "index" ? "index" : "rpc"; - row.sourceId = readerFor(network).id; - row.errorMessage = (span.reason ?? "").slice(0, 4000); - await recordCoverage(row); + const reason = (span.reason ?? "").slice(0, 4000); + const refusals: UnitOutcome[] = []; + for (const [grain, id] of [[RAW_LOGS_TABLE, captureId], [TRANSACTIONS_TABLE, `${captureId}:tx`]] as const) { + const row = baseCoverage(target, id, fromBlock, toBlock, startedAt); + row.targetTable = grain; + row.tableId = grain; + row.status = "refused_budget"; + row.sourceKind = readerFor(network).kind === "index" ? "index" : "rpc"; + row.sourceId = readerFor(network).id; + row.errorMessage = reason; + await recordCoverage(row); + refusals.push(unit( + "refused_budget", grain, + `${label} blocks ${fromBlock}..${toBlock}: ${span.reason}`, + { chainId: target.chainId, address: target.address, fromBlock, toBlock }, + )); + } log.error(`REFUSED ${label}: ${span.reason}`, { requestedBlocks: span.requested, limitBlocks: span.limit, + grainsRecorded: `${RAW_LOGS_TABLE},${TRANSACTIONS_TABLE}`, }); - return 0; + return { outcomes: refusals }; } // --------------------------------------------------------------------- fetch and write @@ -217,6 +266,34 @@ export async function processTarget(target: CaptureTarget, opts: PipelineOpts): log.warn(`No era map for ${label}; every row will carry era_resolution 'unresolved'`); } + return { sink: makeSink({ target, network, captureId, fromBlock, toBlock, startedAt, label, eras }) }; +} + +/** Everything one target needs to consume chunks and then write its own verdict. */ +interface PreparedCapture { + target: CaptureTarget; + network: NetworkConfig; + captureId: string; + fromBlock: number; + toBlock: number; + startedAt: string; + label: string; + eras: EraMapEntry[]; +} + +/** + * One target's share of a capture: its buffers, its counters, and its own verdict at the end. + * + * WHY THIS IS AN OBJECT NOW. It used to be a page of local variables inside `processTarget`, + * which was fine while one target owned one fetch. Closing H2 means ONE fetch feeds MANY targets, + * so the per-target state has to be something a chunk can be handed to. Extracting it is what + * keeps a single capture implementation: the single-target path and the batched path run this + * same code, so a fix to one cannot leave the other behind -- which is the defect the previous + * repair path shipped, sixty-five lines duplicated almost verbatim. + */ +function makeSink(p: PreparedCapture) { + const { target, network, captureId, fromBlock, toBlock, startedAt, label, eras } = p; + let logBuffer: Record[] = []; let txBuffer: Record[] = []; let lastBlockInBuffer = -1; @@ -227,7 +304,9 @@ export async function processTarget(target: CaptureTarget, opts: PipelineOpts): let txInserted = 0; let txUpdated = 0; let missingTx = 0; - const ingestedAt = new Date().toISOString(); + let logsSeen = 0; + const emptyChunks: [number, number][] = []; + const ingestedAt = nowIso(); // The widest window any flush of this capture actually wrote under, kept so the grade can be // applied afterwards over exactly the partitions the rows landed in and no more. let writtenWindow: MergeWindow | null = null; @@ -265,13 +344,15 @@ export async function processTarget(target: CaptureTarget, opts: PipelineOpts): } }; - // THE FETCH AND THE WRITE SIT INSIDE A try, AND THAT IS NOT DEFENSIVE HABIT. If this throws - // part way, rows are already in the table and, without the catch below, no coverage row would - // exist for the range that produced them. That is the one state L0-8 exists to prevent: data - // present, and nothing recording that anybody looked. A live run found this by failing here. - let fetch: FetchResult; - try { - fetch = await fetchRange(network, [target.address], fromBlock, toBlock, async (chunk) => { + return { + member: { address: target.address.toLowerCase(), fromBlock, toBlock }, + captureId, + label, + /** Per-member figures the batched FetchResult cannot carry, because they are per address. */ + tally: () => ({ logsSeen, emptyChunks }), + + /** Consume one chunk ALREADY PROJECTED onto this target. */ + accept: async (chunk: ChunkResult) => { const ctx = { chainId: target.chainId, captureId, runId: RUN_ID, @@ -284,6 +365,11 @@ export async function processTarget(target: CaptureTarget, opts: PipelineOpts): ingestedAt, }; + logsSeen += chunk.logs.length; + // Empty FOR THIS TARGET. A batched chunk full of another contract's logs is not empty for + // the batch and is empty for this one, and it is this one that has to confirm the negative. + if (chunk.logs.length === 0) emptyChunks.push([chunk.fromBlock, chunk.toBlock]); + const logs = rawLogRows(chunk, ctx, eras); const txs = transactionRows(chunk, ctx); missingTx += missingTransactionCount(chunk, txs.length); @@ -299,153 +385,400 @@ export async function processTarget(target: CaptureTarget, opts: PipelineOpts): if (row.block_number > lastBlockInBuffer) lastBlockInBuffer = row.block_number; } txBuffer.push(...txs); - }); + }, + + flush, + + /** + * Record that the capture threw part way. + * + * If the fetch throws, rows are already in the table and without this no coverage row would + * exist for the range that produced them. That is the one state L0-8 exists to prevent: data + * present, and nothing recording that anybody looked. A live run found this by failing here. + */ + recordThrow: async (e: any) => { + const failed = baseCoverage(target, captureId, fromBlock, toBlock, startedAt); + failed.status = "incomplete"; + failed.rowsInserted = inserted; + failed.rowsUpdated = updated; + failed.rowsMerged = distinctOffered; + failed.sourceKind = readerFor(network).kind === "index" ? "index" : "rpc"; + failed.sourceId = readerFor(network).id; + failed.errorMessage = + `CAPTURE_THREW: ${String(e?.message ?? e)}. Any rows already written for this range are ` + + `present without a clean capture, so the resume point stays at or below ${fromBlock}.`.slice(0, 4000); + // A failure to record the failure is worse than the failure, so it is logged rather than + // allowed to replace the original error. + try { await recordCoverage(failed); } catch (e2: any) { + log.error(`Could not record the coverage row for a failed capture: ${e2.message}`, { capture: captureId }); + } + }, + + /** Write this target's two coverage rows and return its two outcomes. */ + finish: async (fetch: FetchResult): Promise => { + // ------------------------------------------- every empty chunk is a negative to confirm + const unconfirmed: string[] = []; + let confirmationResult = "unavailable"; + let confirmingSourceId: string | null = null; + // FINDING C6. The admissibility grade the reader put ON its answer, read here rather than + // re-decided. The worst grade any empty chunk earned is what the capture carries, because a + // capture is only as corroborated as its weakest unconfirmed range. + const evidenceGrades: string[] = []; + if (CONFIG.CONFIRM_EMPTY_CHUNKS && fetch.emptyChunks.length > 0) { + log.info(`Confirming ${fetch.emptyChunks.length} empty chunk(s) against independent endpoints`, { + capture: captureId, + }); + let anyConfirmed = false; + let refuted = false; + for (const [lo, hi] of fetch.emptyChunks) { + const c = await confirmEmptyRange(network, [target.address], lo, hi); + evidenceGrades.push(c.evidence.grade); + const corroborating = c.probe.perEndpoint.filter((e) => e.failures === 0 && e.found === 0); + if (corroborating.length > 0) confirmingSourceId = corroborating.map((e) => new URL(e.url).host).join("+"); + if (c.evidence.grade === "refutation") refuted = true; + if (!c.confirmed) { + unconfirmed.push(`${lo}..${hi} [${c.evidence.grade}]: ${c.reason}`); + // A REFUTATION is an error: the primary reader missed data that demonstrably exists. + // An uncorroborated empty range is NOT. It is the ordinary result of asking endpoints + // that this project has measured returning false zeros, and its consequence is already + // correct and sufficient: the coverage frontier does not move past it and it is read + // again. Logging it at error level trained readers to ignore the level. + if (c.evidence.grade === "refutation") { + log.error(`REFUTED EMPTY RANGE ${lo}..${hi}`, { + capture: captureId, reason: c.reason, probeErrors: c.probe.errors.slice(0, 5), + }); + } else { + log.warn(`UNCORROBORATED EMPTY RANGE ${lo}..${hi}`, { + capture: captureId, grade: c.evidence.grade, reason: c.reason, + cleanEndpoints: c.evidence.cleanEndpoints, + zeroLogAnswers: c.probe.zeroLogAnswers, + falseZeroSuspects: c.probe.falseZeroSuspects, + probeErrors: c.probe.errors.slice(0, 5), + }); + } + } else anyConfirmed = true; + } + // `disagreed` is not produced here any more, and the reason is worth stating: in an + // emptiness probe, an endpoint finding logs where another found none IS the refutation + // case, so the two labels named one fact. What the old code actually wrote `disagreed` on + // was the case where a second endpoint never answered at all, which is a missing opinion, + // not a conflict -- the same false label reader.ts already corrected on the chunk path. + confirmationResult = refuted + ? "refuted_emptiness" + : unconfirmed.length > 0 ? "uncorroborated" + : anyConfirmed ? "identical" : "unavailable"; + } + + // FINDING SA-C23a, the remaining half. PR 71 fixed the half that DROPPED the guard, and + // hs-worker.mjs forwards it now. The half left was that the guard changed nothing: status + // was computed before the guard was read, and all the guard did was append a sentence to + // `error_message`. So a range the reader ITSELF says is still reorganisable was recorded + // `complete`, and because `isClean` in coverage.ts is `status === "complete" && no skips`, + // the resume frontier moved straight past it and nothing ever read it again. + // + // The guard is the reader saying "I am still holding blocks from here down, and they may be + // replaced". When the block it names is at or below this capture's own start, the whole + // capture sits inside that window. That is a status, not a note. + const rollbackHeld = fetch.rollbackGuards.filter((g) => g.firstBlockNumber <= fromBlock); + + const status = !fetch.complete ? "incomplete" + : rollbackHeld.length > 0 ? "rollback_eligible" + : unconfirmed.length > 0 ? "unconfirmed_empty" + : "complete"; + + // FINDING H5. The transaction grain gets its own verdict, because it can fail on its own. A + // reader that returns every log and omits one of the transactions those logs point at has + // produced a complete RawLogs range and an incomplete Transactions range, and the previous + // code copied the log verdict onto the transaction row verbatim. The count was detected, + // written into `error_message`, and contradicted by the `status` column beside it -- and + // downstream, an absent Transactions row is indistinguishable from one that does not exist. + const txStatus = missingTx > 0 ? "incomplete" : status; + const assurance = gradeCapture(network, fetch, confirmationResult); + + // The rows were written with the conservative provisional grade C, because a grade is a + // property of the whole capture and is not known while the rows are streaming. Correct them + // now that the range is settled. Without this the ledger and the rows disagree, which a live + // run produced: a capture recorded as grade A over rows that every one of them said were C. + if (assurance !== "C" && writtenWindow !== null) { + try { + await setCaptureAssurance(RAW_LOGS_TABLE, captureId, assurance, writtenWindow); + await setCaptureAssurance(TRANSACTIONS_TABLE, captureId, assurance, writtenWindow); + } catch (e: any) { + // Leaving C in place under-claims, which is the only safe direction for this to be wrong. + log.error( + `Could not raise the assurance grade on the rows of ${captureId} to ${assurance}: ${e.message}. ` + + `They keep the conservative grade C while the coverage row carries ${assurance}.` + ); + } + } - await flush(); + const notes = [...fetch.errors, ...unconfirmed]; + if (reorgSuspects > 0) { + notes.push( + `REORG_APPLIED: ${reorgSuspects} row(s) changed block_hash under an existing key and were ` + + `rewritten whole, including block_number, block_hash, block_timestamp and provenance` + ); + } + if (missingTx > 0) { + notes.push( + `MISSING_TRANSACTIONS: ${missingTx} transaction(s) were pointed at by a captured log and ` + + `were not returned by the reader, so no Transactions row exists for them` + ); + } + for (const g of rollbackHeld) { + notes.push( + `ROLLBACK_GUARD: the reader holds blocks from ${g.firstBlockNumber} in memory, which is at ` + + `or below this capture's start ${fromBlock}, so part of this range is still ` + + `rollback-eligible at the source. The capture is recorded 'rollback_eligible' rather than ` + + `complete, so the resume frontier stays at or below ${fromBlock} and this range is read ` + + `again once it settles` + ); + } + if (evidenceGrades.length > 0) { + notes.push(`EVIDENCE_GRADES: ${[...new Set(evidenceGrades)].sort().join(",")}`); + } + + const row = baseCoverage(target, captureId, fromBlock, toBlock, startedAt); + row.status = status; + row.chunksPlanned = fetch.chunksPlanned; + row.chunksOk = fetch.chunksOk; + row.skippedRanges = JSON.stringify(fetch.skipped); + row.rowsMerged = distinctOffered; + row.rowsInserted = inserted; + row.rowsUpdated = updated; + row.logsSeen = fetch.logsSeen; + row.sourceKind = fetch.sourceKind; + row.sourceId = fetch.sourceId; + row.confirmingSourceKind = confirmingSourceId ? "rpc" : null; + row.confirmingSourceId = confirmingSourceId; + row.confirmationResult = confirmationResult; + row.assurance = assurance; + row.headAtCapture = fetch.headAtCapture; + row.completedAt = nowIso(); + row.errorMessage = notes.join(" | ").slice(0, 4000); + await recordCoverage(row); + + // The transactions written by this capture get their own coverage row, because they are a + // different grain into a different table and an empty Transactions table for a range has to + // be interpretable on its own terms. + const txRow = baseCoverage(target, `${captureId}:tx`, fromBlock, toBlock, startedAt); + txRow.targetTable = TRANSACTIONS_TABLE; + txRow.tableId = TRANSACTIONS_TABLE; + txRow.status = txStatus; + txRow.chunksPlanned = fetch.chunksPlanned; + txRow.chunksOk = fetch.chunksOk; + txRow.skippedRanges = JSON.stringify(fetch.skipped); + txRow.rowsInserted = txInserted; + txRow.rowsUpdated = txUpdated; + txRow.rowsMerged = txInserted + txUpdated; + txRow.logsSeen = fetch.logsSeen; + txRow.sourceKind = fetch.sourceKind; + txRow.sourceId = fetch.sourceId; + txRow.confirmationResult = confirmationResult; + txRow.assurance = assurance; + txRow.headAtCapture = fetch.headAtCapture; + txRow.completedAt = nowIso(); + txRow.errorMessage = missingTx > 0 + ? `MISSING_TRANSACTIONS: ${missingTx} transaction(s) pointed at by a captured log were not ` + + `returned by the reader, so this range is NOT complete for the transaction grain` + : ""; + await recordCoverage(txRow); + + if (status !== "complete") { + throw new IncompleteFetchError( + `${label} ${fromBlock}..${toBlock} is ${status}: ${fetch.skipped.length} skipped chunk(s), ` + + `${unconfirmed.length} uncorroborated empty range(s), ${rollbackHeld.length} rollback ` + + `guard(s) holding blocks at or below the start. The coverage row records the gap, so the ` + + `next run resumes at the edge of the last clean capture rather than above it.` + ); + } + + if (txStatus !== "complete") { + log.error( + `${label} ${fromBlock}..${toBlock}: the RawLogs range is complete and the Transactions ` + + `range is ${txStatus}. ${missingTx} transaction(s) are missing.`, + { capture: captureId } + ); + } + + log.info( + `Done ${label}: ${inserted} log(s) inserted, ${updated} updated, ${txInserted} transaction(s) ` + + `inserted, ${fetch.chunksOk}/${fetch.chunksPlanned} chunks, assurance ${assurance}`, + { capture: captureId } + ); + + // One outcome per grain, matching the two coverage rows just written. Returning only the + // first is what let a complete log range speak for an incomplete transaction range. + return [ + unit( + "completed", RAW_LOGS_TABLE, + `${label} ${fromBlock}..${toBlock} complete at assurance ${assurance}`, + { + chainId: target.chainId, address: target.address, fromBlock, toBlock, + rows: inserted + updated, + }, + ), + unit( + txStatus === "complete" ? "completed" : "incomplete", TRANSACTIONS_TABLE, + txStatus === "complete" + ? `${label} ${fromBlock}..${toBlock}: ${txInserted + txUpdated} transaction(s) merged` + : `${label} ${fromBlock}..${toBlock}: ${missingTx} transaction(s) pointed at by a captured ` + + `log were not returned by the reader, so the transaction grain is incomplete`, + { + chainId: target.chainId, address: target.address, fromBlock, toBlock, + rows: txInserted + txUpdated, + }, + ), + ]; + }, + }; +} + +type CaptureSink = ReturnType; + +/** + * Read one block range ONCE for every target in it, and give each target its own verdict. + * + * THIS IS THE H2 FIX. Every reader in this codebase has always taken a LIST of addresses; the + * pipeline only ever handed it one, inside a loop, so a chain with N contracts issued N chunk + * streams over overlapping ranges. The cost model the project is budgeted against assumes one + * batched address query per chain range, and the gap between the two was measured in tens of + * times, not percentages. + * + * THE RANGE IS THE UNION of the members' ranges, and the projection back onto each member is what + * keeps the coverage ledger honest: a contract created late is not told about blocks below its + * own creation, and a chunk that failed is recorded against exactly the contracts whose declared + * range it overlaps. `batch.ts` owns that projection and is tested on its own, because a + * plausible-looking wrong attribution here is invisible in the warehouse afterwards. + */ +async function captureBatch( + network: NetworkConfig, + sinks: CaptureSink[], + opts: PipelineOpts +): Promise> { + const results = new Map(); + if (sinks.length === 0) return results; + + const span = unionRange(sinks.map((s) => s.member))!; + const addresses = sinks.map((s) => s.member.address); + const chunkRanges: [number, number][] = []; + + log.info( + `${network.name}: one batched read of ${addresses.length} address(es) over ` + + `${span.fromBlock}..${span.toBlock}`, + { mode: opts.mode, reader: readerFor(network).id, addresses: addresses.length } + ); + + let fetch: FetchResult; + try { + fetch = await fetchRange(network, addresses, span.fromBlock, span.toBlock, async (chunk) => { + chunkRanges.push([chunk.fromBlock, chunk.toBlock]); + // Sequentially, never in parallel. Two concurrent MERGEs into one table is finding C1, and + // it is still open, so this loop must not be the thing that starts producing it. + for (const s of sinks) await s.accept(projectChunk(chunk, s.member)); + }); + for (const s of sinks) await s.flush(); } catch (e: any) { - const failed = baseCoverage(target, captureId, fromBlock, toBlock, startedAt); - failed.status = "incomplete"; - failed.rowsInserted = inserted; - failed.rowsUpdated = updated; - failed.rowsMerged = distinctOffered; - failed.sourceKind = readerFor(network).kind === "index" ? "index" : "rpc"; - failed.sourceId = readerFor(network).id; - failed.errorMessage = - `CAPTURE_THREW: ${String(e?.message ?? e)}. Any rows already written for this range are ` + - `present without a clean capture, so the resume point stays at or below ${fromBlock}.`.slice(0, 4000); - // A failure to record the failure is worse than the failure, so it is logged rather than - // allowed to replace the original error. - try { await recordCoverage(failed); } catch (e2: any) { - log.error(`Could not record the coverage row for a failed capture: ${e2.message}`, { capture: captureId }); - } + // The batched read failed, so EVERY member of it is incomplete. Recording the failure against + // only the member being written when it threw would leave the others with rows in the table + // and no coverage row saying anybody looked. + for (const s of sinks) await s.recordThrow(e); throw e; } - // ------------------------------------------- every empty chunk is a negative to confirm - const unconfirmed: string[] = []; - let confirmationResult = "unavailable"; - let confirmingSourceId: string | null = null; - if (CONFIG.CONFIRM_EMPTY_CHUNKS && fetch.emptyChunks.length > 0) { - log.info(`Confirming ${fetch.emptyChunks.length} empty chunk(s) against independent endpoints`, { - capture: captureId, - }); - let anyConfirmed = false; - for (const [lo, hi] of fetch.emptyChunks) { - const c = await confirmEmptyRange(network, [target.address], lo, hi); - confirmingSourceId = c.probe.answeredFully[0] ?? null; - if (!c.confirmed) { - unconfirmed.push(`${lo}..${hi}: ${c.reason}`); - log.error(`UNCONFIRMED EMPTY RANGE ${lo}..${hi}`, { - capture: captureId, reason: c.reason, probeErrors: c.probe.errors.slice(0, 5), - }); - } else anyConfirmed = true; - } - confirmationResult = unconfirmed.length > 0 - ? (unconfirmed.some((u) => u.includes("REFUTED")) ? "refuted_emptiness" : "disagreed") - : anyConfirmed ? "identical" : "unavailable"; + // A chunk range the reader never reported is still planned work. `skipped` carries the ranges + // that failed before a chunk existed, so they are added here or a member could see a skip that + // overlaps no chunk it knows about and compute chunksOk above chunksPlanned. + for (const [a, b] of fetch.skipped) { + if (!chunkRanges.some(([x, y]) => x === a && y === b)) chunkRanges.push([a, b]); } - const status = !fetch.complete ? "incomplete" : unconfirmed.length > 0 ? "unconfirmed_empty" : "complete"; - const assurance = gradeCapture(network, fetch, confirmationResult); - - // The rows were written with the conservative provisional grade C, because a grade is a - // property of the whole capture and is not known while the rows are streaming. Correct them now - // that the range is settled. Without this the ledger and the rows disagree, which a live run - // produced: a capture recorded as grade A over rows that every one of them said were C. - if (assurance !== "C" && writtenWindow !== null) { + for (const s of sinks) { + const mine = projectFetchResult(fetch, s.member, chunkRanges, s.tally()); try { - await setCaptureAssurance(RAW_LOGS_TABLE, captureId, assurance, writtenWindow); - await setCaptureAssurance(TRANSACTIONS_TABLE, captureId, assurance, writtenWindow); + results.set(s.member.address, await s.finish(mine)); } catch (e: any) { - // Leaving C in place under-claims, which is the only safe direction for this to be wrong. - log.error( - `Could not raise the assurance grade on the rows of ${captureId} to ${assurance}: ${e.message}. ` + - `They keep the conservative grade C while the coverage row carries ${assurance}.` - ); + results.set(s.member.address, [unit( + e instanceof IncompleteFetchError ? "incomplete" : "failed", + RAW_LOGS_TABLE, `${s.label}: ${e.message}`, + { chainId: network.chainId, address: s.member.address }, + )]); } } + return results; +} - const notes = [...fetch.errors, ...unconfirmed]; - if (reorgSuspects > 0) { - notes.push( - `REORG_APPLIED: ${reorgSuspects} row(s) changed block_hash under an existing key and were ` + - `rewritten whole, including block_number, block_hash, block_timestamp and provenance` - ); - } - if (missingTx > 0) { - notes.push( - `MISSING_TRANSACTIONS: ${missingTx} transaction(s) were pointed at by a captured log and ` + - `were not returned by the reader, so no Transactions row exists for them` - ); - } - for (const g of fetch.rollbackGuards) { - // The reader's own reorganisation detector. It was dropped entirely by the previous worker, so - // the disappearing-log shape was undetectable: the client offers this and nothing read it. - if (g.firstBlockNumber <= fromBlock) { - notes.push( - `ROLLBACK_GUARD: the reader holds blocks from ${g.firstBlockNumber} in memory, which is at ` + - `or below this capture's start, so part of this range is still rollback-eligible at the source` - ); +/** + * Ingest ONE contract over its own range. Throws on an incomplete fetch rather than recording a + * success, because a partial range recorded as a success is precisely how a gap becomes permanent. + * + * Exported because repair drives the SAME code path over a named range. The previous repair + * carried its own copy of the fetch, decode and write loop, about sixty-five lines duplicated + * almost verbatim, so a fix to one path silently left the other behind. This is a batch of one, + * so it is not a second implementation either. + */ +export async function processTarget(target: CaptureTarget, opts: PipelineOpts): Promise { + const prepared = await prepareTarget(target, opts); + if ("outcomes" in prepared) return prepared.outcomes; + + const results = await captureBatch(target.network, [prepared.sink], opts); + const mine = results.get(prepared.sink.member.address) ?? []; + // A batch of one that produced an incomplete outcome has to throw, because every existing + // caller of this function reads a throw as "this target did not finish". `captureBatch` catches + // per member so one member cannot abort the others; here there is only one, so the catch is + // rethrown rather than swallowed into a returned outcome. + const bad = mine.find((o) => o.kind === "incomplete" || o.kind === "failed"); + if (bad && mine.length === 1) throw new IncompleteFetchError(bad.detail); + return mine; +} + +/** + * Ingest every target on one chain with ONE batched read per chain, which is finding H2. + * + * Targets that resolve to the same reader are read together; a target the budget declines never + * reaches the read and returns its refusal outcomes directly. + */ +async function captureChain( + network: NetworkConfig, + targets: CaptureTarget[], + opts: PipelineOpts +): Promise { + const outcomes: UnitOutcome[] = []; + const sinks: CaptureSink[] = []; + + for (const target of targets) { + try { + const prepared = await prepareTarget(target, opts); + if ("outcomes" in prepared) outcomes.push(...prepared.outcomes); + else sinks.push(prepared.sink); + } catch (e: any) { + log.error(`Failed to prepare ${target.contractName} ${target.address} on ${network.name}: ${e.message}`); + outcomes.push(unit( + "failed", RAW_LOGS_TABLE, + `${target.contractName} ${target.address} on ${network.name}: ${e.message}`, + { chainId: target.chainId, address: target.address }, + )); } } - const row = baseCoverage(target, captureId, fromBlock, toBlock, startedAt); - row.status = status; - row.chunksPlanned = fetch.chunksPlanned; - row.chunksOk = fetch.chunksOk; - row.skippedRanges = JSON.stringify(fetch.skipped); - row.rowsMerged = distinctOffered; - row.rowsInserted = inserted; - row.rowsUpdated = updated; - row.logsSeen = fetch.logsSeen; - row.sourceKind = fetch.sourceKind; - row.sourceId = fetch.sourceId; - row.confirmingSourceKind = confirmingSourceId ? "rpc" : null; - row.confirmingSourceId = confirmingSourceId; - row.confirmationResult = confirmationResult; - row.assurance = assurance; - row.headAtCapture = fetch.headAtCapture; - row.completedAt = new Date().toISOString(); - row.errorMessage = notes.join(" | ").slice(0, 4000); - await recordCoverage(row); - - // The transactions written by this capture get their own coverage row, because they are a - // different grain into a different table and an empty Transactions table for a range has to be - // interpretable on its own terms. - const txRow = baseCoverage(target, `${captureId}:tx`, fromBlock, toBlock, startedAt); - txRow.targetTable = TRANSACTIONS_TABLE; - txRow.tableId = TRANSACTIONS_TABLE; - txRow.status = status; - txRow.chunksPlanned = fetch.chunksPlanned; - txRow.chunksOk = fetch.chunksOk; - txRow.skippedRanges = JSON.stringify(fetch.skipped); - txRow.rowsInserted = txInserted; - txRow.rowsUpdated = txUpdated; - txRow.rowsMerged = txInserted + txUpdated; - txRow.logsSeen = fetch.logsSeen; - txRow.sourceKind = fetch.sourceKind; - txRow.sourceId = fetch.sourceId; - txRow.confirmationResult = confirmationResult; - txRow.assurance = assurance; - txRow.headAtCapture = fetch.headAtCapture; - txRow.completedAt = new Date().toISOString(); - txRow.errorMessage = missingTx > 0 ? `MISSING_TRANSACTIONS: ${missingTx}` : ""; - await recordCoverage(txRow); - - if (status !== "complete") { - throw new IncompleteFetchError( - `${label} ${fromBlock}..${toBlock} is ${status}: ${fetch.skipped.length} skipped chunk(s), ` + - `${unconfirmed.length} unconfirmed empty range(s). The coverage row records the gap, so the ` + - `next run resumes at the edge of the last clean capture rather than above it.` - ); - } + if (sinks.length === 0) return outcomes; - log.info( - `Done ${label}: ${inserted} log(s) inserted, ${updated} updated, ${txInserted} transaction(s) ` + - `inserted, ${fetch.chunksOk}/${fetch.chunksPlanned} chunks, assurance ${assurance}`, - { capture: captureId } - ); - return inserted + updated; + try { + for (const list of (await captureBatch(network, sinks, opts)).values()) outcomes.push(...list); + } catch (e: any) { + // The batched read itself threw, so no member got a verdict. Every one of them has had its + // failure recorded by `recordThrow`; this turns that into an outcome per member so the run + // record and the exit code see the same number of failures the ledger does. + log.error(`Batched read failed on ${network.name}: ${e.message}`, { targets: sinks.length }); + for (const s of sinks) { + outcomes.push(unit( + e instanceof IncompleteFetchError ? "incomplete" : "failed", + RAW_LOGS_TABLE, `${s.label}: ${e.message}`, + { chainId: network.chainId, address: s.member.address }, + )); + } + } + return outcomes; } /** Alert when a chain's newest captured block is older than the threshold. */ @@ -468,6 +801,48 @@ async function checkFreshness(networks: NetworkConfig[]): Promise { } } +/** + * Record that a run declined to start, rather than returning in silence. + * + * The global guard's receipt in the readiness audit is that a bare `daily` planned 142 targets, + * logged REFUSED, and left NOTHING behind: no coverage row, no run row with a real planned count, + * exit 0. So the refusal is now a parent row per selected chain, with no contract address and no + * block range, because a run-level refusal covers no range and must not pretend to. + * + * One row per chain rather than one per target: 142 targets would be 284 rows announcing a single + * decision, and plan task 6 explicitly allows one parent refusal whose target set names both + * grains. `PARENT_GRAIN` is that target set. + */ +async function recordGlobalRefusal( + networks: NetworkConfig[], + reason: string, + plannedTargets: number, +): Promise { + const startedAt = nowIso(); + for (const network of networks) { + await recordCoverage({ + captureId: `${RUN_ID}:${network.chainId}:refused_budget`, + runId: RUN_ID, + chainId: network.chainId, network: network.name, + contractAddress: null, + targetTable: PARENT_GRAIN, tableId: PARENT_GRAIN, + fromBlock: 0, toBlock: 0, + status: "refused_budget", + chunksPlanned: 0, chunksOk: 0, skippedRanges: "[]", + rowsMerged: 0, rowsInserted: 0, rowsUpdated: 0, logsSeen: 0, + sourceKind: "unknown", sourceId: "none", + confirmingSourceKind: null, confirmingSourceId: null, + confirmationResult: "unavailable", + assurance: "C", + headAtCapture: null, missRateCalibrated: null, passesRun: null, gainSeries: null, + startedAt, completedAt: nowIso(), + errorMessage: + `RUN_REFUSED (${plannedTargets} target(s) planned across ${networks.length} chain(s)): ${reason}` + .slice(0, 4000), + }); + } +} + /** * Main pipeline entry. Every selected chain, every contract the registry lists on it. * @@ -475,69 +850,136 @@ async function checkFreshness(networks: NetworkConfig[]): Promise { * "adding the 147th contract needs no code change" true rather than aspirational. The previous * configuration hard coded two addresses, and as a direct consequence had an entire chain * commented out with nothing to notice it. + * + * EVERY EXIT FROM THIS FUNCTION NOW CARRIES A SUMMARY. It used to have three early returns that + * each produced `{ succeeded: 0, failed: 0 }`: no chain matched, the run was globally refused, + * and the implicit one where every chain had zero targets. All three read as a clean run to the + * exit mapping. They are now distinct typed outcomes and every one of them is nonzero. */ export async function runPipeline(opts: PipelineOpts): Promise { await ensureInfraTables(); + const summary = new RunSummary(); const networks = selectedNetworks(opts.chains); if (networks.length === 0) { - log.error(`No chain matched filter: ${opts.chains?.join(", ")}`); - return { succeeded: 0, failed: 0, totalRows: 0 }; + const asked = opts.chains?.join(", ") ?? "(none)"; + log.error(`No chain matched filter: ${asked}`); + summary.add(unit( + "unsupported", PARENT_GRAIN, + `no configured chain matched --chains=${asked}; known chains are ` + + `${Object.values(NETWORKS).map((n) => n.name).join(", ")}`, + )); + return resultOf(summary, 0); + } + + // A chain outside the frozen release scope is REPORTED and skipped, never captured and never + // silently dropped. `targetsFor` refuses it unconditionally as a backstop; this is what turns + // that refusal into an outcome the run record carries, the same shape `plan` mode uses. Without + // it a bare `daily` would abort on the first out-of-scope chain in the configuration and do + // none of the work it could have done. + const { usable: inScope, refused: outOfScope } = partitionByReleaseScope(networks); + for (const r of outOfScope) { + log.error(`UNSUPPORTED: ${r.detail}`, { chainId: r.network.chainId }); + summary.add(unit("unsupported", RAW_LOGS_TABLE, r.detail, { chainId: r.network.chainId })); } // The run size budget, checked before anything is written, including a capability gap row. A // refusal halfway through leaves a warehouse partly covered by a run whose own record says it // failed, which is harder to reason about afterwards than either outcome on its own. - const plannedTargets = networks + const plannedTargets = inScope .filter((n) => n.ingestEnabled && readerFor(n).kind !== "none") .reduce((sum, n) => sum + targetsFor(n, { addresses: opts.addresses }).length, 0); + + // Declared BEFORE the guard runs, because plan task 4 requires the persisted run record to + // carry the REAL planned count of a refused run and that number does not exist afterwards. + summary.plan(RAW_LOGS_TABLE, plannedTargets); + const runSize = checkRunSize(plannedTargets, opts); if (!runSize.allowed) { log.error(`REFUSED: ${runSize.reason}`, { plannedContracts: runSize.requested, limit: runSize.limit, - chains: networks.map((n) => n.name).join(","), + chains: inScope.map((n) => n.name).join(","), }); - return { succeeded: 0, failed: 0, totalRows: 0 }; + await recordGlobalRefusal(inScope, runSize.reason ?? "", plannedTargets); + // One refused unit per planned target. The run declined all of them, and a count of 1 would + // under-report the decision by a factor of the whole registry. + for (const network of inScope) { + for (const target of targetsFor(network, { addresses: opts.addresses })) { + summary.add(unit( + "refused_budget", RAW_LOGS_TABLE, + `${target.contractName} ${target.address} on ${network.name} was never attempted: ${runSize.reason}`, + { chainId: target.chainId, address: target.address }, + )); + } + } + return resultOf(summary, 0); } - let succeeded = 0; - let failed = 0; let totalRows = 0; - for (const network of networks) { + for (const network of inScope) { const reader = readerFor(network); if (!network.ingestEnabled || reader.kind === "none") { - await recordCapabilityGap( - network, - network.disabledReason ?? reader.reason - ); - failed += 1; + const reason = network.disabledReason ?? reader.reason; + await recordCapabilityGap(network, reason); + summary.add(unit( + "unsupported", RAW_LOGS_TABLE, + `${network.name} has no adequate reader: ${reason}`, + { chainId: network.chainId }, + )); continue; } const targets = targetsFor(network, { addresses: opts.addresses }); if (targets.length === 0) { - log.warn(`No contract in the registry for ${network.name} matched this run's filter`); + // Plan task 7: zero selected targets is not a quiet skip. An `--addresses` filter that + // matches nothing on any chain leaves the run with nothing to do, and a run with nothing to + // do must not report success. + const filter = opts.addresses ? `--addresses=${opts.addresses.join(",")}` : "(no filter)"; + log.warn(`No contract in the registry for ${network.name} matched this run's filter ${filter}`); + summary.add(unit( + "unsupported", RAW_LOGS_TABLE, + `no contract in the control plane for ${network.name} matched ${filter}`, + { chainId: network.chainId }, + )); continue; } log.info(`${network.name}: ${targets.length} contract(s) to capture via ${reader.id}`, { reason: reader.reason, }); - for (const target of targets) { - try { - totalRows += await processTarget(target, opts); - succeeded += 1; - } catch (e: any) { - log.error(`Failed: ${target.contractName} ${target.address} on ${network.name}: ${e.message}`, { - error: e.message, - }); - failed += 1; - } + // ONE batched read for the whole chain, which is finding H2. The loop that used to sit here + // called the reader once per contract over overlapping ranges, while every reader in this + // codebase has always accepted a list of addresses. + for (const outcome of await captureChain(network, targets, opts)) { + summary.add(outcome); + // Only the log grain feeds this counter. It is persisted as `totalRowsMerged` and has + // always meant RawLogs rows; adding the transaction rows to it would change what a + // shipped column means rather than report a new fact. + if (outcome.grain === RAW_LOGS_TABLE) totalRows += outcome.rows; } } if (opts.mode === "daily") await checkFreshness(networks); - return { succeeded, failed, totalRows }; + return resultOf(summary, totalRows); +} + +/** + * The flattened two-number projection the warehouse columns and the CLI have always used. + * + * DERIVED, never incremented in parallel. `succeeded` is completions and nothing else, and + * `failed` is every unit that did not complete and was not a no-op, which is what makes a refused + * or unsupported unit reach the exit code at all. A no-op is neither: it is counted, and the + * "zero completed" arm of the exit mapping is what stops a run of pure no-ops exiting 0. + */ +function resultOf(summary: RunSummary, totalRows: number): PipelineResult { + const t = summary.totals; + return { + succeeded: t.completed, + failed: t.refused + t.unsupported + t.incomplete + t.failed, + totalRows, + summary, + }; } + diff --git a/projects/onchain-analytics/pipeline-v5/src/plan.ts b/projects/onchain-analytics/pipeline-v5/src/plan.ts new file mode 100644 index 0000000..a6b1de0 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/src/plan.ts @@ -0,0 +1,291 @@ +/** + * plan.ts -- say exactly what a run would do, without doing any of it. + * + * WHY THIS IS A MODE AND NOT A FLAG. `--dry-run` already exists on `dedup` and `repair`, and it + * means "compute the change and do not apply it", which still reads the warehouse and still costs + * a query. Plan task 9 asks for something stricter: a command that performs NO chain read and NO + * BigQuery write, and returns the exact proposed work units and the budget verdict. That is the + * command you run before an A5-shaped decision, on a laptop, with no credential. + * + * WHAT PURITY COSTS, STATED RATHER THAN HIDDEN. A `daily` unit's start block comes from the + * coverage ledger and its end comes from the chain tip. Neither is knowable without reading + * something, so in plan mode those ranges are UNRESOLVED, and a plan containing an unresolved + * range is reported `incomplete` and exits nonzero. It is not rounded up to a guess and it is not + * quietly reported as complete: the honest answer to "what exactly will this run read" is "I + * cannot tell you without reading the ledger", and a plan that invented a number would be the + * same defect class as a refusal that reports success. + * + * A plan with an explicit `--from` and `--to` is fully resolved and exits 0 when it fits the + * budget, which is the case the plan-before-you-run workflow actually uses. + */ + +import { NETWORKS, RAW_LOGS_TABLE, TRANSACTIONS_TABLE, selectedNetworks } from "./config.js"; +import { RELEASE_SCOPE_FREEZE, type ReleaseScopeFreeze } from "./control-plane/releaseScope.js"; +import { targetsFor } from "./registry.js"; +import { readerFor } from "./reader.js"; +import { checkCaptureSpan, checkRunSize, maxCaptureBlocks, type BudgetVerdict } from "./budget.js"; +import { RunSummary, unit, planExitCode, PARENT_GRAIN, type PlanOutcome } from "./outcome.js"; +import type { PipelineOpts, NetworkConfig } from "./types.js"; + +/** The two grains one capture writes. A refusal or a plan has to speak about both. */ +const CAPTURE_GRAINS = [RAW_LOGS_TABLE, TRANSACTIONS_TABLE] as const; + +export interface PlannedUnit { + readonly chainId: number; + readonly network: string; + readonly address: string; + readonly contractName: string; + readonly grain: string; + /** Null where the bound cannot be known without reading the ledger or the chain. */ + readonly fromBlock: number | null; + readonly toBlock: number | null; + readonly rangeResolved: boolean; + /** Where each bound came from, specifically enough to check. */ + readonly rangeSource: string; + /** The span verdict, present only where the range is resolved enough to judge. */ + readonly spanVerdict: BudgetVerdict | null; +} + +export interface PlanReport { + readonly outcome: PlanOutcome; + readonly exitCode: number; + readonly mode: string; + readonly chains: string[]; + readonly contractsPlanned: number; + readonly unitsPlanned: number; + readonly runSize: BudgetVerdict | null; + readonly units: PlannedUnit[]; + /** Every reason this plan is not `complete`, one sentence each. Empty when it is. */ + readonly refusals: string[]; + readonly summary: RunSummary; +} + +/** + * The chains this command may address at all. + * + * Read from the FROZEN RELEASE SCOPE, never from a list written here. Fuse was dropped from the + * release on 2026-09-28 after the scope was first frozen, and a chain list copied into a second + * file is exactly how a decision like that gets applied in one place and missed in another. The + * freeze module is the single authority; when it changes, this follows with no edit. + */ +export function releaseScopeChains(freeze: ReleaseScopeFreeze = RELEASE_SCOPE_FREEZE): string[] { + return [...freeze.releaseChains]; +} + +/** Configured, and inside the frozen release scope. Both conditions, separately reportable. */ +function scopeVerdict(network: NetworkConfig, freeze: ReleaseScopeFreeze): { inScope: boolean; reason: string } { + if (!freeze.frozen) return { inScope: true, reason: "release scope is not frozen" }; + if (releaseScopeChains(freeze).includes(network.name)) { + return { inScope: true, reason: `in the release scope frozen on ${freeze.decidedOn}` }; + } + return { + inScope: false, + reason: + `${network.name} is configured but is NOT in the release scope frozen on ` + + `${freeze.decidedOn} (${releaseScopeChains(freeze).join(", ")}); see ` + + `${freeze.decisionRecord}`, + }; +} + +/** + * Build the plan. Pure: reads the control-plane seeds and the arguments, nothing else. + * + * No BigQuery client is constructed, no query is issued, no chain tip is fetched and no run row is + * written. A test proves that by running this with every adapter unset. + * + * `freeze` is a parameter with the frozen module as its default, which is the same shape + * `assertReleaseScopeFrozen` uses. It exists so a test can narrow the release scope and watch the + * refusal happen, rather than asserting against whatever the scope happens to say today. + */ +export function buildPlan( + opts: PipelineOpts, + freeze: ReleaseScopeFreeze = RELEASE_SCOPE_FREEZE, +): PlanReport { + const summary = new RunSummary(); + const units: PlannedUnit[] = []; + const refusals: string[] = []; + + const networks = selectedNetworks(opts.chains); + if (networks.length === 0) { + const asked = opts.chains?.join(", ") ?? "(none)"; + const detail = + `no configured chain matched --chains=${asked}; known chains are ` + + `${Object.values(NETWORKS).map((n) => n.name).join(", ")}`; + summary.add(unit("unsupported", PARENT_GRAIN, detail)); + return report("unsupported", opts, [], 0, null, units, [detail], summary); + } + + const usable: NetworkConfig[] = []; + for (const network of networks) { + const scope = scopeVerdict(network, freeze); + if (!scope.inScope) { + refusals.push(scope.reason); + summary.add(unit("unsupported", PARENT_GRAIN, scope.reason, { chainId: network.chainId })); + continue; + } + const reader = readerFor(network); + if (!network.ingestEnabled || reader.kind === "none") { + const detail = `${network.name} has no adequate reader: ${network.disabledReason ?? reader.reason}`; + refusals.push(detail); + summary.add(unit("unsupported", PARENT_GRAIN, detail, { chainId: network.chainId })); + continue; + } + usable.push(network); + } + + const targets = usable.flatMap((n) => + targetsFor(n, { addresses: opts.addresses }).map((t) => ({ network: n, target: t }))); + + if (targets.length === 0) { + const filter = opts.addresses ? `--addresses=${opts.addresses.join(",")}` : "(no address filter)"; + const detail = + `zero capture targets: no contract in the control plane matched ${filter} on ` + + `${usable.map((n) => n.name).join(", ") || "any usable chain"}. Empty work is not success.`; + refusals.push(detail); + summary.add(unit("unsupported", PARENT_GRAIN, detail)); + return report("unsupported", opts, networks.map((n) => n.name), 0, null, units, refusals, summary); + } + + const runSize = checkRunSize(targets.length, opts); + if (!runSize.allowed) { + refusals.push(runSize.reason ?? "the run-size budget refused this plan"); + for (const { network, target } of targets) { + for (const grain of CAPTURE_GRAINS) { + summary.plan(grain, 1); + summary.add(unit( + "refused_budget", grain, + `${target.contractName} ${target.address} on ${network.name}: ${runSize.reason}`, + { chainId: target.chainId, address: target.address }, + )); + } + } + return report( + "refused", opts, networks.map((n) => n.name), targets.length, runSize, units, refusals, summary); + } + + let anyUnresolved = false; + let anyRefusedSpan = false; + + for (const { network, target } of targets) { + const fromBlock = opts.fromBlock ?? (opts.mode === "backfill" ? target.firstBlock : null); + const toBlock = opts.toBlock ?? null; + const rangeResolved = fromBlock !== null && toBlock !== null; + + const rangeSource = [ + opts.fromBlock !== undefined + ? `start from --from=${opts.fromBlock}` + : opts.mode === "backfill" + ? `start from the contract's creation block ${target.firstBlock}` + : "start from the coverage frontier, which plan mode does not read", + opts.toBlock !== undefined + ? `end at --to=${opts.toBlock}` + : `end at the chain tip minus ${network.finality.blocks} finality block(s), which plan mode does not read`, + ].join("; "); + + const spanVerdict = rangeResolved + ? checkCaptureSpan(network, fromBlock!, toBlock!, opts) + : null; + + if (!rangeResolved) anyUnresolved = true; + if (spanVerdict && !spanVerdict.allowed) { + anyRefusedSpan = true; + refusals.push(spanVerdict.reason ?? ""); + } + + for (const grain of CAPTURE_GRAINS) { + summary.plan(grain, 1); + units.push({ + chainId: target.chainId, network: network.name, + address: target.address, contractName: target.contractName, + grain, fromBlock, toBlock, rangeResolved, rangeSource, spanVerdict, + }); + + if (spanVerdict && !spanVerdict.allowed) { + summary.add(unit("refused_budget", grain, spanVerdict.reason ?? "", { + chainId: target.chainId, address: target.address, fromBlock, toBlock, + })); + } else if (!rangeResolved) { + summary.add(unit( + "incomplete", grain, + `${target.contractName} on ${network.name}: ${rangeSource}`, + { chainId: target.chainId, address: target.address, fromBlock, toBlock }, + )); + } else { + summary.add(unit( + "completed", grain, + `${target.contractName} on ${network.name}: blocks ${fromBlock}..${toBlock} is ` + + `${(toBlock! - fromBlock! + 1).toLocaleString()} block(s), inside the limit of ` + + `${maxCaptureBlocks(network, opts).toLocaleString()}`, + { chainId: target.chainId, address: target.address, fromBlock, toBlock }, + )); + } + } + } + + if (anyRefusedSpan) { + return report("refused", opts, networks.map((n) => n.name), targets.length, runSize, units, refusals, summary); + } + if (anyUnresolved) { + refusals.push( + `this plan is INCOMPLETE: at least one unit's block range cannot be resolved without reading ` + + `the coverage ledger or the chain tip, and plan mode does neither. Supply --from and --to for ` + + `an exact plan.` + ); + return report("incomplete", opts, networks.map((n) => n.name), targets.length, runSize, units, refusals, summary); + } + return report("complete", opts, networks.map((n) => n.name), targets.length, runSize, units, refusals, summary); +} + +function report( + outcome: PlanOutcome, + opts: PipelineOpts, + chains: string[], + contractsPlanned: number, + runSize: BudgetVerdict | null, + units: PlannedUnit[], + refusals: string[], + summary: RunSummary, +): PlanReport { + return { + outcome, + exitCode: planExitCode(outcome), + mode: opts.mode, + chains, + contractsPlanned, + unitsPlanned: summary.totals.planned, + runSize, + units, + refusals, + summary, + }; +} + +/** Human-readable rendering for the console. The JSON body is the machine-readable one. */ +export function renderPlan(plan: PlanReport, freeze: ReleaseScopeFreeze = RELEASE_SCOPE_FREEZE): string { + const lines: string[] = []; + lines.push(`PLAN (${plan.mode}): ${plan.outcome.toUpperCase()}, exit ${plan.exitCode}`); + lines.push( + ` chains selected: ${plan.chains.join(", ") || "(none)"}; release scope is ` + + `${releaseScopeChains(freeze).join(", ")} frozen ${freeze.decidedOn}`); + lines.push(` contracts planned: ${plan.contractsPlanned}; work units planned: ${plan.unitsPlanned}`); + if (plan.runSize) { + lines.push( + ` run-size budget: ${plan.runSize.requested} requested against a limit of ` + + `${plan.runSize.limit}, ${plan.runSize.allowed ? "allowed" : "REFUSED"}`); + } + const t = plan.summary.totals; + lines.push( + ` units: ${t.completed} resolved and inside budget, ${t.incomplete} unresolved, ` + + `${t.refused} refused, ${t.unsupported} unsupported`); + for (const [grain, c] of [...plan.summary.byGrain.entries()].sort()) { + lines.push(` ${grain}: planned ${c.planned}, resolved ${c.completed}, unresolved ${c.incomplete}, refused ${c.refused}`); + } + for (const u of plan.units.slice(0, 40)) { + lines.push( + ` - ${u.network} ${u.contractName} ${u.address} [${u.grain}] ` + + `${u.rangeResolved ? `${u.fromBlock}..${u.toBlock}` : "UNRESOLVED"} (${u.rangeSource})`); + } + if (plan.units.length > 40) lines.push(` ... ${plan.units.length - 40} more unit(s)`); + for (const r of plan.refusals) lines.push(` ! ${r}`); + return lines.join("\n"); +} diff --git a/projects/onchain-analytics/pipeline-v5/src/reader.ts b/projects/onchain-analytics/pipeline-v5/src/reader.ts index ca90e0e..22534d9 100644 --- a/projects/onchain-analytics/pipeline-v5/src/reader.ts +++ b/projects/onchain-analytics/pipeline-v5/src/reader.ts @@ -27,6 +27,7 @@ import { CONFIG } from "./config.js"; import { log } from "./log.js"; +import { getReaderOverride } from "./adapters.js"; import { rpcCall } from "./rpc.js"; import { normaliseChunk } from "./normalise.js"; import { fetchRange as hsFetchRange, getChainTip as hsChainTip, hasHypersync } from "./hypersync.js"; @@ -358,6 +359,10 @@ export function fetchRange( toBlock: number, onChunk: (chunk: ChunkResult) => Promise ): Promise { + // A replaced reader takes precedence. The index path runs in a child process and the RPC path + // needs a live endpoint rotation, so neither can be exercised in a test any other way. + const replacement = getReaderOverride(); + if (replacement) return replacement(network, addresses, fromBlock, toBlock, onChunk) as Promise; if (hasHypersync(network)) return hsFetchRange(network, addresses, fromBlock, toBlock, onChunk); if (network.readers.rpcUrls.length > 0) return rpcFetchRange(network, addresses, fromBlock, toBlock, onChunk); throw new Error(`NO_READER: ${network.name} has neither a HyperSync index nor a JSON-RPC endpoint configured`); @@ -396,7 +401,14 @@ export function gradeCapture( confirmationResult: string ): Assurance { if (!fetch.complete) return "C"; - if (confirmationResult === "refuted_emptiness" || confirmationResult === "disagreed") return "C"; + if ( + confirmationResult === "refuted_emptiness" || + confirmationResult === "disagreed" || + // An empty range only one endpoint could vouch for. It is the ordinary outcome on a chain + // whose second endpoint is intermittent, and it must not reach A on the strength of the + // chunk enumeration alone: the thing left uncorroborated is precisely an absence. + confirmationResult === "uncorroborated" + ) return "C"; if (!network.readers.hasIndependentConfirmingReader) return "C"; // A: two independent sources enumerated this range and returned identical results. if (fetch.enumeratingSources >= 2) return "A"; @@ -405,3 +417,4 @@ export function gradeCapture( if (confirmationResult === "identical") return "B"; return "C"; } + diff --git a/projects/onchain-analytics/pipeline-v5/src/reconcile.ts b/projects/onchain-analytics/pipeline-v5/src/reconcile.ts index 07774f7..eb3d144 100644 --- a/projects/onchain-analytics/pipeline-v5/src/reconcile.ts +++ b/projects/onchain-analytics/pipeline-v5/src/reconcile.ts @@ -22,6 +22,8 @@ import { oraclesFor, selectedNetworks, RAW_LOGS_TABLE } from "./config.js"; import type { OracleConfig } from "./config.js"; +import { releaseScopedNetworks } from "./registry.js"; +import type { ReadOnlyOutcome } from "./outcome.js"; import { log, RUN_ID } from "./log.js"; import { pinBlock, readDays, readPeriodStart, readCurrentDay, readInviteStats, dayOf, @@ -65,6 +67,7 @@ export interface ReconcileResult { interiorDays: number; exactDays: number; days: DayVerdict[]; + /** The warehouse's own first and last covered day, or empty when the caller named the days. */ edgeDays: number[]; oracleErrors: string[]; clean: boolean; @@ -129,18 +132,26 @@ export async function reconcileDaily( const cd = await readCurrentDay(network, oracle.address, block); const currentDay = cd.ok && cd.value !== null ? cd.value : null; - const span = await warehouseDaySpan(oracle.network.chainId, oracle.address, topic0, periodStart); - if (!span) { - log.warn(`${RAW_LOGS_TABLE} holds no ${oracle.eventSignature} rows for ${oracle.address}; nothing to reconcile`); - return null; - } - // Interior days only, unless the caller named days explicitly. The first and last day the // warehouse covers are partial by construction and would show a false gap. + // + // A NAMED DAY RANGE DOES NOT NEED A WAREHOUSE SPAN, and requiring one was C4's shape at this + // level. The span exists to derive a window from stored rows; when the caller supplies the + // window, asking the warehouse to justify it means a contract the warehouse holds nothing for + // can never be checked -- which is precisely the case where the answer matters most, and is + // the live state of Celo in this warehouse today. An empty warehouse is a legitimate side of a + // comparison: the contract says N, we hold 0, and that is a result. let wantedDays: number[]; + let span: { first: number; last: number } | null = null; + if (days && days.length > 0) { wantedDays = [...new Set(days)].sort((a, b) => a - b); } else { + span = await warehouseDaySpan(oracle.network.chainId, oracle.address, topic0, periodStart); + if (!span) { + log.warn(`${RAW_LOGS_TABLE} holds no ${oracle.eventSignature} rows for ${oracle.address} and no days were named, so there is no window to reconcile over`); + return null; + } wantedDays = []; for (let d = span.first + 1; d <= span.last - 1; d++) wantedDays.push(d); } @@ -215,7 +226,7 @@ export async function reconcileDaily( chainId: network.chainId, network: network.name, contractAddress: oracle.address, pinnedBlock: block, firstDay, lastDay, interiorDays: verdicts.length, exactDays: exact, - days: verdicts, edgeDays: [span.first, span.last], + days: verdicts, edgeDays: span ? [span.first, span.last] : [], oracleErrors, clean: verdicts.length > 0 && exact === verdicts.length && oracleErrors.length === 0, }; @@ -328,64 +339,276 @@ export async function reconcileInviteStats(oracle: OracleConfig): Promise ({ + outcome: "nothing_to_check", + chainsSelected: [], + chainsWithNoOracle: [], + oraclesSelected: 0, + checks: [], + comparedUnits: 0, + matchedUnits: 0, + discrepantUnits: 0, + unreadableUnits: 0, + oraclesWithNothingToCompare: 0, + summary: "", +}); + +const nothingCompared = (oracle: OracleConfig, detail: string): OracleCheck => ({ + chainId: oracle.network.chainId, + network: oracle.network.name, + contractAddress: oracle.address, + kind: oracle.kind, + comparedUnits: 0, + matchedUnits: 0, + discrepantUnits: 0, + unreadableUnits: 0, + outcome: "nothing_to_compare", + detail, +}); + +function dailyCheck(oracle: OracleConfig, r: ReconcileResult): OracleCheck { + const unreadable = r.days.filter((d) => d.verdict === "oracle_unreadable").length; + const discrepant = r.days.filter((d) => d.verdict !== "exact" && d.verdict !== "oracle_unreadable").length; + return { + chainId: r.chainId, + network: r.network, + contractAddress: r.contractAddress, + kind: oracle.kind, + comparedUnits: r.interiorDays, + matchedUnits: r.exactDays, + discrepantUnits: discrepant, + unreadableUnits: unreadable, + outcome: r.interiorDays === 0 ? "nothing_to_compare" + : unreadable > 0 ? "unreadable" + : discrepant > 0 ? "discrepant" + : "exact", + detail: + `${r.exactDays}/${r.interiorDays} protocol days exact in ${r.firstDay}..${r.lastDay} ` + + `at block ${r.pinnedBlock}` + + (discrepant > 0 ? `, ${discrepant} discrepant` : "") + + (unreadable > 0 ? `, ${unreadable} the oracle could not be read for` : ""), + }; +} + +function statsCheck(oracle: OracleConfig, r: StatsVerdict): OracleCheck { + // A lifetime counter compared over one block window is ONE comparison, not one per bounty. + // Counting it as `gap` units would let a large gap look like a large amount of evidence. + const unreadable = r.errors.length > 0 ? 1 : 0; + return { + chainId: r.chainId, + network: r.network, + contractAddress: r.contractAddress, + kind: oracle.kind, + comparedUnits: unreadable ? 0 : 1, + matchedUnits: !unreadable && r.clean ? 1 : 0, + discrepantUnits: !unreadable && !r.clean ? 1 : 0, + unreadableUnits: unreadable, + outcome: unreadable ? "unreadable" : r.clean ? "exact" : "discrepant", + detail: + `contract counted ${r.bountyDelta} bounties over blocks ${r.windowStartBlock}..${r.windowEndBlock}, ` + + `warehouse holds ${r.warehouseDistinctBounties} distinct (${r.warehouseBountyRows} stored), gap ${r.gap}`, + }; +} + +/** + * The one place the outcome is decided, from the counts rather than from a flag. + * + * `clean` REQUIRES `comparedUnits > 0`. That single conjunct is finding C4: without it, every + * path that compares nothing falls through to success, and there are three such paths. + */ +function finish(report: VerificationReport): VerificationReport { + for (const c of report.checks) { + report.comparedUnits += c.comparedUnits; + report.matchedUnits += c.matchedUnits; + report.discrepantUnits += c.discrepantUnits; + report.unreadableUnits += c.unreadableUnits; + if (c.outcome === "nothing_to_compare") report.oraclesWithNothingToCompare++; + } + + if (report.comparedUnits === 0) { + report.outcome = "nothing_to_check"; + report.summary = + report.oraclesSelected === 0 + ? `no oracle exists on [${report.chainsSelected.join(", ") || "no chain"}], so nothing was compared` + : `${report.oraclesSelected} oracle(s) selected but nothing was compared`; + } else if (report.unreadableUnits > 0 || report.oraclesWithNothingToCompare > 0) { + // Partial evidence is a finding, never a pass. A day the contract could not be read for is + // an unanswered question, and an oracle that compared nothing is a silent half of the scope. + report.outcome = "finding"; + report.summary = + `${report.matchedUnits}/${report.comparedUnits} compared units matched, ` + + `${report.discrepantUnits} disagreed, ${report.unreadableUnits} could not be read, ` + + `${report.oraclesWithNothingToCompare} oracle(s) compared nothing`; + } else if (report.discrepantUnits > 0) { + report.outcome = "finding"; + report.summary = `${report.matchedUnits}/${report.comparedUnits} compared units matched, ${report.discrepantUnits} disagreed`; + } else { + report.outcome = "clean"; + report.summary = `${report.matchedUnits}/${report.comparedUnits} compared units matched against the contract`; + } + + log.info(`verify: ${report.outcome} -- ${report.summary}`); + return report; +} + +/** + * The verify mode. Returns WHAT WAS COMPARED, not whether it went well. * * TWO CONTRACTS OUT OF 146 PUBLISH A USABLE LEDGER, and that is stated here rather than implied * by silence. This is the only EXTERNAL evidence this warehouse has, and it covers about 1.4 * percent of its surface. Coverage, which covers all of it, is a different question and is * answered by the coverage mode. + * + * C4 WAS THE RETURN TYPE, not a missing check. This function used to return `boolean`, so + * "compared 254 protocol days and every one matched" and "compared nothing at all" arrived at + * the caller as the same value `true`, and the CLI mapped both to exit 0. Three paths reached + * that `true` without comparing anything: a chain with no oracle, a contract the warehouse holds + * no rows for, and a window with no frozen day in it. An `if` on any one of them leaves the other + * two, which is why the fix is the type. Same shape as C2 one layer up. + * + * The rule the type enforces, in one sentence: **a run is clean only when it compared something.** */ -export async function runVerify(opts: PipelineOpts): Promise { - let clean = true; - const oracles = oraclesFor(selectedNetworks(opts.chains)); +export async function runVerify(opts: PipelineOpts): Promise { + const report = emptyReport(); + const selected = releaseScopedNetworks(selectedNetworks(opts.chains)); + report.chainsSelected = selected.map((n) => n.name); + + // DECIDED-4, the scope leak Unit 1 named: this used to read `oraclesFor(selectedNetworks(...))` + // with no release-scope filter. It was inert only while ORACLES held XDC entries alone, and + // this unit adds Celo, which is exactly the change that would have made it bite. + const oracles = oraclesFor(selected); + report.oraclesSelected = oracles.length; + report.chainsWithNoOracle = selected + .filter((n) => !oracles.some((o) => o.network.chainId === n.chainId)) + .map((n) => n.name); if (oracles.length === 0) { - log.warn(`No contract oracle exists on the selected chain(s), so nothing can be checked against the chain here`); - return true; + const named = report.chainsSelected.join(", ") || "none"; + log.warn( + `No contract oracle exists on the selected chain(s) [${named}], so NOTHING was compared ` + + `against the chain. That is not a clean result; it is the absence of a result.` + ); + return finish(report); } for (const oracle of oracles) { const label = `${oracle.address} on ${oracle.network.name}`; - if (oracle.kind === "ubi_daily") { - const r = await reconcileDaily(oracle, opts.days); - if (!r) continue; - const bad = r.days.filter((d) => d.verdict !== "exact"); - log.info( - `${label}: ${r.exactDays}/${r.interiorDays} protocol days reconcile exactly at block ${r.pinnedBlock}` - ); - for (const d of bad.slice(0, 50)) { - log.error( - ` day ${d.day} ${d.verdict}: contract ${d.oracleCount}, warehouse ${d.distinctRows} distinct ` + - `(${d.storedRows} stored), count gap ${d.countGap}, amount gap ${d.amountGapRaw} raw units` + - (d.unreadableRows > 0 ? `, ${d.unreadableRows} row(s) whose amount could not be decoded` : "") - ); - } - if (r.oracleErrors.length > 0) { - log.error(` ${r.oracleErrors.length} day(s) the oracle could not be read, which is not a pass`); - } - log.info(` edge days ${r.edgeDays.join(" and ")} are partial by construction and excluded`); - if (!r.clean) clean = false; + // One chain's endpoints having a bad minute must not erase another chain's result. A throw + // here used to abort the whole command, so a Celo quorum failure would have destroyed a + // completed XDC comparison on the way out. An oracle that could not be read is recorded as + // unreadable, which is a finding rather than a pass, and the loop continues. + try { + await checkOracle(oracle, opts, report); + } catch (e: any) { + log.error(`${label}: could not be read: ${e.message}`); + report.checks.push({ + ...nothingCompared(oracle, `could not be read: ${e.message}`), + unreadableUnits: 1, + outcome: "unreadable", + }); } + } - if (oracle.kind === "invites_stats") { - const r = await reconcileInviteStats(oracle); - if (!r) continue; - log.info( - `${label}: contract counted ${r.bountyDelta} bounties over blocks ` + - `${r.windowStartBlock}..${r.windowEndBlock}, warehouse holds ${r.warehouseDistinctBounties} distinct ` + - `(${r.warehouseBountyRows} stored)` + return finish(report); +} + +/** One oracle's contribution, appended to the report. Throws only on an unreadable chain. */ +async function checkOracle(oracle: OracleConfig, opts: PipelineOpts, report: VerificationReport): Promise { + const label = `${oracle.address} on ${oracle.network.name}`; + + if (oracle.kind === "ubi_daily") { + const r = await reconcileDaily(oracle, opts.days); + if (!r) { + // The warehouse holds no rows for this contract, or the window contains no frozen day. + // Before the type existed this was a `continue` and the run still ended clean, which is + // C4 one layer down and is the live state of Celo in this warehouse today. + report.checks.push(nothingCompared(oracle, "the warehouse holds no rows for this contract, or the window contains no frozen protocol day")); + log.warn(`${label}: nothing could be compared, so this chain contributes no evidence either way`); + return; + } + const bad = r.days.filter((d) => d.verdict !== "exact"); + log.info( + `${label}: ${r.exactDays}/${r.interiorDays} protocol days reconcile exactly at block ${r.pinnedBlock}` + ); + for (const d of bad.slice(0, 50)) { + log.error( + ` day ${d.day} ${d.verdict}: contract ${d.oracleCount}, warehouse ${d.distinctRows} distinct ` + + `(${d.storedRows} stored), count gap ${d.countGap}, amount gap ${d.amountGapRaw} raw units` + + (d.unreadableRows > 0 ? `, ${d.unreadableRows} row(s) whose amount could not be decoded` : "") ); - if (!r.clean) { - log.error(` gap ${r.gap}, phantom rows ${r.warehouseBountyRows - r.warehouseDistinctBounties}`); - for (const e of r.errors) log.error(` ${e}`); - clean = false; - } } + if (r.oracleErrors.length > 0) { + log.error(` ${r.oracleErrors.length} day(s) the oracle could not be read, which is not a pass`); + } + if (r.edgeDays.length === 2) { + log.info(` edge days ${r.edgeDays.join(" and ")} are partial by construction and excluded`); + } + report.checks.push(dailyCheck(oracle, r)); + } - const maxTs = await getMaxBlockTimestamp(RAW_LOGS_TABLE, oracle.network.chainId); - if (maxTs) log.info(` newest block_timestamp on chain ${oracle.network.chainId}: ${maxTs.toISOString()}`); + if (oracle.kind === "invites_stats") { + const r = await reconcileInviteStats(oracle); + if (!r) { + report.checks.push(nothingCompared(oracle, "the warehouse holds no bounty rows for this contract")); + log.warn(`${label}: nothing could be compared, so this chain contributes no evidence either way`); + return; + } + log.info( + `${label}: contract counted ${r.bountyDelta} bounties over blocks ` + + `${r.windowStartBlock}..${r.windowEndBlock}, warehouse holds ${r.warehouseDistinctBounties} distinct ` + + `(${r.warehouseBountyRows} stored)` + ); + if (!r.clean) { + log.error(` gap ${r.gap}, phantom rows ${r.warehouseBountyRows - r.warehouseDistinctBounties}`); + for (const e of r.errors) log.error(` ${e}`); + } + report.checks.push(statsCheck(oracle, r)); } - return clean; + const maxTs = await getMaxBlockTimestamp(RAW_LOGS_TABLE, oracle.network.chainId); + if (maxTs) log.info(` newest block_timestamp on chain ${oracle.network.chainId}: ${maxTs.toISOString()}`); } diff --git a/projects/onchain-analytics/pipeline-v5/src/registry.ts b/projects/onchain-analytics/pipeline-v5/src/registry.ts index f6c13e1..67420fa 100644 --- a/projects/onchain-analytics/pipeline-v5/src/registry.ts +++ b/projects/onchain-analytics/pipeline-v5/src/registry.ts @@ -1,181 +1,231 @@ /** - * registry.ts -- the contract universe, read from the reference seed rather than hard coded. + * registry.ts -- the pipeline's view of the contract universe and the era map. * - * WHY A SEED AND NOT A LIST IN THIS FILE. The L0 v4 contract states the property this buys, in as - * many words: adding the 147th contract requires no schema change, it requires a row in the - * contract_deployments seed. A list of addresses in the pipeline would make that false, because - * ingestion would then need a code change per contract, and the one thing this warehouse cannot - * afford is a log going uncaptured because nobody had added a line for it yet. The previous - * configuration hard coded two addresses and, as a direct consequence, had Celo commented out for - * months without anything noticing. + * WHAT CHANGED AND WHY. This module used to own a hand-rolled CSV scanner. That scanner ended + * with `.filter(r => r.length === header.length)`, so a row with one stray comma VANISHED: no + * error, a smaller contract universe, and an ingestion run that silently covered less than it + * claimed. It also read every numeric field through `Number()`, where `Number("")` is 0 rather + * than NaN, so a blank `era_index` became era 0 -- and `era_index` is what decides which ABI + * decodes a log. Both failures were silent, and silence is the expensive part: `lookupEra` cannot + * fail, so a missing era yields a confident wrong decode rather than an error. * - * WHAT THE SEED SUPPLIES THAT NOTHING ELSE CAN. Two things, and the second is the one that is - * easy to miss: + * Parsing, schema and cross-row validation now live in `./control-plane/`, which rejects the whole + * seed on the first malformed physical row. This file keeps only what the PIPELINE needs from a + * registry it has already been told is sound: capture targets and era lookup. * - * 1. WHICH CONTRACTS EXIST, per chain, with each one's own creation block. R8: an absence claim - * states the range it covers and its lower bound is contract creation unless there is a - * stated reason otherwise. Taking a start block from anywhere else has already cost this - * project real data: a scan from a subgraph's declared start rather than the contract's - * creation missed 570 swaps. - * - * 2. THE ERA MAP. L0-4 requires every row to self-identify its era, because an identical getter - * or an identical event signature can mean different things across an upgrade. 179 eras - * announce with Upgraded(address), 66 with CodeUpdated(bytes32,address), and 115 announce - * NOTHING AT ALL, so a resolver that follows announcements cannot reach a third of them. The - * seed carries valid_from_block and valid_to_block per era, which is a block-range lookup and - * needs no chain read. + * WHY A SEED AND NOT A LIST IN THIS FILE. Adding the 147th contract must require a row in + * `contract_deployments`, not a code change, because the one thing this warehouse cannot afford is + * a log going uncaptured because nobody had added a line for it yet. The previous configuration + * hard coded two addresses and, as a direct consequence, had Celo commented out for months. * * THE FAILURE MODE OF AN ERA MAP, WRITTEN DOWN HERE BECAUSE IT IS THE DANGEROUS ONE. A lookup - * that always returns something cannot fail, so a wrong or missing era yields a CONFIDENT WRONG - * ANSWER rather than an error. `lookupEra` therefore returns null where no era covers the block, - * and the caller writes era_resolution 'unresolved' with a NULL era_index, which is what the L0 - * contract asks for: a row that does not know its era says so, and 'unresolved' is not era 1. + * that always returns something cannot fail. `lookupEra` therefore returns null where no era + * covers the block, and the caller writes era_resolution 'unresolved' with a NULL era_index, which + * is what the L0 contract asks for: a row that does not know its era says so, and 'unresolved' is + * not era 1. */ -import { readFileSync, existsSync } from "fs"; -import { fileURLToPath } from "url"; -import { dirname, join, resolve } from "path"; import { log } from "./log.js"; import type { CaptureTarget, EraMapEntry, NetworkConfig } from "./types.js"; +import { loadChains } from "./control-plane/chains.js"; +import { parseRegistry, validateRegistry, REGISTRY_PATH } from "./control-plane/contractRegistry.js"; +import { ControlPlaneInvalidError } from "./control-plane/index.js"; +import { boundToNullableNumber } from "./control-plane/int64.js"; +import { chainStanding, RELEASE_SCOPE_FREEZE, type ReleaseScopeFreeze } from "./control-plane/releaseScope.js"; -const HERE = dirname(fileURLToPath(import.meta.url)); - -/** - * The seed lives in the dbt project, which is the versioned home of every reference table in this - * warehouse. Resolved relative to this file so it works from source and from a build, and checked - * for existence so a moved seed fails loudly at startup rather than as an empty contract list. - */ -export const REGISTRY_PATH = resolve(join(HERE, "..", "..", "gd_dbt", "seeds", "contract_deployments.csv")); - -/** Minimal RFC 4180 reader. Handles quoted fields and embedded commas, which the seed contains. */ -function parseCsv(text: string): Record[] { - const rows: string[][] = []; - let row: string[] = []; - let field = ""; - let inQuotes = false; - - for (let i = 0; i < text.length; i++) { - const c = text[i]; - if (inQuotes) { - if (c === '"') { - if (text[i + 1] === '"') { field += '"'; i++; } else { inQuotes = false; } - } else field += c; - continue; - } - if (c === '"') { inQuotes = true; continue; } - if (c === ",") { row.push(field); field = ""; continue; } - if (c === "\r") continue; - if (c === "\n") { row.push(field); rows.push(row); row = []; field = ""; continue; } - field += c; - } - if (field.length > 0 || row.length > 0) { row.push(field); rows.push(row); } - - if (rows.length === 0) return []; - const header = rows[0]; - return rows.slice(1) - .filter((r) => r.length === header.length) - .map((r) => Object.fromEntries(header.map((h, i) => [h, r[i]]))); -} +export { REGISTRY_PATH }; export interface Registry { /** One entry per contract era, in block order per contract. */ eras: EraMapEntry[]; - /** One entry per distinct (chain_id, proxy_address). */ - contracts: { chainId: number; address: string; contractName: string; firstBlock: number; isLive: boolean }[]; + /** + * One entry per distinct (chain_id, proxy_address). `firstBlock` is null where the seed declares + * no deployed code at that address, which is a real answer and not a block number. + */ + contracts: { chainId: number; address: string; contractName: string; firstBlock: number | null; isLive: boolean }[]; path: string; rowsRead: number; } let cached: Registry | null = null; +/** + * Load and validate the registry, or throw. + * + * There is no partial result and no warning path. The condition this serves is that one malformed + * byte in a control seed prevents the pipeline from starting, so every failure mode -- a missing + * file, a malformed row, a bad integer lexeme, an overlapping era, a chain id that disagrees with + * its chain name -- raises here rather than quietly producing a smaller universe. + */ export function loadRegistry(path = REGISTRY_PATH): Registry { if (cached && cached.path === path) return cached; - if (!existsSync(path)) { - throw new Error( - `REGISTRY_MISSING: ${path} does not exist. The contract universe is defined by that seed, ` + - `so an ingestion run with no registry would silently cover nothing.` - ); - } + const chains = loadChains(); + const parsed = parseRegistry(path); + const violations = validateRegistry(parsed, chains); + if (violations.length > 0) throw new ControlPlaneInvalidError(violations); - const rows = parseCsv(readFileSync(path, "utf8")); const eras: EraMapEntry[] = []; - const byContract = new Map(); - - for (const r of rows) { - const chainId = Number(r.chain_id); - const address = String(r.proxy_address ?? "").toLowerCase(); - if (!Number.isFinite(chainId) || !address.startsWith("0x")) continue; - - const validFrom = Number(r.valid_from_block); - const validTo = r.valid_to_block === "" || r.valid_to_block === undefined ? null : Number(r.valid_to_block); - eras.push({ - chainId, - proxyAddress: address, - eraIndex: Number(r.era_index), - implementationAddress: r.implementation_address ? String(r.implementation_address).toLowerCase() : null, - validFromBlock: Number.isFinite(validFrom) ? validFrom : 0, - validToBlock: validTo !== null && Number.isFinite(validTo) ? validTo : null, - }); - - const key = `${chainId}|${address}`; - const creation = Number(r.creation_block); + const byContract = new Map(); + + for (const r of parsed.rows) { + if (!r.noCodeDeployed) { + eras.push({ + chainId: r.chainId, + proxyAddress: r.proxyAddress, + eraIndex: r.eraIndex, + implementationAddress: r.implementationAddress, + validFromBlock: boundToNullableNumber(r.validFrom!)!, + // Open ended becomes null, never a large number: null propagates as "still in force", + // while a number propagates as a block that exists and can be compared against. + validToBlock: boundToNullableNumber(r.validTo!), + }); + } + + const key = `${r.chainId}|${r.proxyAddress}`; const existing = byContract.get(key); - // The contract's own creation block, taken as the minimum across its eras so that a seed row - // with a missing creation_block cannot raise the floor above a real one. - const first = Number.isFinite(creation) ? creation : (Number.isFinite(validFrom) ? validFrom : 0); if (!existing) { byContract.set(key, { - chainId, address, contractName: String(r.contract_name ?? "unknown"), - firstBlock: first, isLive: String(r.is_live).toLowerCase() === "true", + chainId: r.chainId, address: r.proxyAddress, contractName: r.contractName, + firstBlock: r.creationBlock, isLive: r.isLive, }); } else { - if (first > 0 && (existing.firstBlock === 0 || first < existing.firstBlock)) existing.firstBlock = first; - if (String(r.is_live).toLowerCase() === "true") existing.isLive = true; + if (r.creationBlock !== null && (existing.firstBlock === null || r.creationBlock < existing.firstBlock)) { + existing.firstBlock = r.creationBlock; + } + if (r.isLive) existing.isLive = true; } } eras.sort((a, b) => a.chainId - b.chainId || a.proxyAddress.localeCompare(b.proxyAddress) || a.validFromBlock - b.validFromBlock); - cached = { eras, contracts: [...byContract.values()], path, rowsRead: rows.length }; + cached = { eras, contracts: [...byContract.values()], path, rowsRead: parsed.rows.length }; log.info( - `Registry loaded: ${cached.contracts.length} contracts, ${cached.eras.length} eras, from ${rows.length} seed rows`, - { path } + `Registry loaded: ${cached.contracts.length} contracts, ${cached.eras.length} eras, from ${parsed.rows.length} seed rows`, + { path, recordDelimiter: parsed.csv.recordDelimiter, boundaryColumns: parsed.hasBoundaryColumns } ); return cached; } +/** Test seam. The cache is keyed on path, so a fixture cannot silently reuse a real load. */ +export function clearRegistryCache(): void { + cached = null; +} + +export class ChainOutOfReleaseScopeError extends Error { + constructor(readonly chain: string, message: string) { + super(message); + this.name = "ChainOutOfReleaseScopeError"; + } +} + +/** Why one chain may not be acted on, in the words a command can print or persist. */ +export interface RefusedChain { + readonly network: NetworkConfig; + readonly detail: string; +} + +function outOfScopeDetail(network: NetworkConfig, freeze: ReleaseScopeFreeze): string { + const drop = freeze.chainsDropped.find((c) => c.chain === network.name); + const why = drop + ? `was dropped from the release on ${drop.droppedOn}` + : `is NOT in the release scope frozen on ${freeze.decidedOn} and is not recorded as dropped either, so nobody has decided about it`; + return ( + `${network.name} is configured but ${why}; release scope is ` + + `${freeze.releaseChains.join(", ")}; see ${freeze.decisionRecord}` + ); +} + +/** + * Split selected networks into the ones the release covers and the ones it refuses. + * + * Every command that acts per chain runs its network list through here first, so a dropped chain + * is skipped with a stated reason instead of either being captured or aborting the whole run. + * `targetsFor` refuses the same chain unconditionally, which is the backstop: this function makes + * the refusal reportable, it does not make it optional. + */ +export function partitionByReleaseScope( + networks: readonly NetworkConfig[], + freeze: ReleaseScopeFreeze = RELEASE_SCOPE_FREEZE, +): { usable: NetworkConfig[]; refused: RefusedChain[] } { + if (!freeze.frozen) return { usable: [...networks], refused: [] }; + const usable: NetworkConfig[] = []; + const refused: RefusedChain[] = []; + for (const network of networks) { + if (chainStanding(network.name, freeze) === "in_release") usable.push(network); + else refused.push({ network, detail: outOfScopeDetail(network, freeze) }); + } + return { usable, refused }; +} + +/** + * The networks a per-chain command may act on, with each refusal logged exactly once. + * + * For commands that report through the log rather than through a run summary. `runPipeline` uses + * `partitionByReleaseScope` directly because its refusals have to become typed outcomes. + */ +export function releaseScopedNetworks( + networks: readonly NetworkConfig[], + freeze: ReleaseScopeFreeze = RELEASE_SCOPE_FREEZE, +): NetworkConfig[] { + const { usable, refused } = partitionByReleaseScope(networks, freeze); + for (const r of refused) log.warn(`Skipping ${r.network.name}: ${r.detail}`, { chainId: r.network.chainId }); + return usable; +} + /** * Capture targets for one chain, in address order. * - * EXCLUDES a contract whose creation block could not be resolved from the seed, which this - * registry represents as firstBlock 0. Six seed rows carry an empty `creation_block`, all of them - * addresses A1 established have no code on that chain, and `Number("")` is 0 rather than NaN, so - * the fallback to `valid_from_block` never fires for them and 0 survives. Handing those to the - * pipeline asks it to scan from genesis to head for an address that has never held code, on four - * chains. Resuming from block 0 is not a conservative default here, it is a guess wearing one. + * REFUSES a chain outside the frozen release scope, and this is the enforcement point for it on + * the path that writes. Before this check the scope decision bound `plan` mode and the tests and + * bound nothing on capture: `loadControlPlane`, which is what calls `assertReleaseScopeFrozen`, + * has no caller in this package, and `loadRegistry` deliberately does not perform the + * frozen-scope checks. Every command that captures, repairs or calibrates reaches a chain's + * contracts through here, so one refusal covers all of them. * - * Note the sentinel is only safe because no contract in this registry is genesis allocated. If one - * ever is, firstBlock has to become nullable rather than overloading 0, and this comment is the - * warning that the change is not local. + * Thrown rather than returned empty. An empty target list is indistinguishable from "this chain + * has no contracts yet", and a run that silently covers nothing while exiting 0 is the exact + * failure this pipeline has already paid for once. Callers that need to carry on with the chains + * they CAN do filter first, through `partitionByReleaseScope`. + * + * `freeze` is a parameter with the frozen module as its default, matching `buildPlan` and + * `assertReleaseScopeFrozen`, so a test can narrow the scope and watch the refusal instead of + * asserting against whatever the scope happens to say today. + * + * EXCLUDES a contract the seed declares has no deployed code. Those rows carry an empty + * `creation_block`, which this module now represents as null rather than 0. The distinction is the + * whole point: handing a 0 to the pipeline asks it to scan genesis to head for an address that has + * never held code, and "resume from block 0" is a guess wearing the costume of a conservative + * default. * * It does NOT filter on isLive. A contract that was live and has since been retired still has * history worth ingesting, and dropping it would lose exactly the data L0 exists to hold. */ -export function targetsFor(network: NetworkConfig, opts: { addresses?: string[] } = {}): CaptureTarget[] { +export function targetsFor( + network: NetworkConfig, + opts: { addresses?: string[] } = {}, + freeze: ReleaseScopeFreeze = RELEASE_SCOPE_FREEZE, +): CaptureTarget[] { + if (freeze.frozen && chainStanding(network.name, freeze) !== "in_release") { + throw new ChainOutOfReleaseScopeError( + network.name, + `${network.name} cannot be captured: ${outOfScopeDetail(network, freeze)}`, + ); + } + const reg = loadRegistry(); const wanted = opts.addresses ? new Set(opts.addresses.map((a) => a.toLowerCase())) : null; const onChain = reg.contracts.filter((c) => c.chainId === network.chainId); - const unresolved = onChain.filter((c) => c.firstBlock === 0); + const unresolved = onChain.filter((c) => c.firstBlock === null); if (unresolved.length > 0) { log.warn( - `${network.name}: ${unresolved.length} contract(s) excluded, no creation block in the seed`, + `${network.name}: ${unresolved.length} contract(s) excluded, the seed declares no deployed code there`, { contracts: unresolved.map((c) => `${c.contractName} ${c.address}`).join(", ") } ); } return onChain - .filter((c) => c.firstBlock > 0) + .filter((c): c is typeof c & { firstBlock: number } => c.firstBlock !== null) .filter((c) => (wanted ? wanted.has(c.address) : true)) .sort((a, b) => a.address.localeCompare(b.address)) .map((c) => ({ diff --git a/projects/onchain-analytics/pipeline-v5/src/repair.ts b/projects/onchain-analytics/pipeline-v5/src/repair.ts index 3062860..5f61b5d 100644 --- a/projects/onchain-analytics/pipeline-v5/src/repair.ts +++ b/projects/onchain-analytics/pipeline-v5/src/repair.ts @@ -35,8 +35,9 @@ import { selectedNetworks, RAW_LOGS_TABLE, TRANSACTIONS_TABLE, oraclesFor, networkByChainId } from "./config.js"; import { log } from "./log.js"; import { dedupTable } from "./bq.js"; -import { targetsFor } from "./registry.js"; -import { loadCoverage, openGaps } from "./coverage.js"; +import { targetsFor, releaseScopedNetworks } from "./registry.js"; +import { loadCoverage, openGaps, loadDecodeCoverage } from "./coverage.js"; +import { loadControlPlane } from "./control-plane/index.js"; import { processTarget } from "./pipeline.js"; import { reconcileDaily } from "./reconcile.js"; import type { PipelineOpts } from "./types.js"; @@ -45,7 +46,7 @@ import type { PipelineOpts } from "./types.js"; export async function runDedup(opts: PipelineOpts): Promise { let clean = true; - for (const network of selectedNetworks(opts.chains)) { + for (const network of releaseScopedNetworks(selectedNetworks(opts.chains))) { for (const tableId of [RAW_LOGS_TABLE, TRANSACTIONS_TABLE]) { const r = await dedupTable(tableId, network.chainId, !!opts.dryRun); if (opts.dryRun) { @@ -73,11 +74,19 @@ export async function runDedup(opts: PipelineOpts): Promise { * Worth having as its own mode because the question "what does this warehouse not cover" was * previously unanswerable: the data could not be asked, since an empty result has two causes, and * the ledger was write only. + * + * TWO QUESTIONS, REPORTED SIDE BY SIDE (plan 5.2.1). Block coverage says what was read. Decode + * coverage says what could be decoded once read, per `(chain, address)`. A range can be covered + * by a clean capture and still contribute nothing to any model, because every log in it carries a + * `topic0` the event surface does not know. Reporting only the first question is how that stays + * invisible, so the second is printed beside it and its errors are counted separately: a count of + * zero undecodable rows means nothing unless the error count beside it is also zero. */ export async function reportCoverage(opts: PipelineOpts): Promise { let clean = true; + const surface = loadControlPlane().eventSurface; - for (const network of selectedNetworks(opts.chains)) { + for (const network of releaseScopedNetworks(selectedNetworks(opts.chains))) { for (const target of targetsFor(network, { addresses: opts.addresses })) { const captures = await loadCoverage(target.chainId, RAW_LOGS_TABLE, target.address); const gaps = openGaps(captures); @@ -90,14 +99,39 @@ export async function reportCoverage(opts: PipelineOpts): Promise { clean = false; continue; } + + const decode = await loadDecodeCoverage(target.chainId, target.address, surface); + const decodeNote = + `decode: ${decode.rowsUndecodable} of ${decode.rowsConsidered} captured row(s) match no ` + + `surface entry, ${decode.errors} row(s) unclassifiable` + + (decode.byContract.some((c) => c.unmatchedTopic0s.length > 0) + ? `, unmatched topic0 ${decode.byContract.flatMap((c) => c.unmatchedTopic0s).join(", ")}` + : ""); + + // An unclassifiable row is a finding in its own right. It is not folded into the + // undecodable count and it does not pass silently either. + if (decode.errors > 0) { + clean = false; + log.error( + `${network.name} ${target.contractName} ${target.address}: ${decode.errors} row(s) could ` + + `not be classified, so the undecodable count beside them is not a measurement: ` + + decode.errorDetail.join("; ") + ); + } else if (decode.rowsUndecodable > 0) { + clean = false; + log.error(`${network.name} ${target.contractName} ${target.address}: ${decodeNote}`); + } + if (gaps.length === 0) { - log.info(`${network.name} ${target.contractName}: ${captures.length} capture(s), no open gap`); + log.info( + `${network.name} ${target.contractName}: ${captures.length} capture(s), no open gap, ${decodeNote}` + ); continue; } clean = false; log.error( `${network.name} ${target.contractName} ${target.address}: ${gaps.length} open gap(s): ` + - gaps.map(([a, b]) => `${a}..${b}`).join(", ") + gaps.map(([a, b]) => `${a}..${b}`).join(", ") + `; ${decodeNote}` ); } } @@ -114,7 +148,7 @@ export async function reportCoverage(opts: PipelineOpts): Promise { export async function runRepair(opts: PipelineOpts): Promise { let allClean = true; - for (const network of selectedNetworks(opts.chains)) { + for (const network of releaseScopedNetworks(selectedNetworks(opts.chains))) { for (const target of targetsFor(network, { addresses: opts.addresses })) { const captures = await loadCoverage(target.chainId, RAW_LOGS_TABLE, target.address); const gaps = openGaps(captures); @@ -133,7 +167,15 @@ export async function runRepair(opts: PipelineOpts): Promise { try { // The same code path an ordinary ingestion uses, over a named range. Re-reading is free // of duplicates under MERGE, so over-covering a gap costs time and nothing else. - await processTarget(target, { mode: "backfill", fromBlock: from, toBlock: to }); + const outcomes = await processTarget(target, { mode: "backfill", fromBlock: from, toBlock: to }); + // A repair that was REFUSED is not a repair. Before the outcome type existed this + // returned 0 and read here as a clean re-read, so a refused gap was reported healed. + // EVERY grain has to complete: a re-read that recovers the logs and still misses a + // transaction has not repaired the range, and one outcome per capture used to hide that. + for (const outcome of outcomes.filter((o) => o.kind !== "completed")) { + log.error(` repair of ${from}..${to} did not complete for ${outcome.grain} (${outcome.kind}): ${outcome.detail}`); + allClean = false; + } } catch (e: any) { log.error(` repair of ${from}..${to} did not complete: ${e.message}`); allClean = false; @@ -153,7 +195,10 @@ export async function runRepair(opts: PipelineOpts): Promise { // The external check, where one exists. Two contracts out of 146 publish a usable ledger, so // this cannot be the only route to a re-read, but it is the only evidence in this system that // does not come from the system itself. - for (const oracle of oraclesFor(selectedNetworks(opts.chains))) { + // + // Release-scoped like every other loop in this file. It was not, and that was inert only while + // ORACLES held entries for one chain; it stops being inert the moment a second chain is added. + for (const oracle of oraclesFor(releaseScopedNetworks(selectedNetworks(opts.chains)))) { if (oracle.kind !== "ubi_daily") continue; const network = networkByChainId(oracle.network.chainId); if (!network) continue; diff --git a/projects/onchain-analytics/pipeline-v5/src/rpc.ts b/projects/onchain-analytics/pipeline-v5/src/rpc.ts index dc2f25a..d822a06 100644 --- a/projects/onchain-analytics/pipeline-v5/src/rpc.ts +++ b/projects/onchain-analytics/pipeline-v5/src/rpc.ts @@ -22,10 +22,18 @@ import { CONFIG } from "./config.js"; import { log } from "./log.js"; +import { getRpcTransport } from "./adapters.js"; import type { NetworkConfig } from "./types.js"; let idCounter = 0; +/** + * R4, in one place: a value is a measurement only when at least two independent endpoints return + * it. One endpoint's answer is a claim about that endpoint, and this project has measured what + * such claims are worth. + */ +export const MIN_INDEPENDENT_ENDPOINTS = 2; + export interface RpcResult { ok: boolean; result?: any; @@ -44,7 +52,10 @@ export async function rpcCall( ): Promise { const body = JSON.stringify({ jsonrpc: "2.0", id: ++idCounter, method, params }); try { - const res = await fetch(url, { + // Through the transport adapter rather than global fetch, so a test can read the exact + // envelope this call puts on the wire. SA-C7 was a defect that only exists on the wire: a + // read the caller believed was pinned sent `latest`, and no return value could show it. + const res = await getRpcTransport()(url, { method: "POST", headers: { "content-type": "application/json" }, body, @@ -96,12 +107,21 @@ export async function consensusRead( // another. A full-window reconciliation is two calls per protocol day; sequential querying // made that three times longer than it needed to be and long enough to be fragile. // - // Historical STATE is read from the ARCHIVE endpoints only. A pruned node answers a historical + // Historical STATE is read from the STATE endpoints only. A pruned node answers a historical // call with LATEST state, silently and with no error, so including one here would not produce // an error, it would produce agreement on the wrong value. - const urls = network.readers.archiveRpcUrls.length > 0 - ? network.readers.archiveRpcUrls - : network.readers.rpcUrls; + // + // `stateRpcUrls` rather than `archiveRpcUrls`, and the distinction earns its keep. Every call + // that reaches here is a read at a RECENT pin, which a node that prunes deep history still + // answers correctly. Qualifying those reads against the DEEP-archive list scored Celo at one + // endpoint, made the two-endpoint rule unmeetable, and turned a solved problem into a request + // to buy an endpoint. A chain that names no state endpoints falls back to the deep-archive + // list and then to the general one, so a chain configured the old way still behaves. + const urls = network.readers.stateRpcUrls.length > 0 + ? network.readers.stateRpcUrls + : network.readers.archiveRpcUrls.length > 0 + ? network.readers.archiveRpcUrls + : network.readers.rpcUrls; const results = await Promise.all( urls.map(async (url) => ({ url, r: await rpcCall(url, method, params) })) ); @@ -143,6 +163,60 @@ export async function consensusRead( }; } +/** + * What a log-scan answer is worth AS EVIDENCE, carried on the answer rather than decided by + * whoever happens to read it. + * + * FINDING C6 is that an RPC absence was treated as admissible at one call site and nowhere else, + * so the judgement lived in a conditional instead of on the value. A grade refused at one call + * site is refused only there; a grade carried on the answer travels with it into the coverage + * ledger, and downstream can read WHY a range is recorded the way it is. + */ +export type LogEvidenceGrade = + /** Logs were found. A find is sound while a miss is not, so this is the one sound direction. */ + | "refutation" + /** Two or more independent endpoints each covered the whole range without error and found nothing. */ + | "corroborated_absence" + /** Exactly one endpoint covered the whole range without error and found nothing. */ + | "single_source_absence" + /** No endpoint covered the whole range without an error, so nothing was established either way. */ + | "no_clean_answer"; + +export interface LogEvidence { + grade: LogEvidenceGrade; + /** + * ALWAYS false. It is the literal type rather than `boolean` so that no consumer can ever + * branch on a log scan having proved an absence, and so that anyone trying to gets a compile + * error rather than a plausible run. + * + * R7 of the binding verification standard: log absence is not evidence of absence, at any + * repetition count, on any endpoint. Corroboration by a second endpoint raises how well + * attested a NON-OBSERVATION is. It never converts one into a measurement. + */ + readonly admissibleAsAbsence: false; + /** True only for a refutation, which is the only claim a log scan can actually support. */ + admissibleAsRefutation: boolean; + /** Endpoints that covered EVERY sub-range without a single error. */ + cleanEndpoints: number; + /** Of those, how many found nothing at all. */ + cleanEndpointsFindingNothing: number; + /** The rule the grade was assigned under, so a reader can check it instead of trusting it. */ + standard: string; +} + +/** One endpoint's behaviour over the probed range, with results and failures never conflated. */ +export interface EndpointTally { + url: string; + /** Sub-ranges this endpoint answered with an empty array. A ZERO IS AN ANSWER, not a failure. */ + zeroAnswers: number; + /** Sub-ranges this endpoint answered with at least one log. */ + nonZeroAnswers: number; + /** Sub-ranges this endpoint failed outright. Counted separately from results, always. */ + failures: number; + /** Logs this endpoint saw across the whole range. A floor, never a count. */ + found: number; +} + export interface LogProbe { ok: boolean; /** Total logs found across every sub-range that succeeded. A floor, never a count. */ @@ -151,15 +225,35 @@ export interface LogProbe { answeredFully: string[]; errors: string[]; subRanges: number; + /** + * Sub-ranges answered with zero logs, per endpoint url. + * + * FINDING SA-C8. The tally used to be `{ found, failures }`, in which an endpoint answering + * zero is indistinguishable from one answering with rows: both leave `failures` at 0 and only + * `found` moves, and `found` is summed across endpoints. That is the exact signal a false zero + * produces, and forno's false-zero rate on this project was measured between 20 and 90 percent + * depending on range age with no error raised on any occasion. A tally that cannot see a false + * zero cannot report one. + */ + zeroLogAnswers: Record; + /** The full per-endpoint tally the counts above are taken from. */ + perEndpoint: EndpointTally[]; + /** + * Endpoints that answered zero on a sub-range where another endpoint found logs, with no error + * raised. This is a false zero caught in the act, and it is named rather than averaged away. + */ + falseZeroSuspects: string[]; + /** What this answer is worth as evidence. See `LogEvidence`. */ + evidence: LogEvidence; } /** - * Ask an independent RPC source whether a block range really is empty. + * Ask independent RPC sources whether a block range really is empty. * * This is used ONLY to refute an emptiness claim, never to establish one. Finding one log * refutes "there are none", and a refutation from a log query is sound. A second zero proves * nothing and is reported as such: `ok` means the probe ran cleanly, not that the range is - * empty. + * empty. The grade on `evidence` says which of those happened. * * Ranges are split to each chain's eth_getLogs cap, because a range-too-large error renders as * nothing found unless errors are counted separately from results. @@ -177,10 +271,15 @@ export async function probeLogsPresent( } const errors: string[] = []; - const perEndpoint = new Map(); + const perEndpoint = new Map(); + // Logs seen per endpoint per sub-range, null where the sub-range failed. Kept because a false + // zero is only visible by comparing the SAME sub-range across endpoints: an endpoint whose + // total is zero while another's total is not may simply have been asked different questions. + const perRange = new Map(); for (const url of network.readers.rpcUrls) { - perEndpoint.set(url, { found: 0, failures: 0 }); + perEndpoint.set(url, { url, zeroAnswers: 0, nonZeroAnswers: 0, failures: 0, found: 0 }); + perRange.set(url, []); for (const [lo, hi] of ranges) { const r = await rpcCall(url, "eth_getLogs", [{ address: addresses.length === 1 ? addresses[0] : addresses, @@ -190,45 +289,96 @@ export async function probeLogsPresent( const e = perEndpoint.get(url)!; if (!r.ok) { e.failures += 1; + perRange.get(url)!.push(null); errors.push(`${url} [${lo},${hi}]: ${r.error}`); } else if (Array.isArray(r.result)) { e.found += r.result.length; + if (r.result.length === 0) e.zeroAnswers += 1; else e.nonZeroAnswers += 1; + perRange.get(url)!.push(r.result.length); } else { e.failures += 1; + perRange.get(url)!.push(null); errors.push(`${url} [${lo},${hi}]: non-array result`); } await sleep(CONFIG.RPC_PAUSE_MS); } } - const answeredFully = [...perEndpoint.entries()].filter(([, e]) => e.failures === 0).map(([u]) => u); - const found = Math.max(0, ...[...perEndpoint.values()].map((e) => e.found)); + const tallies = [...perEndpoint.values()]; + const answeredFully = tallies.filter((e) => e.failures === 0).map((e) => e.url); + const found = Math.max(0, ...tallies.map((e) => e.found)); + + const falseZeroSuspects: string[] = []; + for (const [url, seen] of perRange) { + const caught = seen.some((n, i) => + n === 0 && [...perRange.entries()].some(([other, s]) => other !== url && (s[i] ?? 0) > 0)); + if (caught) falseZeroSuspects.push(url); + } + if (falseZeroSuspects.length > 0) { + log.error( + `FALSE ZERO IN THE TALLY: ${falseZeroSuspects.join(", ")} answered a sub-range of ` + + `${fromBlock}..${toBlock} with zero logs, raising no error, while another endpoint found logs ` + + `in that same sub-range`, + { network: network.name, suspects: falseZeroSuspects } + ); + } - return { ok: answeredFully.length > 0, found, answeredFully, errors, subRanges: ranges.length }; + const cleanFindingNothing = tallies.filter((e) => e.failures === 0 && e.found === 0); + const grade: LogEvidenceGrade = + found > 0 ? "refutation" + : answeredFully.length === 0 ? "no_clean_answer" + : cleanFindingNothing.length >= MIN_INDEPENDENT_ENDPOINTS ? "corroborated_absence" + : "single_source_absence"; + + return { + ok: answeredFully.length > 0, + found, + answeredFully, + errors, + subRanges: ranges.length, + zeroLogAnswers: Object.fromEntries(tallies.map((e) => [e.url, e.zeroAnswers])), + perEndpoint: tallies, + falseZeroSuspects, + evidence: { + grade, + admissibleAsAbsence: false, + admissibleAsRefutation: grade === "refutation", + cleanEndpoints: answeredFully.length, + cleanEndpointsFindingNothing: cleanFindingNothing.length, + standard: + "verification-standard R7 (a log scan is never evidence of absence, at any endpoint " + + "count) and R4 (a value is a measurement only when two independent endpoints return it)", + }, + }; } /** * Confirm that an empty HyperSync chunk really is empty. * - * Returns true only when at least one independent endpoint covered the whole range without a - * single error and also found nothing. Anything else, including every endpoint failing, is - * UNCONFIRMED, and an unconfirmed empty range does not let a watermark past it. + * FINDING SA-C8. This used to require only `answeredFully.length > 0` and then render the + * sentence "two sources agree the range is empty". That sentence is false whenever one source + * answered, and one source's zero is a claim about that source: R4 says a value is a measurement + * only when at least two independent endpoints return it, and forno -- frequently the only Celo + * endpoint that answers an old range -- returns false zeros between 20 and 90 percent of the time + * with no error raised. + * + * So confirmation now needs two independent endpoints that each covered the whole range without + * a single error and each found nothing, and the rendered reason states the count it actually + * observed rather than a fixed sentence. + * + * AN UNCONFIRMED EMPTY RANGE IS A NORMAL RESULT, not an error. It means nobody has corroborated + * the emptiness yet, so the coverage frontier does not move past it and the range is read again. + * The one thing that IS an error is a refutation, because that means the primary reader missed + * data that exists. */ export async function confirmEmptyRange( network: NetworkConfig, addresses: string[], fromBlock: number, toBlock: number -): Promise<{ confirmed: boolean; reason: string; probe: LogProbe }> { +): Promise<{ confirmed: boolean; reason: string; evidence: LogEvidence; probe: LogProbe }> { const probe = await probeLogsPresent(network, addresses, fromBlock, toBlock); - if (probe.answeredFully.length === 0) { - return { - confirmed: false, - reason: `no independent endpoint covered ${fromBlock}..${toBlock} without error, so the emptiness is a claim by one source`, - probe, - }; - } if (probe.found > 0) { log.error(`FALSE ZERO CAUGHT: HyperSync reported no logs for ${fromBlock}..${toBlock}, RPC found ${probe.found}`, { network: network.name, endpoints: probe.answeredFully, @@ -236,12 +386,31 @@ export async function confirmEmptyRange( return { confirmed: false, reason: `REFUTED: an independent endpoint found ${probe.found} log(s) in a range HyperSync reported empty`, - probe, + evidence: probe.evidence, probe, }; } + + const clean = probe.evidence.cleanEndpointsFindingNothing; + if (clean < MIN_INDEPENDENT_ENDPOINTS) { + return { + confirmed: false, + reason: + `UNCONFIRMED: ${clean} of ${network.readers.rpcUrls.length} endpoint(s) covered ` + + `${fromBlock}..${toBlock} without error and found nothing, and ${MIN_INDEPENDENT_ENDPOINTS} ` + + `independent endpoints are required, so the emptiness is a claim by ` + + `${clean === 0 ? "no source that completed the range" : "one source"} rather than a corroborated one`, + evidence: probe.evidence, probe, + }; + } + return { confirmed: true, - reason: `two sources agree the range is empty (${probe.answeredFully.length} endpoint(s) covered it with zero errors)`, - probe, + // States what was observed and nothing beyond it. The previous sentence asserted agreement + // between two sources on evidence that could be a single endpoint's clean pass. + reason: + `${clean} independent endpoints each covered ${fromBlock}..${toBlock} with zero errors and ` + + `each found no logs. This CORROBORATES the emptiness; under R7 it does not prove it, and the ` + + `range is recorded as a corroborated non-observation rather than a measured absence`, + evidence: probe.evidence, probe, }; } diff --git a/projects/onchain-analytics/pipeline-v5/src/run-ledger.ts b/projects/onchain-analytics/pipeline-v5/src/run-ledger.ts new file mode 100644 index 0000000..cb1d280 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/src/run-ledger.ts @@ -0,0 +1,595 @@ +/** + * run-ledger.ts -- the nonrecursive job-ledger contract. Plan Phase 3, task 12. + * + * WHAT THIS FILE IS, AND WHAT IT IS NOT. Task 12 says "DEFINE the nonrecursive job-ledger + * contract", and the phase's deliverables list does not include a running terminalizer. That + * split is not a convenience: the terminalizer is a BigQuery multi-statement transaction executed + * by the mutation broker, which Phase 5 builds, under IAM grants that Phase 14 issues and + * revokes. Phase 3 is forbidden from touching a cloud resource at all. So this module is the + * CONTRACT in executable form: the shapes, the encodings, the hashes and the decisions, every one + * of them a pure function that can be exercised on a laptop with no credential. Phases 5, 8 and + * 14 wire it to jobs.insert, jobs.get and the receipt bucket. Nothing here submits anything. + * + * WHY A CONTRACT AND NOT A HELPER. The failure this guards against is a run reporting that it + * closed when it did not, which is finding C2's shape one layer up. Three specific ways that + * happens, all named in the plan and all encoded below: + * + * 1. RECURSION. If the terminalizer appends itself to the ledger it is terminalizing, the + * ledger can never be complete, so "every work job is terminal" becomes unprovable and the + * implementation quietly relaxes it. The terminalizer is therefore NOT a work job, by + * construction, and `appendJobTerminal` refuses it. + * + * 2. A LABEL THAT LOOKS RIGHT. BigQuery labels are lowercase, 63 characters, and a restricted + * alphabet. A 64-character hex hash does not fit, so the plan encodes it as base32 and + * requires a byte comparison against the canonical hex rather than a prefix match. This + * project has already produced a false finding by comparing a TRUNCATION of a value: three + * different token supplies compared equal because a uint256 is left-padded. Truncation is + * refused here rather than discouraged. + * + * 3. RECOVERY THAT GUESSES. After a crash the question is whether the terminalizer transaction + * committed. A successful COMMIT child is the authoritative witness, and it is authoritative + * even when the parent job and the trailing SELECT failed or were cancelled. If the COMMIT's + * status cannot be established, the honest answer is to stop, not to retry: retrying a + * transaction that may have committed is how one run gets two terminal rows. + */ + +import { createHash } from "crypto"; + +// ---------------------------------------------------------------------------- label encoding + +/** The stages a job may be submitted under. Fixed lowercase enum, per plan task 12. */ +export const JOB_STAGES = [ + "capture", "stage", "merge", "coverage", "oracle", "repair", "migration", "terminalizer", +] as const; +export type JobStage = (typeof JOB_STAGES)[number]; + +/** BigQuery's own label rules: lowercase letters, digits, dash and underscore, 63 characters. */ +const LABEL_VALUE = /^[a-z0-9_-]{1,63}$/; +const LOWER_HEX_64 = /^[0-9a-f]{64}$/; +const LOWER_SHA1_40 = /^[0-9a-f]{40}$/; +const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-([1-8])[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/; + +/** RFC 4648 base32, lowercase, no padding. 32 bytes encode to exactly 52 characters. */ +const BASE32_ALPHABET = "abcdefghijklmnopqrstuvwxyz234567"; + +export function base32EncodeNoPad(bytes: Uint8Array): string { + let bits = 0; + let value = 0; + let out = ""; + for (const byte of bytes) { + value = (value << 8) | byte; + bits += 8; + while (bits >= 5) { + out += BASE32_ALPHABET[(value >>> (bits - 5)) & 31]; + bits -= 5; + } + } + if (bits > 0) out += BASE32_ALPHABET[(value << (5 - bits)) & 31]; + return out; +} + +export function base32DecodeNoPad(text: string): Uint8Array { + const out: number[] = []; + let bits = 0; + let value = 0; + for (const ch of text) { + const idx = BASE32_ALPHABET.indexOf(ch); + if (idx < 0) throw new Error(`LABEL_ALPHABET: '${ch}' is not RFC 4648 lowercase base32`); + value = (value << 5) | idx; + bits += 5; + if (bits >= 8) { + out.push((value >>> (bits - 8)) & 0xff); + bits -= 8; + } + } + return Uint8Array.from(out); +} + +/** The 52-character label form of a 64-character lowercase hex hash. */ +export function planHashLabel(hexHash: string): string { + if (!LOWER_HEX_64.test(hexHash)) { + throw new Error(`PLAN_HASH_SHAPE: expected 64 lowercase hex characters, got '${hexHash}'`); + } + return base32EncodeNoPad(Uint8Array.from(Buffer.from(hexHash, "hex"))); +} + +/** + * Decode a plan-hash label and BYTE-COMPARE it against the canonical hex. + * + * Not a prefix match and not a length check. The plan says "decode the label and byte-compare it + * with the canonical 64-character lowercase hex hash in submit intent, receipt ledger and + * PipelineRuns; truncation is forbidden", and the reason that sentence exists is that a + * comparison of truncated values has already manufactured a false result in this project. + */ +export function planHashLabelMatches(label: string, hexHash: string): boolean { + if (!LOWER_HEX_64.test(hexHash)) return false; + let decoded: Uint8Array; + try { + decoded = base32DecodeNoPad(label); + } catch { + return false; + } + const canonical = Uint8Array.from(Buffer.from(hexHash, "hex")); + if (decoded.length !== canonical.length) return false; + return decoded.every((b, i) => b === canonical[i]); +} + +export interface JobLabels { + readonly run_id: string; + readonly stage: string; + readonly release_sha: string; + readonly plan_hash: string; +} + +export interface LabelViolation { + readonly key: string; + readonly value: string; + readonly reason: string; +} + +/** The UUID version, or null when the string is not a UUID this contract accepts at all. */ +export function uuidVersion(id: string): number | null { + const m = UUID.exec(id); + return m ? Number(m[1]) : null; +} + +export interface LabelContext { + /** True only for the authenticated A5 child path described in plan task 12. */ + readonly isRootedA5Child: boolean; + /** The canonical hex plan hash the label must decode to. */ + readonly canonicalPlanHashHex: string; +} + +/** + * Validate a job's labels before `jobs.insert`. Returns every violation rather than the first, + * because a caller fixing labels one round trip at a time is how a submission loop gets written. + * + * THE UUID VERSION RULE IS THE SHARP EDGE. Ordinary, remediation and A5 PARENT runs must be + * UUIDv7. The sole exception is an A5 child or rooted A5 control/refresh child, which must be the + * deterministic UUIDv5 derived from its parent and plan. Every other combination refuses: a + * UUIDv5 outside that authenticated path, a UUIDv7 A5 child, and any other version. The point is + * that a run id carries a claim about WHAT KIND of run it is, and an unchecked claim is the same + * as no claim. + */ +export function validateJobLabels(labels: JobLabels, ctx: LabelContext): LabelViolation[] { + const v: LabelViolation[] = []; + const bad = (key: string, value: string, reason: string) => v.push({ key, value, reason }); + + const version = uuidVersion(labels.run_id); + if (labels.run_id !== labels.run_id.toLowerCase() || labels.run_id.length !== 36 || version === null) { + bad("run_id", labels.run_id, "not a 36-character lowercase RFC 9562 UUID"); + } else if (ctx.isRootedA5Child) { + if (version !== 5) { + bad("run_id", labels.run_id, + `a rooted A5 child must be the deterministic UUIDv5 derived from its parent and plan, not v${version}`); + } + } else if (version !== 7) { + bad("run_id", labels.run_id, + `an ordinary, remediation or A5 parent run must be UUIDv7, not v${version}` + + (version === 5 ? "; a UUIDv5 outside the authenticated A5 child path refuses" : "")); + } + + if (!(JOB_STAGES as readonly string[]).includes(labels.stage)) { + bad("stage", labels.stage, `not one of the fixed lowercase stages ${JOB_STAGES.join(", ")}`); + } + + if (!LOWER_SHA1_40.test(labels.release_sha)) { + bad("release_sha", labels.release_sha, "not a 40-character lowercase Git SHA"); + } + + if (!planHashLabelMatches(labels.plan_hash, ctx.canonicalPlanHashHex)) { + bad("plan_hash", labels.plan_hash, + "does not DECODE, byte for byte, to the canonical 64-character lowercase hex plan hash; " + + "a prefix or truncated match is not a match"); + } + + for (const [key, value] of Object.entries(labels)) { + if (!LABEL_VALUE.test(value)) { + bad(key, value, "outside BigQuery's lowercase label alphabet or over its 63-character limit"); + } + } + return v; +} + +/** + * The deterministic child run id, RFC 9562 UUIDv5 over the canonical tuple plan task 12 fixes. + * + * The tuple is joined with a separator that cannot occur in any member, so two different tuples + * cannot render to one string. That is not pedantry: a delimiter collision is how a deterministic + * id stops being deterministic, and the whole point of this id is that the wrapper can recompute + * it byte for byte before submitting anything. + */ +export function deterministicChildRunId( + namespaceUuid: string, + parts: { + parentRunId: string; + manifestSetId: string; + approvalRevisionOrZero: number; + childPlanHash: string; + globalOrControlOrdinal: number; + attempt: number; + }, +): string { + if (uuidVersion(parts.parentRunId) !== 7) { + throw new Error( + `A5_CHILD_PARENT: the parent run id must be a UUIDv7, got '${parts.parentRunId}'. A child ` + + `derived from a non-v7 parent would be deterministic and meaningless.` + ); + } + const canonical = [ + parts.parentRunId, parts.manifestSetId, String(parts.approvalRevisionOrZero), + parts.childPlanHash, String(parts.globalOrControlOrdinal), String(parts.attempt), + ].join("\u001f"); + + const ns = Buffer.from(namespaceUuid.replace(/-/g, ""), "hex"); + if (ns.length !== 16) throw new Error(`A5_CHILD_NAMESPACE: '${namespaceUuid}' is not a UUID`); + + const digest = createHash("sha1").update(ns).update(Buffer.from(canonical, "utf8")).digest(); + digest[6] = (digest[6] & 0x0f) | 0x50; + digest[8] = (digest[8] & 0x3f) | 0x80; + const hex = digest.subarray(0, 16).toString("hex"); + return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`; +} + +// ------------------------------------------------------------------------- the ledger itself + +export type JobState = "PENDING" | "RUNNING" | "DONE" | "FAILED" | "CANCELLED"; + +/** Terminal means the job cannot change again. PENDING and RUNNING are not terminal. */ +export function isTerminal(state: JobState): boolean { + return state === "DONE" || state === "FAILED" || state === "CANCELLED"; +} + +export interface SubmitIntent { + readonly jobId: string; + readonly location: string; + readonly principal: string; + readonly statementClass: string; + readonly targets: readonly string[]; + readonly templateHash: string; + readonly submittedAt: string; + readonly stage: JobStage; + /** Set for a generated child of a multi-statement script; null for an ordinary work job. */ + readonly parentJobId: string | null; +} + +export interface JobTerminal { + readonly jobId: string; + readonly state: JobState; + readonly errorMessage: string | null; + readonly transactionId: string | null; + readonly affectedRows: number | null; +} + +export type LedgerEntry = + | { readonly kind: "submit_intent"; readonly intent: SubmitIntent } + | { readonly kind: "job_terminal"; readonly terminal: JobTerminal } + | { readonly kind: "reconciliation"; readonly scannedJobIds: readonly string[]; readonly at: string } + | { readonly kind: "terminalized_snapshot"; readonly rowHash: string; readonly ledgerHash: string; + readonly terminalizerJobId: string; readonly terminalizerState: JobState } + | { readonly kind: "read_only_report_snapshot"; readonly reportHash: string; readonly at: string } + | { readonly kind: "closure"; readonly scanWatermark: string; readonly revokedBindings: readonly string[] } + | { readonly kind: "closure_invalidated"; readonly lateJobIds: readonly string[] }; + +export class LedgerError extends Error {} + +/** + * The append-only work-job ledger for one run. + * + * THE TERMINALIZER IS NOT IN IT. That is the whole meaning of "nonrecursive", and it is enforced + * here rather than remembered: `appendSubmitIntent` and `appendJobTerminal` both refuse a job + * whose stage is `terminalizer`. Its id lives in `PipelineRuns.terminalizer_job_id` and its state + * lives in the snapshot, neither of which is the ledger it closes. + */ +export class JobLedger { + private readonly entries: LedgerEntry[] = []; + private readonly intents = new Map(); + private readonly terminals = new Map(); + + constructor(readonly runId: string) {} + + /** Before `jobs.insert`, never after. An intent recorded afterwards fixes nothing. */ + appendSubmitIntent(intent: SubmitIntent): void { + if (intent.stage === "terminalizer") { + throw new LedgerError( + "LEDGER_RECURSION: the terminalizer is not a work job and is never added to the ledger it " + + "terminalizes. Its id belongs in PipelineRuns.terminalizer_job_id." + ); + } + if (this.intents.has(intent.jobId)) { + throw new LedgerError(`LEDGER_DUPLICATE_INTENT: ${intent.jobId} already has a submit intent`); + } + this.intents.set(intent.jobId, intent); + this.entries.push({ kind: "submit_intent", intent }); + } + + appendJobTerminal(terminal: JobTerminal): void { + const intent = this.intents.get(terminal.jobId); + if (!intent) { + throw new LedgerError( + `LEDGER_NO_INTENT: ${terminal.jobId} reported a terminal state with no submit intent. A job ` + + `the ledger never authorised cannot be reconciled into it after the fact.` + ); + } + if (!isTerminal(terminal.state)) { + throw new LedgerError(`LEDGER_NOT_TERMINAL: ${terminal.jobId} is ${terminal.state}`); + } + this.terminals.set(terminal.jobId, terminal); + this.entries.push({ kind: "job_terminal", terminal }); + } + + append(entry: LedgerEntry): void { + this.entries.push(entry); + } + + get all(): readonly LedgerEntry[] { + return this.entries; + } + + /** + * Every job that was submitted but has not reported a terminal state, plus every job the Jobs + * API reported that this ledger never authorised. + * + * The second half is the one that matters. "Parent status alone is insufficient": a + * multi-statement script's generated children are separate jobs, and a ledger that only knows + * about the parent will call a run terminal while a child is still running. + */ + reconcile(jobsApiIds: readonly string[]): { nonterminal: string[]; unledgered: string[] } { + const nonterminal = [...this.intents.keys()].filter((id) => !this.terminals.has(id)); + const known = new Set(this.intents.keys()); + const unledgered = jobsApiIds.filter((id) => !known.has(id)); + return { nonterminal, unledgered }; + } + + /** True only when every authorised job is terminal AND the Jobs API surfaced nothing extra. */ + workJobsTerminal(jobsApiIds: readonly string[]): boolean { + const { nonterminal, unledgered } = this.reconcile(jobsApiIds); + return nonterminal.length === 0 && unledgered.length === 0; + } + + /** Hash over the canonical ledger. Computed before terminalization, per plan task 12. */ + hash(): string { + return sha256Hex(canonicalJson(this.entries)); + } +} + +// --------------------------------------------------------- canonical_terminal_row_v1 + +/** BigQuery caps a receipt object at 256 KiB. Over it, terminalization refuses. */ +export const RECEIPT_CAP_BYTES = 256 * 1024; + +export type TypedValue = + | { readonly type: "STRING"; readonly value: string | null } + | { readonly type: "INT64"; readonly value: number | null } + | { readonly type: "BOOL"; readonly value: boolean | null } + | { readonly type: "TIMESTAMP"; readonly value: string | null } + | { readonly type: "JSON"; readonly value: string | null }; + +/** + * The complete versioned PipelineRuns row, as typed field/value pairs, fixed at intent creation. + * + * EVERY NULLABLE FIELD IS PRESENT AND EXPLICITLY NULL. That is not tidiness. The BigQuery client + * cannot infer a type from a JS null and rejects the whole statement with "Parameter types must + * be provided for null values"; this project lost a coverage row to exactly that. It is also what + * makes the row reconstructable after a crash: a field that is absent and a field that is null + * are indistinguishable in JSON, and recovery has to produce a BYTE-IDENTICAL row. + */ +export interface CanonicalTerminalRow { + readonly version: "canonical_terminal_row_v1"; + readonly runId: string; + readonly fields: Readonly>; +} + +/** + * Deterministic JSON: object keys sorted, no insignificant whitespace, no locale, no Date. + * + * `JSON.stringify` preserves insertion order, so two structurally identical rows built by + * different code paths hash differently. Recovery builds the row from the stored intent and the + * original built it from live counters, so those ARE two different code paths, and the whole + * proof rests on their hashes matching. + */ +export function canonicalJson(value: unknown): string { + const walk = (v: unknown): unknown => { + if (Array.isArray(v)) return v.map(walk); + if (v && typeof v === "object") { + const out: Record = {}; + for (const key of Object.keys(v as object).sort()) out[key] = walk((v as any)[key]); + return out; + } + return v; + }; + return JSON.stringify(walk(value)); +} + +export function sha256Hex(text: string): string { + return createHash("sha256").update(Buffer.from(text, "utf8")).digest("hex"); +} + +/** + * The row hash: over the canonical final fields, EXCLUDING the hash field itself. + * + * A hash that covered itself would be uncomputable, and the usual mistake is to hash the row with + * the field set to empty string and then compare against a row where it is populated. Excluding + * the key entirely is the only form that both sides can reproduce. + */ +export const ROW_HASH_FIELD = "terminalized_row_hash"; + +export function terminalRowHash(row: CanonicalTerminalRow): string { + const fields: Record = { ...row.fields }; + delete fields[ROW_HASH_FIELD]; + return sha256Hex(canonicalJson({ version: row.version, runId: row.runId, fields })); +} + +export interface TerminalizerIntent { + readonly terminalizerJobId: string; + readonly runId: string; + readonly row: CanonicalTerminalRow; + readonly rowHash: string; + readonly ledgerHash: string; + /** Fixed at intent creation. The script may not call CURRENT_TIMESTAMP() to replace it. */ + readonly terminalizedAt: string; + readonly closureReceiptUri: string; +} + +export function buildTerminalizerIntent( + args: Omit, +): TerminalizerIntent { + const rowHash = terminalRowHash(args.row); + const intent: TerminalizerIntent = { ...args, rowHash }; + const size = Buffer.byteLength(canonicalJson(intent), "utf8"); + if (size > RECEIPT_CAP_BYTES) { + throw new LedgerError( + `RECEIPT_TOO_LARGE: the terminalizer intent is ${size} bytes against a cap of ` + + `${RECEIPT_CAP_BYTES}. Terminalization refuses rather than truncating: a receipt that does ` + + `not contain the whole row cannot reconstruct it.` + ); + } + if (args.row.fields[ROW_HASH_FIELD] !== undefined && + args.row.fields[ROW_HASH_FIELD].value !== null) { + throw new LedgerError( + `ROW_HASH_PRESET: ${ROW_HASH_FIELD} must be null in the intent. It is computed over the ` + + `other fields, so a preset value would be hashing a claim about itself.` + ); + } + return intent; +} + +// ------------------------------------------------------------------------------- recovery + +/** + * What the Jobs API says about a terminalizer attempt after a crash. + * + * The fields are deliberately separate rather than a single "did it work". The plan's whole + * recovery rule turns on the COMMIT child being authoritative INDEPENDENTLY of the parent and the + * trailing SELECT, so collapsing them into one boolean would erase the distinction the rule is + * made of. + */ +export interface TerminalizerJobEvidence { + readonly parentState: JobState | "MISSING"; + /** Terminal state of the generated DML child, or MISSING when it never appeared. */ + readonly dmlChildState: JobState | "MISSING"; + readonly dmlChildAffectedRows: number | null; + /** Terminal state of the generated COMMIT child. UNKNOWN is a real answer and it stops. */ + readonly commitChildState: JobState | "MISSING" | "UNKNOWN"; + /** Terminal state of the trailing no-FROM SELECT that returns the canonical row. */ + readonly trailingSelectState: JobState | "MISSING"; + /** True when the result of the trailing SELECT is still retrievable. */ + readonly resultAvailable: boolean; + /** True only if a rollback has been POSITIVELY proven, not merely assumed from a failure. */ + readonly rollbackProven: boolean; +} + +export type RecoveryAction = + /** The transaction committed. Reconstruct the row from the intent. Submit nothing. */ + | { readonly action: "reconstruct_from_intent"; readonly reason: string } + /** The result is still there. Read it; no reconstruction and no new job. */ + | { readonly action: "read_existing_result"; readonly reason: string } + /** Rollback is proven. One linked recovery run may submit the next deterministic attempt. */ + | { readonly action: "retry_linked_recovery"; readonly reason: string } + /** Ambiguous. Stop. Never guess whether a transaction committed. */ + | { readonly action: "stop"; readonly reason: string }; + +/** + * Decide what a crashed terminalizer may do next. + * + * READ THE ORDER, IT IS THE CONTRACT. A successful COMMIT child freezes the attempt as committed + * REGARDLESS of the parent's and the trailing SELECT's status, because the transaction is what + * changed the world and the parent job is only the thing that asked for it. Only when no + * successful COMMIT is provable does rollback matter, and rollback must be PROVEN rather than + * inferred from a failure: a cancelled parent tells you nothing about whether its COMMIT child + * landed first. Everything else stops. + */ +export function decideRecovery(e: TerminalizerJobEvidence): RecoveryAction { + if (e.commitChildState === "DONE") { + if (e.dmlChildState !== "DONE") { + return { + action: "stop", + reason: + `a COMMIT child succeeded but its DML child is ${e.dmlChildState}. The contiguous ` + + `prefix is broken, so the committed transaction is not the one this intent describes.`, + }; + } + if (e.dmlChildAffectedRows !== 1) { + return { + action: "stop", + reason: + `a COMMIT child succeeded and the DML child reports ${e.dmlChildAffectedRows} affected ` + + `row(s), not exactly 1. One run terminalizes exactly one row.`, + }; + } + if (e.resultAvailable && e.trailingSelectState === "DONE" && e.parentState === "DONE") { + return { + action: "read_existing_result", + reason: "the parent and every generated child succeeded and the result is still retrievable", + }; + } + return { + action: "reconstruct_from_intent", + reason: + `the COMMIT child succeeded and the DML child affected exactly one row, so the ` + + `transaction committed. Parent is ${e.parentState} and the trailing SELECT is ` + + `${e.trailingSelectState}, which is recorded in the snapshot and changes nothing: the ` + + `row is reconstructed from canonical_terminal_row_v1 and NO replacement terminalizer is ` + + `submitted.`, + }; + } + + if (e.commitChildState === "UNKNOWN" || e.commitChildState === "MISSING") { + if (e.rollbackProven) { + return { + action: "retry_linked_recovery", + reason: + "no COMMIT child is provable and rollback has been positively proven, so exactly one " + + "linked recovery run may submit the next deterministic attempt id", + }; + } + return { + action: "stop", + reason: + `the COMMIT child is ${e.commitChildState} and rollback is NOT proven. Retrying a ` + + `transaction that may have committed is how one run acquires two terminal rows. ` + + `Ambiguity stops.`, + }; + } + + // The COMMIT child exists and did not succeed. + if (e.rollbackProven) { + return { + action: "retry_linked_recovery", + reason: `the COMMIT child is ${e.commitChildState} and rollback is proven`, + }; + } + return { + action: "stop", + reason: + `the COMMIT child is ${e.commitChildState} and rollback is not proven. A failed or ` + + `cancelled attempt must be proven rolled back before a linked recovery run may submit the ` + + `next deterministic attempt id.`, + }; +} + +/** + * Rebuild the exact terminal row from the intent alone, and prove it is the intended one. + * + * Takes NOTHING but the immutable intent. It cannot scan PipelineRuns, cannot open a Storage Read + * session and cannot submit a query, because it is a pure function over a value: there is nothing + * here that could. That is the point of the plan's GREEN check counting zero `tabledata.list`, + * zero Storage Read sessions and zero replacement `jobs.insert` calls. + */ +export function reconstructTerminalRow(intent: TerminalizerIntent): { + row: CanonicalTerminalRow; + rowHash: string; +} { + const rowHash = terminalRowHash(intent.row); + if (rowHash !== intent.rowHash) { + throw new LedgerError( + `ROW_HASH_MISMATCH: the intent's row hashes to ${rowHash} and the intent records ` + + `${intent.rowHash}. All hashes must match or recovery stops.` + ); + } + const fields: Record = { + ...intent.row.fields, + [ROW_HASH_FIELD]: { type: "STRING", value: rowHash }, + }; + return { row: { ...intent.row, fields }, rowHash }; +} diff --git a/projects/onchain-analytics/pipeline-v5/src/sandbox.ts b/projects/onchain-analytics/pipeline-v5/src/sandbox.ts new file mode 100644 index 0000000..fa8d195 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/src/sandbox.ts @@ -0,0 +1,310 @@ +/** + * sandbox.ts -- the control that stands between a disposable experiment and the production dataset. + * + * WHY THIS IS A CONTROL AND NOT A CONVENIENCE WRAPPER. The reason is on the record twice. One + * maintenance script extracted a single CREATE statement from a DDL file by string substitution, + * the substitution rewrote only the first table reference, and BigQuery ran the remainder as a + * multi-statement script against `gooddollar.BlockchainEvents`: it dropped and recreated a + * production table. And two undocumented sandbox datasets sit in this project today, one of them + * recorded as deleted in a maintenance note and still present. So a cleanup receipt here is known + * wrong at least once, and a script that merely intends to hit a sandbox is not evidence of + * anything. + * + * THE FOUR RULES, each of which exists because its absence has already cost something: + * + * 1. PROTECTED DATASETS ARE REFUSED BY HARD-CODED NAME. Not by a configuration default. The + * default value of `DATASET_ID` in `config.ts` IS `BlockchainEvents`, so an agent that + * forgets one environment variable points the whole pipeline at production and nothing in + * the configuration layer objects. A refusal that a different config can flip is not a + * control; this one cannot be reached by any configuration at all. + * 2. THE TARGET MUST BE UNIQUELY NAMED, and its absence is checked against a live listing + * before creation. Reusing a name is how a long-lived scratch space appears. + * 3. A PURPOSE LABEL IS MANDATORY. The two leftover datasets in this project carry no labels, + * which is precisely why nobody could say whether either was disposable. + * 4. THE LABEL IS READ BACK AND CHECKED BEFORE ANYTHING IS DELETED, and absence afterwards is + * proven by a LISTING, never by the delete call's return value. + * + * MEASURED, 2026-09-29, before anything was built on it: project-scope `bigquery.datasets.delete` + * is DENIED for the ordinary analytics identity, and the delete of a dataset that identity created + * still returns HTTP 204, after which the dataset is absent from a listing with an error count of + * zero. A project-scope denial is a floor, not a ceiling, because the creator of a dataset becomes + * its owner. + */ + +import { log } from "./log.js"; + +/** Refusal by this control. Distinct from an API error so a caller cannot conflate the two. */ +export class SandboxRefusal extends Error { + constructor(message: string) { + super(message); + this.name = "SandboxRefusal"; + } +} + +/** + * Datasets no sandbox operation may ever touch, by name. + * + * `BlockchainEvents` is the production raw layer. The other three are the dbt layers built on it. + * This list is a literal in the source: it is not read from configuration, not overridable by an + * environment variable, and not a default parameter. + */ +export const PROTECTED_DATASETS: readonly string[] = [ + "BlockchainEvents", + "Staging", + "Semantic", + "Marts", +]; + +/** The label key every sandbox must carry. Checked before any delete. */ +export const SANDBOX_PURPOSE_LABEL = "purpose"; + +/** BigQuery dataset ids accept letters, digits and underscores only. */ +const DATASET_ID_PATTERN = /^[A-Za-z0-9_]{1,1024}$/; + +/** BigQuery label values accept lowercase letters, digits, dashes and underscores, max 63. */ +const LABEL_VALUE_PATTERN = /^[a-z0-9][a-z0-9_-]{2,62}$/; + +export function isProtectedDataset(datasetId: string): boolean { + const target = datasetId.trim().toLowerCase(); + return PROTECTED_DATASETS.some((p) => p.toLowerCase() === target); +} + +/** + * The refusal itself. Every path in this module goes through it, and so must every caller that + * is about to write anywhere on this identity's behalf. + */ +export function assertNotProtectedDataset(datasetId: string, operation: string): void { + if (isProtectedDataset(datasetId)) { + throw new SandboxRefusal( + `REFUSED: ${operation} targets ${datasetId}, which is a protected dataset. This refusal is ` + + `hard-coded in sandbox.ts and cannot be turned off by configuration. If a sandbox is ` + + `wanted, name one; if production is wanted, this is not the route to it.` + ); + } +} + +/** What this module needs from a BigQuery administrative client, and nothing more. */ +export interface DatasetAdmin { + /** Every dataset id in the project. Throws on failure; an errored listing proves nothing. */ + listDatasets(): Promise; + createDataset(datasetId: string, options: CreateDatasetOptions): Promise; + /** The dataset's labels, or null when it does not exist. */ + labelsOf(datasetId: string): Promise | null>; + deleteDataset(datasetId: string, options: { deleteContents: boolean }): Promise; +} + +export interface CreateDatasetOptions { + location: string; + labels: Record; + description: string; + defaultTableExpirationMs: number; +} + +let admin: DatasetAdmin | null = null; +let adminFactory: (() => DatasetAdmin) | null = null; + +/** Register how a real admin client is built, without building one. Same reason as `bq.ts`. */ +export function setDatasetAdminFactory(factory: () => DatasetAdmin): void { + adminFactory = factory; +} + +/** Replace the admin. Tests use this; nothing in `src/` does. */ +export function setDatasetAdmin(replacement: DatasetAdmin | null): void { + admin = replacement; +} + +export function getDatasetAdmin(): DatasetAdmin { + if (admin) return admin; + if (!adminFactory) { + throw new SandboxRefusal( + "SANDBOX_ADMIN_UNSET: no dataset admin and no factory registered. Call " + + "setDatasetAdminFactory() with a real client, or setDatasetAdmin() with a double." + ); + } + admin = adminFactory(); + return admin; +} + +export interface SandboxOptions { + /** What this sandbox is FOR. Becomes the `purpose` label and part of the dataset name. */ + purpose: string; + /** Defaults to `US`, which every dataset in this project uses. */ + location?: string; + /** + * Belt and braces. Every table created in the sandbox expires on its own, so a failed cleanup + * leaves nothing durable behind rather than a permanent scratch space. + */ + tableExpirationHours?: number; + /** Supply a name instead of generating one. Still checked for uniqueness and protection. */ + datasetId?: string; +} + +export interface SandboxHandle { + readonly datasetId: string; + readonly purposeLabel: string; + readonly location: string; + readonly createdAt: string; +} + +/** + * A unique, self-describing dataset name. + * + * Reads as what it is at a glance in the console, which the two leftovers do not: + * `sbx_unit03_coverage_20260929T014230Z_q3bywk`. + */ +export function sandboxDatasetId(purpose: string, now: Date, nonce: string): string { + const stamp = now.toISOString().replace(/[-:.]/g, "").replace(/\d{3}Z$/, "Z"); + const slug = purpose.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, ""); + const id = `sbx_${slug}_${stamp}_${nonce}`; + if (!DATASET_ID_PATTERN.test(id)) { + throw new SandboxRefusal(`Generated dataset id ${id} is not a legal BigQuery dataset id.`); + } + return id; +} + +/** The purpose, in the form a BigQuery label value accepts. */ +export function purposeLabelValue(purpose: string): string { + const value = purpose.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 63); + if (!LABEL_VALUE_PATTERN.test(value)) { + throw new SandboxRefusal( + `Purpose "${purpose}" does not reduce to a legal BigQuery label value. Use at least three ` + + `characters of letters, digits, dashes or underscores.` + ); + } + return value; +} + +/** + * Create a disposable, labelled sandbox dataset. + * + * Refuses a protected name, refuses a name that already exists, and refuses to create anything + * without a purpose. + */ +export async function createSandbox(options: SandboxOptions): Promise { + const purposeLabel = purposeLabelValue(options.purpose); + const location = options.location ?? "US"; + const expirationHours = options.tableExpirationHours ?? 6; + const client = getDatasetAdmin(); + + const datasetId = options.datasetId + ?? sandboxDatasetId(options.purpose, new Date(), Math.random().toString(36).slice(2, 8)); + + assertNotProtectedDataset(datasetId, "sandbox creation"); + if (!DATASET_ID_PATTERN.test(datasetId)) { + throw new SandboxRefusal(`${datasetId} is not a legal BigQuery dataset id.`); + } + + // Uniqueness is checked against a live listing, not against a naming convention. If the listing + // fails, this throws rather than proceeding: an unverified name is not a unique one. + const existing = await client.listDatasets(); + if (existing.includes(datasetId)) { + throw new SandboxRefusal( + `REFUSED: dataset ${datasetId} already exists. A sandbox is created for one piece of work ` + + `and dropped after it, so reusing a name would make its contents ambiguous.` + ); + } + + await client.createDataset(datasetId, { + location, + labels: { [SANDBOX_PURPOSE_LABEL]: purposeLabel }, + description: + `Disposable sandbox for ${options.purpose}. Created by pipeline-v5 sandbox.ts. ` + + `Every table expires after ${expirationHours}h. Safe to delete.`, + defaultTableExpirationMs: expirationHours * 60 * 60 * 1000, + }); + + log.info(`Sandbox ${datasetId} created in ${location} for ${purposeLabel}`); + return { datasetId, purposeLabel, location, createdAt: new Date().toISOString() }; +} + +export interface CleanupResult { + readonly datasetId: string; + /** True only when a LISTING taken after the delete does not contain the dataset. */ + readonly provenAbsent: boolean; + readonly datasetsAfter: readonly string[]; + readonly labelChecked: string | null; + readonly detail: string; +} + +/** + * Drop a sandbox, having first checked it is one, and prove it is gone. + * + * THE LABEL CHECK COMES BEFORE THE DELETE, not after and not instead of it. A handle is a claim + * about what a dataset is; the label read back off the live dataset is evidence. They disagree + * exactly when something has gone wrong, which is the moment a delete must not proceed. + * + * ABSENCE IS PROVEN BY A LISTING. The delete call's own success is not admissible: this project + * holds a cleanup receipt that says a dataset was dropped, and that dataset is still there. + */ +export async function dropSandbox(handle: SandboxHandle): Promise { + const client = getDatasetAdmin(); + assertNotProtectedDataset(handle.datasetId, "sandbox cleanup"); + + const labels = await client.labelsOf(handle.datasetId); + if (labels === null) { + const after = await client.listDatasets(); + return { + datasetId: handle.datasetId, + provenAbsent: !after.includes(handle.datasetId), + datasetsAfter: after, + labelChecked: null, + detail: `${handle.datasetId} does not exist, so there was nothing to delete.`, + }; + } + + const found = labels[SANDBOX_PURPOSE_LABEL] ?? null; + if (found !== handle.purposeLabel) { + throw new SandboxRefusal( + `REFUSED: ${handle.datasetId} carries ${SANDBOX_PURPOSE_LABEL}=${found ?? "(none)"} and this ` + + `handle claims ${handle.purposeLabel}. Nothing is deleted when the dataset is not provably ` + + `the one this run created.` + ); + } + + await client.deleteDataset(handle.datasetId, { deleteContents: true }); + + const after = await client.listDatasets(); + const provenAbsent = !after.includes(handle.datasetId); + if (!provenAbsent) { + log.error( + `Sandbox ${handle.datasetId} is STILL PRESENT after a delete that reported success. ` + + `The listing is the measurement and it says the dataset is there.` + ); + } + + return { + datasetId: handle.datasetId, + provenAbsent, + datasetsAfter: after, + labelChecked: found, + detail: provenAbsent + ? `${handle.datasetId} is absent from a listing of ${after.length} dataset(s) taken after the delete.` + : `${handle.datasetId} is still present in a listing of ${after.length} dataset(s) taken after the delete.`, + }; +} + +/** + * Run work against a fresh sandbox and drop it afterwards, whatever the work did. + * + * The cleanup runs on the failure path too, because the run that leaves a dataset behind is + * always the one that went wrong. + */ +export async function withSandbox( + options: SandboxOptions, + work: (handle: SandboxHandle) => Promise, +): Promise<{ result: T; cleanup: CleanupResult }> { + const handle = await createSandbox(options); + try { + const result = await work(handle); + return { result, cleanup: await dropSandbox(handle) }; + } catch (e) { + const cleanup = await dropSandbox(handle).catch((ce: Error) => { + log.error(`Sandbox cleanup failed after the work threw: ${ce.message}`); + return null; + }); + if (cleanup && !cleanup.provenAbsent) { + log.error(`Sandbox ${handle.datasetId} was NOT proven absent after a failed run.`); + } + throw e; + } +} diff --git a/projects/onchain-analytics/pipeline-v5/src/slack.ts b/projects/onchain-analytics/pipeline-v5/src/slack.ts index eccd440..4a3b1a9 100644 --- a/projects/onchain-analytics/pipeline-v5/src/slack.ts +++ b/projects/onchain-analytics/pipeline-v5/src/slack.ts @@ -4,8 +4,15 @@ import { CONFIG } from "./config.js"; import { log } from "./log.js"; +import { getNotifier } from "./adapters.js"; async function postToSlack(payload: Record): Promise { + // A replaced notifier takes precedence, so a test observes the alert instead of the network. + const replacement = getNotifier(); + if (replacement) { + await replacement.post(payload); + return; + } if (!CONFIG.SLACK_WEBHOOK_URL) return; try { diff --git a/projects/onchain-analytics/pipeline-v5/src/types.ts b/projects/onchain-analytics/pipeline-v5/src/types.ts index 69acacd..9e46d9d 100644 --- a/projects/onchain-analytics/pipeline-v5/src/types.ts +++ b/projects/onchain-analytics/pipeline-v5/src/types.ts @@ -7,6 +7,8 @@ * range of which contract, how far the result can be trusted, and what it failed on. */ +import type { RunSummary } from "./outcome.js"; + // --------------------------------------------------------------------------------------------- // Chains and readers // --------------------------------------------------------------------------------------------- @@ -38,7 +40,24 @@ export interface ReaderCapability { hypersyncUrl: string | null; /** JSON-RPC endpoints, for confirming negatives, reading state, and enumerating logs where HyperSync cannot. */ rpcUrls: string[]; - /** Endpoints able to serve historical state. Empty means historical state is unreadable here. */ + /** + * Endpoints able to serve state at a RECENT pinned block, which is what every state read this + * pipeline currently performs actually needs. + * + * Separate from `archiveRpcUrls` because the two answer different questions and an endpoint + * that fails one can pass the other. Treating them as one list scored Celo at a single + * qualified endpoint and produced a spend request; measured against the question actually + * being asked, four free endpoints qualify. + */ + stateRpcUrls: string[]; + /** + * Endpoints able to serve DEEP historical state -- state old enough that a pruned node has + * discarded it. Empty means deep historical state is unreadable here. + * + * A pruned node answers a historical call with LATEST state, silently and with no error, so + * this list is qualified by a tripwire that reads a value which MUST have changed, never by a + * liveness probe. + */ archiveRpcUrls: string[]; /** Largest block span this chain's RPC endpoints accept for eth_getLogs. */ rpcLogRange: number; @@ -199,7 +218,7 @@ export interface MergeWindow { } export interface PipelineOpts { - mode: "daily" | "backfill" | "verify" | "dedup" | "repair" | "calibrate" | "coverage"; + mode: "daily" | "backfill" | "plan" | "verify" | "dedup" | "repair" | "calibrate" | "coverage"; /** Limit to these chain names, for example CELO,XDC. */ chains?: string[]; /** Limit to these contract addresses. */ @@ -220,6 +239,15 @@ export interface PipelineResult { succeeded: number; failed: number; totalRows: number; + /** + * The typed outcome of every unit this run produced. C2's fix. + * + * `succeeded` and `failed` are kept as the flattened projection of it, because they are what + * the two `PipelineRuns` count columns have always held and renaming a column is a warehouse + * change rather than a control-flow one. They are DERIVED from the summary now, never + * incremented independently, so the two can no longer disagree. + */ + summary: RunSummary; } /** @@ -246,7 +274,14 @@ export interface CoverageRecord { tableId: string; fromBlock: number; toBlock: number; - /** complete, incomplete, unconfirmed_empty, nothing_to_fetch, or capability_gap. Never "success". */ + /** + * complete, incomplete, unconfirmed_empty, rollback_eligible, nothing_to_fetch, refused_budget + * or capability_gap. Never "success". + * + * `rollback_eligible` means the reader reported it still holds blocks at or below this + * capture's start, so the source itself says the range can still be reorganised. Only + * `complete` is clean, so anything else holds the resume frontier at or below the range. + */ status: string; chunksPlanned: number; chunksOk: number; @@ -287,4 +322,25 @@ export interface PipelineRunRecord { capturesOk: number; capturesFailed: number; pipelineVersion: string; + + // -- Plan Phase 3 task 11. Additive outcome columns. -- + // + // The migration that adds them to an existing table is one statement in one file at + // `warehouse/L1/08_PipelineRunsOutcome_v1.sql`. Phase 8 rehearses and applies it; nothing here + // applies anything. `host` and `pipeline_version` are REUSED for runner identity and release + // version rather than aliased, which plan task 11 names explicitly. + + /** `completed`, `partial`, `refused`, `unsupported`, `empty` or `failed`. Never plain success. */ + executionStatus: string; + unitsPlanned: number; + unitsAttempted: number; + unitsCompleted: number; + unitsNoop: number; + unitsRefused: number; + unitsUnsupported: number; + unitsFailed: number; + /** `OutcomeCounters` per target grain, as JSON. Reconciles exactly to the unit counts. */ + outcomeCountsByGrain: string; + releaseSha: string | null; + planHash: string | null; } diff --git a/projects/onchain-analytics/pipeline-v5/src/writelock.ts b/projects/onchain-analytics/pipeline-v5/src/writelock.ts new file mode 100644 index 0000000..4ba463e --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/src/writelock.ts @@ -0,0 +1,216 @@ +/** + * writelock.ts -- the cross-process write lease. `C1`'s fix. + * + * THE DEFECT, WITH ITS RECEIPT. Two captures of XDC 105,201,000..105,201,500 ran at the same + * time. Each staged its own copy of the same 47 merge keys, each measured the target before its + * own MERGE, each MERGE matched against a target snapshot taken before the other had inserted, + * and so both inserted. `RawLogs` ended with 149 stored rows over 102 distinct keys -- 47 + * phantoms -- and BOTH processes exited 0 while every coverage row and every `PipelineRuns` row + * said complete. Nothing in the write path excluded the second writer, and nothing in the + * bookkeeping recorded that there had been one. + * + * WHY A FILE AND NOT A TABLE. A lease in BigQuery would need `tables.updateData` on a production + * dataset held for the whole run, which is one of the permissions this project exists to keep + * revoked, and it would put the lock's own correctness behind the same MERGE semantics that + * produced the defect. The thing being excluded is a second OS PROCESS on one host invoking one + * operator-run pipeline, so the exclusion belongs at the host. `open(..., "wx")` is a single + * atomic create-if-absent syscall on both Windows and POSIX: exactly one caller can win it, with + * no compare-then-write window for a second caller to land in. + * + * WHAT IT DOES NOT CLAIM. This excludes concurrent writers on ONE HOST. Two machines writing the + * same table at once would need a lease the cloud arbitrates, and nothing in this deployment can + * produce that: there is one operator-invoked writer. If a second host ever becomes real, this + * file is the wrong mechanism and the right one is a fenced broker -- stated here rather than + * discovered when it silently fails to exclude anything. + * + * THREE PROPERTIES, each guarding a way a naive file lock goes wrong. + * + * THE HOLDER IS IDENTIFIED BY A TOKEN, NOT BY THE PATH. A lease reclaimed as stale can be + * re-acquired by someone else while the original holder is still alive; if release only + * unlinked the path, that holder would delete a lease it no longer owns and admit a third + * writer. Release reads the file back and unlinks only if the token still matches. + * + * A STALE LEASE IS RECLAIMED, BUT SLOWLY. A process killed mid-MERGE leaves its file behind, + * and a lock that never expires turns one crash into a permanently unwritable table. The + * expiry is deliberately much longer than any MERGE: reclaiming a lease that is merely slow + * would reintroduce exactly the concurrent write this exists to prevent. + * + * REFUSAL IS AN OUTCOME, NOT A HANG. A waiter that blocks for ever turns a duplicate-row bug + * into a stuck pipeline. After `waitMs` the acquire returns null, `stageAndMerge` throws, and + * the capture records `incomplete` -- which is the half of `C1` the row count never showed. + * Both processes exiting 0 is what made the original incident invisible. + */ + +import { openSync, closeSync, writeSync, readFileSync, unlinkSync, mkdirSync } from "fs"; +import { tmpdir, hostname } from "os"; +import { join } from "path"; +import { randomUUID } from "crypto"; +import { CONFIG } from "./config.js"; +import { log } from "./log.js"; +import type { WriteLock, WriteLockHandle } from "./adapters.js"; +import type { MergeWindow } from "./types.js"; + +/** What is written into a lease file. Read back on release, and on a staleness decision. */ +export interface LeaseRecord { + token: string; + pid: number; + host: string; + tableId: string; + acquiredAt: string; + window: string | null; +} + +export interface FileWriteLockOptions { + /** Where lease files live. Defaults to `CONFIG.WRITE_LOCK_DIR`, then the system temp dir. */ + dir?: string; + /** How long to wait for a held lease before refusing. */ + waitMs?: number; + /** How old a lease must be before it is treated as abandoned. */ + staleMs?: number; + /** Gap between attempts. */ + pollMs?: number; + /** Injectable for tests, so a staleness test does not have to wait an hour. */ + now?: () => number; +} + +function sleep(ms: number): Promise { + return new Promise((r) => setTimeout(r, ms)); +} + +/** + * One lease file per (project, dataset, table). + * + * The dataset is in the name because the same table id in a sandbox and in production are + * different tables, and serialising a test against production writes would be a lock that + * reports contention which does not exist. + */ +export function leaseFileName(projectId: string, datasetId: string, tableId: string): string { + const safe = `${projectId}.${datasetId}.${tableId}`.replace(/[^A-Za-z0-9._-]/g, "_"); + return `gd-pipeline-write.${safe}.lock`; +} + +function readLease(path: string): LeaseRecord | null { + try { + return JSON.parse(readFileSync(path, "utf8")) as LeaseRecord; + } catch { + // Either the holder released between our failed create and this read, or the file is + // half-written. Both mean "no readable lease", and both are handled by retrying. + return null; + } +} + +/** + * Whether the process named in a lease is still running, where that is knowable. + * + * Signal 0 performs the permission and existence checks and delivers nothing, so it answers + * "does this pid exist" without disturbing it. ESRCH means no such process; EPERM means it + * exists and belongs to someone else, which still counts as alive. + * + * This is what keeps the age rule from becoming a foot-gun. Without it a killed run leaves a + * lease that blocks the next run for a full expiry period, and the expiry has to stay long + * because shortening it would let a merely-slow MERGE be overrun. With it, the common case -- + * same host, dead pid -- is reclaimed at once, and the age rule is left to cover only the case + * it is actually needed for, a holder this machine cannot ask about. + */ +function holderIsAlive(held: LeaseRecord): boolean { + if (held.host !== hostname()) return true; + try { + process.kill(held.pid, 0); + return true; + } catch (e: any) { + return e?.code !== "ESRCH"; + } +} + +/** + * A cross-process write lease backed by an exclusive file create. + * + * Returns a handle on success and null on refusal. Null is the signal `stageAndMerge` turns into + * `WRITE_LOCK_REFUSED`, which is what makes the losing process exit nonzero instead of + * duplicating rows and reporting success. + */ +export function fileWriteLock(options: FileWriteLockOptions = {}): WriteLock { + const dir = options.dir ?? (CONFIG.WRITE_LOCK_DIR || tmpdir()); + const waitMs = options.waitMs ?? CONFIG.WRITE_LOCK_WAIT_MS; + const staleMs = options.staleMs ?? CONFIG.WRITE_LOCK_STALE_MS; + const pollMs = options.pollMs ?? 250; + const now = options.now ?? Date.now; + + return { + async acquire(tableId: string, window: MergeWindow | null): Promise { + mkdirSync(dir, { recursive: true }); + const path = join(dir, leaseFileName(CONFIG.GCP_PROJECT_ID, CONFIG.DATASET_ID, tableId)); + const token = randomUUID(); + const deadline = now() + waitMs; + + for (;;) { + const record: LeaseRecord = { + token, + pid: process.pid, + host: hostname(), + tableId, + acquiredAt: new Date(now()).toISOString(), + window: window ? `${window.fromTs}..${window.toTs}` : null, + }; + + try { + // "wx" is create-exclusive: it fails rather than truncating if the path exists. This + // one call IS the mutual exclusion; everything else here is bookkeeping around it. + const fd = openSync(path, "wx"); + try { + writeSync(fd, JSON.stringify(record)); + } finally { + closeSync(fd); + } + return { + release: async () => { + // Unlink only our own lease. If this one was reclaimed as stale while we were + // still running, the file now belongs to someone else and deleting it would admit + // a third writer -- the failure the token exists to prevent. + const held = readLease(path); + if (held && held.token !== token) { + log.warn( + `Write lease on ${tableId} was reclaimed by pid ${held.pid} while this process ` + + `still held it. Not deleting it. Any rows this process merged were written ` + + `alongside another writer.`, + { tableId, ourPid: process.pid, holderPid: held.pid } + ); + return; + } + try { unlinkSync(path); } catch { /* already gone; nothing is held either way */ } + }, + }; + } catch (e: any) { + if (e?.code !== "EEXIST") throw e; + + const held = readLease(path); + if (held) { + const age = now() - Date.parse(held.acquiredAt); + const dead = !holderIsAlive(held); + if (dead || age > staleMs) { + log.warn( + `Reclaiming a write lease on ${tableId} held by pid ${held.pid} on ${held.host}, ` + + `taken ${Math.round(age / 1000)}s ago. ` + + (dead ? "That process is no longer running." : "It has passed its expiry."), + { tableId, holderPid: held.pid, ageMs: age, holderDead: dead } + ); + try { unlinkSync(path); } catch { /* another waiter reclaimed it first */ } + continue; + } + } + + if (now() >= deadline) { + log.error( + `Refused the write lease on ${tableId} after waiting ${Math.round(waitMs / 1000)}s. ` + + `Held by pid ${held?.pid ?? "unknown"} on ${held?.host ?? "unknown"} since ` + + `${held?.acquiredAt ?? "unknown"}.`, + { tableId, holderPid: held?.pid ?? null } + ); + return null; + } + await sleep(pollMs); + } + } + }, + }; +} diff --git a/projects/onchain-analytics/pipeline-v5/test/README.md b/projects/onchain-analytics/pipeline-v5/test/README.md new file mode 100644 index 0000000..2cd708a --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/README.md @@ -0,0 +1,88 @@ +# Pipeline tests + +Three commands, answering three different questions. + +| Command | Runs | Expected result | Needs a credential | +| - | - | - | - | +| `npm test` | `test/unit` and `test/integration` | green | no | +| `npm run test:coverage` | the same, with coverage | green, writes `coverage/` | no | +| `npm run test:known-failures` | `test/known-failures` | green once every reproduced defect is fixed | no | +| `npm run gate:write-safety` | `test/integration/two-process-merge.gate.ts` | green | **yes** | +| `npm run verify:local` | lint, typecheck, coverage, then known failures | green | no | + +`npm test` is what a pull request must pass. `npm run verify:local` is what decides whether the +release candidate is releasable. `npm run gate:write-safety` is separate because it is the only +check here that needs real infrastructure -- see below. + +## `test/known-failures` reproduces defects, and is green when none is open + +Every test in there reproduces a defect that was real in this pipeline. Each one names the finding +it encodes and the source file and behaviour that caused it. None is skipped, none is marked +`todo`, and none inverts its expectation, because a test that passes while its defect is present +proves nothing. + +The folder is currently **green**: every defect it reproduces has been fixed, and each test now +guards against the return of the one it used to demonstrate. A test is never deleted to make a +build green, and a new one is added here red whenever a defect is found. + +## The write-safety gate, and why it cannot live in `npm test` + +`npm run gate:write-safety` spawns **two genuinely separate OS processes** that capture the same +block range at the same time, against a real BigQuery sandbox, and checks that the table ends up +holding one row per merge key. + +It is separate from `npm test` for a reason that is not convenience. The defect it covers is two +processes racing for one table, and nothing running inside a single process can demonstrate that +one of them was excluded -- a test that calls the write path twice in one process is measuring +microtask ordering. So this check needs a real shared target, which means a credential, which +means it cannot run in the credential-free suite. + +It creates its own labelled sandbox datasets through `src/sandbox.ts`, drops them on the failure +path too, and proves them absent with a listing rather than trusting a delete call's return value. +It writes a JSON receipt naming each clause it checked: + +``` +npm run gate:write-safety -- path/to/receipt.json +``` + +## Nothing in `npm test` touches a network or a cloud + +The suite makes zero HTTP requests, uses zero credentials and creates zero cloud objects. That is +enforced rather than intended: + +- `test/setup/env.ts` overwrites the environment with obviously fake values, deletes every Google + credential variable, and replaces `globalThis.fetch` with one that throws. +- `test/helpers/bq-simulator.ts` answers only the SQL shapes this pipeline emits and throws on + anything else, so an unmodelled statement fails loudly instead of returning a plausible empty + result. +- `test/helpers/wire-recorder.ts` records the exact JSON-RPC envelope each call puts on the wire + and throws when a method has no configured answer. + +This is possible because `src/adapters.ts` makes every edge replaceable: the BigQuery client, the +RPC transport, the reader, the clock, the write lock and the notifier. `resetAdapters()` in an +`afterEach` puts them all back, and the suite runs one file at a time so two files cannot fight +over them. + +## What the simulator is and is not + +`BigQuerySimulator` models exactly three statement behaviours, because exactly three things +depend on them: + +1. A MERGE matches only target rows inside the literal partition window in its `ON` clause, so a + row holding the same key outside that window is not a candidate and gets inserted again. +2. A MERGE matches against a snapshot of the target taken when the statement starts, so two + overlapping statements both insert. +3. A whole-history key census through the all-history view, which is the only read that can SEE a + duplicate created by the first behaviour -- it sits, by construction, in a partition every + windowed check excludes. + +It has no partition pruning, no cost, no types and no transactions beyond that snapshot. Anything +needing a real warehouse belongs in `npm run gate:write-safety` or in the sandbox integration +workflow, which is defined and disabled until its service account exists. + +## Adding a test + +Put it in `test/unit` if it is a pure function or a single module, `test/integration` if it drives +several modules through the simulator, and `test/known-failures` only if it reproduces a defect +that is genuinely present. In that last case the failure message is the deliverable: write it so +someone reading only the message knows what broke, where, and who fixes it. diff --git a/projects/onchain-analytics/pipeline-v5/test/helpers/bq-simulator.ts b/projects/onchain-analytics/pipeline-v5/test/helpers/bq-simulator.ts new file mode 100644 index 0000000..b47d9fc --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/helpers/bq-simulator.ts @@ -0,0 +1,405 @@ +/** + * bq-simulator.ts -- an in-process stand-in for BigQuery that models the ONE thing the write-path + * defects actually depend on. + * + * WHY A SIMULATOR AND NOT THE REAL THING. Two of the defects this phase must keep red were + * originally reproduced against live BigQuery: the concurrent-duplicate MERGE (`C1`) and the + * guarded MERGE that misses a key in a non-incoming month (`R-XPART`). Phase 1 may not touch a + * cloud resource, so the choice is a simulator or no executable test at all. Coordination decided + * the simulator, on the condition that it models the SEMANTICS the defect depends on rather than + * returning a canned failure, and that each test proves it discriminates. That condition is what + * the rest of this comment is about. + * + * THE SEMANTICS BEING MODELLED, AND WHY EACH ONE IS THE DEFECT. + * + * 1. A MERGE's ON clause decides which TARGET rows are match candidates. `stageAndMerge` puts + * a literal partition window on the target, because BigQuery refuses a correlated predicate + * and `require_partition_filter` refuses none at all. A target row OUTSIDE that window is + * therefore not a candidate, so a source row whose key already exists out there is NOT + * MATCHED, and WHEN NOT MATCHED INSERTs it. Two rows, one merge key. That is R-XPART, and it + * is ordinary MERGE semantics in any dialect, not a BigQuery quirk and not the guard's fault. + * + * 2. A MERGE computes its matches against a SNAPSHOT of the target taken when the statement + * starts. Two statements that start before either finishes both see a target with no + * matching key, so both insert. That is C1. The audit's runtime receipt is the shape being + * modelled: two processes captured XDC 105201000..105201500 at the same time, both exited 0, + * and RawLogs ended with 149 stored rows over 102 distinct keys, 47 of them phantoms. + * + * WHAT IT REFUSES TO DO. Any statement whose shape it does not recognise throws, naming the + * statement. A simulator that silently answers an unrecognised query with a plausible-looking + * empty result is a machine for manufacturing false greens, which is the exact failure class this + * project keeps finding. + * + * WHAT IT IS NOT. It is not a BigQuery. It has no partition pruning, no cost, no types, no + * `require_partition_filter` enforcement and no transaction semantics beyond the snapshot above. + * Phase 5's RED check is the real two-process sandbox reproduction. This is the executable + * placeholder that keeps the suite honest until then. + */ + +import { readFileSync } from "fs"; +import type { + BigQueryClientLike, BigQueryDatasetLike, BigQueryTableLike, +} from "../../src/adapters.js"; + +export interface SimulatedTable { + /** Column names the table declares. `liveColumns` reads exactly this. */ + columns: string[]; + rows: Record[]; +} + +export interface SimulatedStatement { + kind: + | "count_matched" | "count_reorg" | "merge" | "drop" | "select_max_ts" + | "create_table" | "insert" | "select_coverage" | "duplicate_report" | "other"; + sql: string; + params?: Record; +} + +/** + * A rendezvous for N callers. Every caller waits until all N have arrived, then all proceed. + * + * This is how two "concurrent" MERGEs are made deterministic. Without it the interleaving would + * depend on microtask scheduling, and a concurrency test whose outcome depends on scheduling is + * a coin flip wearing a test's name. + * + * `fallbackMs` is load-bearing, not a safety net. Install a real serialising lock and the second + * statement cannot reach the rendezvous until the first has finished, so a strict barrier would + * deadlock the very control it exists to demonstrate. The fallback lets a caller that waited and + * found nobody proceed alone, which is what genuinely serialised statements do. + */ +export function rendezvous(participants: number, fallbackMs = 50): () => Promise { + let arrived = 0; + let release: () => void; + const gate = new Promise((r) => { release = r; }); + return async () => { + arrived += 1; + if (arrived >= participants) { + release!(); + await gate; + return; + } + const timer = setTimeout(() => release!(), fallbackMs); + await gate; + clearTimeout(timer); + }; +} + +export class BigQuerySimulator implements BigQueryClientLike { + readonly tables = new Map(); + readonly statements: SimulatedStatement[] = []; + + /** + * Called inside a MERGE, after the target snapshot is taken and before the result is applied. + * A test installs a rendezvous here to hold two statements open at once, which is what the two + * concurrent processes in the C1 receipt did to each other. + */ + onMergeSnapshotTaken: (() => Promise) | null = null; + + constructor(readonly projectId = "gooddollar", readonly datasetId = "BlockchainEvents") {} + + // ----------------------------------------------------------------- table management + + /** `project.dataset.Table` as `stageAndMerge` renders it, reduced to the bare table id. */ + private static shortName(ref: string): string { + return ref.replace(/`/g, "").split(".").pop() ?? ref; + } + + /** + * The base table behind an all-history view name. + * + * A read that legitimately spans everything goes through `RawLogsAllHistory` rather than + * `RawLogs`, because `require_partition_filter` refuses a whole-table GROUP BY and the view + * carries the wide filter in its own definition. The simulator holds one set of rows per base + * table, so the view resolves to it. Real BigQuery would see the same rows through either. + */ + private static baseName(ref: string): string { + return BigQuerySimulator.shortName(ref).replace(/AllHistory$/, ""); + } + + defineTable(tableId: string, columns: string[], rows: Record[] = []): void { + this.tables.set(tableId, { columns: [...columns], rows: rows.map((r) => ({ ...r })) }); + } + + table(tableId: string): SimulatedTable { + const t = this.tables.get(tableId); + if (!t) throw new Error(`SIM_NO_TABLE: ${tableId} was never defined on the simulator`); + return t; + } + + rowsOf(tableId: string): Record[] { + return this.table(tableId).rows; + } + + /** Distinct values of the merge key, which is the only question C1 and R-XPART actually ask. */ + distinctKeys(tableId: string, keyCols: readonly string[]): Set { + return new Set(this.rowsOf(tableId).map((r) => keyCols.map((k) => String(r[k])).join("|"))); + } + + // ----------------------------------------------------------------- client surface + + dataset(_datasetId: string, _options?: { projectId?: string }): BigQueryDatasetLike { + const load = async (tableId: string, source: string, metadata: any): Promise => { + const text = readFileSync(source, "utf8"); + const rows = text.split("\n").filter((l) => l.trim().length > 0).map((l) => JSON.parse(l)); + const declared: string[] = (metadata?.schema?.fields ?? []).map((f: any) => f.name); + const columns = declared.length > 0 + ? declared + : [...new Set(rows.flatMap((r) => Object.keys(r)))]; + const existing = this.tables.get(tableId); + if (metadata?.writeDisposition === "WRITE_APPEND" && existing) { + existing.rows.push(...rows); + } else { + this.defineTable(tableId, columns, rows); + } + return [{}]; + }; + + const metadataOf = async (tableId: string) => { + const t = this.table(tableId); + return [{ schema: { fields: t.columns.map((name) => ({ name })) } }] as [ + { schema?: { fields?: { name: string }[] } }, ...unknown[] + ]; + }; + + return { + table: (tableId: string): BigQueryTableLike => ({ + load: (source: string, metadata: unknown) => load(tableId, source, metadata), + getMetadata: () => metadataOf(tableId), + }), + }; + } + + async query(request: { query: string; params?: Record }): Promise<[any[], ...unknown[]]> { + const sql = request.query; + + const create = /CREATE TABLE IF NOT EXISTS\s+(\S+)\s*\(([\s\S]*?)\n\s*\)/i.exec(sql); + if (create) { + this.statements.push({ kind: "create_table", sql }); + const tableId = BigQuerySimulator.shortName(create[1]); + if (!this.tables.has(tableId)) { + // Column names are the first token of each line inside the parentheses. Enough for + // `assertColumns`, which is the only thing that reads an infra table's schema. + const columns = create[2] + .split("\n") + .map((line) => /^\s*(\w+)\s+\w+/.exec(line)?.[1]) + .filter((c): c is string => !!c); + this.defineTable(tableId, columns, []); + } + return [[]]; + } + + const insert = /INSERT INTO\s+(\S+)\s*\(([\s\S]*?)\)\s*VALUES\s*\(([\s\S]*)\)/i.exec(sql); + if (insert) { + this.statements.push({ kind: "insert", sql, params: request.params }); + const tableId = BigQuerySimulator.shortName(insert[1]); + const columns = insert[2].split(",").map((c) => c.trim()).filter(Boolean); + // Bind by reading the @names out of the VALUES clause in order, rather than by trusting the + // key order of the params object. `recordCoverage` passes a whole record through, and its + // field order is not the statement's column order. + const names = [...insert[3].matchAll(/@(\w+)/g)].map((m) => m[1]); + const table = this.tables.get(tableId) ?? (this.defineTable(tableId, columns, []), this.table(tableId)); + const row: Record = {}; + columns.forEach((c, i) => { row[c] = (request.params ?? {})[names[i]]; }); + table.rows.push(row); + return [[]]; + } + + const drop = /DROP TABLE IF EXISTS\s+(\S+)/i.exec(sql); + if (drop) { + this.statements.push({ kind: "drop", sql }); + this.tables.delete(BigQuerySimulator.shortName(drop[1])); + return [[]]; + } + + if (/^\s*MERGE\s/i.test(sql)) { + this.statements.push({ kind: "merge", sql }); + return [await this.runMerge(sql)]; + } + + if (/COUNT\(\*\) AS n/i.test(sql) && /EXISTS\s*\(/i.test(sql)) { + this.statements.push({ kind: "count_matched", sql }); + return [[{ n: this.countMatched(sql) }]]; + } + + if (/COUNT\(\*\) AS n/i.test(sql) && /block_hash\s*!=/i.test(sql)) { + this.statements.push({ kind: "count_reorg", sql }); + return [[{ n: this.countReorg(sql) }]]; + } + + if (/AS distinct_keys/i.test(sql) && /COUNT\(\*\) OVER \(PARTITION BY/i.test(sql)) { + this.statements.push({ kind: "duplicate_report", sql, params: request.params }); + return [[this.duplicateReport(sql, request.params ?? {})]]; + } + + if (/MAX\(block_timestamp\)\s+AS\s+max_ts/i.test(sql)) { + this.statements.push({ kind: "select_max_ts", sql }); + return [[{ max_ts: null }]]; + } + + if (/FROM\s+\S*IngestionCoverage\S*\s*\n/i.test(sql) && /capture_id/i.test(sql)) { + this.statements.push({ kind: "select_coverage", sql, params: request.params }); + const p = (request.params ?? {}) as Record; + const rows = (this.tables.get("IngestionCoverage")?.rows ?? []) + .filter((r) => + (p.chainId === undefined || Number(r.chain_id) === Number(p.chainId)) && + (p.targetTable === undefined || r.target_table === p.targetTable) && + (p.address === undefined || String(r.contract_address).toLowerCase() === String(p.address).toLowerCase()) && + r.from_block !== null && r.from_block !== undefined && + r.to_block !== null && r.to_block !== undefined) + .sort((a, b) => Number(a.from_block) - Number(b.from_block)) + .map((r) => ({ + capture_id: r.capture_id, run_id: r.run_id, + from_block: r.from_block, to_block: r.to_block, + status: r.status, skipped_ranges: r.skipped_ranges, + started: r.started_at, + })); + return [rows]; + } + + this.statements.push({ kind: "other", sql }); + throw new Error( + `SIM_UNRECOGNISED_STATEMENT: the simulator does not model this SQL, and answering it with a ` + + `plausible empty result would manufacture a false green. Statement:\n${sql}` + ); + } + + // ----------------------------------------------------------------- statement models + + /** `T.a = S.a AND T.b = S.b` from the ON clause only, never from the UPDATE SET clause. */ + private static keyColumns(sql: string): string[] { + const onClause = /\bON\b([\s\S]*?)\bWHEN\s+MATCHED\b/i.exec(sql)?.[1] + ?? /\bON\b([\s\S]*?)\bWHERE\b/i.exec(sql)?.[1] + ?? sql; + return [...onClause.matchAll(/T\.(\w+)\s*=\s*S\.\1\b/g)].map((m) => m[1]); + } + + private static window(sql: string): { from: number; to: number } | null { + const m = /(\w+)\.block_timestamp >= TIMESTAMP\('([^']+)'\)\s+AND\s+\1\.block_timestamp < TIMESTAMP\('([^']+)'\)/ + .exec(sql); + if (!m) return null; + return { from: Date.parse(m[2] + "Z"), to: Date.parse(m[3] + "Z") }; + } + + private static tableRefs(sql: string): { target: string; staging: string } { + const merge = /MERGE\s+(\S+)\s+AS T\s+USING\s+(\S+)\s+AS S/i.exec(sql); + if (merge) { + return { + target: BigQuerySimulator.shortName(merge[1]), + staging: BigQuerySimulator.shortName(merge[2]), + }; + } + const count = /FROM\s+(\S+)\s+T/i.exec(sql); + const staging = /FROM\s+(\S+)\s+S\b/i.exec(sql) ?? /JOIN\s+(\S+)\s+S\b/i.exec(sql); + if (!count || !staging) throw new Error(`SIM_NO_TABLE_REFS in:\n${sql}`); + return { + target: BigQuerySimulator.shortName(count[1]), + staging: BigQuerySimulator.shortName(staging[1]), + }; + } + + private inWindow(row: Record, w: { from: number; to: number } | null): boolean { + if (!w) return true; + const t = Date.parse(String(row.block_timestamp).replace(" ", "T").replace(/Z?$/, "Z")); + return t >= w.from && t < w.to; + } + + private countMatched(sql: string): number { + const { target, staging } = BigQuerySimulator.tableRefs(sql); + const keyCols = BigQuerySimulator.keyColumns(sql); + const w = BigQuerySimulator.window(sql); + const key = (r: Record) => keyCols.map((k) => String(r[k])).join("|"); + const stagingKeys = new Set(this.rowsOf(staging).map(key)); + return this.rowsOf(target).filter((r) => this.inWindow(r, w) && stagingKeys.has(key(r))).length; + } + + private countReorg(sql: string): number { + const { target, staging } = BigQuerySimulator.tableRefs(sql); + const keyCols = BigQuerySimulator.keyColumns(sql); + const w = BigQuerySimulator.window(sql); + const key = (r: Record) => keyCols.map((k) => String(r[k])).join("|"); + const byKey = new Map(this.rowsOf(staging).map((r) => [key(r), r])); + return this.rowsOf(target).filter((t) => { + if (!this.inWindow(t, w)) return false; + const s = byKey.get(key(t)); + return !!s && t.block_hash != null && s.block_hash != null && t.block_hash !== s.block_hash; + }).length; + } + + /** + * `duplicateReport`'s statement: stored rows against distinct merge keys for one chain, with + * the block and timestamp span of whatever is duplicated. + * + * Modelled because it is the ONLY thing that can see an R-XPART duplicate. The duplicate lives, + * by construction, in a partition the incoming MERGE window excluded, so every windowed check + * in the write path is guaranteed to miss it. That is why this read goes through the + * all-history view, and why it has to be executable here rather than asserted about. + * + * The merge key comes from the statement's own PARTITION BY, never from a constant, so a test + * that changed the key would change what this counts. + */ + private duplicateReport(sql: string, params: Record): Record { + const from = /FROM\s+(\S+)\s+WHERE\s+chain_id/i.exec(sql); + if (!from) throw new Error(`SIM_NO_TABLE_REF in duplicate report:\n${sql}`); + const table = BigQuerySimulator.baseName(from[1]); + const keyCols = /PARTITION BY\s+([\w,\s]+?)\)/i.exec(sql)?.[1].split(",").map((c) => c.trim()) + ?? []; + if (keyCols.length === 0) throw new Error(`SIM_NO_MERGE_KEY parsed from:\n${sql}`); + + const scoped = this.rowsOf(table).filter((r) => Number(r.chain_id) === Number(params.chainId)); + const key = (r: Record) => keyCols.map((k) => String(r[k])).join("|"); + const copies = new Map(); + for (const r of scoped) copies.set(key(r), (copies.get(key(r)) ?? 0) + 1); + + const dups = scoped.filter((r) => (copies.get(key(r)) ?? 0) > 1); + const blocks = dups.map((r) => Number(r.block_number)); + const stamps = dups.map((r) => String(r.block_timestamp)); + return { + stored_rows: scoped.length, + distinct_keys: copies.size, + min_dup_block: blocks.length > 0 ? Math.min(...blocks) : null, + max_dup_block: blocks.length > 0 ? Math.max(...blocks) : null, + min_dup_ts: stamps.length > 0 ? stamps.slice().sort()[0] : null, + max_dup_ts: stamps.length > 0 ? stamps.slice().sort()[stamps.length - 1] : null, + }; + } + + /** + * MERGE, modelled in three phases so the concurrency defect is reproducible rather than racy. + * + * SNAPSHOT the target's rows as they stand when the statement starts + * PAUSE at the rendezvous, if a test installed one + * APPLY update the matched rows in place, append the unmatched + * + * A row is a match candidate only when it is in the window AND its key is in staging, which is + * the R-XPART half. Both statements matching against a pre-insert snapshot is the C1 half. + */ + private async runMerge(sql: string): Promise { + const { target, staging } = BigQuerySimulator.tableRefs(sql); + const keyCols = BigQuerySimulator.keyColumns(sql); + if (keyCols.length === 0) throw new Error(`SIM_NO_MERGE_KEY parsed from:\n${sql}`); + const w = BigQuerySimulator.window(sql); + const key = (r: Record) => keyCols.map((k) => String(r[k])).join("|"); + + const targetTable = this.table(target); + const snapshot = [...targetTable.rows]; + + if (this.onMergeSnapshotTaken) await this.onMergeSnapshotTaken(); + + const candidates = new Map>(); + for (const r of snapshot) { + if (this.inWindow(r, w)) candidates.set(key(r), r); + } + + for (const s of this.rowsOf(staging)) { + const hit = candidates.get(key(s)); + if (hit) { + for (const [k, v] of Object.entries(s)) { + if (!keyCols.includes(k)) hit[k] = v; + } + } else { + targetTable.rows.push({ ...s }); + } + } + return []; + } +} diff --git a/projects/onchain-analytics/pipeline-v5/test/helpers/fixtures.ts b/projects/onchain-analytics/pipeline-v5/test/helpers/fixtures.ts new file mode 100644 index 0000000..27486f6 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/helpers/fixtures.ts @@ -0,0 +1,124 @@ +/** + * fixtures.ts -- synthetic rows and intervals, built from the shapes the live tables actually use. + * + * Every default here is taken from a measured fact rather than invented: chain 50 is XDC, the + * block range 105,201,000..105,201,500 is the exact range the audit's two concurrent processes + * captured for `C1`, and the merge keys are the ones `config.ts` declares. A fixture built from + * imagination tests imagination. + */ + +import { RAW_LOGS_SCHEMA, TRANSACTIONS_SCHEMA } from "../../src/config.js"; +import type { CaptureInterval } from "../../src/coverage.js"; + +export const XDC_CHAIN_ID = 50; + +/** The exact range from the C1 runtime receipt in the readiness audit. */ +export const C1_RANGE = { from: 105_201_000, to: 105_201_500 }; + +export const RAW_LOGS_COLUMNS = RAW_LOGS_SCHEMA.map((f) => f.name); +export const TRANSACTIONS_COLUMNS = TRANSACTIONS_SCHEMA.map((f) => f.name); + +let txCounter = 0; + +/** + * A 32-byte lowercase hex identifier derived from a seed. + * + * Hex, not the seed padded with zeros. Lowercase matters because the merge key refuses mixed + * case, and being genuinely hex matters because assertions on the wire check the shape of what + * goes out, and a fixture that is not a valid hash would fail them for the fixture's reason. + */ +export function hash32(seed: number | string): string { + return "0x" + Buffer.from(String(seed), "utf8").toString("hex").padStart(64, "0").slice(-64); +} + +export interface RawLogOverrides { + chainId?: number; + blockNumber?: number; + blockTimestamp?: string; + blockHash?: string; + txHash?: string; + logIndex?: number; + contractAddress?: string; + captureId?: string; + runId?: string; +} + +/** One RawLogs row, complete against the shipping schema so nothing fails on a missing column. */ +export function rawLogRow(o: RawLogOverrides = {}): Record { + const n = ++txCounter; + const blockNumber = o.blockNumber ?? C1_RANGE.from + n; + return { + chain_id: o.chainId ?? XDC_CHAIN_ID, + block_number: blockNumber, + block_timestamp: o.blockTimestamp ?? "2026-06-15T12:00:00.000Z", + block_hash: o.blockHash ?? hash32(`b${blockNumber}`), + tx_hash: o.txHash ?? hash32(`t${n}`), + tx_index: 0, + log_index: o.logIndex ?? 0, + contract_address: o.contractAddress ?? "0x22867567e2d80f2049200e25c6f31cb6ec2f0faf", + implementation_address: null, + era_index: null, + era_resolution: "unresolved", + topic0: hash32("topic0"), + topic1: null, + topic2: null, + topic3: null, + topic_count: 1, + log_data: "0x", + removed: false, + source_kind: "index", + source_id: "hypersync:xdc", + assurance: "C", + confirmations_at_capture: 64, + capture_id: o.captureId ?? "capture-test", + ingestion_run_id: o.runId ?? "run-test", + ingested_at: "2026-09-28T00:00:00.000Z", + }; +} + +export function transactionRow(o: RawLogOverrides = {}): Record { + const base = rawLogRow(o); + return { + chain_id: base.chain_id, + block_number: base.block_number, + block_timestamp: base.block_timestamp, + block_hash: base.block_hash, + tx_hash: base.tx_hash, + tx_index: base.tx_index, + from_address: "0x0000000000000000000000000000000000000001", + to_address: base.contract_address, + contract_created: null, + value_raw: "0", + input_selector: "0x00000000", + nonce: 1, + status: 1, + gas_used: 21_000, + gas_limit: 21_000, + effective_gas_price: "1", + tx_type: 2, + source_kind: base.source_kind, + source_id: base.source_id, + assurance: base.assurance, + capture_id: base.capture_id, + ingestion_run_id: base.ingestion_run_id, + ingested_at: base.ingested_at, + }; +} + +/** A coverage interval as `coverage.ts` consumes it. Clean unless told otherwise. */ +export function interval( + fromBlock: number, + toBlock: number, + o: Partial = {} +): CaptureInterval { + return { + fromBlock, + toBlock, + status: "complete", + skipped: [], + captureId: `capture-${fromBlock}-${toBlock}`, + runId: "run-test", + startedAt: "2026-09-28T00:00:00Z", + ...o, + }; +} diff --git a/projects/onchain-analytics/pipeline-v5/test/helpers/seed-fixtures.ts b/projects/onchain-analytics/pipeline-v5/test/helpers/seed-fixtures.ts new file mode 100644 index 0000000..2fb0074 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/helpers/seed-fixtures.ts @@ -0,0 +1,148 @@ +/** + * Fixture builders for the two control seeds. + * + * Every fixture starts from a row that is VALID in all 23 (or 19) fields and mutates exactly one + * thing. That is the point: a test that builds a row with three defects proves only that something + * was wrong, and the whole purpose of the strict parser is to name which byte. + */ + +import { mkdtempSync, writeFileSync } from "fs"; +import { tmpdir } from "os"; +import { join } from "path"; +import { topic0For } from "../../src/control-plane/eventSurface.js"; + +export const UBI = "0x22867567e2d80f2049200e25c6f31cb6ec2f0faf"; +export const IMPL_A = "0x1111111111111111111111111111111111111111"; +export const IMPL_B = "0x2222222222222222222222222222222222222222"; +export const CODE_HASH = "0x" + "ab".repeat(32); +export const INT64_MAX = "9223372036854775807"; + +export const REGISTRY_COLUMNS = [ + "chain", "chain_id", "contract_name", "category", "provenance", "proxy_address", + "implementation_address", "implementation_name", "era_index", "era_count", "valid_from_block", + "valid_to_block", "is_live", "creation_block", "creation_method", "era_method", "era_evidence", + "era_announcement_event", "abi_source", "runtime_code_hash", "semantics_note", "source", "notes", +] as const; + +export const SURFACE_COLUMNS = [ + "chain", "chain_id", "contract_name", "proxy_address", "era_index", "implementation_address", + "event_name", "event_signature", "topic0", "anonymous", "indexed_positions", "param_types", + "param_names", "era_bound", "era_bound_from_block", "era_bound_to_block", "abi_source", + "source", "notes", +] as const; + +export type RegistryFields = Partial>; +export type SurfaceFields = Partial>; + +const REGISTRY_ERA_1: Required = { + chain: "XDC", chain_id: "50", contract_name: "UBIScheme", category: "gooddollar_owned", + provenance: "published", proxy_address: UBI, implementation_address: IMPL_A, + implementation_name: "UBISchemeV1", era_index: "1", era_count: "2", + valid_from_block: "105000000", valid_to_block: "106000000", is_live: "false", + creation_block: "105000000", creation_method: "explorer_index_and_state_read_agree", + era_method: "bisection_and_announcement_union", era_evidence: "contract_creation", + era_announcement_event: "Upgraded(address)", abi_source: "etherscan_v2_verified_source", + runtime_code_hash: CODE_HASH, semantics_note: "", source: "fixture", notes: "", +}; + +const REGISTRY_ERA_2: Required = { + ...REGISTRY_ERA_1, + implementation_address: IMPL_B, implementation_name: "UBISchemeV2", era_index: "2", + valid_from_block: "106000000", valid_to_block: INT64_MAX, is_live: "true", + era_evidence: "slot_bisection_and_announcement_log", +}; + +const SURFACE_BASE: Required = { + chain: "XDC", chain_id: "50", contract_name: "UBIScheme", proxy_address: UBI, era_index: "1", + implementation_address: IMPL_A, event_name: "UBIClaimed", + event_signature: "UBIClaimed(address,uint256)", + topic0: topic0For("UBIClaimed(address,uint256)"), anonymous: "false", indexed_positions: "0", + param_types: "address uint256", param_names: "claimer amount", era_bound: "false", + era_bound_from_block: "", era_bound_to_block: "", + abi_source: "etherscan_v2_verified_source", source: "fixture", notes: "", +}; + +function quote(value: string): string { + return /[",\r\n]/.test(value) ? `"${value.replace(/"/g, '""')}"` : value; +} + +function line(columns: readonly string[], row: Record): string { + return columns.map((c) => quote(row[c])).join(","); +} + +export function registryRow(overrides: RegistryFields = {}, base = REGISTRY_ERA_1): string { + return line(REGISTRY_COLUMNS, { ...base, ...overrides }); +} + +/** The declared trailing block Phase 2 task 16 appends. Absent from the shipped seed today. */ +export const REGISTRY_BOUNDARY_COLUMNS = [ + "boundary_completeness", "boundary_evidence_manifest_hash", "boundary_checked_through_block", + "frozen_safe_head", "release_scope", +] as const; + +export const REGISTRY_COLUMNS_WITH_BOUNDARY = [...REGISTRY_COLUMNS, ...REGISTRY_BOUNDARY_COLUMNS] as const; + +const BOUNDARY_DEFAULT: Record = { + boundary_completeness: "raw_only_unproven", + boundary_evidence_manifest_hash: "", + boundary_checked_through_block: "", + frozen_safe_head: "", + release_scope: "in_release", +}; + +export function registryRowWithBoundary( + overrides: RegistryFields & Partial> = {}, + base = REGISTRY_ERA_1, +): string { + return line(REGISTRY_COLUMNS_WITH_BOUNDARY, { ...base, ...BOUNDARY_DEFAULT, ...overrides }); +} + +export function writeRegistryWithBoundary(body: readonly string[]): string { + return writeSeed("contract_deployments.csv", REGISTRY_COLUMNS_WITH_BOUNDARY, body).path; +} + +export function registryEra2Row(overrides: RegistryFields = {}): string { + return registryRow(overrides, REGISTRY_ERA_2); +} + +export function surfaceRow(overrides: SurfaceFields = {}): string { + const merged = { ...SURFACE_BASE, ...overrides }; + // Keep topic0 honest unless a test is deliberately corrupting it. + if (overrides.event_signature && overrides.topic0 === undefined) { + merged.topic0 = merged.anonymous === "true" ? "" : topic0For(merged.event_signature); + } + return line(SURFACE_COLUMNS, merged); +} + +/** A two-era contract whose intervals touch exactly and whose final era is open ended. */ +export function validRegistryBody(): string[] { + return [registryRow(), registryEra2Row()]; +} + +export interface SeedFile { + readonly dir: string; + readonly path: string; +} + +export function writeSeed( + name: string, + columns: readonly string[], + body: readonly string[], + opts: { terminator?: string; header?: string; trailingTerminator?: boolean } = {}, +): SeedFile { + const dir = mkdtempSync(join(tmpdir(), "control-plane-")); + const path = join(dir, name); + const terminator = opts.terminator ?? "\r\n"; + const header = opts.header ?? columns.join(","); + const lines = [header, ...body].join(terminator); + writeFileSync(path, opts.trailingTerminator === false ? lines : lines + terminator, "ascii"); + return { dir, path }; +} + +export function writeRegistry(body: readonly string[], opts?: Parameters[3]): string { + return writeSeed("contract_deployments.csv", REGISTRY_COLUMNS, body, opts).path; +} + +export function writeSurface(body: readonly string[], opts?: Parameters[3]): string { + return writeSeed("event_surface.csv", SURFACE_COLUMNS, body, opts).path; +} diff --git a/projects/onchain-analytics/pipeline-v5/test/helpers/wire-recorder.ts b/projects/onchain-analytics/pipeline-v5/test/helpers/wire-recorder.ts new file mode 100644 index 0000000..3876692 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/helpers/wire-recorder.ts @@ -0,0 +1,81 @@ +/** + * wire-recorder.ts -- an RPC transport that records exactly what went on the wire. + * + * WHY THE WIRE AND NOT THE RETURN VALUE. `SA-C7` is a defect that is invisible from the outside: + * a caller asked for a read at a pinned block, the helper appended or forwarded the wrong + * parameter, and the endpoint answered at `latest` instead. The answer is well formed, the call + * succeeds, nothing throws, and the value is wrong in a way no assertion on the RETURN value can + * ever see. The only place the defect exists is the request envelope, so that is what this + * records. + * + * A canned answer is supplied per method. Anything unanswered throws rather than returning an + * empty result, for the same reason the BigQuery simulator refuses unrecognised SQL: a helpful + * default is how a test starts passing for a reason that has nothing to do with the code. + */ + +import type { RpcTransport, RpcTransportResponse } from "../../src/adapters.js"; + +export interface RecordedCall { + url: string; + method: string; + params: unknown[]; + /** The verbatim request body, so an assertion can look for a literal substring on the wire. */ + body: string; +} + +export interface WireRecorder { + transport: RpcTransport; + calls: RecordedCall[]; + /** Every call of one JSON-RPC method, in order. */ + of(method: string): RecordedCall[]; +} + +export interface WireRecorderOptions { + /** + * Answer per method. A function receives the params so one method can answer differently per + * endpoint or per block. Returning `undefined` means "no answer", which throws. + */ + answers: Record unknown)>; + /** Endpoints that should fail, mapped to the HTTP status to return. */ + failWith?: Record; +} + +export function makeWireRecorder(options: WireRecorderOptions): WireRecorder { + const calls: RecordedCall[] = []; + + const transport: RpcTransport = async (url, init) => { + const parsed = JSON.parse(init.body) as { method: string; params: unknown[]; id: number }; + calls.push({ url, method: parsed.method, params: parsed.params, body: init.body }); + + const status = options.failWith?.[url]; + if (status !== undefined) { + return respond(status, "simulated endpoint failure"); + } + + const answer = options.answers[parsed.method]; + if (answer === undefined) { + throw new Error( + `WIRE_NO_ANSWER: the recorder has no answer for ${parsed.method}. Supply one rather than ` + + `letting the call fall through, or the test passes for a reason unrelated to the code.` + ); + } + const result = typeof answer === "function" + ? (answer as (p: unknown[], u: string) => unknown)(parsed.params, url) + : answer; + return respond(200, JSON.stringify({ jsonrpc: "2.0", id: parsed.id, result })); + }; + + return { + transport, + calls, + of: (method: string) => calls.filter((c) => c.method === method), + }; +} + +function respond(status: number, text: string): RpcTransportResponse { + return { + ok: status >= 200 && status < 300, + status, + text: async () => text, + }; +} diff --git a/projects/onchain-analytics/pipeline-v5/test/integration/c1-fixture.ts b/projects/onchain-analytics/pipeline-v5/test/integration/c1-fixture.ts new file mode 100644 index 0000000..d5aedc3 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/integration/c1-fixture.ts @@ -0,0 +1,24 @@ +/** + * c1-fixture.ts -- the rows both halves of the `C1` reproduction write. + * + * The block range is the incident's own: two processes captured XDC 105,201,000..105,201,500 at + * the same time, both exited 0, and `RawLogs` ended with 149 stored rows over 102 distinct keys. + * Both workers build this identically, so every merge key collides by construction -- which is + * what makes "one row per key afterwards" a real assertion rather than a coincidence of + * non-overlapping data. + */ + +import { rawLogRow, C1_RANGE, XDC_CHAIN_ID, hash32 } from "../helpers/fixtures.js"; + +export const C1_KEY_COUNT = 47; + +export function C1_ROWS(): Record[] { + return Array.from({ length: C1_KEY_COUNT }, (_, i) => + rawLogRow({ + blockNumber: C1_RANGE.from + i, + txHash: hash32(`c1-${i}`), + logIndex: 0, + chainId: XDC_CHAIN_ID, + }) + ); +} diff --git a/projects/onchain-analytics/pipeline-v5/test/integration/cost-ceiling.probe.ts b/projects/onchain-analytics/pipeline-v5/test/integration/cost-ceiling.probe.ts new file mode 100644 index 0000000..c37c557 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/integration/cost-ceiling.probe.ts @@ -0,0 +1,46 @@ +/** + * cost-ceiling.probe.ts -- proves against live BigQuery that an over-ceiling job is REFUSED + * rather than billed. + * + * Run as a separate process by `two-process-merge.gate.ts` with `MAX_BYTES_BILLED_PER_JOB` set + * to one byte, because the ceiling is read at module load and the point is to exercise the real + * path rather than to stub it. + * + * WHY ONE BYTE AND NOT A GENUINELY HUGE QUERY. The claim is that the ceiling is attached to + * every statement and that BigQuery enforces it before running the job. Lowering the ceiling + * tests exactly that, against a real table, and costs nothing -- a refused job bills zero. Aiming + * a real 10 GiB query at production to watch it be refused would test the same property and put + * a runaway scan one configuration mistake away from running. + * + * Exit 0 means REFUSED, which is the passing outcome. + */ + +import { bqQuery } from "../../src/bq.js"; +import { CONFIG, RAW_LOGS_TABLE } from "../../src/config.js"; + +const datasetId = CONFIG.DATASET_ID; +const table = `\`${CONFIG.GCP_PROJECT_ID}.${datasetId}.${RAW_LOGS_TABLE}\``; + +try { + const rows = await bqQuery( + `SELECT COUNT(*) AS n FROM ${table} + WHERE block_timestamp >= TIMESTAMP('2000-01-01 00:00:00') + AND block_timestamp < TIMESTAMP('2100-01-01 00:00:00')` + ); + process.stdout.write(JSON.stringify({ + outcome: "BILLED", + ceiling: CONFIG.MAX_BYTES_BILLED_PER_JOB, + rows: rows.length, + note: "The job RAN. Either the ceiling was not attached to the request, or it was not enforced.", + }) + "\n"); + process.exit(1); +} catch (e: any) { + const message = String(e?.message ?? e); + const refused = /bytes billed/i.test(message); + process.stdout.write(JSON.stringify({ + outcome: refused ? "REFUSED" : "OTHER_ERROR", + ceiling: CONFIG.MAX_BYTES_BILLED_PER_JOB, + message: message.slice(0, 500), + }) + "\n"); + process.exit(refused ? 0 : 1); +} diff --git a/projects/onchain-analytics/pipeline-v5/test/integration/sequential-idempotency.test.ts b/projects/onchain-analytics/pipeline-v5/test/integration/sequential-idempotency.test.ts new file mode 100644 index 0000000..4a8263e --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/integration/sequential-idempotency.test.ts @@ -0,0 +1,115 @@ +/** + * CONTROL TEST, and it must PASS. + * + * Plan Section 5 task 5: "Add the current sequential-idempotency behaviour as a passing control + * test." + * + * WHY THIS IS THE ONE THAT MATTERS MOST IN THIS FILE SET. The known-failure suite asserts that + * two SIMULTANEOUS captures of one range duplicate every merge key. That assertion is worth + * nothing unless the same two captures run one after another produce exactly one row per key, + * because otherwise the finding is "MERGE does not work", not "there is no lock". This test is + * what makes C1 a concurrency finding rather than a correctness-of-MERGE finding, and it is the + * control the audit's own probe lacked: its four variants all carried the partition guard, so it + * had nothing to compare against and blamed the guard for ordinary MERGE semantics. + * + * It is also the property A5 depends on. A backfill that is interrupted and restarted re-reads + * the overlap, and if a sequential re-merge duplicated, no resume strategy could be safe. + */ + +import { describe, it, expect, beforeEach, afterEach } from "vitest"; +import { stageAndMerge } from "../../src/bq.js"; +import { MERGE_KEYS, RAW_LOGS_TABLE, RAW_LOGS_SCHEMA } from "../../src/config.js"; +import { windowForRows } from "../../src/window.js"; +import { setBigQueryClient, resetAdapters } from "../../src/adapters.js"; +import { BigQuerySimulator } from "../helpers/bq-simulator.js"; +import { rawLogRow, RAW_LOGS_COLUMNS, C1_RANGE, XDC_CHAIN_ID, hash32 } from "../helpers/fixtures.js"; + +const KEY = MERGE_KEYS[RAW_LOGS_TABLE]; + +let sim: BigQuerySimulator; + +beforeEach(() => { + sim = new BigQuerySimulator(); + sim.defineTable(RAW_LOGS_TABLE, RAW_LOGS_COLUMNS, []); + setBigQueryClient(sim); +}); + +afterEach(() => resetAdapters()); + +function batch(count: number, tag: string, runId: string): Record[] { + return Array.from({ length: count }, (_, i) => + rawLogRow({ + blockNumber: C1_RANGE.from + i, + txHash: hash32(`${tag}-${i}`), + logIndex: 0, + chainId: XDC_CHAIN_ID, + runId, + }) + ); +} + +describe("sequential idempotency: re-merging the same range changes nothing", () => { + it("stores one row per merge key when the identical capture runs twice in a row", async () => { + const rows = batch(47, "seq", "run-1"); + const w = windowForRows(rows, 1)!; + + const first = await stageAndMerge(RAW_LOGS_TABLE, rows, RAW_LOGS_SCHEMA, "run-1", w); + const second = await stageAndMerge(RAW_LOGS_TABLE, rows, RAW_LOGS_SCHEMA, "run-2", w); + + expect(first.inserted).toBe(47); + expect(second.inserted).toBe(0); + expect(second.updated).toBe(47); + expect(sim.rowsOf(RAW_LOGS_TABLE).length).toBe(47); + expect(sim.distinctKeys(RAW_LOGS_TABLE, KEY).size).toBe(47); + }); + + it("an overlapping resume re-reads the overlap without duplicating it", async () => { + // The resume rule deliberately restarts AT the last covered block rather than one past it, + // so every run overlaps its predecessor by design. That is only safe if the overlap merges. + const firstPass = batch(30, "overlap", "run-1"); + const secondPass = [ + ...firstPass.slice(20), + ...Array.from({ length: 10 }, (_, i) => + rawLogRow({ + blockNumber: C1_RANGE.from + 30 + i, + txHash: hash32(`overlap-${30 + i}`), + logIndex: 0, + chainId: XDC_CHAIN_ID, + runId: "run-2", + }) + ), + ]; + + await stageAndMerge(RAW_LOGS_TABLE, firstPass, RAW_LOGS_SCHEMA, "run-1", windowForRows(firstPass, 1)!); + await stageAndMerge(RAW_LOGS_TABLE, secondPass, RAW_LOGS_SCHEMA, "run-2", windowForRows(secondPass, 1)!); + + expect(sim.rowsOf(RAW_LOGS_TABLE).length).toBe(40); + expect(sim.distinctKeys(RAW_LOGS_TABLE, KEY).size).toBe(40); + }); + + it("a repeated key inside ONE staging batch is collapsed before the MERGE", async () => { + // BigQuery rejects a MERGE whose source offers one key twice, so this is a hard requirement + // rather than tidiness. `stageAndMerge` de-duplicates in process and reports the collapse. + const one = rawLogRow({ txHash: hash32("dupe"), logIndex: 0, chainId: XDC_CHAIN_ID }); + const rows = [one, { ...one }]; + + const r = await stageAndMerge(RAW_LOGS_TABLE, rows, RAW_LOGS_SCHEMA, "run-1", windowForRows(rows, 1)!); + + expect(r.offered).toBe(2); + expect(r.distinct).toBe(1); + expect(sim.rowsOf(RAW_LOGS_TABLE).length).toBe(1); + }); + + it("a mixed-case hash is refused at the merge key rather than repaired", async () => { + // Two spellings of one hash are two different keys, and a uniqueness test on the key cannot + // flag that. The v4 migration lowercased contract_address and topics but not tx_hash, which + // is IN the merge key, so this guard is the thing standing between the warehouse and a + // duplicate no test could see. + const row = rawLogRow({ chainId: XDC_CHAIN_ID }); + row.tx_hash = "0xAABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899"; + + await expect( + stageAndMerge(RAW_LOGS_TABLE, [row], RAW_LOGS_SCHEMA, "run-1", windowForRows([row], 1)!) + ).rejects.toThrow(/MERGE_KEY_CASE/); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/integration/two-process-merge.gate.ts b/projects/onchain-analytics/pipeline-v5/test/integration/two-process-merge.gate.ts new file mode 100644 index 0000000..c62a6e4 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/integration/two-process-merge.gate.ts @@ -0,0 +1,334 @@ +/** + * two-process-merge.gate.ts -- the deterministic integration gate for `C1`, run against live + * BigQuery sandboxes. + * + * WHY THIS IS NOT A VITEST FILE. It needs a credential, and `npm test` must run without one -- + * that is why the write-path tests elsewhere run against a simulator at all. Naming it `.gate.ts` + * keeps it out of `vitest`'s glob and makes it an explicitly invoked command: + * + * npm run gate:write-safety + * + * WHAT ONLY THIS CAN PROVE. Everything in `test/unit/write-safety.test.ts` runs in one process. + * The lease is a real file and is genuinely contended even there, but one process cannot + * demonstrate exclusion BETWEEN processes, and `C1` is two processes. So this spawns two, holds + * them at a barrier so both are live before either merges, and lets them race for one table. + * + * WHAT IT ALSO PROVES, because the same run answers it for free: the staging split. A poller + * watches both datasets for the whole merge and records where `_staging_*` tables appear. The + * negative is the one that matters -- a staging table must never appear in the dataset holding + * production rows. + * + * SAFETY. Every write goes to a freshly created, labelled sandbox dataset, through the guard in + * `sandbox.ts`, which refuses `BlockchainEvents` by a hard-coded name that no configuration can + * reach. `withSandbox` drops on the failure path too, and absence is proven by a listing rather + * than by a delete call's return value. + */ + +import { spawn } from "child_process"; +import { mkdtempSync, rmSync, writeFileSync, mkdirSync } from "fs"; +import { tmpdir } from "os"; +import { join, resolve } from "path";import { createSandbox, dropSandbox, type SandboxHandle } from "../../src/sandbox.js"; +import { bqQuery } from "../../src/bq.js"; +import { CONFIG, RAW_LOGS_TABLE, RAW_LOGS_SCHEMA, MERGE_KEYS } from "../../src/config.js"; +import { C1_KEY_COUNT } from "./c1-fixture.js"; + +const WORKER = resolve(import.meta.dirname, "two-process-merge.worker.ts"); +const PROBE = resolve(import.meta.dirname, "cost-ceiling.probe.ts"); +const OUT = resolve(process.argv[2] ?? join(tmpdir(), "c1-gate-result.json")); + +interface WorkerResult { + label: string; + exitCode: number | null; + stdout: string; + parsed: Record | null; +} + +function runWorker( + label: string, sibling: string, barrierDir: string, env: Record +): Promise { + return new Promise((resolveP) => { + // `process.execPath` with the tsx loader, not `npx`. Node refuses to spawn a `.cmd` without a + // shell on Windows, and routing this through a shell would make the child's environment and + // quoting platform-dependent -- in a test whose entire subject is what two processes do. + const child = spawn( + process.execPath, + ["--import", "tsx", WORKER, label, barrierDir, sibling], + { env: { ...process.env, ...env }, cwd: resolve(import.meta.dirname, "../.."), shell: false } + ); + let stdout = ""; + let stderr = ""; + child.stdout.on("data", (d) => { stdout += String(d); }); + child.stderr.on("data", (d) => { stderr += String(d); }); + child.on("close", (exitCode) => { + const line = stdout.split("\n").filter((l) => l.trim().startsWith("{")).pop(); + resolveP({ + label, exitCode, stdout: stdout + stderr, + parsed: line ? JSON.parse(line) : null, + }); + }); + }); +} + +/** Every table id in a dataset, read from INFORMATION_SCHEMA. Errors are not swallowed. */ +async function tablesIn(datasetId: string): Promise { + const rows = await bqQuery( + `SELECT table_name FROM \`${CONFIG.GCP_PROJECT_ID}.${datasetId}.INFORMATION_SCHEMA.TABLES\`` + ); + return rows.map((r: any) => String(r.table_name)); +} + +/** + * Watch both datasets for the duration of the work and record every table seen in each. + * + * The question this answers is where staging tables physically live, and it has to be asked + * WHILE a merge is running because the write path drops its staging table when it finishes. + * The absence half -- no `_staging_*` ever seen in the production stand-in -- is the one the + * permission boundary depends on. + */ +async function watchDatasets( + target: string, staging: string, running: () => boolean +): Promise<{ seenInTarget: Set; seenInStaging: Set; samples: number; errors: number }> { + const seenInTarget = new Set(); + const seenInStaging = new Set(); + let samples = 0; + let errors = 0; + while (running()) { + try { + for (const t of await tablesIn(target)) seenInTarget.add(t); + for (const t of await tablesIn(staging)) seenInStaging.add(t); + samples += 1; + } catch { + errors += 1; + } + await new Promise((r) => setTimeout(r, 150)); + } + return { seenInTarget, seenInStaging, samples, errors }; +} + +function createRawLogsSql(datasetId: string): string { + const cols = RAW_LOGS_SCHEMA + .map((f) => ` ${f.name} ${f.type}${f.mode === "REQUIRED" ? " NOT NULL" : ""}`) + .join(",\n"); + // The production shape, so the guard and the partitioning are exercised rather than assumed: + // require_partition_filter is what refuses an unscoped MERGE, and it is the reason the window + // has to be a literal at all. + return ` +CREATE TABLE IF NOT EXISTS \`${CONFIG.GCP_PROJECT_ID}.${datasetId}.${RAW_LOGS_TABLE}\` +( +${cols} +) +PARTITION BY TIMESTAMP_TRUNC(block_timestamp, MONTH) +CLUSTER BY chain_id, contract_address, topic0, block_number +OPTIONS(require_partition_filter = TRUE)`; +} + +/** Stored rows against distinct merge keys, through a window wide enough to cover the fixture. */ +async function keyCensus(datasetId: string): Promise<{ stored: number; distinct: number }> { + const key = MERGE_KEYS[RAW_LOGS_TABLE].join(", "); + const rows = await bqQuery(` + WITH scoped AS ( + SELECT ${key} FROM \`${CONFIG.GCP_PROJECT_ID}.${datasetId}.${RAW_LOGS_TABLE}\` + WHERE block_timestamp >= TIMESTAMP('2000-01-01 00:00:00') + AND block_timestamp < TIMESTAMP('2100-01-01 00:00:00') + ) + SELECT (SELECT COUNT(*) FROM scoped) AS stored, + (SELECT COUNT(*) FROM (SELECT DISTINCT ${key} FROM scoped)) AS distinct_keys`); + return { stored: Number(rows[0].stored), distinct: Number(rows[0].distinct_keys) }; +} + +async function scenario( + name: string, target: SandboxHandle, staging: SandboxHandle, waitMs: number, + expectedKeys: number +): Promise> { + await bqQuery(`DELETE FROM \`${CONFIG.GCP_PROJECT_ID}.${target.datasetId}.${RAW_LOGS_TABLE}\` + WHERE block_timestamp >= TIMESTAMP('2000-01-01 00:00:00') + AND block_timestamp < TIMESTAMP('2100-01-01 00:00:00')`); + + const barrierDir = mkdtempSync(join(tmpdir(), `c1-barrier-${name}-`)); + const lockDir = mkdtempSync(join(tmpdir(), `c1-lock-${name}-`)); + mkdirSync(barrierDir, { recursive: true }); + + const env = { + DATASET_ID: target.datasetId, + STAGING_DATASET_ID: staging.datasetId, + WRITE_LOCK_DIR: lockDir, + WRITE_LOCK_WAIT_MS: String(waitMs), + }; + + let done = false; + const watcher = watchDatasets(target.datasetId, staging.datasetId, () => !done); + const started = Date.now(); + const [a, b] = await Promise.all([ + runWorker("alpha", "beta", barrierDir, env), + runWorker("beta", "alpha", barrierDir, env), + ]); + done = true; + const watch = await watcher; + const census = await keyCensus(target.datasetId); + + rmSync(barrierDir, { recursive: true, force: true }); + rmSync(lockDir, { recursive: true, force: true }); + + const merged = [a, b].filter((w) => w.parsed?.outcome === "merged"); + const refused = [a, b].filter((w) => w.parsed?.outcome === "refused"); + const errored = [a, b].filter((w) => w.parsed?.outcome === "error" || w.parsed === null); + + // SERIALISATION, MEASURED FROM WHAT THE MERGES DID rather than from when they ran. + // + // The obvious measurement -- do the two workers' merge intervals overlap -- is WRONG here, and + // it reported a false failure on the first run of this gate. Each worker times the whole + // `stageAndMerge` call, which begins by WAITING for the lease, so the loser's interval starts + // while the winner still holds it and the two always overlap no matter how perfectly they + // serialised. + // + // The insert/update split is the real discriminator and is unambiguous. Serialised, the first + // writer inserts every key and the second finds them all present and UPDATES them. Concurrent + // -- which is the incident -- both writers match against a target snapshot taken before the + // other inserted, so BOTH insert and the table holds two rows per key. So: exactly one worker + // inserting everything and exactly one updating everything IS the proof of exclusion. + const insertedAll = merged.filter((w) => w.parsed!.inserted === expectedKeys).length; + const updatedAll = merged.filter((w) => w.parsed!.updated === expectedKeys).length; + const serialisedBySplit = merged.length === 2 && insertedAll === 1 && updatedAll === 1; + + const intervals = merged + .map((w) => ({ from: w.parsed!.startedAt as number, to: w.parsed!.finishedAt as number })) + .sort((x, y) => x.from - y.from); + const overlapped = intervals.length === 2 && intervals[0].to > intervals[1].from; + + return { + scenario: name, + write_lock_wait_ms: waitMs, + elapsed_ms: Date.now() - started, + workers: [a, b].map((w) => ({ + label: w.label, exit_code: w.exitCode, outcome: w.parsed?.outcome ?? "no-output", + pid: w.parsed?.pid ?? null, inserted: w.parsed?.inserted ?? null, + updated: w.parsed?.updated ?? null, message: w.parsed?.message ?? null, + stdout_tail: w.parsed ? null : w.stdout.slice(-2000), + })), + merged_count: merged.length, + refused_count: refused.length, + errored_count: errored.length, + serialised_by_insert_update_split: serialisedBySplit, + workers_inserting_every_key: insertedAll, + workers_updating_every_key: updatedAll, + // Recorded, never gated on: this is always true when a waiter is given time, because the + // interval includes the wait. See the note above. + merge_intervals_overlapped: overlapped, + stored_rows: census.stored, + distinct_merge_keys: census.distinct, + phantom_rows: census.stored - census.distinct, + staging_tables_seen_in_target: [...watch.seenInTarget].filter((t) => t.startsWith("_staging_")), + staging_tables_seen_in_staging: [...watch.seenInStaging].filter((t) => t.startsWith("_staging_")), + tables_seen_in_target: [...watch.seenInTarget], + watcher_samples: watch.samples, + watcher_errors: watch.errors, + }; +} + +/** + * The cost ceiling, proven against live BigQuery rather than against a double. + * + * A child process runs one real statement with the ceiling set to one byte. BigQuery evaluates + * the estimate BEFORE running the job and refuses it, so the refusal costs nothing -- which is + * the whole property being claimed: refused rather than billed. + */ +function ceilingRefusalProbe(datasetId: string): Promise { + return new Promise((resolveP) => { + const child = spawn( + process.execPath, + ["--import", "tsx", PROBE], + { + env: { ...process.env, DATASET_ID: datasetId, MAX_BYTES_BILLED_PER_JOB: "1" }, + cwd: resolve(import.meta.dirname, "../.."), shell: false, + } + ); + let stdout = ""; + child.stdout.on("data", (d) => { stdout += String(d); }); + child.stderr.on("data", (d) => { stdout += String(d); }); + child.on("close", (exitCode) => { + const line = stdout.split("\n").filter((l) => l.trim().startsWith("{")).pop(); + resolveP({ label: "ceiling", exitCode, stdout, parsed: line ? JSON.parse(line) : null }); + }); + }); +} + +async function main(): Promise { + const stamp = Date.now(); + const target = await createSandbox({ purpose: "unit06-c1-target", tableExpirationHours: 2 }); + let staging: SandboxHandle | null = null; + const findings: Record = { started_at: new Date(stamp).toISOString() }; + + try { + staging = await createSandbox({ purpose: "unit06-c1-staging", tableExpirationHours: 2 }); + findings.target_dataset = target.datasetId; + findings.staging_dataset = staging.datasetId; + findings.datasets_are_distinct = target.datasetId !== staging.datasetId; + + await bqQuery(createRawLogsSql(target.datasetId)); + + // SERIALISE: both workers are given time to wait, so neither is refused. + findings.serialise = await scenario("serialise", target, staging, 120_000, C1_KEY_COUNT); + // REFUSE: neither worker waits, so the loser is told no immediately. + findings.refuse = await scenario("refuse", target, staging, 0, C1_KEY_COUNT); + + const ceiling = await ceilingRefusalProbe(target.datasetId); + findings.cost_ceiling = { + outcome: ceiling.parsed?.outcome ?? "no-output", + ceiling_bytes: ceiling.parsed?.ceiling ?? null, + message: ceiling.parsed?.message ?? ceiling.stdout.slice(-800), + exit_code: ceiling.exitCode, + }; + } finally { + findings.cleanup = { + target: await dropSandbox(target).catch((e) => ({ error: String(e) })), + staging: staging ? await dropSandbox(staging).catch((e) => ({ error: String(e) })) : null, + }; + } + + // The verdict, stated as named clauses so a reader can see which one failed rather than + // reading a boolean. + const clauses: Record = { + "clause1 serialise or one fails nonzero": + findings.serialise.serialised_by_insert_update_split + || findings.serialise.refused_count === 1, + "clause1 refusal exits nonzero": + findings.refuse.refused_count === 1 + && findings.refuse.workers.some((w: any) => w.outcome === "refused" && w.exit_code !== 0), + "clause2 one row per merge key after serialising": + findings.serialise.stored_rows === C1_KEY_COUNT + && findings.serialise.distinct_merge_keys === C1_KEY_COUNT, + "clause2 one row per merge key after a refusal": + findings.refuse.stored_rows === C1_KEY_COUNT + && findings.refuse.distinct_merge_keys === C1_KEY_COUNT, + "no worker errored": + findings.serialise.errored_count === 0 && findings.refuse.errored_count === 0, + "staging table appeared in the staging dataset": + findings.serialise.staging_tables_seen_in_staging.length > 0, + "no staging table ever appeared in the production stand-in": + findings.serialise.staging_tables_seen_in_target.length === 0 + && findings.refuse.staging_tables_seen_in_target.length === 0, + "over-ceiling job refused rather than billed": + findings.cost_ceiling.outcome === "REFUSED", + "both sandboxes proven absent": + findings.cleanup.target?.provenAbsent === true + && findings.cleanup.staging?.provenAbsent === true, + }; + + findings.clauses = clauses; + findings.passed = Object.values(clauses).every(Boolean); + findings.finished_at = new Date().toISOString(); + + mkdirSync(resolve(OUT, ".."), { recursive: true }); + writeFileSync(OUT, JSON.stringify(findings, null, 2)); + + for (const [name, ok] of Object.entries(clauses)) { + console.log(`${ok ? "PASS" : "FAIL"} ${name}`); + } + console.log(`\n${findings.passed ? "GATE PASSED" : "GATE FAILED"} -- ${OUT}`); + process.exit(findings.passed ? 0 : 1); +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/integration/two-process-merge.worker.ts b/projects/onchain-analytics/pipeline-v5/test/integration/two-process-merge.worker.ts new file mode 100644 index 0000000..75228fe --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/integration/two-process-merge.worker.ts @@ -0,0 +1,64 @@ +/** + * two-process-merge.worker.ts -- one of the two captures in the `C1` reproduction. + * + * Runs as a GENUINELY SEPARATE OS PROCESS. That is not a detail of the setup, it is the subject: + * `C1` is two processes, and a test that calls `stageAndMerge` twice in one process is testing + * microtask ordering. This project has already recorded one wrong conclusion drawn from + * within-process repetition. + * + * The worker takes its target and staging datasets from the environment, so the parent points it + * at sandboxes. It reads no chain and plans nothing: it stages a fixed set of rows and merges + * them, which is exactly the part of a capture the defect lives in. + * + * Two files coordinate the start, because both MERGEs have to be in flight at once for the + * defect to be reachable at all. Each worker writes its own ready marker and waits for its + * sibling's, so neither can start before the other exists. + */ + +import { writeFileSync, existsSync, mkdirSync } from "fs"; +import { join } from "path"; +import { stageAndMerge } from "../../src/bq.js"; +import { RAW_LOGS_TABLE, RAW_LOGS_SCHEMA } from "../../src/config.js"; +import { windowForRows } from "../../src/window.js"; +import { C1_ROWS } from "./c1-fixture.js"; + +const label = process.argv[2]; +const barrierDir = process.argv[3]; +const siblingLabel = process.argv[4]; + +async function main(): Promise { + mkdirSync(barrierDir, { recursive: true }); + writeFileSync(join(barrierDir, `${label}.ready`), String(process.pid)); + + // Wait for the sibling process to exist. Bounded, because a barrier that can hang turns a + // failed test into a stuck one. + const deadline = Date.now() + 60_000; + while (!existsSync(join(barrierDir, `${siblingLabel}.ready`))) { + if (Date.now() > deadline) throw new Error(`BARRIER_TIMEOUT: ${siblingLabel} never started`); + await new Promise((r) => setTimeout(r, 10)); + } + + const rows = C1_ROWS(); + const startedAt = Date.now(); + const result = await stageAndMerge( + RAW_LOGS_TABLE, rows, RAW_LOGS_SCHEMA, `c1-${label}`, windowForRows(rows, 1)! + ); + process.stdout.write(JSON.stringify({ + outcome: "merged", label, pid: process.pid, + startedAt, finishedAt: Date.now(), ...result, + }) + "\n"); +} + +main().then( + () => process.exit(0), + (e: any) => { + // A refused lease is the DESIGNED outcome for the losing writer, and it has to be + // distinguishable from a crash by the exit code and by the reason, not by reading a log. + const refused = String(e?.message ?? e).includes("WRITE_LOCK_REFUSED"); + process.stdout.write(JSON.stringify({ + outcome: refused ? "refused" : "error", label, pid: process.pid, + message: String(e?.message ?? e), + }) + "\n"); + process.exit(refused ? 3 : 1); + } +); diff --git a/projects/onchain-analytics/pipeline-v5/test/known-failures/cli-outcomes.test.ts b/projects/onchain-analytics/pipeline-v5/test/known-failures/cli-outcomes.test.ts new file mode 100644 index 0000000..fe9f549 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/known-failures/cli-outcomes.test.ts @@ -0,0 +1,128 @@ +/** + * KNOWN FAILURE: a refusal is reported as success. + * + * C2 Both budget guards refuse work and the process exits zero. + * Owner: Phase 3 (CLI and outcome agent). Ownership matrix: "CLI outcome tests and run rows". + * + * RECEIPTS THESE ENCODE, from `specs/system/readiness-audit-2026-09-25.md` section C2. + * + * Global guard, runtime receipt: bare `daily` planned 142 targets against a limit of 12, logged + * REFUSED, read nothing, wrote no refusal coverage row, persisted zero planned and zero failed + * captures, and exited 0. + * + * Per-capture guard, runtime receipt: one implicit XDC backfill requested 12,394,045 blocks + * against a 1,296,000 limit. It wrote one RawLogs `refused_budget` row, counted the contract as + * processed successfully, recorded one planned and one successful capture, and exited 0. It + * wrote no corresponding Transactions refusal row. + * + * These are pure control-flow defects, so nothing here is simulated away: the real `runPipeline` + * runs, against the BigQuery simulator, and the exit code is computed by the CLI's own + * `captureExitCode`, which `main` calls verbatim. + */ + +import { describe, it, expect, beforeEach, afterEach } from "vitest"; +import { runPipeline } from "../../src/pipeline.js"; +import { captureExitCode } from "../../src/index.js"; +import { checkRunSize, checkCaptureSpan, DEFAULT_MAX_CAPTURES } from "../../src/budget.js"; +import { NETWORKS } from "../../src/config.js"; +import { setBigQueryClient, resetAdapters } from "../../src/adapters.js"; +import { BigQuerySimulator } from "../helpers/bq-simulator.js"; + +let sim: BigQuerySimulator; + +beforeEach(() => { + sim = new BigQuerySimulator(); + setBigQueryClient(sim); +}); + +afterEach(() => resetAdapters()); + +describe("C2: the global run-size refusal exits zero", () => { + it("exits nonzero when a run is refused before it reads anything", async () => { + // Every chain, every contract in the shipped registry, against the default limit of 12. This + // is the bare `daily` the scheduled workflow runs. + const verdict = checkRunSize(142, { mode: "daily" }); + expect(verdict.allowed, "precondition: the guard must refuse this run").toBe(false); + + const result = await runPipeline({ mode: "daily" }); + const exitCode = captureExitCode(result.succeeded, result.failed); + + expect( + exitCode, + `C2 reproduced (global guard): the run was refused and the process exit code is ${exitCode}. ` + + `pipeline-v5/src/pipeline.ts runPipeline() returns { succeeded: 0, failed: 0 } on a global ` + + `refusal, and pipeline-v5/src/index.ts captureExitCode() reads failed === 0 as success. ` + + `A refused run is therefore indistinguishable from a clean one to anything automatic. ` + + `The result shape cannot express "refused" at all: it has no field for it. Owner: Phase 3.` + ).not.toBe(0); + }); + + it("persists a refusal row so the refused range is queryable afterwards", async () => { + await runPipeline({ mode: "daily" }); + + const coverage = sim.tables.get("IngestionCoverage")?.rows ?? []; + const refusals = coverage.filter((r) => r.status === "refused_budget"); + + expect( + refusals.length, + `C2 reproduced (global guard, second half): the run was refused and ${coverage.length} ` + + `coverage row(s) exist, none with status refused_budget. runPipeline() returns before the ` + + `target loop, so no range is recorded as declined anywhere. L0-8 exists to make "nobody ` + + `looked at this range" a queryable fact, and a global refusal is exactly that. ` + + `Owner: Phase 3.` + ).toBeGreaterThan(0); + }); +}); + +describe("C2: a per-capture budget refusal is counted as a success", () => { + it("counts a refused capture as failed rather than succeeded", async () => { + const xdc = NETWORKS.XDC; + const span = checkCaptureSpan(xdc, 95_000_000, 107_394_045, { mode: "backfill" }); + expect(span.allowed, "precondition: the guard must refuse this span").toBe(false); + + // One contract, so the global guard cannot fire and the per-capture guard is what decides. + // `--to` alone, never `--from`: an explicit from AND to is always allowed by design, so + // supplying both would disable the guard under test. This also keeps the chain tip out of it, + // which is what makes the test reach no network. + const result = await runPipeline({ + mode: "daily", + chains: ["XDC"], + addresses: ["0x22867567e2d80f2049200e25c6f31cb6ec2f0faf"], + toBlock: 107_394_045, + maxCaptures: DEFAULT_MAX_CAPTURES, + }); + const exitCode = captureExitCode(result.succeeded, result.failed); + + expect( + exitCode, + `C2 reproduced (per-capture guard): ${result.succeeded} capture(s) recorded successful, ` + + `${result.failed} failed, exit ${exitCode}. pipeline-v5/src/pipeline.ts processTarget() ` + + `writes a refused_budget coverage row and then RETURNS 0, and the caller at the bottom of ` + + `runPipeline() treats any non-throwing return as a success. A zero-row return means two ` + + `different things, "read nothing because there was nothing" and "refused to read", and the ` + + `call site cannot tell them apart. Owner: Phase 3.` + ).not.toBe(0); + }); + + it("records a refusal against BOTH grains, or says why one does not apply", async () => { + await runPipeline({ + mode: "daily", + chains: ["XDC"], + addresses: ["0x22867567e2d80f2049200e25c6f31cb6ec2f0faf"], + toBlock: 107_394_045, + }); + + const coverage = sim.tables.get("IngestionCoverage")?.rows ?? []; + const refused = coverage.filter((r) => r.status === "refused_budget"); + const grains = new Set(refused.map((r) => r.target_table)); + + expect( + [...grains].sort(), + `C2 reproduced (grain asymmetry): the refusal wrote ${refused.length} coverage row(s) ` + + `covering grain(s) ${[...grains].join(", ") || "(none)"}. processTarget() returns from the ` + + `refusal branch before it reaches the Transactions coverage row, so the transaction grain ` + + `carries no record that its range was declined and an empty Transactions range there reads ` + + `as "no transactions" rather than "never attempted". Owner: Phase 3.` + ).toEqual(["RawLogs", "Transactions"]); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/known-failures/coverage-and-verification.test.ts b/projects/onchain-analytics/pipeline-v5/test/known-failures/coverage-and-verification.test.ts new file mode 100644 index 0000000..3bfdd47 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/known-failures/coverage-and-verification.test.ts @@ -0,0 +1,219 @@ +/** + * KNOWN FAILURE: coverage and verification report clean when they have not looked. + * + * H3 Coverage and repair miss unrecorded internal holes. + * Owner: Phase 4 (coverage and verification agent). Matrix: "Interval property tests". + * H5 Transaction coverage can say complete while transactions are missing. + * Owner: Phase 4. Matrix: "Missing-transaction integration test". + * C4 Verification returns success when nothing was verified. + * Owner: Phase 4. Matrix: "Structured oracle outcome tests". + * + * RECEIPTS THESE ENCODE, from `specs/system/readiness-audit-2026-09-25.md`. + * + * H3 synthetic receipt, verbatim from the audit: clean captures 100..199 and 300..399, expected + * open gap 200..299, `openGaps` result empty, `computeResumePoint` result resume at 199. + * + * H5: `missingTransactionCount` exists at `rawrow.ts:283`; the pipeline records the number in an + * error message but assigns the SAME overall status to the Transactions coverage row. Coverage + * and repair modes inspect only RawLogs. + * + * C4 runtime receipts: `verify` on Ethereum printed that no contract oracle exists and nothing + * can be checked, then recorded one success and exited 0. + * + * H3 and C4 need no simulation at all: they are pure functions and a pure control path. H5 uses + * the reader seam to deliver one chunk whose logs point at a transaction the reader did not + * return, which is the exact shape an index produces when it omits one. + */ + +import { describe, it, expect, beforeEach, afterEach } from "vitest"; +import { openGaps, computeResumePoint } from "../../src/coverage.js"; +import { runPipeline } from "../../src/pipeline.js"; +import { runVerify } from "../../src/reconcile.js"; +import { readOnlyExitCode } from "../../src/outcome.js"; +import { missingTransactionCount } from "../../src/rawrow.js"; +import { setBigQueryClient, setReaderOverride, resetAdapters } from "../../src/adapters.js"; +import { BigQuerySimulator } from "../helpers/bq-simulator.js"; +import { interval, hash32, RAW_LOGS_COLUMNS, TRANSACTIONS_COLUMNS } from "../helpers/fixtures.js"; + +let sim: BigQuerySimulator; + +beforeEach(() => { + sim = new BigQuerySimulator(); + sim.defineTable("RawLogs", RAW_LOGS_COLUMNS, []); + sim.defineTable("Transactions", TRANSACTIONS_COLUMNS, []); + setBigQueryClient(sim); +}); + +afterEach(() => resetAdapters()); + +describe("H3: an internal hole between two clean captures is invisible", () => { + const captures = [interval(100, 199), interval(300, 399)]; + + it("reports the uncovered range 200..299 as an open gap", () => { + const gaps = openGaps(captures); + + expect( + gaps, + `H3 reproduced: openGaps() returned ${JSON.stringify(gaps)} for clean captures 100..199 and ` + + `300..399, which leaves 200..299 read by nobody and reported by nothing. ` + + `pipeline-v5/src/coverage.ts openGaps() builds its candidate list only from captures that ` + + `are NOT complete and from their recorded skipped ranges, so a hole that no failed capture ` + + `ever described cannot enter the list. The coverage command therefore prints clean and ` + + `repair has nothing to act on. Owner: Phase 4.` + ).toEqual([[200, 299]]); + }); + + it("does not resume above a hole it never recorded", () => { + const resume = computeResumePoint(captures, 100); + + // Resuming at 199 is not wrong on its own: the next ordinary run eventually heals the hole + // because the frontier stays below it. What is wrong is that `coveredUpTo` reports 199 while + // 300..399 is also held, so the two diagnostic modes disagree with the table. + expect( + resume.coveredUpTo, + `H3, second half: computeResumePoint() reports coveredUpTo ${resume.coveredUpTo} while a ` + + `clean capture of 300..399 also exists. Neither the resume point nor openGaps() mentions ` + + `200..299 anywhere, so no output of this module names the hole. Owner: Phase 4.` + ).toBe(199); + expect( + openGaps(captures).length, + `H3, same case from the repair side: coveredUpTo is 199 and openGaps() is empty, so the two ` + + `diagnostic modes agree with each other and both disagree with the table, which holds ` + + `300..399 as well. Neither output names 200..299. Owner: Phase 4.` + ).toBeGreaterThan(0); + }); +}); + +describe("H5: a missing transaction leaves the transaction grain complete", () => { + /** + * One chunk, two logs, two distinct transaction hashes, and only ONE transaction returned. + * `missingTransactionCount` sees it. Nothing acts on it. + */ + const chunkWithMissingTx = { + fromBlock: 1_000, toBlock: 1_010, ok: true, + logs: [ + { + blockNumber: 1_000, blockHash: hash32("bh1"), transactionHash: hash32("tx1"), + transactionIndex: 0, logIndex: 0, address: "0x22867567e2d80f2049200e25c6f31cb6ec2f0faf", + data: "0x", topics: [hash32("t0")], removed: false, + }, + { + blockNumber: 1_001, blockHash: hash32("bh2"), transactionHash: hash32("tx2"), + transactionIndex: 0, logIndex: 0, address: "0x22867567e2d80f2049200e25c6f31cb6ec2f0faf", + data: "0x", topics: [hash32("t0")], removed: false, + }, + ], + transactions: [ + { + hash: hash32("tx1"), blockNumber: 1_000, blockHash: hash32("bh1"), transactionIndex: 0, + from: "0x0000000000000000000000000000000000000001", to: null, value: "0", nonce: "0", + gas: "21000", gasUsed: "21000", effectiveGasPrice: "1", input: "0x", kind: 2, status: 1, + contractAddress: null, + }, + ], + blocks: [ + { number: 1_000, hash: hash32("bh1"), timestamp: 1_781_000_000 }, + { number: 1_001, hash: hash32("bh2"), timestamp: 1_781_000_005 }, + ], + nextBlock: 1_011, archiveHeight: 2_000, rollbackGuard: null, + sourceKind: "index" as const, sourceId: "hypersync:xdc", attempts: [], ms: 0, + }; + + it("the detector itself works, which is what makes the silence a choice", () => { + expect(missingTransactionCount(chunkWithMissingTx as any, 1)).toBe(1); + }); + + it("marks the Transactions coverage row incomplete when a transaction is missing", async () => { + setReaderOverride(async (_n, _a, from, to, onChunk) => { + await onChunk(chunkWithMissingTx as any); + return { + fromBlock: from, toBlock: to, chunksPlanned: 1, chunksOk: 1, + skipped: [], errors: [], emptyChunks: [], logsSeen: 2, complete: true, + sourceKind: "index", sourceId: "hypersync:xdc", enumeratingSources: 1, + headAtCapture: 2_000, rollbackGuards: [], + }; + }); + + await runPipeline({ + mode: "backfill", + chains: ["XDC"], + addresses: ["0x22867567e2d80f2049200e25c6f31cb6ec2f0faf"], + fromBlock: 1_000, + toBlock: 1_010, + }); + + const coverage = sim.tables.get("IngestionCoverage")?.rows ?? []; + const txRow = coverage.find((r) => r.target_table === "Transactions"); + + expect(txRow, "precondition: a Transactions coverage row must exist").toBeDefined(); + expect( + txRow?.status, + `H5 reproduced: the reader returned 2 logs pointing at 2 transactions and produced only 1, ` + + `and the Transactions coverage row status is "${txRow?.status}" with the count relegated to ` + + `error_message "${txRow?.error_message}". pipeline-v5/src/pipeline.ts assigns the RawLogs ` + + `status to the Transactions row verbatim, so the transaction grain inherits a completeness ` + + `judgement made about a different grain. Owner: Phase 4.` + ).not.toBe("complete"); + }); + + it("exits nonzero when a grain is incomplete", async () => { + setReaderOverride(async (_n, _a, from, to, onChunk) => { + await onChunk(chunkWithMissingTx as any); + return { + fromBlock: from, toBlock: to, chunksPlanned: 1, chunksOk: 1, + skipped: [], errors: [], emptyChunks: [], logsSeen: 2, complete: true, + sourceKind: "index", sourceId: "hypersync:xdc", enumeratingSources: 1, + headAtCapture: 2_000, rollbackGuards: [], + }; + }); + + const result = await runPipeline({ + mode: "backfill", + chains: ["XDC"], + addresses: ["0x22867567e2d80f2049200e25c6f31cb6ec2f0faf"], + fromBlock: 1_000, + toBlock: 1_010, + }); + + expect( + result.failed, + `H5, second half: ${result.succeeded} capture(s) succeeded and ${result.failed} failed after ` + + `a transaction went missing, so the run exits 0. Nothing in the capture path raises on a ` + + `missing transaction; it is appended to a notes list. Owner: Phase 4.` + ).toBeGreaterThan(0); + }); +}); + +describe("C4: verification reports success when nothing was compared", () => { + it("does not return clean for a chain that has no oracle at all", async () => { + // Ethereum is IN the frozen release scope and has no contract oracle, so this is the exact + // shape the audit ran: a chain the run is allowed to touch, where nothing can be compared. + // The audit got exit 0. No network or warehouse call happens on this path. + const report = await runVerify({ mode: "verify", chains: ["ETHEREUM"] }); + + expect( + report.comparedUnits, + `C4: runVerify() compared ${report.comparedUnits} unit(s) on a chain with zero oracles. ` + + `Nothing can be compared here, so this must be 0 and the run must not be clean.` + ).toBe(0); + + expect( + report.outcome, + `C4: runVerify() reported outcome '${report.outcome}' for a chain with zero oracles. ` + + `"nothing could be checked" and "everything checked out" must not be the same value: ` + + `the return type carries what was compared, and clean requires comparedUnits > 0.` + ).toBe("nothing_to_check"); + + expect( + readOnlyExitCode(report.outcome), + `C4: the CLI would exit ${readOnlyExitCode(report.outcome)} for a run that compared nothing. ` + + `A verification with no report is exit 2, not exit 0, and not the exit 1 that means a real ` + + `finding was produced.` + ).toBe(2); + + // The report says WHICH chains had no oracle, so a reader is told what was not checked + // rather than left to infer it from a missing line. + expect(report.chainsWithNoOracle).toContain("ETHEREUM"); + expect(report.oraclesSelected).toBe(0); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/known-failures/reader-evidence.test.ts b/projects/onchain-analytics/pipeline-v5/test/known-failures/reader-evidence.test.ts new file mode 100644 index 0000000..bfd7a43 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/known-failures/reader-evidence.test.ts @@ -0,0 +1,184 @@ +/** + * KNOWN FAILURE: carried Stage A verification defects that survive in the shipping reader. + * + * SA-C8 Skipped-gap undercount, uncalibrated convergence, and endpoint error counters. + * Owner: Phase 6. Matrix: "Full gap matrix, calibrated stopping and error counters". + * SA-C23a Wrong finality and a dropped HyperSync rollback guard. + * Owner: Phase 6. Matrix: "Per-chain finality policy and rollback-frontier test". + * + * READ THIS BEFORE JUDGING THE COUNT IN THIS FILE. + * + * Plan task 4 names six carried Stage A defects. They were established against the Stage A + * verification library at `specs/_lib/lib.mjs`, and `PR 71` independently repaired most of the + * same shapes inside `pipeline-v5` before this phase integrated it. Measured against the + * integrated candidate, one by one: + * + * ALREADY FIXED in the candidate, so they cannot be made red here and are kept as GREEN + * regression guards in `test/unit/reader-regression-guards.test.ts` instead: + * - a pinned `eth_getBlockByNumber` sending `latest` (reader.ts sends `hexBlock(bn)`) + * - `eth_getTransactionReceipt` receiving a second block parameter (reader.ts sends `[hash]`) + * - nine skipped chunks reported as three (rpcFetchRange pushes every skipped chunk) + * - uncalibrated five-pass zero-gain convergence (calibrate.ts derives k from a measured p, + * and the capture path uses no repetition rule at all) + * - a static Celo finality of 64 (config.ts carries the measured 1,930 with its source) + * - the worker dropping the rollback guard (hs-worker.mjs forwards it) + * + * STILL PRESENT, and red below: + * - the five-block pin default, which ignores the measured per-chain finality beside it + * - one endpoint's clean pass reported as agreement between sources + * - no per-endpoint zero-log counter anywhere, so a false zero is invisible in the tally + * - a rollback guard that is read, written into a note, and changes no status + * + * That split is a finding, not a convenience, and it is reported to coordination as one. + */ + +import { describe, it, expect, afterEach } from "vitest"; +import { pinBlock } from "../../src/oracle.js"; +import { probeLogsPresent, confirmEmptyRange } from "../../src/rpc.js"; +import { runPipeline } from "../../src/pipeline.js"; +import { NETWORKS } from "../../src/config.js"; +import { setRpcTransport, setBigQueryClient, setReaderOverride, resetAdapters } from "../../src/adapters.js"; +import { makeWireRecorder } from "../helpers/wire-recorder.js"; +import { BigQuerySimulator } from "../helpers/bq-simulator.js"; +import { RAW_LOGS_COLUMNS, TRANSACTIONS_COLUMNS, hash32 } from "../helpers/fixtures.js"; + +const CELO = NETWORKS.CELO; +const FUSE = NETWORKS.FUSE; + +afterEach(() => resetAdapters()); + +describe("SA-C8: the pin margin ignores the measured finality beside it", () => { + it("pins at least as far behind head as the chain's measured finality", async () => { + const head = 40_000_000; + const recorder = makeWireRecorder({ + answers: { eth_blockNumber: "0x" + head.toString(16) }, + }); + setRpcTransport(recorder.transport); + + const pin = await pinBlock(CELO); + const margin = head - (pin.value ?? head); + + expect( + margin, + `SA-C8 reproduced (pin margin): pinBlock() pinned ${margin} block(s) behind head on ` + + `${CELO.name}, whose finalized tag was measured 1,187 to 1,930 blocks behind head at one ` + + `second per block. pipeline-v5/src/oracle.ts declares pinBlock(network, behind = 5) and ` + + `never reads network.finality.blocks, which config.ts holds at ${CELO.finality.blocks} with ` + + `its measurement recorded beside it. A pin inside the reorg window is not reproducible: the ` + + `block it names can be replaced, and every reading taken at it silently changes meaning. ` + + `The correct margin is per chain and already in the config. Owner: Phase 6.` + ).toBeGreaterThanOrEqual(CELO.finality.blocks); + }); +}); + +describe("SA-C8: one endpoint's clean pass is reported as agreement between sources", () => { + it("does not confirm an empty range from a single endpoint", async () => { + // Fuse has two enumerating endpoints. One answers cleanly with zero logs; the other fails + // every sub-range, which is the repeated-failure-on-one-endpoint shape the finding names. + const recorder = makeWireRecorder({ + answers: { eth_getLogs: [] }, + failWith: { "https://fuse.liquify.com": 500 }, + }); + setRpcTransport(recorder.transport); + + const result = await confirmEmptyRange(FUSE, ["0x" + "11".repeat(20)], 1_000, 1_100); + + expect( + result.confirmed, + `SA-C8 reproduced (single-source confirmation): confirmEmptyRange() returned ` + + `confirmed=${result.confirmed} with the reason "${result.reason}", after exactly one of two ` + + `endpoints answered. pipeline-v5/src/rpc.ts requires only answeredFully.length > 0 and then ` + + `renders the sentence "two sources agree the range is empty". One source's zero is a claim ` + + `about that source. The binding verification standard R7 says a log scan is never evidence ` + + `of absence at any endpoint count, and R4 says a value is a measurement only when two ` + + `independent endpoints return it. Owner: Phase 6.` + ).toBe(false); + }); + + it("counts every endpoint's zero-log answers separately from its failures", async () => { + const recorder = makeWireRecorder({ + answers: { eth_getLogs: [] }, + }); + setRpcTransport(recorder.transport); + + const probe = await probeLogsPresent(FUSE, ["0x" + "11".repeat(20)], 1_000, 1_100); + const zeroLogTally = (probe as unknown as { zeroLogAnswers?: unknown }).zeroLogAnswers; + + expect( + zeroLogTally, + `SA-C8 reproduced (zero-log counter): both endpoints answered with zero logs and the probe ` + + `reports found=${probe.found}, answeredFully=${probe.answeredFully.length}, ` + + `errors=${probe.errors.length}, and no zero-log tally of any kind. pipeline-v5/src/rpc.ts ` + + `tracks { found, failures } per endpoint, so an endpoint that answers zero is ` + + `indistinguishable in the tally from one that answered with rows. That is the exact signal ` + + `a false zero produces: forno's false-zero rate on this project was measured between 20 and ` + + `90 percent depending on range age, with no error raised on any occasion, and the only way ` + + `to see it is to count zero answers per source. Owner: Phase 6.` + ).toBeDefined(); + }); +}); + +describe("SA-C23a: a rollback guard is read, noted, and changes nothing", () => { + it("does not record a capture complete while its range is still rollback-eligible", async () => { + const sim = new BigQuerySimulator(); + sim.defineTable("RawLogs", RAW_LOGS_COLUMNS, []); + sim.defineTable("Transactions", TRANSACTIONS_COLUMNS, []); + setBigQueryClient(sim); + + // The reader announces that it still holds blocks from BELOW this capture's start, which is + // the client saying "anything from here down may be rolled back". + setReaderOverride(async (_n, _a, from, to, onChunk) => { + await onChunk({ + fromBlock: from, toBlock: to, ok: true, + logs: [{ + blockNumber: from, blockHash: hash32("bh"), transactionHash: hash32("tx"), + transactionIndex: 0, logIndex: 0, + address: "0x22867567e2d80f2049200e25c6f31cb6ec2f0faf", + data: "0x", topics: [hash32("t0")], removed: false, + }], + transactions: [{ + hash: hash32("tx"), blockNumber: from, blockHash: hash32("bh"), transactionIndex: 0, + from: "0x0000000000000000000000000000000000000001", to: null, value: "0", nonce: "0", + gas: "21000", gasUsed: "21000", effectiveGasPrice: "1", input: "0x", kind: 2, + status: 1, contractAddress: null, + }], + blocks: [{ number: from, hash: hash32("bh"), timestamp: 1_781_000_000 }], + nextBlock: to + 1, archiveHeight: to + 100, rollbackGuard: null, + sourceKind: "index", sourceId: "hypersync:xdc", attempts: [], ms: 0, + } as any); + return { + fromBlock: from, toBlock: to, chunksPlanned: 1, chunksOk: 1, + skipped: [], errors: [], emptyChunks: [], logsSeen: 1, complete: true, + sourceKind: "index", sourceId: "hypersync:xdc", enumeratingSources: 1, + headAtCapture: to + 100, + rollbackGuards: [{ + blockNumber: from - 10, timestamp: 0, hash: hash32("rbg"), + firstBlockNumber: from - 10, firstParentHash: hash32("rbp"), + }], + }; + }); + + await runPipeline({ + mode: "backfill", + chains: ["XDC"], + addresses: ["0x22867567e2d80f2049200e25c6f31cb6ec2f0faf"], + fromBlock: 2_000, + toBlock: 2_010, + }); + + const coverage = sim.tables.get("IngestionCoverage")?.rows ?? []; + const rawRow = coverage.find((r) => r.target_table === "RawLogs"); + + expect(rawRow, "precondition: a RawLogs coverage row must exist").toBeDefined(); + expect( + rawRow?.status, + `SA-C23a reproduced (inert guard): the reader reported a rollback guard whose first held ` + + `block is BELOW this capture's start, and the coverage row status is "${rawRow?.status}" ` + + `with the warning relegated to error_message. PR 71 fixed the half of this finding that ` + + `DROPPED the guard, and pipeline-v5/src/hs-worker.mjs now forwards it. The remaining half ` + + `is that pipeline-v5/src/pipeline.ts computes status before it reads the guards and then ` + + `only appends a note, so a range the source itself says is still reorganisable is recorded ` + + `as settled and the resume frontier moves past it. Owner: Phase 6.` + ).not.toBe("complete"); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/known-failures/registry-validation.test.ts b/projects/onchain-analytics/pipeline-v5/test/known-failures/registry-validation.test.ts new file mode 100644 index 0000000..dc068b4 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/known-failures/registry-validation.test.ts @@ -0,0 +1,130 @@ +/** + * KNOWN FAILURE: the registry loses and invents control data without saying so. + * + * H4 Registry loading silently drops or invents control data. + * Owner: Phase 2 (registry and inventory agent). Matrix: "Strict parser RED/GREEN suite". + * + * RECEIPTS THESE ENCODE, from `specs/system/readiness-audit-2026-09-25.md` section H4. + * + * "A CSV with two physical data rows, one malformed, loaded one row and did not throw." + * "An empty `era_index` loaded as era 0 and did not throw." + * + * The source lines the audit names are still there: `pipeline-v5/src/registry.ts` discards any + * row whose field count differs from the header, and uses JavaScript `Number` on control fields, + * where `Number("")` is 0 rather than NaN. + * + * WHY THIS MATTERS MORE THAN A PARSE ERROR. A dropped contract row is a contract that is never + * ingested, and nothing downstream can tell "this contract has no logs" from "this contract was + * never asked about". A blank era becoming era 0 is worse: `era_index` decides which ABI decodes + * a log, two addresses in this registry genuinely change their indexed layout across their own + * eras, and an era map lookup that always succeeds turns a missing era into a confident wrong + * answer. Both are silent. + * + * No adapter is replaced here. `loadRegistry` reads a CSV from disk, so the fixture IS a CSV + * written to a temporary directory, parsed by the real parser. + */ + +import { describe, it, expect, beforeEach, afterEach } from "vitest"; +import { mkdtempSync, writeFileSync, rmSync } from "fs"; +import { tmpdir } from "os"; +import { join } from "path"; +import { loadRegistry } from "../../src/registry.js"; + +let dir: string; + +beforeEach(() => { dir = mkdtempSync(join(tmpdir(), "registry-red-")); }); +afterEach(() => { rmSync(dir, { recursive: true, force: true }); }); + +const HEADER = + "chain_id,proxy_address,contract_name,era_index,implementation_address," + + "creation_block,valid_from_block,valid_to_block,is_live"; + +function seed(name: string, body: string): string { + const path = join(dir, name); + writeFileSync(path, `${HEADER}\n${body}\n`, "utf8"); + return path; +} + +describe("H4: a malformed registry row disappears", () => { + it("refuses a CSV whose physical row count does not match what it loaded", () => { + // Two physical data rows. The second is missing its last two fields, which is what a + // hand-edited seed or a truncated export looks like. + const path = seed( + "dropped-row.csv", + [ + "50,0x22867567e2d80f2049200e25c6f31cb6ec2f0faf,UBIScheme,1,,105000000,105000000,,true", + "50,0x6bd698566632bf2e81e2278f1656cb24aaf06d2e,Invites,1,,105000001", + ].join("\n") + ); + + let threw: Error | null = null; + let contracts = -1; + try { + const reg = loadRegistry(path); + contracts = reg.contracts.length; + } catch (e: any) { + threw = e; + } + + expect( + threw, + `H4 reproduced (dropped row): the CSV holds 2 physical data rows and loadRegistry() ` + + `returned ${contracts} contract(s) without throwing. pipeline-v5/src/registry.ts parseCsv() ` + + `filters out every row whose field count differs from the header, so a malformed row is ` + + `removed from the contract universe and nothing records that it existed. A contract that ` + + `is never asked about produces no logs and no error. Owner: Phase 2.` + ).not.toBeNull(); + }); +}); + +describe("H4: a blank era index becomes era zero", () => { + it("refuses a row whose era_index is blank rather than reading it as 0", () => { + const path = seed( + "blank-era.csv", + "50,0x22867567e2d80f2049200e25c6f31cb6ec2f0faf,UBIScheme,,,105000000,105000000,,true" + ); + + let threw: Error | null = null; + let eraIndex: unknown = "not loaded"; + try { + const reg = loadRegistry(path); + eraIndex = reg.eras[0]?.eraIndex; + } catch (e: any) { + threw = e; + } + + expect( + threw, + `H4 reproduced (blank era): era_index was empty and loaded as ${JSON.stringify(eraIndex)} ` + + `without throwing. pipeline-v5/src/registry.ts uses Number(r.era_index), and Number("") is ` + + `0, not NaN. Era 0 is not a real era in this registry: eras are 1-based, and era_index is ` + + `what decides which ABI decodes a log. Two (chain, address) keys in the shipped seed change ` + + `their indexed layout across their own eras, so a wrong era is a confident wrong decode ` + + `rather than a missing one. Owner: Phase 2.` + ).not.toBeNull(); + }); + + it("refuses a row whose chain_id is not one of the four in release scope", () => { + const path = seed( + "bad-chain.csv", + "999999,0x22867567e2d80f2049200e25c6f31cb6ec2f0faf,UBIScheme,1,,105000000,105000000,,true" + ); + + let threw: Error | null = null; + let chains: number[] = []; + try { + const reg = loadRegistry(path); + chains = reg.contracts.map((c) => c.chainId); + } catch (e: any) { + threw = e; + } + + expect( + threw, + `H4 reproduced (unsupported chain): chain_id 999999 loaded as ${JSON.stringify(chains)} ` + + `without throwing. The release scope is Celo, XDC, Fuse and Ethereum, decided in plan ` + + `Section 2 item 3, and nothing in the loader checks a chain id against it. A row for a ` + + `chain with no reader is a contract that silently never ingests. Owner: Phase 2.` + ).not.toBeNull(); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/known-failures/write-path-duplicates.test.ts b/projects/onchain-analytics/pipeline-v5/test/known-failures/write-path-duplicates.test.ts new file mode 100644 index 0000000..11d06d5 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/known-failures/write-path-duplicates.test.ts @@ -0,0 +1,253 @@ +/** + * THE WRITE PATH AND ITS TWO DUPLICATE-KEY DEFECTS. BOTH NOW CLOSED; THIS FILE IS THE GUARD. + * + * C1 Two concurrent captures of the same range both insert the same keys. + * CLOSED by a cross-process write lease, `src/writelock.ts`, installed as the default in + * `adapters.ts` and acquired in `stageAndMerge`. A second writer on the host is excluded; + * a refused writer throws, is recorded `incomplete`, and exits nonzero. + * R-XPART A guarded MERGE whose literal window does not cover an existing row inserts a second + * row under the same key. CLOSED WITHIN A BOUND by the padded whole-month window in + * `src/window.ts`, plus `verifyMergeKeyUniqueness` so that the residue beyond the bound is + * reported rather than silent. The bound is 31 to 62 days and is stated everywhere it + * matters, including beside the MERGE itself. + * + * SIMULATOR-BACKED, AND HERE IS THE RECEIPT EACH ONE ENCODES. + * + * C1 was proven on real infrastructure. `specs/system/readiness-audit-2026-09-25.md` section + * "C1. Two concurrent successful runs duplicate RawLogs" records two processes capturing XDC + * 105,201,000..105,201,500 at the same time: both exited 0, RawLogs held 149 stored rows over + * 102 distinct keys, 47 phantoms, while every coverage row and every PipelineRuns row said + * complete. The fixture below uses that exact range. + * + * R-XPART was proven on a faithful sandbox fixture: 1 row becoming 2 under one merge key when + * the MERGE's target window did not cover the existing row, measured on an UNGUARDED table as + * well, which is what established it as ordinary MERGE semantics rather than a fault of + * `require_partition_filter`. + * + * WHAT THIS FILE CAN AND CANNOT PROVE. It runs against `test/helpers/bq-simulator.ts`, which + * models the two semantics the defects depend on and nothing else. That is enough to show the + * write path's own logic is right, and it is NOT enough to prove cross-process exclusion: two + * `stageAndMerge` calls here are two calls in one process. The lease is a real file and is + * genuinely contended even here, but the two-OS-process reproduction lives in + * `test/integration/`, because within-process repetition has already produced a wrong conclusion + * on this project once. Each test below is followed by a DISCRIMINATION check that proves the + * simulator would report a correct implementation as correct, so a green here means the defect + * is gone rather than that the harness is blind. + */ + +import { describe, it, expect, beforeEach, afterEach } from "vitest"; +import { stageAndMerge, verifyMergeKeyUniqueness } from "../../src/bq.js"; +import { MERGE_KEYS, RAW_LOGS_TABLE, RAW_LOGS_SCHEMA } from "../../src/config.js"; +import { windowForRows } from "../../src/window.js"; +import { + setBigQueryClient, setWriteLock, resetAdapters, + type WriteLock, type WriteLockHandle, +} from "../../src/adapters.js"; +import { BigQuerySimulator, rendezvous } from "../helpers/bq-simulator.js"; +import { rawLogRow, RAW_LOGS_COLUMNS, C1_RANGE, XDC_CHAIN_ID, hash32 } from "../helpers/fixtures.js"; + +const KEY = MERGE_KEYS[RAW_LOGS_TABLE]; + +let sim: BigQuerySimulator; + +beforeEach(() => { + sim = new BigQuerySimulator(); + sim.defineTable(RAW_LOGS_TABLE, RAW_LOGS_COLUMNS, []); + setBigQueryClient(sim); +}); + +afterEach(() => resetAdapters()); + +/** A lock that admits one holder at a time. This is what Phase 5 has to build for real. */ +function serialisingLock(): WriteLock { + let chain: Promise = Promise.resolve(); + return { + async acquire(): Promise { + let releaseThis: () => void; + const mine = new Promise((r) => { releaseThis = r; }); + const waitFor = chain; + chain = chain.then(() => mine); + await waitFor; + return { release: async () => { releaseThis!(); } }; + }, + }; +} + +describe("C1: two concurrent captures of one range duplicate every merge key", () => { + /** + * Both captures stage the same 47 keys and merge them at the same time. Each MERGE matches + * against the target as it stood when that statement started, so neither sees the other's + * inserts and both insert. + */ + async function twoConcurrentCaptures(): Promise { + const rows = Array.from({ length: 47 }, (_, i) => + rawLogRow({ + blockNumber: C1_RANGE.from + i, + txHash: hash32(`c1-${i}`), + logIndex: 0, + chainId: XDC_CHAIN_ID, + }) + ); + const w = windowForRows(rows, 1)!; + + // Hold both statements open until both have taken their snapshot. Two real processes did + // this to each other by accident; here it is deterministic so the test cannot flake. + sim.onMergeSnapshotTaken = rendezvous(2); + + await Promise.all([ + stageAndMerge(RAW_LOGS_TABLE, rows, RAW_LOGS_SCHEMA, "run-process-1", w), + stageAndMerge(RAW_LOGS_TABLE, rows, RAW_LOGS_SCHEMA, "run-process-2", w), + ]); + } + + it("stores exactly one row per merge key after two simultaneous identical captures", async () => { + await twoConcurrentCaptures(); + + const stored = sim.rowsOf(RAW_LOGS_TABLE).length; + const distinct = sim.distinctKeys(RAW_LOGS_TABLE, KEY).size; + + expect( + stored, + `C1 HAS REOPENED: ${stored} stored rows over ${distinct} distinct merge keys ` + + `(${stored - distinct} phantom rows). Two concurrent captures of the same range each ` + + `matched against a target snapshot taken before the other inserted, so both inserted. ` + + `The lease in pipeline-v5/src/writelock.ts is supposed to exclude the second writer at ` + + `the seam in stageAndMerge. Either it is no longer the registered default -- check that ` + + `adapters.setWriteLockFactory is still called on bq.ts import -- or acquire() is granting ` + + `two holders at once.` + ).toBe(distinct); + }); + + it("DISCRIMINATION: a serialising lock in the same seam produces one row per key", async () => { + setWriteLock(serialisingLock()); + await twoConcurrentCaptures(); + + const stored = sim.rowsOf(RAW_LOGS_TABLE).length; + const distinct = sim.distinctKeys(RAW_LOGS_TABLE, KEY).size; + + // If this ever fails, the simulator cannot tell a fixed implementation from a broken one and + // the RED test above proves nothing. + expect(distinct).toBe(47); + expect(stored).toBe(47); + }); +}); + +describe("R-XPART: a guarded MERGE misses the same key in a non-incoming month", () => { + /** + * Re-merge one existing key from a month `displacedDays` in the past, and return what the + * table ends up holding. + * + * The key already exists under an older timestamp. The incoming batch carries the same key + * under a newer one, so the window derived from the incoming rows may or may not reach back + * far enough to make the existing row a match candidate. Whether it does is the whole subject. + */ + async function mergeDisplacedBy(displacedDays: number, seed: string): Promise { + const key = { txHash: hash32(seed), logIndex: 0, chainId: XDC_CHAIN_ID }; + const incomingTs = new Date("2026-08-05T00:00:00.000Z"); + const existingTs = new Date(incomingTs.getTime() - displacedDays * 86_400_000); + + sim.defineTable(RAW_LOGS_TABLE, RAW_LOGS_COLUMNS, [ + rawLogRow({ ...key, blockNumber: 105_100_000, blockTimestamp: existingTs.toISOString() }), + ]); + + const incoming = [ + rawLogRow({ ...key, blockNumber: 105_100_000, blockTimestamp: incomingTs.toISOString() }), + ]; + await stageAndMerge( + RAW_LOGS_TABLE, incoming, RAW_LOGS_SCHEMA, `run-xpart-${displacedDays}`, + windowForRows(incoming, 1)! + ); + } + + /** + * R-XPART closes as a BOUNDED fix plus a detector, and this test asserts both halves, because + * either one alone would be a misleading pass. + * + * WHAT THE PADDED WINDOW CLOSES. `windowForRows` truncates the incoming rows' span to whole + * months and pads one month each side, so an existing row displaced back as far as the start + * of the month before the source's own month is still a match candidate and is UPDATED. The + * reachable displacement is therefore 31 to 62 days depending where in its month the source + * sits, and the arithmetic is worth doing once rather than trusting the range: the source here + * is 2026-08-05, so the window opens at 2026-07-01, which is 4 days back through August plus + * the 31 of July -- 35 days. 30 is inside it and crosses a month boundary, which is the case + * the padding exists for. + * + * WHAT IT DOES NOT CLOSE, MEASURED RATHER THAN ASSUMED. A row displaced 95 days is outside the + * padding and still duplicates. That residue is accepted deliberately: the general fix is a + * key directory recording where each key already lives, and it is deferred because nothing in + * this deployment writes outside a recent window. A re-read that moves a timestamp by more + * than the bound is a CORRECTION rather than a reorganisation, and a correction states its own + * window through `windowForSpan`. + * + * WHY THE SECOND HALF IS STILL A PASS AND NOT A FAILURE. What made every duplicate incident in + * this project expensive was not the duplicate, it was the SILENCE: the rows were wrong and + * every count, grain and referential test passed. An accepted residue is only defensible if it + * is visible, so the closure condition is not "no duplicate is possible", it is "no duplicate + * is silent". `verifyMergeKeyUniqueness` is that detector, and it reads through the + * all-history view because a duplicate created by a non-covering window sits by construction + * in a partition every windowed check excludes. + * + * Renamed from "stores one row per merge key when a row is re-merged from a distant month", + * which asserted the unbounded property. That test could not pass under the fix the plan + * specifies and records as accepted at 31 to 62 days; it asserted the deferred key directory. + */ + it("bounds a distant-month re-merge to the padding, and detects the duplicate beyond it", async () => { + await mergeDisplacedBy(30, "xpart-inbound"); + + expect( + sim.rowsOf(RAW_LOGS_TABLE).length, + `A 30-day displacement from 2026-08-05 reaches 2026-07-06, which is inside the window the ` + + `padding opens at 2026-07-01, so the existing row is a match candidate and the MERGE ` + + `updates it rather than inserting beside it.` + ).toBe(1); + expect(sim.distinctKeys(RAW_LOGS_TABLE, KEY).size).toBe(1); + + const inBound = await verifyMergeKeyUniqueness(RAW_LOGS_TABLE, XDC_CHAIN_ID); + expect(inBound.ok, "nothing to detect when the window covered the row").toBe(true); + expect(inBound.report.phantomRows).toBe(0); + + // Beyond the bound the duplicate is real. The closure condition is that it is REPORTED. + await mergeDisplacedBy(95, "xpart-outofbound"); + + const stored = sim.rowsOf(RAW_LOGS_TABLE).length; + const distinct = sim.distinctKeys(RAW_LOGS_TABLE, KEY).size; + expect( + stored - distinct, + `95 days is outside the 31-to-62-day padding bound, so this duplicates. That is the ` + + `accepted residue, not a regression.` + ).toBe(1); + + const outOfBound = await verifyMergeKeyUniqueness(RAW_LOGS_TABLE, XDC_CHAIN_ID); + expect( + outOfBound.ok, + `R-XPART's residue must never be silent. verifyMergeKeyUniqueness reads through the ` + + `all-history view precisely because the phantom sits in a partition the incoming window ` + + `excluded, so every windowed check in the write path is guaranteed to miss it.` + ).toBe(false); + expect(outOfBound.report.phantomRows).toBe(1); + expect(outOfBound.report.storedRows).toBe(stored); + expect(outOfBound.report.distinctKeys).toBe(distinct); + }); + + it("DISCRIMINATION: the same merge inside the window updates instead of inserting", async () => { + const key = { txHash: hash32("xpart-2"), logIndex: 0, chainId: XDC_CHAIN_ID }; + sim.defineTable(RAW_LOGS_TABLE, RAW_LOGS_COLUMNS, [ + rawLogRow({ ...key, blockNumber: 105_100_000, blockTimestamp: "2026-08-02T00:00:00.000Z" }), + ]); + const incoming = [ + rawLogRow({ ...key, blockNumber: 105_100_000, blockTimestamp: "2026-08-05T00:00:00.000Z" }), + ]; + await stageAndMerge( + RAW_LOGS_TABLE, incoming, RAW_LOGS_SCHEMA, "run-xpart-control", windowForRows(incoming, 1)! + ); + + expect(sim.rowsOf(RAW_LOGS_TABLE).length).toBe(1); + expect(sim.distinctKeys(RAW_LOGS_TABLE, KEY).size).toBe(1); + + // And the detector agrees with the row count. A detector that reported a phantom here would + // be a machine for false alarms, which is as useless as one that reports nothing. + const clean = await verifyMergeKeyUniqueness(RAW_LOGS_TABLE, XDC_CHAIN_ID); + expect(clean.ok).toBe(true); + expect(clean.report.phantomRows).toBe(0); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/setup/env.ts b/projects/onchain-analytics/pipeline-v5/test/setup/env.ts new file mode 100644 index 0000000..55789d4 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/setup/env.ts @@ -0,0 +1,74 @@ +/** + * env.ts -- the test environment, established before any `src/` module is imported. + * + * WHY THIS FILE EXISTS. `config.ts` runs `requireEnv("ENVIO_API_TOKEN")` at module scope and calls + * `process.exit(2)` when it is absent, so importing any module that transitively reaches config + * kills the test runner before a single assertion runs. That is a fail-fast the pipeline should + * keep: a scheduled run with no token should die immediately rather than half-ingest. So the + * environment is supplied here rather than the check being softened in production code. + * + * WHY THE VALUES ARE OBVIOUSLY FAKE, AND CHECKED. Phase 1 is bound to consume zero cloud + * resources and use zero credentials. A test suite that silently picked up a developer's real + * token or a real GCP project from the ambient environment would violate that without anyone + * noticing, so this file OVERWRITES those variables unconditionally and then asserts the values + * in force are the fake ones. If a real credential is present in the environment, this file + * removes its reach rather than inheriting it. + * + * `dotenv` is also neutralised: `config.ts` calls `loadDotenv()` at import, which would read a + * real `.env` sitting beside the package. Pointing DOTENV_CONFIG_PATH at a file that does not + * exist makes that call a no-op. + */ + +const FAKE = { + ENVIO_API_TOKEN: "test-token-not-a-credential", + GCP_PROJECT_ID: "test-project-no-such-project", + DATASET_ID: "test_dataset_no_such_dataset", + SLACK_WEBHOOK_URL: "", + LOG_FILE: "", + // Pacing to zero. These exist to be polite to real endpoints; no test reaches one, and the + // real defaults would add minutes of sleep to a suite that makes no network call. + RPC_PAUSE_MS: "0", + HS_CHUNK_PAUSE_MS: "0", + BQ_RETRIES: "1", + HYPERSYNC_RETRIES: "1", +} as const; + +process.env.DOTENV_CONFIG_PATH = "test/setup/.env.absent-on-purpose"; + +for (const [key, value] of Object.entries(FAKE)) { + process.env[key] = value; +} + +// Credentials that would let something reach Google Cloud by accident. Removed, not overwritten, +// because an empty string is a value the client libraries will still try to use. +for (const key of ["GOOGLE_APPLICATION_CREDENTIALS", "GOOGLE_CLOUD_PROJECT", "GCLOUD_PROJECT"]) { + delete process.env[key]; +} + +if (process.env.ENVIO_API_TOKEN !== FAKE.ENVIO_API_TOKEN) { + throw new Error("TEST_ENV_NOT_ISOLATED: the fake environment did not take effect"); +} + +/** + * No test reaches the network. This is the control that says so rather than the comment. + * + * `globalThis.fetch` is replaced with one that throws. Every JSON-RPC call in this pipeline goes + * through `adapters.getRpcTransport()`, whose real implementation is this function, so a test that + * forgets to install the wire recorder fails loudly and immediately instead of quietly contacting + * a public endpoint. The Slack notifier uses `fetch` directly and is caught by the same guard. + * + * THE HONEST LIMIT OF THIS GUARD. It covers `fetch` only. The BigQuery client library has its own + * HTTP stack, and the HyperSync client is a native module driven in a child process, so neither is + * blocked here. Both are covered instead by construction: no test issues a query against a real + * BigQuery client, and no test installs a real reader. + */ +const BLOCKED_FETCH = (input: unknown): never => { + const target = typeof input === "string" ? input : String((input as { url?: string })?.url ?? input); + throw new Error( + `TEST_NETWORK_BLOCKED: a test attempted a real network request to ${target}. ` + + `Install a wire recorder with setRpcTransport() or a reader with setReaderOverride(). ` + + `Nothing in this suite is allowed to contact a live endpoint.` + ); +}; + +globalThis.fetch = BLOCKED_FETCH as unknown as typeof fetch; diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/calibration.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/calibration.test.ts new file mode 100644 index 0000000..df9ce66 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/calibration.test.ts @@ -0,0 +1,210 @@ +/** + * calibration.test.ts -- the module that measures a source's false-zero rate. + * + * WHY THIS MODULE MATTERS ENOUGH TO TEST. It is the only thing in this pipeline that measures + * whether a reader can be believed. The stop rule it replaced was "stop when two consecutive + * passes add nothing", which fired falsely twice on one range: the identical query on the + * identical endpoint measured a 0.30 miss rate one day and 0.70 the next, so no fixed pass count + * bounds anything. Everything here exists to turn that into a number measured in session. + * + * Until now only its pure summariser was exercised, and the three functions that actually drive a + * reader and an endpoint were not covered at all -- in the module whose subject is whether a + * reader is lying. These tests install a scripted reader and a scripted endpoint, so the + * repetition, the per-endpoint isolation and the error accounting are all exercised without + * reaching a network. + */ + +import { describe, it, expect, afterEach } from "vitest"; +import { runCalibrate, __testing } from "../../src/calibrate.js"; +import { setReaderOverride, setRpcTransport, resetAdapters } from "../../src/adapters.js"; +import { makeWireRecorder } from "../helpers/wire-recorder.js"; +import { hash32 } from "../helpers/fixtures.js"; + +const XDC_CONTRACT = "0x22867567e2d80f2049200e25c6f31cb6ec2f0faf"; + +afterEach(() => resetAdapters()); + +/** A reader that returns a scripted log count per pass, and reports incompleteness on demand. */ +function scriptedReader(perPass: (number | "incomplete")[]): () => number { + let pass = 0; + setReaderOverride(async (_n, _addresses, from, to) => { + const scripted = perPass[Math.min(pass, perPass.length - 1)]; + pass += 1; + const incomplete = scripted === "incomplete"; + return { + fromBlock: from, toBlock: to, + chunksPlanned: 1, chunksOk: incomplete ? 0 : 1, + skipped: incomplete ? [[from, to]] : [], + errors: incomplete ? ["scripted failure"] : [], + emptyChunks: [], logsSeen: incomplete ? 0 : (scripted as number), + complete: !incomplete, + sourceKind: "index", sourceId: "hypersync:xdc.hypersync.xyz", + enumeratingSources: 1, headAtCapture: to + 100, rollbackGuards: [], + } as any; + }); + return () => pass; +} + +/** An endpoint whose `eth_getLogs` answer is scripted per URL, so one endpoint can drop answers. */ +function scriptedEndpoints(logsByUrl: (url: string, call: number) => number): void { + const callsByUrl = new Map(); + setRpcTransport(makeWireRecorder({ + answers: { + eth_getLogs: (_params: unknown[], url: string) => { + const n = (callsByUrl.get(url) ?? 0) + 1; + callsByUrl.set(url, n); + return logsOf(logsByUrl(url, n)); + }, + }, + }).transport); +} + +function logsOf(count: number): Record[] { + return Array.from({ length: count }, (_, i) => ({ + address: XDC_CONTRACT, blockNumber: "0x1", blockHash: hash32(`b${i}`), + transactionHash: hash32(`t${i}`), transactionIndex: "0x0", + logIndex: `0x${i.toString(16)}`, topics: [hash32("topic0")], data: "0x", removed: false, + })); +} + +describe("the miss rate is measured, never assumed", () => { + it("reports a consistent source as consistent WITH its repeat count, not as proven", async () => { + // The distinction is the whole point. "No short answer in 4 repeats" is a fact about this + // session; "this source is reliable" is a claim about the source, and this module is + // deliberately not allowed to make it. + const clean = __testing.summarise("src", "CELO", 1, 100, [10, 10, 10, 10], 0); + + expect(clean.p).toBe(0); + expect(clean.kForOnePercent).toBe(1); + expect(clean.verdict).toContain("4 repeats"); + expect( + clean.verdict, + "a clean calibration must say what it is a fact ABOUT, or it reads as a guarantee" + ).toContain("fact about this session"); + }); + + it("derives the pass count a repetition rule would need from the measured rate", async () => { + // At p = 0.5 a stop rule needs ceil(log 0.01 / log 0.5) = 7 consecutive zero-gain passes to + // stop falsely less than one time in a hundred. The five-pass rule this replaced would stop + // falsely about three times in a hundred at that rate. + const half = __testing.summarise("src", "CELO", 1, 100, [10, 10, 0, 0], 0); + expect(half.p).toBe(0.5); + expect(half.kForOnePercent).toBe(7); + + // A quarter short needs four. + const quarter = __testing.summarise("src", "CELO", 1, 100, [10, 10, 10, 0], 0); + expect(quarter.p).toBe(0.25); + expect(quarter.kForOnePercent).toBe(4); + }); + + it("MEASURES SHORTNESS AGAINST THE MODE, so a source that is usually zero reads as consistent", () => { + // Pinned because it is surprising and it is load-bearing, not because it is wrong. + // + // `p` is the share of passes that returned FEWER than the modal answer. When most passes + // return zero, zero IS the mode, nothing is below it, and p comes out 0 -- the same value a + // perfectly consistent source produces. The two are told apart by `zeroAnswers`, which is + // why that field is counted separately rather than folded into the rate. + // + // This is safe HERE because the module is advisory: the pipeline never decides anything from + // repetition, it refuses short collections outright and confirms every empty range against an + // independent source. It would not be safe in anything that read `p` alone as a verdict, so + // the behaviour is asserted where a future reader will find it. + const mostlyZero = __testing.summarise("src", "CELO", 1, 100, [10, 0, 0, 0], 0); + + expect(mostlyZero.modeAnswer, "zero is the most frequent answer, so zero is the mode").toBe(0); + expect(mostlyZero.shortAnswers, "nothing is below zero").toBe(0); + expect(mostlyZero.p).toBe(0); + expect( + mostlyZero.zeroAnswers, + "the zero count is what distinguishes this from a genuinely consistent source" + ).toBe(3); + }); + + it("calls a source that answered nothing UNUSABLE, and does not divide by its zero answers", async () => { + const dead = __testing.summarise("src", "CELO", 1, 100, [], 5); + expect(dead.modeAnswer).toBeNull(); + expect(dead.p, "no answer at all is a miss rate of one, not a division by zero").toBe(1); + expect(dead.kForOnePercent).toBeNull(); + expect(dead.verdict).toContain("UNUSABLE"); + expect(dead.repeats, "the repeats count must include the passes that errored").toBe(5); + }); + + it("counts a ZERO answer separately from an error, because only one of them is visible", async () => { + // A 14-day scan once reported zero skipped chunks while holding 12 of 26 real logs. An error + // announces itself; a confident zero does not, and conflating them is what hid that. + const mixed = __testing.summarise("src", "CELO", 1, 100, [26, 26, 0], 2); + expect(mixed.zeroAnswers).toBe(1); + expect(mixed.errors).toBe(2); + expect(mixed.shortAnswers, "a zero is short, and so is any answer below the mode").toBe(1); + expect(mixed.repeats).toBe(5); + }); +}); + +describe("calibration drives every source and keeps their results apart", () => { + it("repeats the query against the primary reader and reports what each pass returned", async () => { + const passes = scriptedReader([12, 12, 12]); + scriptedEndpoints(() => 12); + + const allConsistent = await runCalibrate({ + mode: "calibrate", chains: ["XDC"], addresses: [XDC_CONTRACT], + fromBlock: 100_000_000, toBlock: 100_000_100, + } as any); + + expect(passes(), "the primary reader must be asked more than once").toBeGreaterThan(1); + expect(allConsistent, "every source answered on every pass").toBe(true); + }); + + it("reports NOT every source answering when the primary reader returns incomplete every pass", async () => { + scriptedReader(["incomplete"]); + scriptedEndpoints(() => 12); + + const allConsistent = await runCalibrate({ + mode: "calibrate", chains: ["XDC"], addresses: [XDC_CONTRACT], + fromBlock: 100_000_000, toBlock: 100_000_100, + } as any); + + expect( + allConsistent, + "a reader that never completed a pass is not a source that answered" + ).toBe(false); + }); + + it("probes each endpoint SEPARATELY, so one endpoint dropping answers cannot hide in a union", async () => { + // This is the property the whole module turns on. Probing several endpoints together + // measures their union, and the union hides exactly the endpoint the rule exists to find. + const seen = new Set(); + scriptedReader([12, 12, 12]); + setRpcTransport(makeWireRecorder({ + answers: { + eth_getLogs: (_params: unknown[], url: string) => { + seen.add(url); + // One endpoint returns nothing while the others return the real answer. + return logsOf(url.includes("public-rpc") ? 0 : 12); + }, + }, + }).transport); + + await runCalibrate({ + mode: "calibrate", chains: ["XDC"], addresses: [XDC_CONTRACT], + fromBlock: 100_000_000, toBlock: 100_000_100, + } as any); + + expect( + seen.size, + `Only ${seen.size} endpoint(s) were probed. Calibration must ask each one on its own, or ` + + `the endpoint returning zero is averaged away by the ones that answered.` + ).toBeGreaterThan(1); + }); + + it("returns without reaching a reader when the chain selection matches no contract", async () => { + let touched = false; + setReaderOverride(async () => { touched = true; return {} as any; }); + + const result = await runCalibrate({ + mode: "calibrate", chains: ["XDC"], addresses: ["0x0000000000000000000000000000000000000000"], + } as any); + + expect(touched, "no target means nothing to calibrate, not a read of the whole chain").toBe(false); + expect(result, "vacuously true: every one of no sources answered").toBe(true); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/cli-and-adapters.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/cli-and-adapters.test.ts new file mode 100644 index 0000000..8edaafd --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/cli-and-adapters.test.ts @@ -0,0 +1,145 @@ +/** + * The CLI parser and the adapter seams, tested as the pure things plan task 3 made them. + * + * The parser used to call `process.exit` from inside itself, so exercising a bad argument killed + * the runner. It now returns data or throws a typed error, and the process wrapper is the only + * thing that ends a process. These tests are what make that claim checkable. + */ + +import { describe, it, expect, afterEach } from "vitest"; +import { parseArgs, CliUsageError, captureExitCode } from "../../src/index.js"; +import { + setBigQueryClient, setRpcTransport, setClock, setWriteLock, setNotifier, setReaderOverride, + getBigQueryClient, getRpcTransport, getWriteLock, getNotifier, getReaderOverride, + resetAdapters, nowIso, NO_LOCK, +} from "../../src/adapters.js"; + +afterEach(() => resetAdapters()); + +describe("CLI parser returns data and throws typed errors", () => { + it("parses a full command line into options", () => { + const opts = parseArgs([ + "backfill", "--chains=XDC,CELO", "--addresses=0xAAA,0xBBB", + "--from=100", "--to=200", "--days=1,2,3", "--dry-run", + "--max-capture-blocks=5000", "--max-captures=3", + ]); + + expect(opts.mode).toBe("backfill"); + expect(opts.chains).toEqual(["XDC", "CELO"]); + expect(opts.addresses).toEqual(["0xaaa", "0xbbb"]); + expect(opts.fromBlock).toBe(100); + expect(opts.toBlock).toBe(200); + expect(opts.days).toEqual([1, 2, 3]); + expect(opts.dryRun).toBe(true); + expect(opts.maxCaptureBlocks).toBe(5_000); + expect(opts.maxCaptures).toBe(3); + }); + + it("throws rather than exiting on an unknown mode", () => { + expect(() => parseArgs(["nonsense"])).toThrow(CliUsageError); + try { + parseArgs(["nonsense"]); + } catch (e) { + expect((e as CliUsageError).exitCode).toBe(2); + expect((e as CliUsageError).showUsage).toBe(true); + } + }); + + it("throws on an unrecognised argument, a reversed range and a non-numeric bound", () => { + expect(() => parseArgs(["daily", "--nope"])).toThrow(/Unrecognised argument/); + expect(() => parseArgs(["backfill", "--from=200", "--to=100"])).toThrow(/below --from/); + expect(() => parseArgs(["backfill", "--from=abc"])).toThrow(/--from is not a number/); + }); + + it("refuses a limit that would silently become NaN and disable the guard it raises", () => { + // A NaN limit compares false against every span, so passing --max-captures=x would turn the + // budget guard OFF rather than raise it. That is the defect shape this check exists for. + expect(() => parseArgs(["daily", "--max-captures=x"])).toThrow(/positive whole number/); + expect(() => parseArgs(["daily", "--max-capture-blocks=0"])).toThrow(/positive whole number/); + }); + + it("maps capture counts to exit codes the way main does", () => { + expect(captureExitCode(5, 0)).toBe(0); + expect(captureExitCode(5, 1)).toBe(1); + expect(captureExitCode(0, 3)).toBe(2); + }); +}); + +describe("every adapter is replaceable and resets to its real default", () => { + it("refuses to invent a BigQuery client when none is registered for a test", () => { + setBigQueryClient(null); + // `bq.ts` registers the real factory on import, so this returns a real client rather than + // throwing. What matters is that a test-installed client wins and that reset removes it. + const fake = { query: async () => [[]] as [any[]], dataset: () => ({ table: () => ({}) }) } as any; + setBigQueryClient(fake); + expect(getBigQueryClient()).toBe(fake); + }); + + it("replaces the RPC transport and restores the real one", () => { + const real = getRpcTransport(); + const fake = (async () => ({ ok: true, status: 200, text: async () => "{}" })) as any; + setRpcTransport(fake); + expect(getRpcTransport()).toBe(fake); + setRpcTransport(null); + expect(getRpcTransport()).toBe(real); + }); + + it("replaces the clock, so a timestamp in a record is assertable", () => { + setClock({ now: () => new Date("2020-01-02T03:04:05.000Z") }); + expect(nowIso()).toBe("2020-01-02T03:04:05.000Z"); + setClock(null); + expect(nowIso()).not.toBe("2020-01-02T03:04:05.000Z"); + }); + + it("defaults the write lock to the real cross-process lease, not to NO_LOCK", async () => { + // Renamed from "defaults the write lock to NO_LOCK, which is the control that does not exist + // yet". The control now exists, so the assertion is inverted rather than relaxed: the point + // of the original test was that the default is whatever production actually gets, and that + // is the thing still being asserted. + // + // `bq.ts` registers the lease factory on import, so importing it is what makes the default + // real. A control you have to remember to install is not a control. + await import("../../src/bq.js"); + const active = getWriteLock(); + expect(active, "production must not get the do-nothing lock").not.toBe(NO_LOCK); + + // NO_LOCK stays exported and stays meaningful: it is the absence of exclusion, which a test + // installs deliberately to show what the write path does without it. + const handle = await NO_LOCK.acquire("RawLogs", null); + expect(handle, "NO_LOCK grants every request instantly and excludes nothing").not.toBeNull(); + + const refusing = { acquire: async () => null }; + setWriteLock(refusing); + expect(getWriteLock()).toBe(refusing); + }); + + it("replaces the reader and the notifier", () => { + const reader = (async () => ({})) as any; + setReaderOverride(reader); + expect(getReaderOverride()).toBe(reader); + + const notifier = { post: async () => {} }; + setNotifier(notifier); + expect(getNotifier()).toBe(notifier); + }); + + it("resetAdapters clears every seam, so one file cannot leak into the next", () => { + setRpcTransport((async () => ({ ok: true, status: 200, text: async () => "{}" })) as any); + setClock({ now: () => new Date(0) }); + const refusing = { acquire: async () => null }; + setWriteLock(refusing); + setNotifier({ post: async () => {} }); + setReaderOverride((async () => ({})) as any); + + resetAdapters(); + + // The lock resets to whatever the process default is rather than to a fixed object, because + // the default is now built from a factory. What has to be true is that the double installed + // above is gone; asserting a specific identity here would make this test depend on whether + // some other file happened to import `bq.ts` first. + expect(getWriteLock()).not.toBe(refusing); + expect(getNotifier()).toBeNull(); + expect(getReaderOverride()).toBeNull(); + expect(nowIso()).not.toBe(new Date(0).toISOString()); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/cli-outcome-model.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/cli-outcome-model.test.ts new file mode 100644 index 0000000..2744ec9 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/cli-outcome-model.test.ts @@ -0,0 +1,349 @@ +/** + * The typed outcome model, the exit mapping and the run record, asserted rather than assumed. + * + * WHAT THIS FILE IS FOR. Finding `C2`'s four regression tests prove the two refusal paths are + * fixed. They do not prove the model AROUND the fix is sound, and that is the part that has to + * survive every later phase adding a new outcome. So: + * + * * every value of `UnitOutcomeKind` is produced by something, and its exit code is asserted, + * not inferred from a comment + * * the invariant the plan states as this phase's exit gate is exercised in both directions, + * including the direction where it must THROW + * * the persisted `PipelineRuns` row is read back out of the simulator and reconciled against + * the exit code, because "the run record agrees with the exit code" is a claim about a row, + * not about a variable + * + * FIXTURE FIDELITY. Nothing here invents a row shape. The coverage rows are the ones + * `recordCoverage` actually writes, read back from the simulator, and the `PipelineRuns` row is + * bound by the real INSERT statement's own column list. A fixture that agrees with an assumption + * instead of with the artifact is how Phase 1's registry fixtures ended up failing for the wrong + * reason. + */ + +import { describe, it, expect, beforeEach, afterEach } from "vitest"; +import { + RunSummary, unit, UNIT_OUTCOME_KINDS, PARENT_GRAIN, + captureExitCode, captureExitCodeFor, readOnlyExitCode, planExitCode, + executionStatusOf, assertExitAgreesWithSummary, + type UnitOutcomeKind, +} from "../../src/outcome.js"; +import { runPipeline } from "../../src/pipeline.js"; +import { recordPipelineRun } from "../../src/bq.js"; +import { RAW_LOGS_TABLE, TRANSACTIONS_TABLE, NETWORKS } from "../../src/config.js"; +import { checkCaptureSpan, checkRunSize, DEFAULT_MAX_CAPTURES } from "../../src/budget.js"; +import { setBigQueryClient, resetAdapters } from "../../src/adapters.js"; +import { BigQuerySimulator } from "../helpers/bq-simulator.js"; + +let sim: BigQuerySimulator; + +beforeEach(() => { + sim = new BigQuerySimulator(); + setBigQueryClient(sim); +}); + +afterEach(() => resetAdapters()); + +/** A summary holding exactly one unit of the given kind, for the mapping assertions. */ +function summaryWith(...kinds: UnitOutcomeKind[]): RunSummary { + const s = new RunSummary(); + s.plan(RAW_LOGS_TABLE, kinds.length); + for (const k of kinds) s.add(unit(k, RAW_LOGS_TABLE, `synthetic ${k}`)); + return s; +} + +describe("every outcome kind exists, counts once, and maps to a stated exit code", () => { + it("counts each kind into exactly one counter, and only attempts what was attempted", () => { + const s = summaryWith(...UNIT_OUTCOME_KINDS); + const t = s.totals; + + expect(t.planned).toBe(6); + expect([t.completed, t.noop, t.refused, t.unsupported, t.incomplete, t.failed]) + .toEqual([1, 1, 1, 1, 1, 1]); + // completed, incomplete and failed ran. nothing_to_fetch, refused_budget and unsupported + // never reached a reader, which is what makes planned-minus-attempted a real number. + expect(t.attempted).toBe(3); + expect(s.units).toHaveLength(6); + expect(s.problems.map((u) => u.kind)) + .toEqual(["refused_budget", "unsupported", "incomplete", "failed"]); + }); + + it("maps each kind to an exit code, one assertion per kind, no inference", () => { + // Alone, every non-completed kind is "nothing completed", which is exit 2. + for (const kind of UNIT_OUTCOME_KINDS) { + const expected = kind === "completed" ? 0 : 2; + expect(captureExitCodeFor(summaryWith(kind)), `${kind} alone`).toBe(expected); + } + // Paired with a completion, every not-done kind is the partial arm, exit 1. + for (const kind of UNIT_OUTCOME_KINDS) { + const expected = kind === "completed" || kind === "nothing_to_fetch" ? 0 : 1; + expect(captureExitCodeFor(summaryWith("completed", kind)), `completed + ${kind}`).toBe(expected); + } + }); + + it("refuses to call empty work a success", () => { + // Gate item 5. A run whose every unit was a no-op did nothing, and a run that did nothing + // must not report success even though nothing went wrong. + expect(captureExitCodeFor(summaryWith("nothing_to_fetch", "nothing_to_fetch"))).toBe(2); + expect(captureExitCodeFor(new RunSummary())).toBe(2); + expect(captureExitCode(0, 0)).toBe(2); + }); + + it("keeps the two-number mapping the audit receipts were taken against", () => { + expect(captureExitCode(5, 0)).toBe(0); + expect(captureExitCode(5, 1)).toBe(1); + expect(captureExitCode(0, 3)).toBe(2); + }); + + it("counts separately by target grain", () => { + const s = new RunSummary(); + s.plan(RAW_LOGS_TABLE, 1); + s.plan(TRANSACTIONS_TABLE, 1); + s.add(unit("completed", RAW_LOGS_TABLE, "logs done")); + s.add(unit("refused_budget", TRANSACTIONS_TABLE, "transactions declined")); + + expect(s.byGrain.get(RAW_LOGS_TABLE)).toMatchObject({ planned: 1, completed: 1, refused: 0 }); + expect(s.byGrain.get(TRANSACTIONS_TABLE)).toMatchObject({ planned: 1, completed: 0, refused: 1 }); + expect(JSON.parse(s.countsByGrainJson())).toHaveProperty([TRANSACTIONS_TABLE, "refused"], 1); + }); +}); + +describe("the read-only and plan matrices are separate from the capture rules", () => { + it("lets a read-only command report a real finding without calling it a crash", () => { + expect(readOnlyExitCode("clean")).toBe(0); + expect(readOnlyExitCode("finding")).toBe(1); + // "I could not look" is not "I looked and found nothing". This is where C4's fix lands. + expect(readOnlyExitCode("nothing_to_check")).toBe(2); + expect(readOnlyExitCode("unsupported")).toBe(2); + expect(readOnlyExitCode("failed")).toBe(2); + }); + + it("exits plan mode nonzero unless the plan is complete and inside budget", () => { + expect(planExitCode("complete")).toBe(0); + expect(planExitCode("incomplete")).toBe(1); + expect(planExitCode("refused")).toBe(2); + expect(planExitCode("unsupported")).toBe(2); + }); +}); + +describe("the exit gate is checked, not promised", () => { + it("throws when exit 0 is claimed over a unit that did not complete", () => { + // This is the plan's Phase 3 exit gate, in the one direction that matters: a contradiction + // must be loud. Every kind that is not a completion or a no-op has to trip it. + for (const kind of ["refused_budget", "unsupported", "incomplete", "failed"] as const) { + expect(() => assertExitAgreesWithSummary(0, summaryWith("completed", kind)), kind) + .toThrow(/OUTCOME_CONTRADICTION/); + } + }); + + it("throws when exit 0 is claimed over zero completed units", () => { + expect(() => assertExitAgreesWithSummary(0, summaryWith("nothing_to_fetch"))) + .toThrow(/zero completed unit/); + }); + + it("stays silent on a genuinely clean run and on every nonzero exit", () => { + expect(() => assertExitAgreesWithSummary(0, summaryWith("completed"))).not.toThrow(); + expect(() => assertExitAgreesWithSummary(1, summaryWith("completed", "failed"))).not.toThrow(); + expect(() => assertExitAgreesWithSummary(2, summaryWith("refused_budget"))).not.toThrow(); + }); +}); + +describe("the persisted run record agrees with the exit code", () => { + /** + * Gate item 4's second half. The row is written through the REAL insert statement and read back + * out of the simulator, so the column list, the parameter binding and the counter arithmetic + * are all exercised rather than described. + */ + async function persist(summary: RunSummary, exitCode: number) { + const t = summary.totals; + await recordPipelineRun({ + runId: "run-under-test", mode: "daily", + startedAt: "2026-09-28T00:00:00.000Z", completedAt: "2026-09-28T00:00:01.000Z", + exitCode, + totalRowsMerged: 0, + contractsProcessed: t.completed, + contractsFailed: t.refused + t.unsupported + t.incomplete + t.failed, + host: "test-host", errorMessage: "", chainsProcessed: "50", + capturesPlanned: t.planned, capturesOk: t.completed, + capturesFailed: t.refused + t.unsupported + t.incomplete + t.failed, + pipelineVersion: "test", + executionStatus: executionStatusOf(exitCode, summary), + unitsPlanned: t.planned, unitsAttempted: t.attempted, unitsCompleted: t.completed, + unitsNoop: t.noop, unitsRefused: t.refused, unitsUnsupported: t.unsupported, + unitsFailed: t.incomplete + t.failed, + outcomeCountsByGrain: summary.countsByGrainJson(), + releaseSha: null, planHash: null, + }); + return sim.tables.get("PipelineRuns")!.rows.at(-1)!; + } + + it("writes a refused run as refused, with the real planned count and a nonzero exit", async () => { + const summary = new RunSummary(); + summary.plan(RAW_LOGS_TABLE, 142); + for (let i = 0; i < 142; i++) summary.add(unit("refused_budget", RAW_LOGS_TABLE, "over the run-size limit")); + + const exitCode = captureExitCodeFor(summary); + const row = await persist(summary, exitCode); + + // The audit's receipt for this exact case was: zero planned, zero failed, exit 0. + expect(exitCode).toBe(2); + expect(row.execution_status).toBe("refused"); + expect(row.units_planned).toBe(142); + expect(row.units_refused).toBe(142); + expect(row.units_attempted).toBe(0); + expect(row.units_completed).toBe(0); + expect(row.exit_code).toBe(2); + // No column may say the run was fine while another says it was refused. + expect(row.captures_ok).toBe(0); + expect(row.captures_failed).toBe(142); + }); + + it("reconciles the grain breakdown exactly to the unit counters", async () => { + const summary = new RunSummary(); + summary.plan(RAW_LOGS_TABLE, 2); + summary.plan(TRANSACTIONS_TABLE, 2); + summary.add(unit("completed", RAW_LOGS_TABLE, "ok")); + summary.add(unit("refused_budget", RAW_LOGS_TABLE, "declined")); + summary.add(unit("completed", TRANSACTIONS_TABLE, "ok")); + summary.add(unit("failed", TRANSACTIONS_TABLE, "threw")); + + const exitCode = captureExitCodeFor(summary); + const row = await persist(summary, exitCode); + const byGrain = JSON.parse(row.outcome_counts_by_grain); + + expect(exitCode).toBe(1); + expect(row.execution_status).toBe("partial"); + // "PipelineRuns can be reconciled exactly to child outcomes", from the plan's GREEN checks. + const sum = (field: string) => + Object.values(byGrain).reduce((a: number, c: any) => a + c[field], 0); + expect(sum("planned")).toBe(row.units_planned); + expect(sum("completed")).toBe(row.units_completed); + expect(sum("refused")).toBe(row.units_refused); + expect(sum("failed") + sum("incomplete")).toBe(row.units_failed); + }); + + it("names a crash and an empty scope differently, because they need different responses", () => { + expect(executionStatusOf(2, summaryWith("failed"))).toBe("failed"); + expect(executionStatusOf(2, summaryWith("refused_budget"))).toBe("refused"); + expect(executionStatusOf(2, summaryWith("unsupported"))).toBe("unsupported"); + expect(executionStatusOf(2, new RunSummary())).toBe("empty"); + expect(executionStatusOf(0, summaryWith("completed"))).toBe("completed"); + expect(executionStatusOf(1, summaryWith("completed", "failed"))).toBe("partial"); + }); +}); + +describe("the budget verdicts say what they refused and what would allow it", () => { + const xdc = NETWORKS.XDC; + + it("allows an implicit span inside the per-chain limit and refuses one above it", () => { + const inside = checkCaptureSpan(xdc, 1, 30 * xdc.blocksPerDay, { mode: "daily" }); + expect(inside.allowed).toBe(true); + expect(inside.reason).toBeNull(); + expect(inside.limit).toBe(30 * xdc.blocksPerDay); + + // The audit's per-capture receipt: 12,394,045 blocks against a limit of 1,296,000. + const over = checkCaptureSpan(xdc, 95_000_000, 107_394_045, { mode: "daily" }); + expect(over.allowed).toBe(false); + expect(over.requested).toBe(12_394_046); + expect(over.reason).toMatch(/--max-capture-blocks=N/); + }); + + it("honours an explicit --max-capture-blocks over the per-chain default", () => { + const raised = checkCaptureSpan(xdc, 1, 2_000_000, { mode: "daily", maxCaptureBlocks: 3_000_000 }); + expect(raised.allowed).toBe(true); + expect(raised.limit).toBe(3_000_000); + }); + + it("never reports a negative span for a reversed range", () => { + // `nothing_to_fetch` is decided before the guard, but a verdict that reported a negative + // number would make the refusal message nonsense if the order ever changed. + expect(checkCaptureSpan(xdc, 100, 50, { mode: "daily" }).requested).toBe(0); + }); + + it("allows a run at the size limit and refuses the one above it", () => { + expect(checkRunSize(DEFAULT_MAX_CAPTURES, { mode: "daily" }).allowed).toBe(true); + const refused = checkRunSize(DEFAULT_MAX_CAPTURES + 1, { mode: "daily" }); + expect(refused.allowed).toBe(false); + expect(refused.reason).toMatch(/--max-captures=N/); + expect(checkRunSize(50, { mode: "daily", maxCaptures: 50 }).allowed).toBe(true); + }); +}); + +describe("a run with nothing to do says so, in the coverage ledger and in the exit code", () => { + it("treats an address the control plane does not know as unsupported, not as a clean run", async () => { + // Plan task 7. A lowercase 40-hex address that is in no seed. Every chain therefore yields + // zero targets, which used to `continue` past a warning and exit 0. + const result = await runPipeline({ + mode: "daily", + addresses: ["0x000000000000000000000000000000000000dead"], + }); + + expect(result.summary.totals.completed).toBe(0); + expect(result.summary.totals.unsupported).toBeGreaterThan(0); + expect(captureExitCodeFor(result.summary)).toBe(2); + expect(result.summary.problems.every((u) => u.kind === "unsupported")).toBe(true); + }); + + it("treats a chain name no configuration declares as unsupported", async () => { + const result = await runPipeline({ mode: "daily", chains: ["SOLANA"] }); + + expect(captureExitCodeFor(result.summary)).toBe(2); + expect(result.summary.units).toHaveLength(1); + expect(result.summary.units[0].kind).toBe("unsupported"); + expect(result.summary.units[0].grain).toBe(PARENT_GRAIN); + expect(result.summary.units[0].detail).toMatch(/no configured chain matched/); + }); + + it("records a globally refused run against both grains without claiming a range", async () => { + // 114 across 3 chains, MEASURED 2026-09-28 after Fuse left the release. It was 142 across 4 + // while Fuse was still captured. Exact on purpose: the number of contracts a bare run would + // attempt is a consequence of the release scope, so it moving is a decision to acknowledge + // here rather than a detail to absorb with a loose matcher. + const verdict = checkRunSize(114, { mode: "daily" }); + expect(verdict.allowed, "precondition: the run-size guard must refuse").toBe(false); + + await runPipeline({ mode: "daily" }); + + const refusals = (sim.tables.get("IngestionCoverage")?.rows ?? []) + .filter((r) => r.status === "refused_budget"); + + expect(refusals.length).toBeGreaterThan(0); + for (const row of refusals) { + // A run-level refusal covers no range and must not pretend to. Both grains are named in one + // parent target set, which is the form plan task 6 allows for a parent refusal. + expect(row.target_table).toBe(PARENT_GRAIN); + expect(row.contract_address).toBeNull(); + expect(row.from_block).toBe(0); + expect(row.to_block).toBe(0); + expect(row.rows_merged).toBe(0); + expect(row.error_message).toMatch(/RUN_REFUSED \(114 target\(s\) planned across 3 chain\(s\)\)/); + } + }); + + it("writes a per-capture refusal as two rows, one per grain, over the real range", async () => { + const xdc = NETWORKS.XDC; + const span = checkCaptureSpan(xdc, 95_000_000, 107_394_045, { mode: "backfill" }); + expect(span.allowed, "precondition: the span guard must refuse").toBe(false); + + await runPipeline({ + mode: "daily", + chains: ["XDC"], + addresses: ["0x22867567e2d80f2049200e25c6f31cb6ec2f0faf"], + toBlock: 107_394_045, + maxCaptures: DEFAULT_MAX_CAPTURES, + }); + + const refusals = (sim.tables.get("IngestionCoverage")?.rows ?? []) + .filter((r) => r.status === "refused_budget"); + + expect(refusals.map((r) => r.target_table).sort()).toEqual([RAW_LOGS_TABLE, TRANSACTIONS_TABLE]); + // Two coverage rows, two capture ids. A shared id would make a row unable to name the capture + // that produced it, which is the defect L0-6 exists for. + expect(new Set(refusals.map((r) => r.capture_id)).size).toBe(2); + for (const row of refusals) { + expect(row.to_block).toBe(107_394_045); + expect(row.contract_address).toBe("0x22867567e2d80f2049200e25c6f31cb6ec2f0faf"); + expect(row.error_message).toMatch(/Refusing a capture of/); + expect(row.rows_inserted).toBe(0); + } + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-decode-surface.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-decode-surface.test.ts new file mode 100644 index 0000000..b25e76f --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-decode-surface.test.ts @@ -0,0 +1,307 @@ +/** + * The decode layer: union ABIs, the computed ambiguous set, and the undecodable-log counter. + * + * The centrepiece is the union-order test. It does not merely assert that a list is sorted -- it + * decodes a real log both ways with the same decoder the system would use, and pins the exact + * wrong value the wrong order produces. An ordering assertion that only checks the array would + * still pass if the ordering stopped mattering, and the whole point is that it matters. + */ + +import { describe, it, expect } from "vitest"; +import { decodeEventLog, encodeAbiParameters, keccak256, pad, toHex } from "viem"; +import { parseEventSurface } from "../../src/control-plane/eventSurface.js"; +import { parseRegistry } from "../../src/control-plane/contractRegistry.js"; +import { inspectControlPlane } from "../../src/control-plane/index.js"; +import { + buildUnionAbi, + buildAllUnionAbis, + isNewestFirst, + computeAmbiguousKeys, + assertNoUnhandledDecodeAmbiguity, + countUndecodableLogs, + intervalsWithNoDecodableSurface, + abiItemIdentity, + UnhandledDecodeAmbiguityError, + KNOWN_DECODE_AMBIGUITIES, +} from "../../src/control-plane/decodeSurface.js"; +import { runBuildCheck, parseArgs } from "../../src/control-plane/build-check.js"; +import { surfaceRow, writeSurface, UBI } from "../helpers/seed-fixtures.js"; + +/* + * The real ambiguity, reproduced at fixture scale. + * + * `GReputation.StateHashProof(string,address,uint256)` declares no indexed parameter in era 1 and + * indexes the address in eras 2 and 3. Indexed modifiers are excluded from the signature hash, so + * both layouts share one topic0 and a topic0-keyed decoder has two candidates. + */ +const SIG = "StateHashProof(string,address,uint256)"; +const TOPIC0 = keccak256(toHex(SIG)); +const USER = "0x603b8c0f110e037b51a381cbcacabb8d6c6e4543"; +const BALANCE = 1234567890123456789n; + +const stateHashProofRow = (era: string, indexed: string) => + surfaceRow({ + contract_name: "GReputation", proxy_address: UBI, era_index: era, + event_name: "StateHashProof", event_signature: SIG, topic0: TOPIC0, + indexed_positions: indexed, param_types: "string address uint256", + param_names: "blockchain user balance", + }); + +const twoLayoutSurface = () => + parseEventSurface(writeSurface([stateHashProofRow("1", ""), stateHashProofRow("2", "1")])); + +/** A real era-2 log: the address is lifted into topic1 and is absent from the data. */ +const ERA_2_LOG = { + topics: [TOPIC0, pad(USER as `0x${string}`, { size: 32 })] as [`0x${string}`, `0x${string}`], + data: encodeAbiParameters([{ type: "string" }, { type: "uint256" }], ["celo", BALANCE]), +}; + +/** A real era-1 log: everything sits in the data and there is one topic. */ +const ERA_1_LOG = { + topics: [TOPIC0] as [`0x${string}`], + data: encodeAbiParameters( + [{ type: "string" }, { type: "address" }, { type: "uint256" }], + ["celo", USER as `0x${string}`, BALANCE], + ), +}; + +describe("a union ABI is built newest-implementation-first", () => { + it("orders by descending era, and the order survives deduplication", () => { + const union = buildUnionAbi(twoLayoutSurface().rows); + expect(union.eraOrder).toEqual([2, 1]); + expect(isNewestFirst(union)).toBe(true); + }); + + /* + * THE DISCRIMINATOR, and it is the reason the ordering rule exists. + * + * Every value below was MEASURED against viem, not predicted. Reverse the order in + * `buildUnionAbi` and the first assertion fails; the rest of this test is what that failure + * would have cost, spelled out, so nobody reads the ordering rule as a tidiness preference. + */ + it("decodes an era-2 log correctly, where the reversed order decodes it SILENTLY WRONG", () => { + const union = buildUnionAbi(twoLayoutSurface().rows); + + const right = decodeEventLog({ abi: union.abi, data: ERA_2_LOG.data, topics: ERA_2_LOG.topics }); + const rightArgs = right.args as unknown as { user: string; balance: bigint }; + expect(rightArgs.balance).toBe(BALANCE); + expect(rightArgs.user.toLowerCase()).toBe(USER); + + // The SAME log, the SAME decoder, the ONLY difference being the array order. + const reversed = [...union.abi].reverse(); + const wrong = decodeEventLog({ abi: reversed, data: ERA_2_LOG.data, topics: ERA_2_LOG.topics }); + const wrongArgs = wrong.args as unknown as { user: string; balance: bigint }; + + // It does not throw. It returns 4 -- the BYTE LENGTH of the string "celo", read as a uint256 + // because the reader is one word out of step with the writer. Nothing downstream can tell + // this apart from a real balance of 4. + expect(wrongArgs.balance).toBe(4n); + expect(wrongArgs.user.toLowerCase()).toBe("0x000000000000000000000000112210f47de98115"); + expect(wrongArgs.balance).not.toBe(BALANCE); + }); + + it("throws on an old ambiguous log rather than guessing, which is the trade being made", () => { + const union = buildUnionAbi(twoLayoutSurface().rows); + // Newest-first is correct for recent data and LOUD on old ambiguous data. A throw is + // recoverable; a plausible wrong number is not. That asymmetry is the whole argument. + expect(() => decodeEventLog({ abi: union.abi, data: ERA_1_LOG.data, topics: ERA_1_LOG.topics })) + .toThrow(/indexed event parameter/); + }); + + it("keeps both layouts through the merge, because indexed flags are part of an entry's identity", () => { + const rows = twoLayoutSurface().rows; + expect(abiItemIdentity(rows[0])).not.toBe(abiItemIdentity(rows[1])); + expect(buildUnionAbi(rows).entries).toHaveLength(2); + }); + + it("collapses a genuinely identical entry to its newest occurrence", () => { + const surface = parseEventSurface(writeSurface([stateHashProofRow("1", "1"), stateHashProofRow("2", "1")])); + const union = buildUnionAbi(surface.rows); + expect(union.entries).toHaveLength(1); + expect(union.eraOrder).toEqual([2]); + }); + + it("refuses to build a union spanning two contracts", () => { + const surface = parseEventSurface(writeSurface([ + stateHashProofRow("1", ""), + surfaceRow({ proxy_address: "0x3333333333333333333333333333333333333333", era_index: "1" }), + ])); + expect(() => buildUnionAbi(surface.rows)).toThrow(/more than one contract/); + }); + + it("every union built from the shipped seed is newest-first", () => { + const surface = inspectControlPlane().plane!.eventSurface; + const unions = [...buildAllUnionAbis(surface).values()]; + expect(unions.length).toBeGreaterThan(0); + expect(unions.filter((u) => !isNewestFirst(u))).toEqual([]); + }); +}); + +describe("the ambiguous set is computed from the seed, with no chain call", () => { + it("finds a key carrying two physical layouts", () => { + const keys = computeAmbiguousKeys(twoLayoutSurface()); + expect(keys).toHaveLength(1); + expect(keys[0].signature).toBe(SIG); + expect(keys[0].layouts.map((l) => l.indexedPositions)).toEqual(["1", ""]); + expect(keys[0].layouts.find((l) => l.indexedPositions === "1")!.eras).toEqual([2]); + }); + + it("does not flag a key whose layout is stable across its eras", () => { + const stable = parseEventSurface(writeSurface([stateHashProofRow("1", "1"), stateHashProofRow("2", "1")])); + expect(computeAmbiguousKeys(stable)).toEqual([]); + }); + + it("does not flag two DIFFERENT addresses sharing one topic0", () => { + // A global topic0 collision across addresses is not the ambiguous set: each address gets its + // own union, so neither decoder ever sees the other's entry. Conflating the two would report + // five keys where the real number is two. + const shared = parseEventSurface(writeSurface([ + stateHashProofRow("1", ""), + surfaceRow({ + contract_name: "GReputation", proxy_address: "0x3333333333333333333333333333333333333333", + era_index: "1", event_name: "StateHashProof", event_signature: SIG, topic0: TOPIC0, + indexed_positions: "1", param_types: "string address uint256", param_names: "blockchain user balance", + }), + ])); + expect(computeAmbiguousKeys(shared)).toEqual([]); + }); + + it("ignores anonymous rows, which carry no selector to be ambiguous about", () => { + const anon = parseEventSurface(writeSurface([ + surfaceRow({ event_name: "LogNote", event_signature: "LogNote(uint256)", topic0: "", anonymous: "true", indexed_positions: "", param_types: "uint256", param_names: "x", era_index: "1" }), + surfaceRow({ event_name: "LogNote", event_signature: "LogNote(uint256)", topic0: "", anonymous: "true", indexed_positions: "0", param_types: "uint256", param_names: "x", era_index: "2" }), + ])); + expect(computeAmbiguousKeys(anon)).toEqual([]); + }); +}); + +describe("an undeclared ambiguity fails the build", () => { + it("throws, naming the key and both layouts", () => { + let thrown: unknown; + try { + assertNoUnhandledDecodeAmbiguity(twoLayoutSurface()); + } catch (e) { + thrown = e; + } + expect(thrown).toBeInstanceOf(UnhandledDecodeAmbiguityError); + const message = (thrown as Error).message; + expect(message).toContain("DECODE_AMBIGUITY_UNHANDLED"); + expect(message).toContain(SIG); + expect(message).toContain("indexed[1]"); + expect(message).toContain("indexed[]"); + }); + + it("does not throw on a key that has been declared with its disposition", () => { + // The shipped seed carries exactly the two declared keys, so the assertion passes on it and + // would stop passing the moment a third appeared. + const surface = inspectControlPlane().plane!.eventSurface; + const found = assertNoUnhandledDecodeAmbiguity(surface); + expect(found).toHaveLength(2); + expect(found.every((k) => k.signature === SIG)).toBe(true); + expect(found.map((k) => k.chain).sort()).toEqual(["ETHEREUM", "FUSE"]); + }); + + it("declares a disposition for every known ambiguity rather than only listing it", () => { + expect(KNOWN_DECODE_AMBIGUITIES.length).toBeGreaterThan(0); + for (const k of KNOWN_DECODE_AMBIGUITIES) { + expect(k.address).toMatch(/^0x[0-9a-f]{40}$/); + expect(k.disposition.length).toBeGreaterThan(40); + } + }); + + it("makes the control plane invalid, so the running system refuses too", () => { + // Not only the build: a seed carrying an undeclared ambiguity fails inspection, which is what + // stops the assertion being a thing that is true only when somebody runs a script. + const inspection = inspectControlPlane({ eventSurface: writeSurface([stateHashProofRow("1", ""), stateHashProofRow("2", "1")]) }); + expect(inspection.decodeViolations.map((v) => v.check)).toEqual(["decode_ambiguity_declared"]); + expect(inspection.ok).toBe(false); + }); + + it("the shipped seed produces no decode violation", () => { + expect(inspectControlPlane().decodeViolations).toEqual([]); + }); +}); + +describe("the build check is a command that exits non-zero", () => { + it("is clean on the shipped seeds", () => { + const result = runBuildCheck(); + expect(result.ok).toBe(true); + expect(result.ambiguousKeyCount).toBe(2); + expect(result.unionsOutOfOrder).toBe(0); + }); + + it("fails on a fixture that introduces a third ambiguity", () => { + expect(() => runBuildCheck({ eventSurface: writeSurface([stateHashProofRow("1", ""), stateHashProofRow("2", "1")]) })) + .toThrow(UnhandledDecodeAmbiguityError); + }); + + it("refuses an unknown argument rather than ignoring it", () => { + expect(() => parseArgs(["--not-a-flag", "x"])).toThrow(/unknown argument/); + expect(() => parseArgs(["--registry"])).toThrow(/needs a value/); + }); +}); + +describe("decode coverage is counted, not assumed", () => { + const surface = () => parseEventSurface(writeSurface([surfaceRow({ era_index: "1" })])); + + it("counts a log whose topic0 matches no surface entry, per contract", () => { + const s = surface(); + const known = s.rows[0].topic0!; + const report = countUndecodableLogs([ + { chainId: 50, address: UBI, topic0: known }, + { chainId: 50, address: UBI, topic0: "0x" + "ff".repeat(32) }, + { chainId: 50, address: UBI, topic0: "0x" + "ff".repeat(32) }, + ], s); + + expect(report.byContract).toHaveLength(1); + expect(report.byContract[0].rowsConsidered).toBe(3); + expect(report.byContract[0].rowsDecodable).toBe(1); + expect(report.byContract[0].rowsUndecodable).toBe(2); + // The distinct unmatched selector, so the answer names what to go and find an ABI for rather + // than only how many rows were lost. + expect(report.byContract[0].unmatchedTopic0s).toEqual(["0x" + "ff".repeat(32)]); + }); + + it("reports an address with no surface at all as its own state", () => { + const report = countUndecodableLogs([{ chainId: 50, address: "0x9999999999999999999999999999999999999999", topic0: "0x" + "aa".repeat(32) }], surface()); + expect(report.byContract[0].addressHasNoSurface).toBe(true); + expect(report.byContract[0].rowsUndecodable).toBe(1); + }); + + it("counts an unreadable row as an ERROR, never as an undecodable one", () => { + // An absence is a measurement only when its error count is zero. A row with no topic0 is + // unreadable, which is a different fact from "this event is unknown", and folding the two + // together would make a broken reader look like a missing ABI. + const report = countUndecodableLogs([ + { chainId: 50, address: UBI, topic0: null }, + { chainId: 50, address: UBI, topic0: "0x" + "ff".repeat(32) }, + ], surface()); + expect(report.errors).toBe(1); + expect(report.rowsUndecodable).toBe(1); + expect(report.rowsConsidered).toBe(1); + expect(report.errorDetail[0]).toMatch(/no topic0/); + }); + + it("is case-insensitive on the selector, so a checksum difference is not a missing ABI", () => { + const s = surface(); + const report = countUndecodableLogs([{ chainId: 50, address: UBI.toUpperCase(), topic0: s.rows[0].topic0!.toUpperCase() }], s); + expect(report.rowsUndecodable).toBe(0); + }); + + it("names the intervals nothing can decode, split by whether an ABI is held at all", () => { + const plane = inspectControlPlane().plane!; + const intervals = intervalsWithNoDecodableSurface(plane.registry.rows, plane.eventSurface); + const inScope = intervals.filter((i) => ["CELO", "XDC", "ETHEREUM"].includes(i.chain)); + // MEASURED 2026-09-28 against the shipped seeds. + expect(inScope).toHaveLength(24); + expect(inScope.filter((i) => i.reason === "no_abi_held")).toHaveLength(7); + expect(inScope.filter((i) => i.reason === "no_surface_row")).toHaveLength(17); + }); + + it("returns nothing for a registry whose every interval has a surface row", () => { + const s = surface(); + const registry = parseRegistry(); + const covered = registry.rows.filter((r) => r.chainId === 50 && r.proxyAddress === UBI && r.eraIndex === 1); + expect(intervalsWithNoDecodableSurface(covered, s)).toEqual([]); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-era-confidence.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-era-confidence.test.ts new file mode 100644 index 0000000..27e267d --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-era-confidence.test.ts @@ -0,0 +1,263 @@ +/** + * The era confidence-grade rule. + * + * The rule was published and hashed BEFORE any grade was assigned, so these tests pin a mapping + * that already existed rather than describing whatever the data turned out to look like. Each + * clause gets a case, in both directions where the clause has two. + */ + +import { describe, it, expect } from "vitest"; +import { + gradeFromBoundaryEvidence, + gradeFromRegistryRow, + gradeForEra, + parseEraBoundaryEvidence, + slotReadingAdmissible, + eraEvidenceKey, + CONFIDENCE_GRADES, + GRADE_STRENGTH, + type EraBoundaryEvidence, +} from "../../src/control-plane/eraConfidence.js"; +import { parseRegistry } from "../../src/control-plane/contractRegistry.js"; +import { registryRowWithBoundary, writeRegistryWithBoundary, INT64_MAX } from "../helpers/seed-fixtures.js"; + +/** A fully corroborated era: bisected boundary, agreeing order, every event re-read. */ +const BASE: EraBoundaryEvidence = { + chain: "XDC", chainId: 50, proxyAddress: "0x22867567e2d80f2049200e25c6f31cb6ec2f0faf", + eraIndex: 1, implementationAddress: "0x1111111111111111111111111111111111111111", + validFromBlock: 95144756, openEnded: false, + openingTransitionKind: "interior_boundary", + openingEventImplementation: "0x1111111111111111111111111111111111111111", + openingBothMeasured: true, openingAddressAgrees: true, openingOrderAgrees: true, + slotOutcome: "answer", slotAddress: "0x1111111111111111111111111111111111111111", + slotAgreeing: 2, slotErrorCount: 0, + crossCheckBlocked: false, checkPointsMeasured: 5, checkPointsDisagreeing: 0, + claimedEvents: 2, independentlyConfirmedEvents: 2, baselineSkippedChunks: 0, + tailComplete: true, tailSkippedChunks: 0, tailErrorChunks: 0, + obligatorilyEmits: false, frozenSafeHead: 107765548, boundaryCheckedThroughBlock: 107576852, + sourceManifest: "fixture.json", manifestSha256: "ab".repeat(32), +}; + +const ev = (o: Partial): EraBoundaryEvidence => ({ ...BASE, ...o }); + +describe("rule A: the grade of an era a boundary manifest covers", () => { + it("A1 corroborated -- the slot agrees at the boundary AND every event was independently re-read", () => { + const v = gradeFromBoundaryEvidence(BASE); + expect(v.grade).toBe("corroborated"); + expect(v.clause).toBe("A1"); + expect(v.source).toBe("boundary_evidence"); + }); + + it("A1 needs BOTH voices: a bisected boundary alone drops to A2", () => { + // 1 of 2 confirmed. A contract-level count cannot be attributed to one era, so a partial + // count buys nothing rather than being rounded up -- which is the whole reason this is A2. + const v = gradeFromBoundaryEvidence(ev({ independentlyConfirmedEvents: 1 })); + expect(v.grade).toBe("slot_bisected"); + expect(v.clause).toBe("A2"); + expect(v.reason).toContain("1 of 2"); + }); + + it("A1 needs BOTH voices: full event confirmation alone does not reach it", () => { + const v = gradeFromBoundaryEvidence(ev({ openingBothMeasured: false, openingAddressAgrees: null, openingOrderAgrees: null })); + expect(v.grade).not.toBe("corroborated"); + }); + + it("A1 is refused when any checkpoint on the contract disagreed", () => { + expect(gradeFromBoundaryEvidence(ev({ checkPointsDisagreeing: 1 })).clause).toBe("A2"); + }); + + it("A3 slot_bisected -- the live era's implementation matches an admissible head slot read", () => { + const v = gradeFromBoundaryEvidence(ev({ + openEnded: true, openingBothMeasured: false, openingAddressAgrees: null, openingOrderAgrees: null, + checkPointsMeasured: 0, independentlyConfirmedEvents: 1, + })); + expect(v.grade).toBe("slot_bisected"); + expect(v.clause).toBe("A3"); + }); + + it("A3 is unavailable to a CLOSED era, because a head read says nothing about one", () => { + const closed = ev({ + openEnded: false, openingBothMeasured: false, openingAddressAgrees: null, openingOrderAgrees: null, + checkPointsMeasured: 0, independentlyConfirmedEvents: 1, + }); + expect(gradeFromBoundaryEvidence(closed).clause).toBe("A4"); + }); + + it("A3 is unavailable when the head slot names a DIFFERENT implementation", () => { + const v = gradeFromBoundaryEvidence(ev({ + openEnded: true, openingBothMeasured: false, openingAddressAgrees: null, openingOrderAgrees: null, + slotAddress: "0x9999999999999999999999999999999999999999", independentlyConfirmedEvents: 1, + })); + expect(v.clause).toBe("A4"); + }); + + it("A4 announced -- an on-chain record bounds it, whole, with an independent check available", () => { + const v = gradeFromBoundaryEvidence(ev({ + openingBothMeasured: false, openingAddressAgrees: null, openingOrderAgrees: null, + checkPointsMeasured: 0, independentlyConfirmedEvents: 1, + })); + expect(v.grade).toBe("announced"); + expect(v.clause).toBe("A4"); + }); + + it("A4 drops to A5 when the announcement record has a hole", () => { + const holed = ev({ + openingBothMeasured: false, openingAddressAgrees: null, openingOrderAgrees: null, + independentlyConfirmedEvents: 1, tailErrorChunks: 1, + }); + expect(gradeFromBoundaryEvidence(holed).clause).toBe("A5"); + }); + + it("A5 inferred -- no independent check is available AT ALL, which is Fuse's case exactly", () => { + const v = gradeFromBoundaryEvidence(ev({ + openingBothMeasured: false, openingAddressAgrees: null, openingOrderAgrees: null, + crossCheckBlocked: true, checkPointsMeasured: 0, independentlyConfirmedEvents: 0, + })); + expect(v.grade).toBe("inferred"); + expect(v.clause).toBe("A5"); + expect(v.reason).toContain("BLOCKED"); + }); + + it("A5 when no transition opens the era at all", () => { + expect(gradeFromBoundaryEvidence(ev({ + openingEventImplementation: null, openingBothMeasured: false, + openingAddressAgrees: null, openingOrderAgrees: null, independentlyConfirmedEvents: 1, + })).clause).toBe("A5"); + }); + + it("obligatorilyEmits is carried but never decides, because it has one value everywhere", () => { + // It reads false on all six shipped manifests, so it cannot separate one era from another. + // It is the reason no era reaches `complete`, which is a statement about the REMOVED gate. + expect(gradeFromBoundaryEvidence(ev({ obligatorilyEmits: true })).grade) + .toBe(gradeFromBoundaryEvidence(ev({ obligatorilyEmits: false })).grade); + }); +}); + +describe("a slot reading is admissible only when two or more readers agree", () => { + it("accepts a positive answer agreed by two", () => { + expect(slotReadingAdmissible({ slotOutcome: "answer", slotAgreeing: 2, slotErrorCount: 0 })).toBe(true); + }); + + it("accepts a positive answer even with a non-zero error count, and says so in the rule", () => { + // A non-zero error alongside a POSITIVE answer two readers agree on does not void the answer. + // The error count is carried into the receipt so a reader can weigh it. + expect(slotReadingAdmissible({ slotOutcome: "answer", slotAgreeing: 2, slotErrorCount: 1 })).toBe(true); + }); + + it("refuses a single reader", () => { + expect(slotReadingAdmissible({ slotOutcome: "answer", slotAgreeing: 1, slotErrorCount: 0 })).toBe(false); + }); + + it("refuses a ZERO reading whose error count is non-zero", () => { + // An absence is a measurement only when its error count is zero. + expect(slotReadingAdmissible({ slotOutcome: "zero", slotAgreeing: 2, slotErrorCount: 1 })).toBe(false); + expect(slotReadingAdmissible({ slotOutcome: "zero", slotAgreeing: 2, slotErrorCount: 0 })).toBe(true); + }); +}); + +describe("rule B: the grade of an era with no promoted boundary evidence", () => { + const rowWith = (o: Parameters[0]) => + parseRegistry(writeRegistryWithBoundary([ + registryRowWithBoundary({ era_count: "1", valid_to_block: INT64_MAX, is_live: "true", ...o }), + ])).rows[0]; + + it("B1 slot_bisected, from a bisected era_evidence", () => { + expect(gradeFromRegistryRow(rowWith({ era_evidence: "slot_bisection_and_announcement_log" }))) + .toMatchObject({ grade: "slot_bisected", clause: "B1", source: "registry_seed" }); + expect(gradeFromRegistryRow(rowWith({ era_evidence: "slot_bisection_only" })).clause).toBe("B1"); + }); + + it("B2 announced, from an announcement with no state read", () => { + expect(gradeFromRegistryRow(rowWith({ era_evidence: "announcement_log_only" }))) + .toMatchObject({ grade: "announced", clause: "B2" }); + }); + + it("B3 announced, when the creation that opens the era was established by two agreeing voices", () => { + expect(gradeFromRegistryRow(rowWith({ + era_evidence: "contract_creation", creation_method: "explorer_index_and_state_read_agree", + }))).toMatchObject({ grade: "announced", clause: "B3" }); + }); + + it("B4 inferred, when that same creation rests on ONE voice", () => { + expect(gradeFromRegistryRow(rowWith({ + era_evidence: "contract_creation", creation_method: "etherscan_v2_getcontractcreation", + }))).toMatchObject({ grade: "inferred", clause: "B4" }); + }); + + it("is CAPPED at slot_bisected: no registry row can reach corroborated", () => { + // The registry records how an era was found; it carries no second reader's verdict. A grade + // claiming two agreeing voices has to be able to name both, and this one cannot. + for (const evidence of ["slot_bisection_and_announcement_log", "slot_bisection_only", "announcement_log_only", "contract_creation"]) { + const g = gradeFromRegistryRow(rowWith({ era_evidence: evidence })); + expect(GRADE_STRENGTH[g.grade]).toBeLessThan(GRADE_STRENGTH.corroborated); + } + }); +}); + +describe("the promoted evidence seed is what ships, and it re-derives the grades", () => { + const evidence = parseEraBoundaryEvidence(); + const registry = parseRegistry(); + const IN_SCOPE = new Set(["CELO", "XDC", "ETHEREUM"]); + + it("carries every era the six manifests covered", () => { + // MEASURED 2026-09-28: 41 eras across 6 manifests, 15 of them on a release chain. + expect(evidence.size).toBe(41); + expect([...evidence.values()].filter((e) => IN_SCOPE.has(e.chain))).toHaveLength(15); + expect([...evidence.values()].filter((e) => e.chain === "FUSE")).toHaveLength(26); + }); + + it("names its own source manifest and that manifest's hash on every row", () => { + for (const e of evidence.values()) { + expect(e.sourceManifest).toMatch(/\.json$/); + expect(e.manifestSha256).toMatch(/^[0-9a-f]{64}$/); + } + }); + + it("grades all 15 in-scope eras from the manifest, with the measured distribution", () => { + const inScope = registry.rows.filter((r) => IN_SCOPE.has(r.chain) && !r.noCodeDeployed); + const graded = inScope + .map((r) => ({ row: r, verdict: gradeForEra(r, evidence) })) + .filter((g) => g.verdict.source === "boundary_evidence"); + + expect(graded).toHaveLength(15); + const byGrade = graded.reduce>((a, g) => ((a[g.verdict.grade] = (a[g.verdict.grade] ?? 0) + 1), a), {}); + // MEASURED, and it is the distribution the published rule produces: XDC's three eras are the + // only ones with both a bisected boundary and full event confirmation. + expect(byGrade).toEqual({ corroborated: 3, slot_bisected: 2, announced: 10 }); + }); + + it("every in-scope era carries a grade, not only the manifest-backed ones", () => { + const inScope = registry.rows.filter((r) => IN_SCOPE.has(r.chain) && !r.noCodeDeployed); + expect(inScope).toHaveLength(262); + for (const r of inScope) { + const v = gradeForEra(r, evidence); + expect(CONFIDENCE_GRADES).toContain(v.grade); + expect(v.clause).toMatch(/^[AB][1-5]$/); + } + }); + + /* + * THE NON-DEGENERACY CHECK. A rule that gives every era the same answer is not a rule, and a + * suspiciously uniform result is a bug report about the instrument before it is a finding. + * Run over the whole population, the rule must separate the chain where an independent check + * could run from the one where it provably could not. + */ + it("discriminates: Fuse, where no historical state read is obtainable, grades lower", () => { + const fuse = [...evidence.values()].filter((e) => e.chain === "FUSE").map(gradeFromBoundaryEvidence); + const xdc = [...evidence.values()].filter((e) => e.chain === "XDC").map(gradeFromBoundaryEvidence); + + expect(fuse.filter((g) => g.grade === "inferred").length).toBeGreaterThan(0); + expect(fuse.filter((g) => g.grade === "corroborated")).toHaveLength(0); + expect(xdc.every((g) => g.grade === "corroborated")).toBe(true); + }); + + it("uses more than one grade across the whole population", () => { + const all = [...evidence.values()].map((e) => gradeFromBoundaryEvidence(e).grade); + expect(new Set(all).size).toBeGreaterThan(1); + }); + + it("keys evidence case-insensitively on the address", () => { + const one = [...evidence.values()][0]; + expect(evidence.get(eraEvidenceKey(one.chainId, one.proxyAddress.toUpperCase(), one.eraIndex))).toBeDefined(); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-era-intervals.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-era-intervals.test.ts new file mode 100644 index 0000000..fc206d0 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-era-intervals.test.ts @@ -0,0 +1,223 @@ +/** + * The era validity-interval table and its three properties. + * + * Every check here is run in BOTH directions: green on the shipped seed, and red on a seed mutated + * to carry exactly the defect it claims to catch. A structural test that has never been seen to + * fail is an assumption with a test's name on it. + */ + +import { describe, it, expect } from "vitest"; +import { existsSync } from "fs"; +import { join } from "path"; +import { + parseEraIntervals, + assertNoOverlappingIntervals, + assertNoIntervalGaps, + assertExactlyOneIntervalCovers, + boundaryProbes, + ERA_INTERVAL_REQUIRED_COLUMNS, + ERA_INTERVALS_HEADER, + OPEN_ENDED, + type EraInterval, +} from "../../src/control-plane/eraIntervals.js"; +import { parseRegistry } from "../../src/control-plane/contractRegistry.js"; +import { SEEDS_DIR } from "../../src/control-plane/chains.js"; +import { CONFIDENCE_GRADES, parseEraBoundaryEvidence, eraEvidenceKey } from "../../src/control-plane/eraConfidence.js"; + +const intervals = parseEraIntervals(); +const registry = parseRegistry(); + +const creationBlockFor = (chainId: number, proxyAddress: string): bigint | null => { + const era1 = registry.rows.find( + (r) => r.chainId === chainId && r.proxyAddress === proxyAddress && r.eraIndex === 1 && !r.noCodeDeployed, + ); + return era1?.creationBlock === undefined || era1.creationBlock === null ? null : BigInt(era1.creationBlock); +}; + +/** Mutate one interval, leaving every other row exactly as shipped. */ +const mutate = (predicate: (i: EraInterval) => boolean, patch: Partial): EraInterval[] => + intervals.map((i) => (predicate(i) ? { ...i, ...patch } : i)); + +describe("the era interval table carries what plan 5.4 requires", () => { + it("has all eight required columns", () => { + for (const c of ERA_INTERVAL_REQUIRED_COLUMNS) expect(ERA_INTERVALS_HEADER).toContain(c); + }); + + it("covers every in-release deployed era, and the ingestion slice is 206 of them", () => { + // MEASURED 2026-09-28. Plan 5.2 says "208 in-scope rows", which reconciles exactly to the + // CELO + XDC rows of the registry seed -- 168 + 40. Two of those 208 are `no_code_deployed` + // rows that declare NO interval at all, so the interval table carries 206 of them, plus + // Ethereum's 56, which is declared in the release and simply not ingested by this slice. + expect(intervals).toHaveLength(262); + expect(intervals.filter((i) => i.chain === "CELO" || i.chain === "XDC")).toHaveLength(206); + expect(intervals.filter((i) => i.chain === "ETHEREUM")).toHaveLength(56); + }); + + it("carries a grade and a receipt on EVERY row, so neither column is nulls with a name", () => { + for (const i of intervals) { + expect(CONFIDENCE_GRADES).toContain(i.confidenceGrade); + expect(i.evidenceReceiptUri.length).toBeGreaterThan(0); + expect(i.abiId.length).toBeGreaterThan(0); + } + }); + + it("every receipt resolves to a tracked path inside the repository", () => { + // A receipt nobody outside this machine can open is not a receipt, it is an assertion. The + // property asserted here is the positive one -- the path is a real, tracked location in this + // repository -- rather than a copy of any particular tool's list of paths to avoid. + for (const i of intervals) { + const path = i.evidenceReceiptUri.split("#")[0]; + expect(path.startsWith("gd_dbt/seeds/")).toBe(true); + expect(path.endsWith(".csv")).toBe(true); + expect(existsSync(join(SEEDS_DIR, path.replace("gd_dbt/seeds/", "")))).toBe(true); + } + }); + + it("the row key in a receipt resolves to exactly one row of the seed it names", () => { + // `#CHAIN/0xaddress/era=N` has to be resolvable, not decorative. + const evidence = parseEraBoundaryEvidence(); + for (const i of intervals.filter((x) => x.evidenceReceiptUri.includes("era_boundary_evidence"))) { + const key = i.evidenceReceiptUri.split("#")[1]; + expect(key).toBe(`${i.chain}/${i.proxyAddress}/era=${i.eraIndex}`); + expect(evidence.get(eraEvidenceKey(i.chainId, i.proxyAddress, i.eraIndex))).toBeDefined(); + } + }); + + it("points the manifest-backed eras at the PROMOTED evidence seed, not at the registry", () => { + const promoted = intervals.filter((i) => i.evidenceReceiptUri.startsWith("gd_dbt/seeds/era_boundary_evidence.csv")); + expect(promoted).toHaveLength(15); + // And those are exactly the eras that reach a grade the registry alone cannot produce. + expect(promoted.filter((i) => i.confidenceGrade === "corroborated")).toHaveLength(3); + }); +}); + +describe("no overlapping intervals per (chain, address)", () => { + it("GREEN on the shipped seed", () => { + expect(assertNoOverlappingIntervals(intervals)).toEqual([]); + }); + + it("RED when one era is stretched over the next", () => { + const broken = mutate( + (i) => i.chain === "XDC" && i.contractName === "Invites" && i.eraIndex === 1, + { validToBlock: OPEN_ENDED }, + ); + const v = assertNoOverlappingIntervals(broken); + expect(v.length).toBeGreaterThan(0); + expect(v[0].check).toBe("era_intervals_do_not_overlap"); + expect(v[0].detail).toMatch(/overlaps era 2/); + }); + + it("does NOT flag intervals that merely touch, which is the correct shape", () => { + // Half-open [from, to): era 1 ending at block X and era 2 starting at block X share no block. + // A closed-interval reading would call every contiguous pair an overlap. + const touching = intervals.filter((i) => i.chain === "XDC" && i.contractName === "Invites"); + expect(touching.length).toBe(2); + expect(touching[0].validToBlock).toBe(touching[1].validFromBlock); + expect(assertNoOverlappingIntervals(touching)).toEqual([]); + }); +}); + +describe("no gaps from deployment to head", () => { + it("GREEN on the shipped seed", () => { + expect(assertNoIntervalGaps(intervals, creationBlockFor)).toEqual([]); + }); + + it("RED on a hole between two eras", () => { + const broken = mutate( + (i) => i.chain === "XDC" && i.contractName === "Invites" && i.eraIndex === 1, + { validToBlock: 100000000n }, + ); + const v = assertNoIntervalGaps(broken, creationBlockFor); + expect(v.map((x) => x.check)).toContain("era_intervals_have_no_gaps"); + expect(v.some((x) => x.detail.includes("not contiguous"))).toBe(true); + }); + + it("RED when the first era starts after the contract was created", () => { + // The failure that looks healthiest from the inside: an internally perfect chain that simply + // begins late, losing every log before it while every other assertion still passes. + const broken = mutate( + (i) => i.chain === "XDC" && i.contractName === "UBIScheme" && i.eraIndex === 1, + { validFromBlock: 99999999n }, + ); + const v = assertNoIntervalGaps(broken, creationBlockFor); + expect(v.some((x) => x.detail.includes("belong to no era"))).toBe(true); + }); + + it("RED when a live contract's last era is closed", () => { + const broken = mutate((i) => i.chain === "XDC" && i.contractName === "UBIScheme" && i.isLive, { validToBlock: 107000000n }); + const v = assertNoIntervalGaps(broken, creationBlockFor); + expect(v.some((x) => x.detail.includes("open-ended sentinel"))).toBe(true); + }); + + it("RED when an era index is missing from the table entirely", () => { + const broken = intervals.filter((i) => !(i.chain === "CELO" && i.contractName === "Invites" && i.eraIndex === 4)); + const v = assertNoIntervalGaps(broken, creationBlockFor); + expect(v.some((x) => x.detail.includes("an era is missing"))).toBe(true); + }); +}); + +describe("exactly one row covers any queried block", () => { + const probes = boundaryProbes(intervals); + + it("probes every real boundary rather than an invented block", () => { + // Every era's first block, and every closed era's last block. A boundary off by one is the + // defect this shape exists to find, so the probes sit exactly on the boundaries. + expect(probes.length).toBeGreaterThan(intervals.length); + expect(new Set(probes.map((p) => p.kind))).toEqual(new Set(["era_first_block", "era_last_block"])); + }); + + it("GREEN on the shipped seed", () => { + expect(assertExactlyOneIntervalCovers(intervals, probes)).toEqual([]); + }); + + it("RED with TWO covering rows when an interval is written closed instead of half-open", () => { + const broken = mutate( + (i) => i.chain === "CELO" && i.contractName === "UBIScheme" && i.eraIndex === 1, + { validToBlock: 19276073n }, + ); + const v = assertExactlyOneIntervalCovers(broken, boundaryProbes(broken)); + expect(v.length).toBeGreaterThan(0); + expect(v[0].detail).toMatch(/^2 interval\(s\) cover this block/); + }); + + it("RED with ZERO covering rows on a block inside a hole", () => { + const broken = mutate( + (i) => i.chain === "CELO" && i.contractName === "UBIScheme" && i.eraIndex === 1, + { validToBlock: 19000000n }, + ); + const inTheHole = [{ chainId: 42220, proxyAddress: "0x43d72ff17701b2da814620735c39c620ce0ea4a1", block: 19100000n, kind: "inside_the_hole" }]; + const v = assertExactlyOneIntervalCovers(broken, inTheHole); + expect(v).toHaveLength(1); + expect(v[0].detail).toBe("0 interval(s) cover this block"); + }); + + /* + * WHY THE GAP TEST IS A SEPARATE TEST, found by this one failing when it should not have. + * + * The probe set is derived from the intervals themselves, so after a mutation that SHRINKS an + * era, the probes shrink with it: era 1's last block moves down into era 1, era 2's first block + * stays inside era 2, and nothing probes the hole between them. The coverage property is real + * but it is blind to a gap by construction -- it can only speak about blocks somebody asks + * about. That is precisely the work `assertNoIntervalGaps` does, and it is why three tests are + * three tests rather than one with a longer name. + */ + it("cannot see a gap on its own, which is why the gap test exists", () => { + const broken = mutate( + (i) => i.chain === "CELO" && i.contractName === "UBIScheme" && i.eraIndex === 1, + { validToBlock: 19000000n }, + ); + expect(assertExactlyOneIntervalCovers(broken, boundaryProbes(broken))).toEqual([]); + expect(assertNoIntervalGaps(broken, creationBlockFor).length).toBeGreaterThan(0); + }); +}); + +describe("what these three tests deliberately do NOT detect", () => { + it("a perfectly shaped chain can still rest on weak evidence, and the grade is what says so", () => { + // The interval algebra is silent about how well evidenced an interval is. Saying so is the + // difference between a test suite and a reassurance. + expect(assertNoOverlappingIntervals(intervals)).toEqual([]); + expect(assertNoIntervalGaps(intervals, creationBlockFor)).toEqual([]); + const weak = intervals.filter((i) => i.confidenceGrade === "inferred"); + expect(weak.length).toBeGreaterThan(0); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-event-surface.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-event-surface.test.ts new file mode 100644 index 0000000..0efe65c --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-event-surface.test.ts @@ -0,0 +1,340 @@ +/** + * The event surface: topic0 proof, era binding, topic-slot arithmetic and hash-only parameters. + * + * WHY topic0 IS RECOMPUTED RATHER THAN TRUSTED. An indexed flag is NOT part of an event selector. + * A wrong-indexed ABI returns the right row count, throws nothing, and writes values into the + * wrong columns. So a stored topic0 that agrees with a stored signature proves nothing on its own; + * what proves something is recomputing keccak256 over a signature REBUILT from the stored + * parameter types, which binds the selector to the layout rather than to itself. + * + * WHY THE BINDING MATTERS. Two (chain, address, topic0) keys in the shipped seed change their + * indexed layout across their own eras. A surface row that binds to the wrong era therefore + * decodes real logs into the wrong fields, silently and forever. + */ + +import { describe, it, expect } from "vitest"; +import { rmSync } from "fs"; +import { dirname } from "path"; +import { + parseEventSurface, validateEventSurface, topic0For, canonicalSignature, isHashOnlyWhenIndexed, +} from "../../src/control-plane/eventSurface.js"; +import { parseRegistry } from "../../src/control-plane/contractRegistry.js"; +import { loadChains } from "../../src/control-plane/chains.js"; +import { SeedParseError } from "../../src/control-plane/csv.js"; +import { + surfaceRow, registryRow, registryEra2Row, validRegistryBody, writeRegistry, writeSurface, + INT64_MAX, +} from "../helpers/seed-fixtures.js"; + +const chains = loadChains(); + +function withSeeds(surfaceBody: readonly string[], registryBody: readonly string[] = validRegistryBody()) { + const rPath = writeRegistry(registryBody); + const sPath = writeSurface(surfaceBody); + try { + const registry = parseRegistry(rPath); + const surface = parseEventSurface(sPath); + return { registry, surface, ...validateEventSurface(surface, registry, chains) }; + } finally { + rmSync(dirname(rPath), { recursive: true, force: true }); + rmSync(dirname(sPath), { recursive: true, force: true }); + } +} + +function parseSurfaceOnly(body: readonly string[]) { + const path = writeSurface(body); + try { + return parseEventSurface(path); + } finally { + rmSync(dirname(path), { recursive: true, force: true }); + } +} + +function checks(surfaceBody: readonly string[], registryBody?: readonly string[]): string[] { + return withSeeds(surfaceBody, registryBody).violations.map((v) => v.check); +} + +/** An event present in both eras of the fixture contract, so era_bound=false is truthful. */ +function bothEras(over: Parameters[0] = {}): string[] { + return [surfaceRow({ era_index: "1", ...over }), surfaceRow({ era_index: "2", implementation_address: "0x2222222222222222222222222222222222222222", ...over })]; +} + +describe("the fixture itself is valid", () => { + it("passes every surface rule with zero violations", () => { + const r = withSeeds(bothEras()); + expect(r.violations).toEqual([]); + expect(r.advisories).toEqual([]); + expect(r.counts.topic0Checked).toBe(2); + expect(r.counts.topic0Matched).toBe(2); + }); +}); + +describe("topic0 is proven, not trusted", () => { + it("flags a stored topic0 that is not keccak256 of its signature", () => { + const wrong = "0x" + "de".repeat(32); + expect(checks(bothEras({ topic0: wrong }))).toContain("topic0_recompute"); + }); + + it("flags a signature that does not rebuild from event_name and param_types", () => { + // The dangerous shape: topic0 agrees with the stored signature, but the stored signature does + // not describe the stored parameter list, so the decoder and the selector disagree. + const sig = "UBIClaimed(address,uint128)"; + expect(checks(bothEras({ event_signature: sig, topic0: topic0For(sig) }))) + .toContain("signature_canonical"); + }); + + it("counts rows checked separately from rows matched", () => { + const r = withSeeds(bothEras()); + expect(r.counts.signatureChecked).toBe(2); + expect(r.counts.signatureMatched).toBe(2); + }); + + it("recomputes a selector that is independently known", () => { + // ERC20 Transfer. A fixed, externally checkable constant, so a broken keccak wiring in this + // module cannot agree with itself and look correct. + expect(topic0For("Transfer(address,address,uint256)")) + .toBe("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"); + expect(canonicalSignature("Transfer", ["address", "address", "uint256"])) + .toBe("Transfer(address,address,uint256)"); + }); +}); + +describe("every row binds to exactly one deployment era", () => { + it("flags a row whose era does not exist", () => { + expect(checks([surfaceRow({ era_index: "9" })])).toContain("surface_binds_to_one_era"); + }); + + it("flags a row whose contract is not in the registry", () => { + expect(checks([surfaceRow({ proxy_address: "0x9999999999999999999999999999999999999999" })])) + .toContain("surface_binds_to_one_era"); + }); + + it("flags a row that binds to a no_code_deployed registry row", () => { + const noCode = registryRow({ + implementation_address: "", implementation_name: "unknown", era_count: "0", + valid_from_block: "", valid_to_block: "", is_live: "false", creation_block: "", + creation_method: "not applicable, no code is deployed at this address", + era_method: "no_code_deployed", era_evidence: "none", era_announcement_event: "none", + abi_source: "none", runtime_code_hash: "", + }); + expect(checks([surfaceRow({ era_index: "1" })], [noCode])) + .toContain("surface_binds_to_deployed_era"); + }); + + it("flags a chain_id that disagrees with its chain name", () => { + expect(checks(bothEras({ chain_id: "42220" }))).toContain("chain_id_consistency"); + }); + + it("flags an implementation_address that disagrees with the bound era", () => { + expect(checks([surfaceRow({ implementation_address: "0x3333333333333333333333333333333333333333" })])) + .toContain("implementation_agreement"); + }); +}); + +describe("topic slots are physical, so the arithmetic is enforced", () => { + it("flags a non-anonymous event with four indexed parameters", () => { + const sig = "Wide(address,address,address,address)"; + expect(checks(bothEras({ + event_name: "Wide", event_signature: sig, topic0: topic0For(sig), + indexed_positions: "0 1 2 3", param_types: "address address address address", + param_names: "a b c d", + }))).toContain("indexed_slot_limit"); + }); + + it("reports an anonymous four-slot event as an advisory, not a blocking violation", () => { + // The seed is right and the RawLogs grain is narrower than the chain. Refusing to start the + // pipeline over a correct row would be the wrong failure. + const r = withSeeds(bothEras({ + event_name: "LogNote", event_signature: "LogNote(bytes4,address,bytes32,bytes32,bytes)", + topic0: "", anonymous: "true", indexed_positions: "0 1 2 3", + param_types: "bytes4 address bytes32 bytes32 bytes", param_names: "sig usr arg1 arg2 data", + })); + expect(r.violations).toEqual([]); + expect(r.advisories.map((a) => a.check)).toContain("anonymous_not_capturable_in_rawlogs"); + expect(r.counts.anonymousRows).toBe(2); + }); + + it("refuses an anonymous event that still carries a topic0", () => { + expect(() => parseSurfaceOnly([surfaceRow({ anonymous: "true" })])) + .toThrow(/anonymous event .* must leave topic0 empty/); + }); + + it("refuses an indexed position outside the declared parameters", () => { + expect(() => parseSurfaceOnly([surfaceRow({ indexed_positions: "5" })])) + .toThrow(/outside the 2 declared parameter/); + }); + + it("refuses duplicate or unordered indexed positions", () => { + expect(() => parseSurfaceOnly([surfaceRow({ indexed_positions: "0 0" })])).toThrow(/duplicate/); + expect(() => parseSurfaceOnly([surfaceRow({ indexed_positions: "1 0" })])).toThrow(/ascending/); + }); + + it("refuses a param_names list that does not match the parameter count", () => { + expect(() => parseSurfaceOnly([surfaceRow({ param_names: "claimer" })])) + .toThrow(/2 param_types but 1 param_names/); + }); +}); + +describe("an unnamed ABI parameter is representable and unambiguous", () => { + it("accepts a trailing empty name and identifies which parameter is unnamed", () => { + // Uniswap V2: PairCreated(address indexed token0, address indexed token1, address pair, uint). + // The fourth parameter genuinely has no name in the verified source, so the seed is faithful + // and the parser must not trim the field into a shorter list. + const sig = "PairCreated(address,address,address,uint256)"; + const parsed = parseSurfaceOnly([surfaceRow({ + event_name: "PairCreated", event_signature: sig, topic0: topic0For(sig), + indexed_positions: "0 1", param_types: "address address address uint256", + param_names: "token0 token1 pair ", + })]); + expect(parsed.rows[0].paramNames).toEqual(["token0", "token1", "pair", ""]); + expect(parsed.rows[0].paramTypes).toHaveLength(4); + }); + + it("still refuses a blank element in param_types or indexed_positions", () => { + expect(() => parseSurfaceOnly([surfaceRow({ param_types: "address " })])).toThrow(/blank/); + expect(() => parseSurfaceOnly([surfaceRow({ indexed_positions: "0 " })])).toThrow(/blank/); + }); + + it("refuses a parameter name that is not a Solidity identifier", () => { + expect(() => parseSurfaceOnly([surfaceRow({ param_names: "claimer 1amount" })])) + .toThrow(/not a Solidity identifier/); + }); +}); + +describe("indexed dynamic parameters are labelled hash-only", () => { + it("classifies every non-value type as hash-only when indexed", () => { + for (const t of ["string", "bytes", "address[]", "uint256[3]", "(address,uint256)", "tuple"]) { + expect(isHashOnlyWhenIndexed(t), t).toBe(true); + } + for (const t of ["address", "uint256", "bytes32", "bool", "int8", "bytes4"]) { + expect(isHashOnlyWhenIndexed(t), t).toBe(false); + } + }); + + it("records the exact positions whose value can never be recovered from a log", () => { + const sig = "AdminsAdded(address[])"; + const parsed = parseSurfaceOnly([surfaceRow({ + event_name: "AdminsAdded", event_signature: sig, topic0: topic0For(sig), + indexed_positions: "0", param_types: "address[]", param_names: "admins", + })]); + expect(parsed.rows[0].hashOnlyIndexedPositions).toEqual([0]); + }); + + it("does not label a dynamic parameter that is NOT indexed", () => { + // Only an indexed dynamic parameter is replaced by its hash. A non-indexed one is in the data + // payload and is fully recoverable. + const sig = "TransferComment(string)"; + const parsed = parseSurfaceOnly([surfaceRow({ + event_name: "TransferComment", event_signature: sig, topic0: topic0For(sig), + indexed_positions: "", param_types: "string", param_names: "comment", + })]); + expect(parsed.rows[0].hashOnlyIndexedPositions).toEqual([]); + }); +}); + +describe("the era-bound window uses the identical sentinel contract", () => { + const boundOver = { + era_bound: "true", era_bound_from_block: "105000000", era_bound_to_block: INT64_MAX, + }; + + it("accepts a window that is the exact envelope of the eras carrying the event", () => { + const r = withSeeds(bothEras(boundOver)); + expect(r.violations).toEqual([]); + expect(r.counts.boundGroupsChecked).toBe(1); + expect(r.counts.boundGroupsMatchingEnvelope).toBe(1); + }); + + it("keeps the sentinel as a lexeme, never a number", () => { + const parsed = parseSurfaceOnly([surfaceRow(boundOver)]); + expect(parsed.rows[0].eraBoundTo!.kind).toBe("open_ended"); + expect(parsed.rows[0].eraBoundTo!.lexeme).toBe(INT64_MAX); + }); + + it("flags a window narrower than the eras it is declared on", () => { + expect(checks(bothEras({ ...boundOver, era_bound_from_block: "105500000" }))) + .toContain("surface_era_within_window"); + }); + + it("flags a window that is not the exact envelope", () => { + expect(checks(bothEras({ ...boundOver, era_bound_from_block: "104000000" }))) + .toContain("era_bound_window_is_exact_envelope"); + }); + + it("flags a finite window closing before a still-live era", () => { + expect(checks(bothEras({ ...boundOver, era_bound_to_block: "106000000" }))) + .toContain("surface_live_era_needs_open_window"); + }); + + it("flags rows of one event disagreeing about its window", () => { + expect(checks([ + surfaceRow({ era_index: "1", ...boundOver }), + surfaceRow({ era_index: "2", implementation_address: "0x2222222222222222222222222222222222222222", ...boundOver, era_bound_from_block: "105000001" }), + ])).toContain("era_bound_window_agreement"); + }); + + it("flags rows of one event disagreeing about whether it is era bound at all", () => { + expect(checks([ + surfaceRow({ era_index: "1", ...boundOver }), + surfaceRow({ era_index: "2", implementation_address: "0x2222222222222222222222222222222222222222" }), + ])).toContain("era_bound_flag_agreement"); + }); + + it("refuses bound blocks on a row that declares era_bound=false", () => { + expect(() => parseSurfaceOnly([surfaceRow({ era_bound_from_block: "105000000" })])) + .toThrow(/era_bound=false but/); + }); + + it("refuses the sentinel with no era_bound declaration", () => { + expect(() => parseSurfaceOnly([surfaceRow({ era_bound: "true", era_bound_from_block: INT64_MAX, era_bound_to_block: INT64_MAX })])) + .toThrow(SeedParseError); + }); +}); + +describe("era_bound=false is a claim about every era, and is checked", () => { + it("flags an unbound event that is absent from one of its contract's eras", () => { + expect(checks([surfaceRow({ era_index: "1" })])) + .toContain("unbound_event_covers_all_eras"); + }); + + it("accepts an unbound event present in every era", () => { + expect(checks(bothEras())).toEqual([]); + }); + + it("accepts a single-era contract with a single unbound row", () => { + const single = [registryRow({ era_count: "1", valid_to_block: INT64_MAX, is_live: "true" })]; + expect(checks([surfaceRow({ era_index: "1" })], single)).toEqual([]); + }); +}); + +describe("the whole surface is rejected on the first malformed physical row", () => { + it("refuses an extra field rather than dropping the row", () => { + expect(() => parseSurfaceOnly([surfaceRow(), surfaceRow() + ",surplus"])).toThrow(SeedParseError); + }); + + it("refuses a mixed-case proxy address", () => { + expect(() => parseSurfaceOnly([surfaceRow({ proxy_address: "0x22867567E2D80F2049200E25C6F31CB6EC2F0FAF" })])) + .toThrow(/uppercase hex/); + }); + + it("refuses a topic0 that is not 32 lowercase hex bytes", () => { + expect(() => parseSurfaceOnly([surfaceRow({ topic0: "0xABC" })])).toThrow(/lowercase 32-byte/); + }); + + it("refuses an event_name that is not a Solidity identifier", () => { + expect(() => parseSurfaceOnly([surfaceRow({ event_name: "UBI Claimed" })])) + .toThrow(/not a Solidity identifier/); + }); + + it("refuses era_index zero", () => { + expect(() => parseSurfaceOnly([surfaceRow({ era_index: "0" })])).toThrow(/below the minimum permitted value 1/); + }); +}); + +describe("registry era 2 fixture stays consistent", () => { + it("binds a row to era 2 when the implementation matches", () => { + const r = withSeeds(bothEras()); + expect(r.counts.bindingChecked).toBe(2); + expect(r.counts.bindingMatched).toBe(2); + expect(registryEra2Row()).toContain(INT64_MAX); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-int64.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-int64.test.ts new file mode 100644 index 0000000..e99e15d --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-int64.test.ts @@ -0,0 +1,113 @@ +/** + * The INT64 sentinel contract. + * + * WHY THIS IS ITS OWN SUITE. BigQuery INT64 reaches 9,223,372,036,854,775,807. JavaScript numbers + * are exact to 9,007,199,254,740,991. The seeds use the exact INT64 maximum as the "no upper bound + * yet" sentinel on 142 rows, and `Number("9223372036854775807")` silently returns + * 9223372036854775808 -- a DIFFERENT integer that regenerates into the seed as a different lexeme. + * The previous loader did exactly that, on every one of those rows, with no error. + * + * Every case below is a lexeme that a careless parser would accept as "close enough". + */ + +import { describe, it, expect } from "vitest"; +import { + INT64_MAX_LEXEME, Int64ContractError, parseFiniteInt, parseUpperBound, parseLowerBound, + compareBounds, boundLexeme, boundToNullableNumber, +} from "../../src/control-plane/int64.js"; + +const INT64_MAX_MINUS_ONE = "9223372036854775806"; +const INT64_MAX_PLUS_ONE = "9223372036854775808"; + +describe("the sentinel is accepted only as an open-ended upper bound", () => { + it("normalizes the exact INT64-max lexeme to an open-ended bound, never a number", () => { + const b = parseUpperBound("valid_to_block", INT64_MAX_LEXEME, { declaredOpenEnded: true }); + expect(b.kind).toBe("open_ended"); + expect(b).not.toHaveProperty("value"); + expect(boundToNullableNumber(b)).toBeNull(); + }); + + it("round-trips the sentinel lexeme byte for byte", () => { + const b = parseUpperBound("valid_to_block", INT64_MAX_LEXEME, { declaredOpenEnded: true }); + expect(boundLexeme(b)).toBe(INT64_MAX_LEXEME); + // The failure this guards: String(Number(INT64_MAX_LEXEME)) is a different decimal. + expect(String(Number(INT64_MAX_LEXEME))).not.toBe(INT64_MAX_LEXEME); + }); + + it("rejects the sentinel in a lower bound", () => { + expect(() => parseLowerBound("valid_from_block", INT64_MAX_LEXEME)).toThrow(Int64ContractError); + expect(() => parseLowerBound("valid_from_block", INT64_MAX_LEXEME)).toThrow(/open-ended upper bound/); + }); + + it("rejects the sentinel on a row that is not declared open ended", () => { + expect(() => parseUpperBound("valid_to_block", INT64_MAX_LEXEME, { declaredOpenEnded: false })) + .toThrow(/not declared current\/open-ended/); + }); + + it("rejects a finite upper bound on a row that IS declared open ended", () => { + // The other half of the contradiction: if both spellings were tolerated, "is this era still + // current" would have two answers that could disagree. + expect(() => parseUpperBound("valid_to_block", "123456", { declaredOpenEnded: true })) + .toThrow(/declared current\/open-ended but carries a finite upper bound/); + }); + + it("rejects the sentinel in an ordinary integer field", () => { + expect(() => parseFiniteInt("creation_block", INT64_MAX_LEXEME)).toThrow(Int64ContractError); + }); +}); + +describe("unsafe and non-canonical integers are refused rather than rounded", () => { + const rejected: [string, string][] = [ + ["INT64-max minus one", INT64_MAX_MINUS_ONE], + ["INT64-max plus one", INT64_MAX_PLUS_ONE], + ["the Number()-rounded neighbour of the sentinel", String(Number(INT64_MAX_LEXEME))], + ["one above Number.MAX_SAFE_INTEGER", "9007199254740992"], + ["exponent notation", "9.223372036854776e18"], + ["exponent notation, capital E", "1E9"], + ["a decimal point", "105000000.0"], + ["a leading zero", "0105000000"], + ["a leading plus", "+105000000"], + ["a negative", "-1"], + ["leading whitespace", " 105000000"], + ["trailing whitespace", "105000000 "], + ["an internal underscore", "105_000_000"], + ["hexadecimal", "0x6422c40"], + ["empty", ""], + ["not a number at all", "unknown"], + ]; + + for (const [label, lexeme] of rejected) { + it(`rejects ${label} in a finite field`, () => { + expect(() => parseFiniteInt("valid_from_block", lexeme)).toThrow(Int64ContractError); + }); + it(`rejects ${label} in an upper bound`, () => { + expect(() => parseUpperBound("valid_to_block", lexeme, { declaredOpenEnded: false })).toThrow(Int64ContractError); + }); + } + + it("accepts the largest integer a JavaScript number represents exactly", () => { + expect(parseFiniteInt("valid_from_block", "9007199254740991")).toBe(Number.MAX_SAFE_INTEGER); + }); + + it("enforces a minimum without converting first", () => { + expect(() => parseFiniteInt("era_index", "0", { min: 1 })).toThrow(/below the minimum/); + expect(parseFiniteInt("era_index", "1", { min: 1 })).toBe(1); + }); +}); + +describe("interval arithmetic never rounds a bound", () => { + const open = parseUpperBound("valid_to_block", INT64_MAX_LEXEME, { declaredOpenEnded: true }); + const finite = parseUpperBound("valid_to_block", "106000000", { declaredOpenEnded: false }); + const lower = parseLowerBound("valid_from_block", "106000000"); + + it("orders open-ended strictly above every finite bound", () => { + expect(compareBounds(open, finite)).toBeGreaterThan(0); + expect(compareBounds(finite, open)).toBeLessThan(0); + expect(compareBounds(open, open)).toBe(0); + }); + + it("compares an adjacent finite-to-open pair as touching, not overlapping and not gapped", () => { + // Era N ends exactly where era N+1 begins. Half-open intervals, so this is equality. + expect(compareBounds(finite, lower)).toBe(0); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-magnitude.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-magnitude.test.ts new file mode 100644 index 0000000..3bbc599 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-magnitude.test.ts @@ -0,0 +1,161 @@ +/** + * Magnitude tripwires. + * + * Every band below is proven in BOTH directions: green on a value the chain really produces, red + * on the shape a wrong decode really produces. A tripwire that only ever passes is not a tripwire, + * and this file is the proof that none of these is one. + * + * The values are not invented. 1000 GD is the measured inviter bounty on all 939 rows in the + * warehouse; 74 to 333 GD is the measured range of a Celo daily claim; `4` is the exact value a + * reversed union ABI returns for `balance`, being the byte length of the string "celo". + */ + +import { describe, it, expect } from "vitest"; +import { checkMagnitude, checkRowMagnitudes, bandFor, MAGNITUDE_BANDS } from "../../src/control-plane/magnitude.js"; + +const GD_18 = 18; +const GD_2 = 2; +const gd = (whole: number) => BigInt(whole) * 10n ** 18n; + +describe("every consumed numeric field has a band", () => { + it("covers the three numeric fields the consumed events carry", () => { + // UBIClaimed, InviteeJoined and InviterBounty are the consumed events. InviteeJoined carries + // two addresses and no numeric parameter, so three fields need a band, not three events'. + expect(MAGNITUDE_BANDS.map((b) => b.field).sort()).toEqual([ + "InviterBounty.bountyPaid", "InviterBounty.inviterLevel", "UBIClaimed.amount", + ]); + for (const b of MAGNITUDE_BANDS) expect(b.why.length).toBeGreaterThan(40); + }); + + it("refuses to check a field nobody declared a band for", () => { + expect(() => checkMagnitude("UBIClaimed.somethingNew", 1n, 18)).toThrow(/no band declared/); + expect(bandFor("UBIClaimed.somethingNew")).toBeUndefined(); + }); + + it("refuses an implausible decimals argument rather than scaling by it", () => { + expect(() => checkMagnitude("UBIClaimed.amount", gd(300), -1)).toThrow(/implausible token decimals/); + expect(() => checkMagnitude("UBIClaimed.amount", gd(300), 99)).toThrow(/implausible token decimals/); + }); +}); + +describe("UBIClaimed.amount", () => { + it("GREEN on a real claim", () => { + for (const amount of [74, 150, 333]) { + const v = checkMagnitude("UBIClaimed.amount", gd(amount), GD_18); + expect(v.plausible).toBe(true); + expect(v.humanValue).toBe(amount); + } + }); + + /* + * THE CASE THIS EXISTS FOR. A reversed union ABI decodes an era-2 log against the era-1 layout + * and returns the string's byte length as the amount. It does not throw, and every structural + * test passes. 4 raw units of an 18-decimal token is 4e-18 GD, which is not a quantity anybody + * transacts -- and that is the only thing left to notice. + */ + it("RED on a raw 4, which is what a reversed union ABI returns", () => { + const v = checkMagnitude("UBIClaimed.amount", 4n, GD_18); + expect(v.plausible).toBe(false); + expect(v.outcome).toBe("below_raw_floor"); + expect(v.detail).toContain("wrong-layout decode"); + }); + + it("RED when the scale factor is missing entirely", () => { + // The raw value published as if it were already scaled: 3e20 GD. + const v = checkMagnitude("UBIClaimed.amount", gd(300), 0); + expect(v.plausible).toBe(false); + expect(v.outcome).toBe("above_max"); + }); + + it("RED when the token's decimals are read from the wrong chain", () => { + // GD is 18 decimals on Celo and XDC but 2 on Fuse and Ethereum. Scaling a Celo amount by the + // Fuse factor is a real, available mistake, and it is caught. + const v = checkMagnitude("UBIClaimed.amount", gd(300), GD_2); + expect(v.plausible).toBe(false); + expect(v.outcome).toBe("above_max"); + }); + + it("RED on zero, which a claim never is", () => { + expect(checkMagnitude("UBIClaimed.amount", 0n, GD_18).outcome).toBe("below_min"); + }); +}); + +describe("InviterBounty.bountyPaid", () => { + it("GREEN on the measured 1000 GD bounty", () => { + const v = checkMagnitude("InviterBounty.bountyPaid", gd(1000), GD_18); + expect(v.plausible).toBe(true); + expect(v.humanValue).toBe(1000); + }); + + it("GREEN on a level-based bonus well above it, because the band is not a policy", () => { + expect(checkMagnitude("InviterBounty.bountyPaid", gd(5000), GD_18).plausible).toBe(true); + }); + + it("RED when the 1e18 divide is missing", () => { + const v = checkMagnitude("InviterBounty.bountyPaid", gd(1000), 0); + expect(v.plausible).toBe(false); + expect(v.outcome).toBe("above_max"); + }); + + it("RED on a raw value too small to be a bounty", () => { + expect(checkMagnitude("InviterBounty.bountyPaid", 4n, GD_18).outcome).toBe("below_raw_floor"); + }); +}); + +describe("InviterBounty.inviterLevel", () => { + it("GREEN on the measured level 0, and on a plausible higher level", () => { + expect(checkMagnitude("InviterBounty.inviterLevel", 0n, GD_18).plausible).toBe(true); + expect(checkMagnitude("InviterBounty.inviterLevel", 7n, GD_18).plausible).toBe(true); + }); + + it("is NOT decimals-scaled, because a level is an ordinal and not a token amount", () => { + // Passing 18 or 2 makes no difference: an index into the contract's levels array has no scale. + expect(checkMagnitude("InviterBounty.inviterLevel", 3n, GD_18).humanValue).toBe(3); + expect(checkMagnitude("InviterBounty.inviterLevel", 3n, GD_2).humanValue).toBe(3); + }); + + it("RED on a token-shaped value, which is what reading the wrong word gives", () => { + const v = checkMagnitude("InviterBounty.inviterLevel", gd(1000), GD_18); + expect(v.plausible).toBe(false); + expect(v.outcome).toBe("above_max"); + }); + + it("RED on an address-shaped value", () => { + const addressShaped = BigInt("0x603b8c0f110e037b51a381cbcacabb8d6c6e4543"); + expect(checkMagnitude("InviterBounty.inviterLevel", addressShaped, GD_18).plausible).toBe(false); + }); +}); + +describe("a whole decoded row is checked at once", () => { + it("returns nothing when every field is plausible, so an empty result IS the pass", () => { + expect(checkRowMagnitudes([ + { field: "UBIClaimed.amount", rawValue: gd(300), decimals: GD_18 }, + { field: "InviterBounty.bountyPaid", rawValue: gd(1000), decimals: GD_18 }, + { field: "InviterBounty.inviterLevel", rawValue: 0n, decimals: GD_18 }, + ])).toEqual([]); + }); + + it("names every failing field rather than stopping at the first", () => { + const failures = checkRowMagnitudes([ + { field: "UBIClaimed.amount", rawValue: 4n, decimals: GD_18 }, + { field: "InviterBounty.bountyPaid", rawValue: gd(1000), decimals: GD_18 }, + { field: "InviterBounty.inviterLevel", rawValue: gd(1), decimals: GD_18 }, + ]); + expect(failures.map((f) => f.field)).toEqual(["UBIClaimed.amount", "InviterBounty.inviterLevel"]); + }); +}); + +describe("the limit of a magnitude band, stated rather than discovered later", () => { + it("catches a large factor error always", () => { + expect(checkMagnitude("UBIClaimed.amount", gd(300), 0).plausible).toBe(false); + }); + + it("MISSES a 1e2 error on a small value, and this is why it is a SECOND line of defence", () => { + // A 74 GD claim read with a 1e16 factor instead of 1e18 gives 7,400 GD, which is inside the + // band. The band is honest about what it cannot do: the first line of defence is the union + // order and the ambiguity assertion, not this. + const wrongFactor = checkMagnitude("UBIClaimed.amount", gd(74), 16); + expect(wrongFactor.plausible).toBe(true); + expect(wrongFactor.humanValue).toBe(7400); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-registry.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-registry.test.ts new file mode 100644 index 0000000..8b640c9 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-registry.test.ts @@ -0,0 +1,422 @@ +/** + * The strict registry parser and schema. + * + * WHAT THESE REPLACE. The previous loader ended its parse with + * `.filter(r => r.length === header.length)` and read control fields through `Number()`. So a row + * with one stray comma VANISHED from the contract universe with no error, and a blank `era_index` + * became era 0. Both were silent, and silence is what makes them expensive: nothing downstream can + * tell "this contract produced no logs" from "this contract was never asked about", and + * `lookupEra` cannot fail, so era 0 is a confident wrong decode rather than an error. + * + * Each case mutates exactly ONE field of an otherwise valid 23-column row, so a pass proves the + * named rule rather than proving that something somewhere was wrong. + */ + +import { describe, it, expect } from "vitest"; +import { rmSync, readFileSync, writeFileSync } from "fs"; +import { dirname } from "path"; +import { parseRegistry, validateRegistry, assertScopeFrozen, NO_CODE_ERA_METHOD } from "../../src/control-plane/contractRegistry.js"; +import { loadChains } from "../../src/control-plane/chains.js"; +import { SeedParseError } from "../../src/control-plane/csv.js"; +import { + registryRow, registryEra2Row, validRegistryBody, writeRegistry, writeSeed, + registryRowWithBoundary, writeRegistryWithBoundary, + REGISTRY_COLUMNS, UBI, INT64_MAX, +} from "../helpers/seed-fixtures.js"; + +const chains = loadChains(); + +function parse(body: readonly string[], opts?: Parameters[1]) { + const path = writeRegistry(body, opts); + try { + return parseRegistry(path); + } finally { + rmSync(dirname(path), { recursive: true, force: true }); + } +} + +function violations(body: readonly string[]): string[] { + return validateRegistry(parse(body), chains).map((v) => v.check); +} + +describe("the fixture itself is valid", () => { + it("parses two eras with zero violations", () => { + const parsed = parse(validRegistryBody()); + expect(parsed.rows).toHaveLength(2); + expect(validateRegistry(parsed, chains)).toEqual([]); + }); +}); + +describe("a malformed physical row rejects the WHOLE registry", () => { + it("refuses a row with a missing field instead of dropping it", () => { + const short = registryRow().split(",").slice(0, 21).join(","); + expect(() => parse([registryRow(), short])).toThrow(SeedParseError); + }); + + it("refuses a row with an extra field instead of dropping it", () => { + expect(() => parse([registryRow(), registryRow() + ",surplus"])).toThrow(SeedParseError); + }); + + it("names the physical line of the offending row", () => { + // Line 3 = header + one good row + the bad one. Without this a maintainer is told the file is + // bad and left to find the byte. + expect(() => parse([registryRow(), registryRow() + ",surplus"])).toThrow(/line 3/); + }); + + it("keeps every good row rather than returning a smaller universe", () => { + // The defect being guarded: 2 physical rows in, 1 contract out, no error. + let rows = -1; + try { + rows = parse([registryRow(), registryRow().split(",").slice(0, 21).join(",")]).rows.length; + } catch { + rows = -1; + } + expect(rows).toBe(-1); + }); + + it("refuses an unterminated quote", () => { + // Written raw: the fixture builder escapes quotes correctly, which is the opposite of what + // this case needs. + const bad = registryRow().replace(/,fixture,$/, ',"fixture,'); + expect(() => parse([bad])).toThrow(SeedParseError); + }); + + it("refuses a header with the right width but a wrong column name", () => { + const wrong: string[] = [...REGISTRY_COLUMNS]; + wrong[13] = "created_block"; + const path = writeSeed("contract_deployments.csv", REGISTRY_COLUMNS, [registryRow()], { + header: wrong.join(","), + }).path; + try { + expect(() => parseRegistry(path)).toThrow(/header mismatch/); + } finally { + rmSync(dirname(path), { recursive: true, force: true }); + } + }); + + it("refuses a header that is narrower than the schema", () => { + const path = writeSeed("contract_deployments.csv", REGISTRY_COLUMNS, [registryRow()], { + header: REGISTRY_COLUMNS.slice(0, 22).join(","), + }).path; + try { + expect(() => parseRegistry(path)).toThrow(SeedParseError); + } finally { + rmSync(dirname(path), { recursive: true, force: true }); + } + }); + + it("refuses a reordered header even though every column is present", () => { + const reordered = [REGISTRY_COLUMNS[1], REGISTRY_COLUMNS[0], ...REGISTRY_COLUMNS.slice(2)]; + const path = writeSeed("contract_deployments.csv", REGISTRY_COLUMNS, [registryRow()], { + header: reordered.join(","), + }).path; + try { + expect(() => parseRegistry(path)).toThrow(/header mismatch/); + } finally { + rmSync(dirname(path), { recursive: true, force: true }); + } + }); +}); + +describe("physical row count is reconciled against parsed record count", () => { + it("refuses a field containing an embedded line terminator", () => { + // Legal RFC 4180, illegal in a control seed: it would make one record span two physical lines, + // and the row-count reconciliation is what proves nothing was dropped. + expect(() => parse([registryRow({ notes: "line one\r\nline two" })])) + .toThrow(/physical\/parsed row count disagreement|embedded line terminator/); + }); + + it("refuses mixed line terminators", () => { + const path = writeRegistry(validRegistryBody(), { terminator: "\n" }); + // Rewrite one terminator as CRLF to produce a genuinely mixed file. + writeFileSync(path, readFileSync(path, "utf8").replace("\n", "\r\n"), "ascii"); + try { + expect(() => parseRegistry(path)).toThrow(/mixed line terminators/); + } finally { + rmSync(dirname(path), { recursive: true, force: true }); + } + }); + + it("refuses a missing final terminator", () => { + expect(() => parse([registryRow()], { trailingTerminator: false })).toThrow(/does not end with a line terminator/); + }); + + it("refuses a byte-order mark", () => { + const path = writeRegistry([registryRow()]); + writeFileSync(path, Buffer.concat([Buffer.from([0xef, 0xbb, 0xbf]), readFileSync(path)])); + try { + expect(() => parseRegistry(path)).toThrow(/byte-order mark/); + } finally { + rmSync(dirname(path), { recursive: true, force: true }); + } + }); + + it("refuses a non-ASCII byte, which is how an editor corrupts a seed", () => { + expect(() => parse([registryRow({ notes: "re\u2011enabled" })])).toThrow(/non-printable or non-ASCII/); + }); +}); + +describe("field-level schema", () => { + it("refuses a blank era_index rather than reading it as era 0", () => { + expect(() => parse([registryRow({ era_index: "" })])).toThrow(/era_index/); + }); + + it("refuses era_index zero", () => { + expect(() => parse([registryRow({ era_index: "0" })])).toThrow(/below the minimum permitted value 1/); + }); + + it("refuses a mixed-case address", () => { + const checksummed = "0x22867567E2D80F2049200E25C6F31CB6EC2F0FAF"; + expect(() => parse([registryRow({ proxy_address: checksummed })])).toThrow(/uppercase hex/); + }); + + it("refuses an address of the wrong length", () => { + expect(() => parse([registryRow({ proxy_address: "0x2286" })])).toThrow(/lowercase 20-byte/); + }); + + it("refuses is_live spelled any way but exactly true or false", () => { + for (const bad of ["TRUE", "True", "1", "yes", ""]) { + expect(() => parse([registryRow({ is_live: bad })]), bad).toThrow(/is not exactly 'true' or 'false'/); + } + }); + + it("refuses a runtime_code_hash that is not 32 lowercase hex bytes", () => { + expect(() => parse([registryRow({ runtime_code_hash: "0xabc" })])).toThrow(/lowercase 32-byte/); + }); + + it("refuses the open-ended sentinel in valid_from_block", () => { + expect(() => parse([registryRow({ valid_from_block: INT64_MAX })])).toThrow(/open-ended upper bound/); + }); + + it("refuses the sentinel on a row that is not is_live", () => { + expect(() => parse([registryRow({ valid_to_block: INT64_MAX, is_live: "false" })])) + .toThrow(/not declared current\/open-ended/); + }); + + it("refuses a finite upper bound on an is_live row", () => { + expect(() => parse([registryRow({ is_live: "true", valid_to_block: "106000000" })])) + .toThrow(/declared current\/open-ended but carries a finite upper bound/); + }); + + it("keeps the sentinel as a lexeme and never as a number", () => { + const parsed = parse(validRegistryBody()); + const live = parsed.rows.find((r) => r.isLive)!; + expect(live.validTo!.kind).toBe("open_ended"); + expect(live.validTo!.lexeme).toBe(INT64_MAX); + expect(live.raw[11]).toBe(INT64_MAX); + }); +}); + +describe("the no_code_deployed exception shape is enforced, not just tolerated", () => { + const noCode = { + implementation_address: "", implementation_name: "unknown", era_index: "1", era_count: "0", + valid_from_block: "", valid_to_block: "", is_live: "false", creation_block: "", + creation_method: "not applicable, no code is deployed at this address", + era_method: NO_CODE_ERA_METHOD, era_evidence: "none", era_announcement_event: "none", + abi_source: "none", runtime_code_hash: "", + }; + + it("accepts the exact declared shape", () => { + const parsed = parse([registryRow(noCode)]); + expect(parsed.rows[0].noCodeDeployed).toBe(true); + expect(parsed.rows[0].creationBlock).toBeNull(); + expect(validateRegistry(parsed, chains)).toEqual([]); + }); + + it("refuses a no_code row that also carries blocks", () => { + expect(() => parse([registryRow({ ...noCode, creation_block: "105000000" })])) + .toThrow(/must leave valid_from_block, valid_to_block and creation_block empty/); + }); + + it("refuses a no_code row claiming to be live", () => { + expect(() => parse([registryRow({ ...noCode, is_live: "true" })])).toThrow(/cannot be is_live=true/); + }); + + it("refuses a deployed row that leaves its blocks empty", () => { + // Without this, "no blocks" becomes a hiding place for a row that simply failed to resolve. + expect(() => parse([registryRow({ valid_from_block: "" })])).toThrow(/valid_from_block/); + }); +}); + +describe("cross-row interval rules", () => { + it("accepts eras that touch exactly", () => { + expect(violations(validRegistryBody())).toEqual([]); + }); + + it("flags overlapping eras", () => { + expect(violations([registryRow({ valid_to_block: "106000001" }), registryEra2Row()])) + .toContain("era_overlap"); + }); + + it("flags an undeclared gap between eras", () => { + expect(violations([registryRow({ valid_to_block: "105999999" }), registryEra2Row()])) + .toContain("era_gap"); + }); + + it("flags non-contiguous era indexes", () => { + expect(violations([registryRow(), registryEra2Row({ era_index: "3" })])) + .toContain("era_index_contiguous"); + }); + + it("flags era_count that disagrees with the number of rows", () => { + expect(violations([registryRow({ era_count: "3" }), registryEra2Row({ era_count: "3" })])) + .toContain("era_count_matches_rows"); + }); + + it("flags creation_block after the first era", () => { + expect(violations([registryRow({ creation_block: "105000001" }), registryEra2Row()])) + .toContain("creation_before_first_era"); + }); + + it("flags more than one live era on one contract", () => { + expect(violations([ + registryRow({ is_live: "true", valid_to_block: INT64_MAX }), + registryEra2Row(), + ])).toContain("single_live_era"); + }); + + it("flags a chain_id that disagrees with its chain name", () => { + expect(violations([registryRow({ chain_id: "42220" }), registryEra2Row({ chain_id: "42220" })])) + .toContain("chain_id_consistency"); + }); + + it("flags a chain that is not in the chains seed at all", () => { + expect(violations([registryRow({ chain: "BASE", chain_id: "8453" }), registryEra2Row({ chain: "BASE", chain_id: "8453" })])) + .toContain("chain_known"); + }); + + it("flags an era whose block order disagrees with its index", () => { + expect(violations([ + registryRow({ era_index: "2" }), + registryEra2Row({ era_index: "1" }), + ])).toContain("era_order_matches_blocks"); + }); +}); + +describe("what the loader exposes downstream", () => { + it("defaults every era to raw_only_unproven while the boundary columns are absent", () => { + const parsed = parse(validRegistryBody()); + expect(parsed.hasBoundaryColumns).toBe(false); + expect(parsed.rows.every((r) => r.boundaryCompleteness === "raw_only_unproven")).toBe(true); + expect(parsed.rows.every((r) => r.boundaryEvidenceManifestHash === null)).toBe(true); + }); + + it("preserves every original lexeme for byte-exact regeneration", () => { + const body = validRegistryBody(); + const parsed = parse(body); + expect(parsed.rows.map((r) => r.raw.join(","))).toEqual(body.map((b) => b.replace(/"/g, ""))); + }); + + it("uses the contract key, so the same address on two chains is two contracts", () => { + const parsed = parse([ + registryRow({ era_count: "1", valid_to_block: INT64_MAX, is_live: "true" }), + registryRow({ chain: "CELO", chain_id: "42220", era_count: "1", valid_to_block: INT64_MAX, is_live: "true" }), + ]); + expect(validateRegistry(parsed, chains)).toEqual([]); + expect(new Set(parsed.rows.map((r) => `${r.chainId}|${r.proxyAddress}`)).size).toBe(2); + expect(parsed.rows[0].proxyAddress).toBe(UBI); + }); +}); + +/** + * The declared trailing block Phase 2 task 16 appends. It does not exist in the shipped seed, so + * these tests are what proves the contract is enforced the moment it does. + */ +describe("the boundary-evidence and release-scope block", () => { + function parseWithBoundary(body: readonly string[]) { + const path = writeRegistryWithBoundary(body); + try { + return parseRegistry(path); + } finally { + rmSync(dirname(path), { recursive: true, force: true }); + } + } + + it("accepts the wider header and reads the declared values", () => { + const parsed = parseWithBoundary([ + registryRowWithBoundary(), + registryRowWithBoundary({ era_index: "2", valid_from_block: "106000000", valid_to_block: INT64_MAX, is_live: "true" }), + ]); + expect(parsed.hasBoundaryColumns).toBe(true); + expect(parsed.rows[0].releaseScope).toBe("in_release"); + expect(parsed.rows[0].boundaryCompleteness).toBe("raw_only_unproven"); + }); + + it("reports release scope as undeclared when the column is absent, never as included", () => { + const parsed = parse(validRegistryBody()); + expect(parsed.hasBoundaryColumns).toBe(false); + expect(parsed.rows.every((r) => r.releaseScope === "undeclared")).toBe(true); + }); + + it("refuses a release_scope value outside the declared set", () => { + expect(() => parseWithBoundary([registryRowWithBoundary({ release_scope: "maybe" })])) + .toThrow(/is not one of: in_release, out_of_release, scope_pending/); + }); + + it("refuses 'undeclared' written into the column, which is a loader state and not a value", () => { + expect(() => parseWithBoundary([registryRowWithBoundary({ release_scope: "undeclared" })])) + .toThrow(/is not one of/); + }); + + it("refuses a completeness verdict with no reproducible evidence behind it", () => { + expect(() => parseWithBoundary([registryRowWithBoundary({ boundary_completeness: "complete" })])) + .toThrow(/requires boundary_evidence_manifest_hash, boundary_checked_through_block and frozen_safe_head/); + }); + + it("refuses evidence checked past the frozen safe head it cites", () => { + expect(() => parseWithBoundary([registryRowWithBoundary({ + boundary_completeness: "plain_contract", + boundary_evidence_manifest_hash: "0x" + "cd".repeat(32), + boundary_checked_through_block: "106000001", + frozen_safe_head: "106000000", + })])).toThrow(/is above frozen_safe_head/); + }); + + it("accepts a complete verdict that carries all three pieces of evidence", () => { + const parsed = parseWithBoundary([registryRowWithBoundary({ + boundary_completeness: "complete", + boundary_evidence_manifest_hash: "0x" + "cd".repeat(32), + boundary_checked_through_block: "106000000", + frozen_safe_head: "106000000", + })]); + expect(parsed.rows[0].boundaryCompleteness).toBe("complete"); + }); +}); + +describe("scope_pending blocks the freeze, and only the freeze", () => { + function parseWithBoundary(body: readonly string[]) { + const path = writeRegistryWithBoundary(body); + try { + return parseRegistry(path); + } finally { + rmSync(dirname(path), { recursive: true, force: true }); + } + } + + it("is a legal state before the freeze, so an undecided row is recorded rather than resolved", () => { + const parsed = parseWithBoundary([registryRowWithBoundary({ + era_count: "1", valid_to_block: INT64_MAX, is_live: "true", release_scope: "scope_pending", + })]); + expect(validateRegistry(parsed, chains)).toEqual([]); + expect(parsed.rows[0].releaseScope).toBe("scope_pending"); + }); + + it("fails the freeze check, so A5 cannot include or silently exclude it", () => { + const parsed = parseWithBoundary([registryRowWithBoundary({ release_scope: "scope_pending" })]); + expect(assertScopeFrozen(parsed).map((x) => x.check)).toEqual(["no_scope_pending_when_frozen"]); + }); + + it("fails the freeze check when the column is absent entirely", () => { + // The dangerous default: no column at all must not read as "everything is in". + const parsed = parse(validRegistryBody()); + expect(assertScopeFrozen(parsed)).toHaveLength(2); + }); + + it("passes the freeze check once every row is decided either way", () => { + const parsed = parseWithBoundary([ + registryRowWithBoundary({ release_scope: "in_release" }), + registryRowWithBoundary({ era_index: "2", valid_from_block: "106000000", valid_to_block: INT64_MAX, is_live: "true", release_scope: "out_of_release" }), + ]); + expect(assertScopeFrozen(parsed)).toEqual([]); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-release-scope.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-release-scope.test.ts new file mode 100644 index 0000000..d604bb0 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-release-scope.test.ts @@ -0,0 +1,681 @@ +/** + * The frozen release scope. + * + * Every case mutates exactly ONE thing about an otherwise valid seed, and each file starts from a + * control that passes. A test that builds three defects proves only that something was wrong. + * + * The fixtures use the SAME 23-column base header as the shipped seed, plus the declared 5-column + * boundary block. A fixture whose header does not match the artifact it stands in for is rejected + * at the header and passes for a weaker reason than it was written for; that happened once in this + * repository already. + */ + +import { describe, it, expect } from "vitest"; +import { parseRegistry } from "../../src/control-plane/contractRegistry.js"; +import { loadChains, type ChainAuthority } from "../../src/control-plane/chains.js"; +import { loadControlPlane, inspectControlPlane } from "../../src/control-plane/index.js"; +import { + RELEASE_SCOPE_FREEZE, + assertReleaseScopeFrozen, + chainStanding, + releaseScopeState, + eraConsumableBySemanticModel, + assertSemanticErasConsumable, + ERA_CONSUMABILITY_BRANCHES, + type ReleaseScopeFreeze, +} from "../../src/control-plane/releaseScope.js"; +import { parseEraBoundaryEvidence, eraEvidenceKey } from "../../src/control-plane/eraConfidence.js"; +import { runBuildCheck } from "../../src/control-plane/build-check.js"; +import { NETWORKS } from "../../src/config.js"; +import { buildPlan } from "../../src/plan.js"; +import { targetsFor, partitionByReleaseScope, ChainOutOfReleaseScopeError } from "../../src/registry.js"; +import { + registryRow, + registryEra2Row, + registryRowWithBoundary, + surfaceRow, + writeRegistry, + writeRegistryWithBoundary, + writeSeed, + writeSurface, + INT64_MAX, + IMPL_A, +} from "../helpers/seed-fixtures.js"; + +const chains = loadChains(); + +const CHAINS_COLUMNS = [ + "chain", "chain_id", "chain_name", "native_token_symbol", "explorer_url_template", "is_active", "notes", +] as const; + +function chainsWith(rows: readonly string[]): ChainAuthority { + const path = writeSeed("chains.csv", CHAINS_COLUMNS, rows).path; + return loadChains(path); +} + +/** One of the nineteen, copied from the freeze declaration rather than retyped. */ +const EXCLUDED_ETH = RELEASE_SCOPE_FREEZE.excludedContracts.find((c) => c.chain === "ETHEREUM")!; + +const boundaryBody = (overrides: Parameters[0] = {}) => [ + registryRowWithBoundary({ era_index: "1", valid_to_block: "106000000", is_live: "false", ...overrides }), + registryRowWithBoundary({ + era_index: "2", implementation_address: "0x2222222222222222222222222222222222222222", + implementation_name: "UBISchemeV2", valid_from_block: "106000000", + valid_to_block: "9223372036854775807", is_live: "true", + era_evidence: "slot_bisection_and_announcement_log", ...overrides, + }), +]; + +function checks(path: string, freeze: ReleaseScopeFreeze = RELEASE_SCOPE_FREEZE, authority = chains): string[] { + return assertReleaseScopeFrozen(parseRegistry(path), authority, freeze).map((v) => v.check); +} + +describe("the release scope is frozen", () => { + // RENAMED 2026-09-28, along with the record it asserts. The previous name used a word that + // means nothing to a reader outside this project, and the decision record it pointed at was not + // part of the repository, so neither could be resolved by anyone holding only this code. + it("declares the scope decision, its record and its evidence", () => { + expect(RELEASE_SCOPE_FREEZE.frozen).toBe(true); + expect(RELEASE_SCOPE_FREEZE.decidedOn).toBe("2026-09-28"); + expect(RELEASE_SCOPE_FREEZE.decisionRecord).toBe("docs/release-scope.md"); + expect(RELEASE_SCOPE_FREEZE.evidence.length).toBeGreaterThan(0); + }); + + it("covers Celo, XDC and Ethereum, and records Fuse as dropped rather than forgotten", () => { + expect(RELEASE_SCOPE_FREEZE.releaseChains).toEqual(["CELO", "XDC", "ETHEREUM"]); + expect(RELEASE_SCOPE_FREEZE.chainsDropped.map((c) => c.chain)).toEqual(["FUSE"]); + for (const c of RELEASE_SCOPE_FREEZE.chainsDropped) { + expect(c.droppedOn).toMatch(/^\d{4}-\d{2}-\d{2}$/); + expect(c.reason.length).toBeGreaterThan(0); + // Disjoint by construction, so no chain can be read as both in and out. + expect(RELEASE_SCOPE_FREEZE.releaseChains).not.toContain(c.chain); + } + }); + + it("names the plan governing the amended decision and carries the superseded one", () => { + expect(RELEASE_SCOPE_FREEZE.planSha256) + .toBe("BAA0005DEE707BA6BF26DCC100194087AC84299084C372AE5DED6569325ECA02"); + expect(RELEASE_SCOPE_FREEZE.supersededPlanSha256) + .toEqual(["9DCDE225459127C4DA2BEADF9094FD894FE193010F39CB70C0753DD874853E26"]); + expect(RELEASE_SCOPE_FREEZE.supersededPlanSha256).not.toContain(RELEASE_SCOPE_FREEZE.planSha256); + }); + + it("excludes exactly the nineteen A1-R candidates, 6 on Fuse and 13 on Ethereum", () => { + const e = RELEASE_SCOPE_FREEZE.excludedContracts; + expect(e).toHaveLength(19); + expect(e.filter((c) => c.chain === "FUSE")).toHaveLength(6); + expect(e.filter((c) => c.chain === "ETHEREUM")).toHaveLength(13); + expect(new Set(e.map((c) => `${c.chainId}|${c.address}`)).size).toBe(19); + for (const c of e) expect(c.address).toMatch(/^0x[0-9a-f]{40}$/); + }); + + it("records Base and Gnosis as a decision not to assess, not as an assessment", () => { + expect(RELEASE_SCOPE_FREEZE.chainsNotAssessed.map((c) => c.chain)).toEqual(["BASE", "GNOSIS"]); + for (const c of RELEASE_SCOPE_FREEZE.chainsNotAssessed) { + expect(c.note).toMatch(/zero queries were made/); + } + expect(RELEASE_SCOPE_FREEZE.releaseChains).not.toContain("BASE"); + expect(RELEASE_SCOPE_FREEZE.releaseChains).not.toContain("GNOSIS"); + }); +}); + +describe("scope_pending is an illegal state once scope is frozen", () => { + it("accepts a declared seed where every row reads in_release", () => { + expect(checks(writeRegistryWithBoundary(boundaryBody()))).toEqual([]); + }); + + it("fails the build on a single surviving scope_pending row", () => { + const body = boundaryBody(); + body[1] = registryRowWithBoundary({ + era_index: "2", implementation_address: "0x2222222222222222222222222222222222222222", + implementation_name: "UBISchemeV2", valid_from_block: "106000000", + valid_to_block: "9223372036854775807", is_live: "true", + era_evidence: "slot_bisection_and_announcement_log", release_scope: "scope_pending", + }); + expect(checks(writeRegistryWithBoundary(body))).toEqual(["no_scope_pending_when_frozen"]); + }); + + it("names every pending row rather than stopping at the first", () => { + const body = boundaryBody({ release_scope: "scope_pending" }); + expect(checks(writeRegistryWithBoundary(body))).toHaveLength(2); + }); + + it("permits scope_pending while the freeze has not been declared", () => { + const body = boundaryBody({ release_scope: "scope_pending" }); + const unfrozen = { ...RELEASE_SCOPE_FREEZE, frozen: false }; + expect(checks(writeRegistryWithBoundary(body), unfrozen)).toEqual([]); + }); + + it("accepts out_of_release, which is a decision, unlike scope_pending", () => { + expect(checks(writeRegistryWithBoundary(boundaryBody({ release_scope: "out_of_release" })))).toEqual([]); + }); +}); + +describe("the pre-freeze seed is a named state, not a silent pass", () => { + it("reports pre_freeze_seed when the boundary and scope columns are absent", () => { + const parsed = parseRegistry(writeRegistry([registryRow(), registryEra2Row()])); + expect(releaseScopeState(parsed)).toBe("pre_freeze_seed"); + }); + + it("reports frozen_and_declared once the columns are present", () => { + expect(releaseScopeState(parseRegistry(writeRegistryWithBoundary(boundaryBody())))).toBe("frozen_and_declared"); + }); + + /* + * The coupling that makes `undeclared` safe to allow through the loader. Absent the column + * block, release_scope reads `undeclared` AND boundary_completeness is forced to + * `raw_only_unproven`, which forbids every decoder over every era. If a future change ever + * decouples the two, this test fails and the allowance has to be revisited. + */ + it("forbids semantic consumption of every era while the seed is pre-freeze", () => { + const parsed = parseRegistry(writeRegistry([registryRow(), registryEra2Row()])); + for (const row of parsed.rows) { + expect(row.releaseScope).toBe("undeclared"); + expect(row.boundaryCompleteness).toBe("raw_only_unproven"); + expect(eraConsumableBySemanticModel(row).consumable).toBe(false); + } + }); +}); + +describe("an excluded contract may not reappear in the registry", () => { + it("rejects an excluded address used as a proxy_address on its own chain", () => { + const body = [registryRowWithBoundary({ + chain: "ETHEREUM", chain_id: "1", proxy_address: EXCLUDED_ETH.address, + valid_to_block: "9223372036854775807", is_live: "true", era_count: "1", + })]; + expect(checks(writeRegistryWithBoundary(body))).toEqual(["excluded_contract_absent"]); + }); + + it("rejects an excluded address used as an implementation_address on its own chain", () => { + const body = [registryRowWithBoundary({ + chain: "ETHEREUM", chain_id: "1", implementation_address: EXCLUDED_ETH.address, + valid_to_block: "9223372036854775807", is_live: "true", era_count: "1", + })]; + expect(checks(writeRegistryWithBoundary(body))).toEqual(["excluded_contract_absent"]); + }); + + /* + * A1-R's first membership answer was a false positive from a substring match over the whole + * file: the address was real but sat in a different chain's implementation_address column. + * Matching on (chain_id, column) is what removed it, and this pins that. + */ + it("does not flag the same address on a different chain", () => { + const body = [registryRowWithBoundary({ + chain: "XDC", chain_id: "50", implementation_address: EXCLUDED_ETH.address, + valid_to_block: "9223372036854775807", is_live: "true", era_count: "1", + })]; + expect(checks(writeRegistryWithBoundary(body))).toEqual([]); + }); + + it("leaves an ordinary implementation address alone", () => { + const body = [registryRowWithBoundary({ + implementation_address: IMPL_A, valid_to_block: "9223372036854775807", + is_live: "true", era_count: "1", + })]; + expect(checks(writeRegistryWithBoundary(body))).toEqual([]); + }); +}); + +describe("a scope change cannot arrive as a seed edit", () => { + it("rejects a chain the frozen release does not name", () => { + const authority = chainsWith([ + "CELO,42220,Celo,CELO,https://celoscan.io/tx/{tx_hash},true,", + "BASE,8453,Base,ETH,https://basescan.org/tx/{tx_hash},true,", + ]); + const body = [registryRowWithBoundary({ + chain: "CELO", chain_id: "42220", valid_to_block: "9223372036854775807", + is_live: "true", era_count: "1", + })]; + expect(checks(writeRegistryWithBoundary(body), RELEASE_SCOPE_FREEZE, authority)).toEqual(["release_chain_frozen"]); + }); + + // RENAMED 2026-09-28. Was "accepts the four chains the release actually contains", which became + // false when Fuse left: the seed still declares four chains and the release now names three. + // The property that survives the change is the one worth asserting -- every chain in the seed + // has been DECIDED about, whether that decision was in or out. + it("accepts a chains seed where every chain is declared, in release or dropped", () => { + const declared = new Set([ + ...RELEASE_SCOPE_FREEZE.releaseChains, + ...RELEASE_SCOPE_FREEZE.chainsDropped.map((c) => c.chain), + ]); + expect(chains.rows.map((r) => r.chain).sort()).toEqual([...declared].sort()); + expect(assertReleaseScopeFrozen(parseRegistry(writeRegistryWithBoundary(boundaryBody())), chains)).toEqual([]); + }); + + /* + * The discriminator, both directions, on ONE fixture. This is what makes dropping a chain + * different from making the check stop firing: a chain recorded as dropped is silent, and a + * chain nobody decided about still raises. Delete `chainsDropped` and the first assertion + * fails; widen the rule to "anything outside the release is fine" and the rest fail. + */ + it("is silent on a dropped chain and still raises on a chain nobody decided about", () => { + const authority = chainsWith([ + "FUSE,122,Fuse,FUSE,https://explorer.fuse.io/tx/{tx_hash},true,", + "BASE,8453,Base,ETH,https://basescan.org/tx/{tx_hash},true,", + ]); + const registry = writeRegistryWithBoundary([ + registryRowWithBoundary({ + chain: "FUSE", chain_id: "122", release_scope: "out_of_release", + era_count: "1", valid_to_block: INT64_MAX, is_live: "true", + }), + registryRowWithBoundary({ + chain: "BASE", chain_id: "8453", proxy_address: "0x3333333333333333333333333333333333333333", + release_scope: "out_of_release", era_count: "1", valid_to_block: INT64_MAX, is_live: "true", + }), + ]); + + const v = assertReleaseScopeFrozen(parseRegistry(registry), authority); + + expect(v.filter((x) => x.subject.startsWith("FUSE"))).toEqual([]); + expect(v.map((x) => x.check)).toEqual(["release_chain_frozen", "release_chain_frozen"]); + for (const x of v) expect(x.subject).toMatch(/^BASE/); + }); + + it("answers where a chain stands in three cases, not two", () => { + expect(chainStanding("CELO")).toBe("in_release"); + expect(chainStanding("FUSE")).toBe("dropped"); + expect(chainStanding("BASE")).toBe("undeclared"); + }); + + /* + * Retention is a record, not a re-admission. The Fuse rows stay in the seeds because deleting + * the 96 deployment rows would orphan the 616 event-surface rows bound to them, so the one + * claim a retained row must never be allowed to make is that it is back in the release. + */ + it("refuses a retained row on a dropped chain that declares itself in release", () => { + const authority = chainsWith(["FUSE,122,Fuse,FUSE,https://explorer.fuse.io/tx/{tx_hash},true,"]); + const registry = writeRegistryWithBoundary([ + registryRowWithBoundary({ + chain: "FUSE", chain_id: "122", release_scope: "in_release", + era_count: "1", valid_to_block: INT64_MAX, is_live: "true", + }), + ]); + + const v = assertReleaseScopeFrozen(parseRegistry(registry), authority); + + expect(v.map((x) => x.check)).toEqual(["dropped_chain_not_in_release"]); + expect(v[0].detail).toMatch(/dropped from the release on 2026-09-28/); + }); + + it("accepts the same retained row once it declares itself out of the release", () => { + const authority = chainsWith(["FUSE,122,Fuse,FUSE,https://explorer.fuse.io/tx/{tx_hash},true,"]); + const registry = writeRegistryWithBoundary([ + registryRowWithBoundary({ + chain: "FUSE", chain_id: "122", release_scope: "out_of_release", + era_count: "1", valid_to_block: INT64_MAX, is_live: "true", + }), + ]); + expect(assertReleaseScopeFrozen(parseRegistry(registry), authority)).toEqual([]); + }); + + it("refuses a freeze that names one chain as both in release and dropped", () => { + const incoherent: ReleaseScopeFreeze = { + ...RELEASE_SCOPE_FREEZE, + releaseChains: ["CELO", "XDC", "ETHEREUM", "FUSE"], + }; + const v = assertReleaseScopeFrozen( + parseRegistry(writeRegistryWithBoundary(boundaryBody())), chains, incoherent, + ); + expect(v.map((x) => x.check)).toEqual(["release_scope_declaration_coherent"]); + expect(v[0].subject).toBe("FUSE"); + expect(v[0].line).toBeNull(); + }); +}); + +describe("a semantic model may not consume an unreviewed era", () => { + const parseOne = (overrides: Parameters[0]) => + parseRegistry(writeRegistryWithBoundary([ + registryRowWithBoundary({ era_count: "1", valid_to_block: "9223372036854775807", is_live: "true", ...overrides }), + ])).rows[0]; + + const proven = { + boundary_completeness: "complete", + boundary_evidence_manifest_hash: "0x" + "cd".repeat(32), + boundary_checked_through_block: "107000000", + frozen_safe_head: "107000100", + }; + + it("allows a complete era that is in release", () => { + expect(eraConsumableBySemanticModel(parseOne(proven)).consumable).toBe(true); + }); + + it("allows a plain_contract era on the same evidence", () => { + expect(eraConsumableBySemanticModel(parseOne({ ...proven, boundary_completeness: "plain_contract" })).consumable).toBe(true); + }); + + // RENAMED 2026-09-28 by the decode unit. + // was: "refuses a raw_only_unproven era and says why" + // This is the test plan 5.5 obligation 4 names. It asserted the one branch the reversal + // REMOVES, so leaving it would have pinned the rule the change exists to retire. Rewritten to + // assert the reversal itself, in both directions on one fixture. + it("no longer refuses on raw_only_unproven alone, and still refuses with no evidence", () => { + // Same completeness verdict, full boundary evidence: consumable, and it carries a grade. + // The fixture's era_evidence is `contract_creation` on a two-voice creation method, so the + // published rule puts it at `announced` by clause B3. + const withEvidence = eraConsumableBySemanticModel(parseOne({ ...proven, boundary_completeness: "raw_only_unproven" })); + expect(withEvidence.consumable).toBe(true); + expect(withEvidence.branch).toBe("consumable"); + expect(withEvidence.confidenceGrade).toBe("announced"); + + // The grade VARIES with the evidence rather than being a constant dressed as one: the same + // row with a bisected era reads a tier higher, and it is still consumable either way. That + // is the whole reversal -- the grade describes, it does not decide. + const bisected = eraConsumableBySemanticModel(parseOne({ ...proven, era_evidence: "slot_bisection_and_announcement_log" })); + expect(bisected.consumable).toBe(true); + expect(bisected.confidenceGrade).toBe("slot_bisected"); + + // Same completeness verdict, no evidence: still refused, by the RETAINED branch, and the + // reason no longer mentions raw_only_unproven because that is no longer why. + const without = eraConsumableBySemanticModel(parseOne({ boundary_completeness: "raw_only_unproven" })); + expect(without.consumable).toBe(false); + expect(without.branch).toBe("boundary_evidence_incomplete"); + expect(without.reason).not.toMatch(/raw_only_unproven/); + }); + + it("refuses a complete era that is still scope_pending", () => { + const verdict = eraConsumableBySemanticModel(parseOne({ ...proven, release_scope: "scope_pending" })); + expect(verdict.consumable).toBe(false); + expect(verdict.reason).toMatch(/scope_pending/); + }); + + it("refuses an out_of_release era even when its boundary evidence is complete", () => { + expect(eraConsumableBySemanticModel(parseOne({ ...proven, release_scope: "out_of_release" })).consumable).toBe(false); + }); + + it("reports one policy violation per refused era, naming the model", () => { + const parsed = parseRegistry(writeRegistryWithBoundary(boundaryBody())); + const v = assertSemanticErasConsumable(parsed.rows, "Semantic.claim_events"); + expect(v).toHaveLength(2); + expect(v.map((x) => x.check)).toEqual(["semantic_era_reviewed", "semantic_era_reviewed"]); + expect(v[0].subject).toMatch(/^Semantic\.claim_events -> /); + }); +}); + +/* + * THE BRANCH TABLE, asserted branch by branch. + * + * The reversal narrows this control in one place and widens it in three. A test that only asserted + * "consumable" would pass equally well on an implementation that deleted the release-scope refusal + * and made every dropped-chain row consumable -- which is the exact hazard the plan names. So each + * branch gets its own case, and the removed one gets a case proving it is GONE. + */ +describe("the 5.5 branch table, branch by branch", () => { + const row = (o: Parameters[0]) => + parseRegistry(writeRegistryWithBoundary([ + registryRowWithBoundary({ era_count: "1", valid_to_block: INT64_MAX, is_live: "true", ...o }), + ])).rows[0]; + + const evidenced = { + boundary_completeness: "raw_only_unproven", + boundary_evidence_manifest_hash: "0x" + "cd".repeat(32), + boundary_checked_through_block: "107000000", + frozen_safe_head: "107000100", + }; + + it("RETAINED 1 of 5: no code deployed", () => { + const v = eraConsumableBySemanticModel(row({ + era_method: "no_code_deployed", era_index: "1", era_count: "0", valid_from_block: "", + valid_to_block: "", creation_block: "", is_live: "false", implementation_address: "", + })); + expect(v.consumable).toBe(false); + expect(v.branch).toBe("no_code_deployed"); + }); + + it("RETAINED 2 of 5: the row is not in the release -- the branch that keeps dropped chains out", () => { + const v = eraConsumableBySemanticModel(row({ ...evidenced, release_scope: "out_of_release" })); + expect(v.consumable).toBe(false); + expect(v.branch).toBe("release_scope_not_in_release"); + }); + + it("REMOVED 3 of 5: raw_only_unproven no longer refuses, and its name is gone from the branch list", () => { + const v = eraConsumableBySemanticModel(row(evidenced)); + expect(v.consumable).toBe(true); + expect(v.branch).toBe("consumable"); + // The removed branch cannot be named, which is what stops it being reintroduced quietly. + expect(ERA_CONSUMABILITY_BRANCHES).not.toContain("boundary_completeness_raw_only_unproven"); + expect([...ERA_CONSUMABILITY_BRANCHES].filter((b) => b.includes("raw_only_unproven"))).toEqual([]); + }); + + it("RETAINED 4 of 5: boundary evidence incomplete, stated as its refusal condition", () => { + for (const missing of ["boundary_evidence_manifest_hash", "boundary_checked_through_block", "frozen_safe_head"]) { + const v = eraConsumableBySemanticModel(row({ ...evidenced, [missing]: "" })); + expect(v.consumable).toBe(false); + expect(v.branch).toBe("boundary_evidence_incomplete"); + } + }); + + it("RETAINED 5 of 5: otherwise consumable, and it carries its grade", () => { + const v = eraConsumableBySemanticModel(row(evidenced)); + expect(v.consumable).toBe(true); + expect(v.confidenceGrade).toBe("announced"); + expect(v.reason).toContain("confidence 'announced'"); + }); + + it("ADDED 1 of 3: an interval whose ABI is unknown", () => { + const v = eraConsumableBySemanticModel(row({ ...evidenced, abi_source: "none" })); + expect(v.consumable).toBe(false); + expect(v.branch).toBe("abi_unknown"); + expect(v.reason).toMatch(/captured raw and decode is refused/); + }); + + it("ADDED 2 of 3: an unbound decode ambiguity", () => { + const r = row(evidenced); + const v = eraConsumableBySemanticModel(r, RELEASE_SCOPE_FREEZE, { + unboundAmbiguousContracts: new Set([`${r.chainId}|${r.proxyAddress}`]), + }); + expect(v.consumable).toBe(false); + expect(v.branch).toBe("decode_ambiguity_unbound"); + }); + + it("ADDED 3 of 3: a row failing its magnitude tripwire", () => { + const r = row(evidenced); + const v = eraConsumableBySemanticModel(r, RELEASE_SCOPE_FREEZE, { + magnitudeFailures: new Set([`${r.chainId}|${r.proxyAddress}|${r.eraIndex}`]), + }); + expect(v.consumable).toBe(false); + expect(v.branch).toBe("magnitude_tripwire_failed"); + }); + + it("an ABSENT decode context refuses nothing, so a missing input never reads as a finding", () => { + // A control that fires when its input is missing cannot be told apart from one that fires + // because its input said so, and only the second kind is worth having. + expect(eraConsumableBySemanticModel(row(evidenced), RELEASE_SCOPE_FREEZE, {}).consumable).toBe(true); + }); + + it("the grade propagates on a REFUSAL too, because those are different questions", () => { + const v = eraConsumableBySemanticModel(row({ ...evidenced, release_scope: "out_of_release" })); + expect(v.consumable).toBe(false); + expect(v.confidenceGrade).toBe("announced"); + expect(v.gradeClause).toBe("B3"); + }); +}); + +/* + * The enforcement point. Unit 1's precedent: a policy living in a function nothing calls enforces + * nothing, and this policy had exactly that shape -- its only callers were inside its own module. + */ +describe("the semantic-era policy is reached from the build path", () => { + it("runs over the consumed eras and passes on the shipped seeds", () => { + const result = runBuildCheck(); + expect(result.evidencedErasChecked).toBe(15); + expect(result.evidencedErasRefused).toBe(0); + expect(result.ok).toBe(true); + expect(result.lines.some((l) => l.startsWith("semantic era policy:"))).toBe(true); + }); + + it("the 15 consumed eras are exactly the in-release eras carrying promoted evidence", () => { + const evidence = parseEraBoundaryEvidence(); + const rows = inspectControlPlane().plane!.registry.rows.filter( + (r) => RELEASE_SCOPE_FREEZE.releaseChains.includes(r.chain) && !r.noCodeDeployed + && evidence.has(eraEvidenceKey(r.chainId, r.proxyAddress, r.eraIndex)), + ); + expect(rows).toHaveLength(15); + for (const r of rows) expect(eraConsumableBySemanticModel(r, RELEASE_SCOPE_FREEZE, { boundaryEvidence: evidence }).consumable).toBe(true); + }); + + it("goes RED when a consumed era loses its ABI, so the refusal is load-bearing", () => { + const evidence = parseEraBoundaryEvidence(); + const rows = inspectControlPlane().plane!.registry.rows.filter( + (r) => evidence.has(eraEvidenceKey(r.chainId, r.proxyAddress, r.eraIndex)) && r.chain === "XDC", + ); + expect(rows.length).toBeGreaterThan(0); + const stripped = rows.map((r) => ({ ...r, abiSource: "none" })); + const refusals = assertSemanticErasConsumable(stripped, "consumed semantic eras", RELEASE_SCOPE_FREEZE, { boundaryEvidence: evidence }); + expect(refusals).toHaveLength(rows.length); + expect(refusals[0].detail).toMatch(/^abi_source is 'none'/); + }); +}); + +/* + * The checks above run on the rule functions. These run on the fail-closed loader the pipeline + * actually calls at startup, because "the validator fails the build" is the requirement, not + * "a function returns a violation object". + */ +describe("the loader refuses to start the pipeline on a frozen-scope violation", () => { + // `era_bound=false` asserts the event is present in EVERY era, so a two-era fixture needs a + // surface row per era or the control fails on the surface rule instead of the scope rule. + const surface = writeSurface([ + surfaceRow({ era_index: "1", implementation_address: IMPL_A }), + surfaceRow({ era_index: "2", implementation_address: "0x2222222222222222222222222222222222222222" }), + ]); + + it("starts on a declared seed where every row reads in_release", () => { + const registry = writeRegistryWithBoundary(boundaryBody()); + const plane = loadControlPlane({ registry, eventSurface: surface }); + expect(plane.releaseScopeState).toBe("frozen_and_declared"); + }); + + it("throws, naming the check, when one row still reads scope_pending", () => { + const registry = writeRegistryWithBoundary(boundaryBody({ release_scope: "scope_pending" })); + expect(() => loadControlPlane({ registry, eventSurface: surface })) + .toThrow(/CONTROL_PLANE_REJECTED[\s\S]*no_scope_pending_when_frozen/); + }); + + it("reports the same violation through the inspection path, without throwing", () => { + const registry = writeRegistryWithBoundary(boundaryBody({ release_scope: "scope_pending" })); + const inspection = inspectControlPlane({ registry, eventSurface: surface }); + expect(inspection.ok).toBe(false); + expect(inspection.releaseScopeViolations.map((v) => v.check)).toEqual([ + "no_scope_pending_when_frozen", "no_scope_pending_when_frozen", + ]); + }); + + // RENAMED 2026-09-28 by the decode unit, together with the seed it describes. + // was: "still starts on the shipped pre-freeze seed, which carries no scope column at all" + // The shipped seed now carries the declared boundary and scope block, so `pre_freeze_seed` is + // no longer the state it is in. The property worth keeping is the same one: the shipped seed + // starts the pipeline cleanly, and it now does so having STATED every row's scope rather than + // by being silent about it -- which is the stronger of the two, since `scope_pending` exists + // precisely to stop an undecided row passing as decided. + it("starts on the shipped seed, which now declares every row's scope explicitly", () => { + const inspection = inspectControlPlane(); + expect(inspection.releaseScopeState).toBe("frozen_and_declared"); + expect(inspection.releaseScopeViolations).toEqual([]); + expect(inspection.decodeViolations).toEqual([]); + expect(inspection.ok).toBe(true); + }); +}); + +/* + * A dropped chain is refused everywhere it can be asked for. + * + * This block exists because the scope decision used to bind NOTHING on the path that writes: + * `loadControlPlane`, the only caller of `assertReleaseScopeFrozen`, has no caller of its own in + * this package, and `loadRegistry` deliberately does not run the frozen-scope checks. A decision + * that is true in a document and false in the running system is the failure this whole change + * exists to prevent, so each refusal below is asserted by running the thing, not by reading it. + */ +describe("a dropped chain is refused on every path that could act on it", () => { + it("reports it as unsupported in plan mode, with a nonzero exit and the record named", () => { + const plan = buildPlan({ mode: "daily", chains: ["fuse"] }); + + expect(plan.outcome).toBe("unsupported"); + expect(plan.exitCode).not.toBe(0); + expect(plan.refusals.join(" ")).toMatch(/FUSE is configured but is NOT in the release scope/); + expect(plan.refusals.join(" ")).toContain(RELEASE_SCOPE_FREEZE.decisionRecord); + }); + + it("refuses to build capture targets for it, rather than returning none", () => { + // Returning an empty list would be indistinguishable from "this chain has no contracts", + // which is how a run covers nothing and still exits 0. + expect(() => targetsFor(NETWORKS.FUSE)).toThrow(ChainOutOfReleaseScopeError); + expect(() => targetsFor(NETWORKS.FUSE)).toThrow(/dropped from the release on 2026-09-28/); + expect(() => targetsFor(NETWORKS.FUSE)).toThrow(/docs\/release-scope\.md/); + }); + + it("refuses a chain nobody decided about with a different reason than a dropped one", () => { + const narrowed = { ...RELEASE_SCOPE_FREEZE, releaseChains: ["XDC"] as const }; + expect(() => targetsFor(NETWORKS.CELO, {}, narrowed)).toThrow(/nobody has decided about it/); + }); + + it("still builds capture targets for a chain that is in the release", () => { + expect(targetsFor(NETWORKS.XDC).length).toBeGreaterThan(0); + }); + + it("partitions a run's chain list rather than aborting the whole run", () => { + // What keeps a bare `daily` usable: Fuse is reported and skipped, Celo and XDC still run. + const { usable, refused } = partitionByReleaseScope(Object.values(NETWORKS)); + expect(refused.map((r) => r.network.name)).toEqual(["FUSE"]); + expect(usable.map((n) => n.name).sort()).toEqual([...RELEASE_SCOPE_FREEZE.releaseChains].sort()); + expect(refused[0].detail).toContain(RELEASE_SCOPE_FREEZE.decisionRecord); + }); + + it("refuses every Fuse era in the shipped seed, and names which branch refused each", () => { + const fuseRows = inspectControlPlane().plane!.registry.rows.filter((r) => r.chain === "FUSE"); + expect(fuseRows).toHaveLength(96); + + let byNoCode = 0; + let byReleaseScope = 0; + for (const row of fuseRows) { + const verdict = eraConsumableBySemanticModel(row); + expect(verdict.consumable).toBe(false); + if (row.noCodeDeployed) { + // An earlier branch, and it fires first. Counted separately rather than folded in, so a + // claim about the release-scope branch is a claim about the rows it actually decides. + expect(verdict.reason).toMatch(/^no_code_deployed:/); + expect(verdict.branch).toBe("no_code_deployed"); + byNoCode++; + } else { + // CHANGED 2026-09-28 by the decode unit, with the seed. The literal was + // "release_scope is 'undeclared', not 'in_release'" while the seed carried no scope + // column at all. It now carries one, and every Fuse row states its own exclusion rather + // than being excluded by an absence. Same branch, stronger artifact. + expect(verdict.reason).toBe("release_scope is 'out_of_release', not 'in_release'"); + expect(verdict.branch).toBe("release_scope_not_in_release"); + byReleaseScope++; + } + } + // MEASURED 2026-09-28 against the shipped seed. + expect([byNoCode, byReleaseScope]).toEqual([2, 94]); + }); + + /* + * The closing argument, and it names a real seam rather than papering over it. + * + * `eraConsumableBySemanticModel` reads the ROW's `release_scope` column; it never consults the + * freeze's chain list. On its own it would therefore let a Fuse era through if a seed ever + * declared one `in_release` with complete boundary evidence. It cannot happen, because + * `assertReleaseScopeFrozen` refuses exactly that combination and the loader refuses the whole + * control plane on any violation -- so no loadable seed can produce a consumable Fuse era. + * + * Both halves are asserted here so that if either is ever weakened, this fails rather than + * going quiet. The branch table itself is out of scope for this change by design. + */ + it("closes the only route by which a Fuse era could become consumable", () => { + const authority = chainsWith(["FUSE,122,Fuse,FUSE,https://explorer.fuse.io/tx/{tx_hash},true,"]); + const readmitted = { + chain: "FUSE", chain_id: "122", era_count: "1", valid_to_block: INT64_MAX, is_live: "true", + release_scope: "in_release", boundary_completeness: "complete", + boundary_evidence_manifest_hash: "0x" + "cd".repeat(32), + boundary_checked_through_block: "107000000", frozen_safe_head: "107000100", + }; + const parsed = parseRegistry(writeRegistryWithBoundary([registryRowWithBoundary(readmitted)])); + + // Half one: the era predicate alone WOULD admit it. Stated, not hidden. + expect(eraConsumableBySemanticModel(parsed.rows[0]).consumable).toBe(true); + + // Half two: the seed carrying it is refused, so the predicate is never asked. + expect(assertReleaseScopeFrozen(parsed, authority).map((v) => v.check)) + .toEqual(["dropped_chain_not_in_release"]); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-shipped-seeds.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-shipped-seeds.test.ts new file mode 100644 index 0000000..218f49b --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/control-plane-shipped-seeds.test.ts @@ -0,0 +1,111 @@ +/** + * The SHIPPED seeds, through the same code path the pipeline uses. + * + * This is the GREEN half of the strict-parser suite: the real control plane must survive every + * rule with zero dropped rows. A parser that rejects a defect but also rejects the live seed has + * not helped anyone. + * + * It reads three CSV files and touches no network and no warehouse. + */ + +import { describe, it, expect } from "vitest"; +import { inspectControlPlane } from "../../src/control-plane/index.js"; +import { topic0For, RAWLOGS_INDEXED_SLOTS } from "../../src/control-plane/eventSurface.js"; + +const inspection = inspectControlPlane(); + +describe("the shipped control plane parses and validates", () => { + it("has no malformed physical row in any seed", () => { + expect(inspection.parseError, inspection.parseError?.message).toBeNull(); + }); + + it("passes every registry rule", () => { + expect(inspection.registryViolations).toEqual([]); + }); + + it("passes every event-surface rule", () => { + expect(inspection.surfaceViolations).toEqual([]); + }); + + it("drops zero rows: physical line count reconciles with parsed record count", () => { + const { registry, eventSurface } = inspection.plane!; + expect(registry.rows.length).toBe(registry.csv.physicalLines - 1); + expect(eventSurface.rows.length).toBe(eventSurface.csv.physicalLines - 1); + }); +}); + +/** + * Measured on 2026-09-28 against the held-local seeds. These are deliberately exact: a control + * seed changing size is a decision, not a detail, and this test is where that decision has to be + * acknowledged. Plan task 16 regenerates both seeds, and updating these numbers is part of it. + */ +describe("measured shape of the shipped seeds", () => { + const plane = inspection.plane!; + + it("contract_deployments holds 362 rows over 148 contracts", () => { + expect(plane.registry.rows).toHaveLength(362); + expect(new Set(plane.registry.rows.map((r) => `${r.chainId}|${r.proxyAddress}`)).size).toBe(148); + }); + + it("356 of those are deployment eras and 6 declare no deployed code", () => { + expect(plane.registry.rows.filter((r) => !r.noCodeDeployed)).toHaveLength(356); + expect(plane.registry.rows.filter((r) => r.noCodeDeployed)).toHaveLength(6); + }); + + it("every open-ended sentinel row is exactly a live row, and there are 142", () => { + const sentinel = plane.registry.rows.filter((r) => r.validTo?.kind === "open_ended"); + const live = plane.registry.rows.filter((r) => r.isLive); + expect(sentinel).toHaveLength(142); + expect(live).toHaveLength(142); + expect(sentinel.map((r) => r.line)).toEqual(live.map((r) => r.line)); + }); + + it("event_surface holds 2824 rows", () => { + expect(plane.eventSurface.rows).toHaveLength(2824); + }); + + it("recomputes every non-anonymous topic0 and matches all of them", () => { + const nonAnon = plane.eventSurface.rows.filter((r) => !r.anonymous); + expect(nonAnon).toHaveLength(2823); + const mismatched = nonAnon.filter((r) => topic0For(r.eventSignature) !== r.topic0); + expect(mismatched.map((r) => `${r.line} ${r.eventSignature}`)).toEqual([]); + }); + + it("binds all 2824 surface rows to exactly one deployment era", () => { + expect(plane.counts.bindingChecked).toBe(2824); + expect(plane.counts.bindingMatched).toBe(2824); + }); + + it("carries exactly one anonymous event, and it does not fit the RawLogs grain", () => { + const anon = plane.eventSurface.rows.filter((r) => r.anonymous); + expect(anon).toHaveLength(1); + expect(anon[0].eventSignature).toBe("LogNote(bytes4,address,bytes32,bytes32,bytes)"); + expect(anon[0].indexedPositions.length).toBeGreaterThan(RAWLOGS_INDEXED_SLOTS); + expect(inspection.advisories.map((a) => a.check)).toEqual(["anonymous_not_capturable_in_rawlogs"]); + }); + + it("labels 24 indexed dynamic parameters as permanently unrecoverable from a log", () => { + const hashOnly = plane.eventSurface.rows.filter((r) => r.hashOnlyIndexedPositions.length > 0); + expect(hashOnly).toHaveLength(24); + expect([...new Set(hashOnly.map((r) => r.eventSignature))].sort()) + .toEqual(["AdminsAdded(address[])", "AdminsRemoved(address[])"]); + }); + + // RENAMED 2026-09-28 by the decode unit, together with the seed it describes. + // was: "carries no boundary-evidence column, so every era is raw_only_unproven" + // The registry seed now carries the declared five-column boundary block, so the old name states + // the opposite of the artifact. What did NOT change is the verdict every era carries: Phase 2B + // reached `complete` on 0 of 41 assessed eras and the rest were never assessed, so nothing may + // claim anything stronger than raw_only_unproven. + it("carries the boundary-evidence block, and every era still reads raw_only_unproven", () => { + expect(plane.registry.hasBoundaryColumns).toBe(true); + expect(plane.registry.rows.every((r) => r.boundaryCompleteness === "raw_only_unproven")).toBe(true); + // Only the eras an evidence manifest covers carry a hash; the rest declare nothing rather + // than declaring an absence as if it were a measurement. + expect(plane.registry.rows.filter((r) => r.boundaryEvidenceManifestHash !== null)).toHaveLength(41); + // Every row now makes a scope statement, which is what `scope_pending` exists to prevent + // being skipped. + expect(plane.registry.rows.every((r) => r.releaseScope === "in_release" || r.releaseScope === "out_of_release")).toBe(true); + expect(plane.registry.rows.filter((r) => r.releaseScope === "out_of_release")).toHaveLength(96); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/coverage-honesty.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/coverage-honesty.test.ts new file mode 100644 index 0000000..b441903 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/coverage-honesty.test.ts @@ -0,0 +1,178 @@ +/** + * coverage.ts, as a green suite. + * + * The H3 and H5 red tests prove the defects are closed. These prove the rules around them behave, + * including the cases that decide whether the H3 fix is a real rule or a special case that happens + * to satisfy one fixture: a gap ABOVE the newest recorded block is not a gap, a row that describes + * no range must not widen the envelope, and a repaired hole must stop being reported. + */ + +import { describe, it, expect } from "vitest"; +import { + isClean, openGaps, computeResumePoint, weightDecodeCoverage, + type DecodeLogGroup, +} from "../../src/coverage.js"; +import { parseEventSurface } from "../../src/control-plane/eventSurface.js"; +import { interval } from "../helpers/fixtures.js"; +import { EVENT_SURFACE_PATH } from "../../src/control-plane/eventSurface.js"; + +describe("isClean: a capture vouches for its range only when it finished and skipped nothing", () => { + it("accepts a complete capture with no skips", () => { + expect(isClean(interval(100, 199))).toBe(true); + }); + + it("rejects a complete capture that recorded a skip", () => { + expect(isClean(interval(100, 199, { skipped: [[150, 160]] }))).toBe(false); + }); + + it("rejects every non-complete status", () => { + for (const status of ["incomplete", "unconfirmed_empty", "refused_budget", "capability_gap", "nothing_to_fetch"]) { + expect(isClean(interval(100, 199, { status }))).toBe(false); + } + }); +}); + +describe("openGaps names three kinds of hole and nothing else", () => { + it("names a hole no capture ever recorded, between two clean captures", () => { + // H3, stated as a rule rather than as one fixture. + expect(openGaps([interval(100, 199), interval(300, 399)])).toEqual([[200, 299]]); + }); + + it("names a recorded skip", () => { + expect(openGaps([interval(100, 199, { skipped: [[150, 160]] })])).toEqual([[150, 160]]); + }); + + it("names the whole range of a capture that did not complete", () => { + expect(openGaps([interval(100, 199, { status: "incomplete" })])).toEqual([[100, 199]]); + }); + + it("does NOT name anything above the newest recorded block", () => { + // The bound that keeps this from reporting the rest of the chain. Blocks nobody has claimed + // to read are the resume point's subject, not a gap in what was read. + expect(openGaps([interval(100, 199)])).toEqual([]); + }); + + it("does not let a row that describes no range widen the envelope", () => { + // A `nothing_to_fetch` row records toBlock BELOW fromBlock. Counting it would invent a + // gigantic gap out of a read that found nothing to do. + const captures = [interval(100, 199), interval(5_000, 4_999, { status: "nothing_to_fetch" })]; + expect(openGaps(captures)).toEqual([]); + }); + + it("stops naming a hole once a later clean capture covers it", () => { + const captures = [interval(100, 199), interval(300, 399), interval(200, 299)]; + expect(openGaps(captures)).toEqual([]); + }); + + it("returns nothing for an empty ledger, because absence of rows is not a hole in a range", () => { + expect(openGaps([])).toEqual([]); + }); + + it("merges adjacent holes into one range", () => { + const captures = [interval(100, 199), interval(400, 499), interval(200, 299, { status: "incomplete" })]; + expect(openGaps(captures)).toEqual([[200, 399]]); + }); + + it("clamps an unreadable skip to the capture's own range rather than dropping it", () => { + const captures = [interval(100, 199, { status: "incomplete", skipped: [[-Infinity, Infinity]] })]; + expect(openGaps(captures)).toEqual([[100, 199]]); + }); +}); + +describe("computeResumePoint stays below a hole and now names it", () => { + it("resumes at the edge of the contiguous clean run, not at the highest block held", () => { + const resume = computeResumePoint([interval(100, 199), interval(300, 399)], 100); + expect(resume.resumeAt).toBe(199); + expect(resume.coveredUpTo).toBe(199); + }); + + it("names the hole in its own output, so no mode of this module is silent about it", () => { + const resume = computeResumePoint([interval(100, 199), interval(300, 399)], 100); + expect(resume.openGaps).toEqual([[200, 299]]); + expect(resume.reason).toContain("200..299"); + }); + + it("falls back to the creation block when no coverage row exists", () => { + const resume = computeResumePoint([], 12_345); + expect(resume.resumeAt).toBe(12_345); + expect(resume.coveredUpTo).toBeNull(); + expect(resume.reason).toContain("no coverage row exists"); + }); + + it("falls back to the creation block when every row is unclean, and says how many", () => { + const resume = computeResumePoint([interval(100, 199, { status: "incomplete" })], 100); + expect(resume.resumeAt).toBe(100); + expect(resume.coveredUpTo).toBeNull(); + expect(resume.reason).toContain("all 1 coverage row(s) are incomplete"); + }); + + it("falls back to the creation block when clean coverage starts above it", () => { + const resume = computeResumePoint([interval(500, 599)], 100); + expect(resume.resumeAt).toBe(100); + expect(resume.coveredUpTo).toBeNull(); + expect(resume.reason).toContain("no clean capture covers the contract's creation block 100"); + }); +}); + +describe("decode coverage counts rows, and counts what it could not classify separately", () => { + const surface = parseEventSurface(EVENT_SURFACE_PATH); + // A real (chain, address, topic0) from the shipped surface, so the fixture matches the shape of + // the artifact it stands in for rather than an invented one. + const known = surface.rows.find((r) => r.topic0 !== null)!; + const UNKNOWN_TOPIC = "0x" + "ab".repeat(32); + + it("reports zero undecodable when every topic0 is on the surface", () => { + const groups: DecodeLogGroup[] = [ + { chainId: known.chainId, address: known.proxyAddress, topic0: known.topic0!, rows: 2_649_450 }, + ]; + const report = weightDecodeCoverage(groups, surface); + + expect(report.rowsConsidered).toBe(2_649_450); + expect(report.rowsUndecodable).toBe(0); + expect(report.errors).toBe(0); + }); + + it("counts ROWS, not distinct topic0 values", () => { + const groups: DecodeLogGroup[] = [ + { chainId: known.chainId, address: known.proxyAddress, topic0: known.topic0!, rows: 100 }, + { chainId: known.chainId, address: known.proxyAddress, topic0: UNKNOWN_TOPIC, rows: 35_862 }, + ]; + const report = weightDecodeCoverage(groups, surface); + + expect(report.rowsConsidered).toBe(35_962); + expect(report.rowsUndecodable).toBe(35_862); + expect(report.byContract[0].unmatchedTopic0s).toEqual([UNKNOWN_TOPIC]); + }); + + it("never folds an unclassifiable row into the undecodable count", () => { + // A null topic0 means the ROW is unreadable, not that the event is unknown. Merging the two + // would let "we could not look" be reported as "we looked and it was fine". + const groups: DecodeLogGroup[] = [ + { chainId: known.chainId, address: known.proxyAddress, topic0: known.topic0!, rows: 10 }, + { chainId: known.chainId, address: known.proxyAddress, topic0: null, rows: 7 }, + ]; + const report = weightDecodeCoverage(groups, surface); + + expect(report.rowsUndecodable).toBe(0); + expect(report.errors).toBe(7); + expect(report.rowsConsidered).toBe(10); + expect(report.errorDetail.join(" ")).toContain("7 row(s) carry no topic0"); + }); + + it("flags an address the surface does not describe at all", () => { + const groups: DecodeLogGroup[] = [ + { chainId: 50, address: "0x" + "99".repeat(20), topic0: UNKNOWN_TOPIC, rows: 4 }, + ]; + const report = weightDecodeCoverage(groups, surface); + + expect(report.byContract[0].addressHasNoSurface).toBe(true); + expect(report.rowsUndecodable).toBe(4); + }); + + it("reports nothing rather than zero when there are no rows to classify", () => { + const report = weightDecodeCoverage([], surface); + expect(report.byContract).toEqual([]); + expect(report.rowsConsidered).toBe(0); + expect(report.errors).toBe(0); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/harness-discrimination.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/harness-discrimination.test.ts new file mode 100644 index 0000000..ee60d6c --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/harness-discrimination.test.ts @@ -0,0 +1,174 @@ +/** + * The harness proving itself. + * + * Coordination's rule for a simulator-backed test: "A simulator-backed test that would pass + * against a correctly fixed implementation AND against the current broken one is worthless. Prove + * each one discriminates." That obligation lands on the simulator, so this file is where it is + * discharged. + * + * Three properties, and the third is the one that matters most: + * + * 1. It reproduces the defect under the current implementation. + * 2. It reports a correct implementation as correct. + * 3. It REFUSES any SQL it does not model, rather than answering with a plausible empty result. + * + * Without the third, every future statement this pipeline learns to emit would silently return + * nothing and every assertion built on it would pass for no reason. + */ + +import { describe, it, expect, beforeEach, afterEach } from "vitest"; +import { writeFileSync, mkdtempSync, rmSync } from "fs"; +import { tmpdir } from "os"; +import { join } from "path"; +import { BigQuerySimulator, rendezvous } from "../helpers/bq-simulator.js"; +import { makeWireRecorder } from "../helpers/wire-recorder.js"; +import { setRpcTransport, resetAdapters } from "../../src/adapters.js"; +import { rpcCall } from "../../src/rpc.js"; + +const COLUMNS = ["chain_id", "tx_hash", "log_index", "block_timestamp", "block_hash", "payload"]; + +function row(txHash: string, ts: string, extra: Record = {}) { + return { + chain_id: 50, tx_hash: txHash, log_index: 0, + block_timestamp: ts, block_hash: "0xaa", payload: "v1", ...extra, + }; +} + +const MERGE_SQL = (windowFrom: string, windowTo: string) => ` + MERGE \`p.d.Target\` AS T + USING \`p.d.Staging\` AS S + ON T.chain_id = S.chain_id AND T.tx_hash = S.tx_hash AND T.log_index = S.log_index + AND T.block_timestamp >= TIMESTAMP('${windowFrom}') AND T.block_timestamp < TIMESTAMP('${windowTo}') + WHEN MATCHED THEN UPDATE SET T.block_timestamp = S.block_timestamp, T.payload = S.payload + WHEN NOT MATCHED THEN INSERT (chain_id, tx_hash, log_index, block_timestamp, block_hash, payload) VALUES (S.chain_id, S.tx_hash, S.log_index, S.block_timestamp, S.block_hash, S.payload) + `; + +let sim: BigQuerySimulator; + +beforeEach(() => { sim = new BigQuerySimulator(); }); +afterEach(() => resetAdapters()); + +describe("the BigQuery simulator models window-scoped MERGE matching", () => { + it("UPDATES a row inside the window", async () => { + sim.defineTable("Target", COLUMNS, [row("0x01", "2026-08-10T00:00:00.000Z")]); + sim.defineTable("Staging", COLUMNS, [row("0x01", "2026-08-11T00:00:00.000Z", { payload: "v2" })]); + + await sim.query({ query: MERGE_SQL("2026-07-01 00:00:00", "2026-10-01 00:00:00") }); + + expect(sim.rowsOf("Target")).toHaveLength(1); + expect(sim.rowsOf("Target")[0].payload).toBe("v2"); + }); + + it("INSERTS a duplicate when the same key sits outside the window", async () => { + sim.defineTable("Target", COLUMNS, [row("0x01", "2026-05-02T00:00:00.000Z")]); + sim.defineTable("Staging", COLUMNS, [row("0x01", "2026-08-11T00:00:00.000Z", { payload: "v2" })]); + + await sim.query({ query: MERGE_SQL("2026-07-01 00:00:00", "2026-10-01 00:00:00") }); + + expect(sim.rowsOf("Target")).toHaveLength(2); + expect(sim.distinctKeys("Target", ["chain_id", "tx_hash", "log_index"]).size).toBe(1); + }); + + it("does not read the UPDATE SET clause as part of the merge key", async () => { + // `T.payload = S.payload` appears in the UPDATE clause. A naive regex over the whole + // statement would treat payload as a key column, which would make the R-XPART test pass for + // the wrong reason. + sim.defineTable("Target", COLUMNS, [row("0x01", "2026-08-10T00:00:00.000Z", { payload: "old" })]); + sim.defineTable("Staging", COLUMNS, [row("0x01", "2026-08-11T00:00:00.000Z", { payload: "new" })]); + + await sim.query({ query: MERGE_SQL("2026-07-01 00:00:00", "2026-10-01 00:00:00") }); + + expect(sim.rowsOf("Target")).toHaveLength(1); + }); + + it("models snapshot isolation, so two overlapping MERGEs both insert", async () => { + sim.defineTable("Target", COLUMNS, []); + sim.defineTable("Staging", COLUMNS, [row("0x01", "2026-08-11T00:00:00.000Z")]); + sim.onMergeSnapshotTaken = rendezvous(2); + + const sql = MERGE_SQL("2026-07-01 00:00:00", "2026-10-01 00:00:00"); + await Promise.all([sim.query({ query: sql }), sim.query({ query: sql })]); + + expect(sim.rowsOf("Target")).toHaveLength(2); + }); + + it("models serialisation, so two sequential MERGEs leave one row", async () => { + sim.defineTable("Target", COLUMNS, []); + sim.defineTable("Staging", COLUMNS, [row("0x01", "2026-08-11T00:00:00.000Z")]); + + const sql = MERGE_SQL("2026-07-01 00:00:00", "2026-10-01 00:00:00"); + await sim.query({ query: sql }); + await sim.query({ query: sql }); + + expect(sim.rowsOf("Target")).toHaveLength(1); + }); + + it("REFUSES a statement it does not model rather than answering it", async () => { + await expect( + sim.query({ query: "SELECT something_novel FROM `p.d.Target` WHERE 1 = 1" }) + ).rejects.toThrow(/SIM_UNRECOGNISED_STATEMENT/); + }); + + it("binds an INSERT by the @names in its VALUES clause, not by parameter order", async () => { + sim.defineTable("Cover", ["a", "b"], []); + await sim.query({ + query: "INSERT INTO `p.d.Cover` (a, b) VALUES (@second, @first)", + params: { first: "F", second: "S" }, + }); + expect(sim.rowsOf("Cover")[0]).toEqual({ a: "S", b: "F" }); + }); + + it("loads NDJSON through the table handle the way a staging load does", async () => { + const dir = mkdtempSync(join(tmpdir(), "sim-load-")); + const file = join(dir, "rows.ndjson"); + writeFileSync(file, [JSON.stringify(row("0x01", "2026-08-11T00:00:00.000Z"))].join("\n")); + + await sim.dataset("d").table("Staging").load(file, { + sourceFormat: "NEWLINE_DELIMITED_JSON", + writeDisposition: "WRITE_TRUNCATE", + schema: { fields: COLUMNS.map((name) => ({ name })) }, + }); + + expect(sim.rowsOf("Staging")).toHaveLength(1); + const [meta] = await sim.dataset("d").table("Staging").getMetadata(); + expect(meta.schema?.fields?.map((f) => f.name)).toEqual(COLUMNS); + rmSync(dir, { recursive: true, force: true }); + }); +}); + +describe("the wire recorder captures the request envelope", () => { + it("records the method, params and verbatim body of every call", async () => { + const recorder = makeWireRecorder({ answers: { eth_blockNumber: "0x10" } }); + setRpcTransport(recorder.transport); + + const r = await rpcCall("https://example.invalid/rpc", "eth_blockNumber", []); + + expect(r.ok).toBe(true); + expect(r.result).toBe("0x10"); + expect(recorder.of("eth_blockNumber")).toHaveLength(1); + expect(recorder.calls[0].url).toBe("https://example.invalid/rpc"); + expect(recorder.calls[0].body).toContain('"method":"eth_blockNumber"'); + }); + + it("surfaces an unanswered method as an error rather than letting the call look successful", async () => { + const recorder = makeWireRecorder({ answers: {} }); + setRpcTransport(recorder.transport); + // `rpcCall` converts a thrown transport error into { ok: false }, which is its contract, so + // the recorder's refusal arrives as a counted error and never as an empty result. + const r = await rpcCall("https://example.invalid/rpc", "eth_chainId", []); + expect(r.ok).toBe(false); + expect(r.error).toMatch(/WIRE_NO_ANSWER/); + }); + + it("turns a configured failure into a non-ok HTTP response, which rpcCall counts as an error", async () => { + const recorder = makeWireRecorder({ + answers: { eth_blockNumber: "0x10" }, + failWith: { "https://down.invalid/rpc": 500 }, + }); + setRpcTransport(recorder.transport); + + const r = await rpcCall("https://down.invalid/rpc", "eth_blockNumber", []); + expect(r.ok).toBe(false); + expect(r.error).toMatch(/HTTP_500/); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/index-reader.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/index-reader.test.ts new file mode 100644 index 0000000..d45837e --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/index-reader.test.ts @@ -0,0 +1,222 @@ +/** + * The HyperSync index reader, exercised for real. + * + * WHY THIS FILE EXISTS. `setReaderOverride` replaces the WHOLE reader, so every test that used it + * -- which was all of them -- flew straight over `hypersync.ts`. The module measured 7.10 percent + * statements with a passing suite, and the parts nobody reached are not incidental: chunk + * planning, the bounded retry, the SHORT-COLLECTION refusal, empty-chunk tracking, and the + * rollback-guard forwarding that half of SA-C23a depends on. A reader-policy unit that leaves the + * index reader untested has tested its policy against a stub of itself. + * + * `setWorkerRunner` replaces one request/response and nothing else, so what runs below is the + * real chunking and the real retry policy against a scripted worker. + */ + +import { describe, it, expect, afterEach } from "vitest"; +import { fetchRange, getChainTip, hasHypersync } from "../../src/hypersync.js"; +import { NETWORKS, CONFIG } from "../../src/config.js"; +import { setWorkerRunner, resetAdapters } from "../../src/adapters.js"; +import { hash32 } from "../helpers/fixtures.js"; +import type { ChunkResult } from "../../src/types.js"; + +const XDC = NETWORKS.XDC; +const FUSE = NETWORKS.FUSE; + +afterEach(() => resetAdapters()); + +/** A worker that answers `collect` with a scripted result, recording every request it saw. */ +function scriptedWorker(reply: (req: any, callNumber: number) => Record) { + const requests: any[] = []; + setWorkerRunner(async (request) => { + requests.push(request); + return reply(request, requests.length); + }); + return requests; +} + +function okCollect(req: any, logs: any[] = []): Record { + return { + ok: true, ms: 1, + logs, transactions: [], blocks: [], + nextBlock: req.toBlock, archiveHeight: req.toBlock + 500, rollbackGuard: null, + }; +} + +function logAt(blockNumber: number, address: string): any { + return { + blockNumber, blockHash: hash32(`b${blockNumber}`), transactionHash: hash32(`t${blockNumber}`), + transactionIndex: 0, logIndex: 0, address, data: "0x", + topics: [hash32("t0")], removed: false, + }; +} + +const ADDR = "0x22867567e2d80f2049200e25c6f31cb6ec2f0faf"; + +describe("the index reader plans chunks from the chain's own chunk size", () => { + it("splits an inclusive range into the configured chunk size and covers it exactly", async () => { + const requests = scriptedWorker((req) => okCollect(req)); + const seen: ChunkResult[] = []; + + const result = await fetchRange(XDC, [ADDR], 1_000, 1_000 + XDC.chunkBlocks * 3 - 1, + async (c) => { seen.push(c); }); + + expect(requests).toHaveLength(3); + expect(result.chunksPlanned).toBe(3); + expect(result.chunksOk).toBe(3); + expect(result.complete).toBe(true); + // The worker takes an EXCLUSIVE upper bound; the chunk reports an inclusive one. An off-by-one + // here loses one block per chunk, silently, forever. + expect(seen.map((c) => [c.fromBlock, c.toBlock])).toEqual([ + [1_000, 1_000 + XDC.chunkBlocks - 1], + [1_000 + XDC.chunkBlocks, 1_000 + XDC.chunkBlocks * 2 - 1], + [1_000 + XDC.chunkBlocks * 2, 1_000 + XDC.chunkBlocks * 3 - 1], + ]); + expect(requests.map((r) => r.toBlock)).toEqual(seen.map((c) => c.toBlock + 1)); + }); + + it("passes every address to the worker in one request, which is what makes batching possible", async () => { + const other = "0x21eac3fe218307bee0463f77ebca3b50f452c0ce"; + const requests = scriptedWorker((req) => okCollect(req)); + + await fetchRange(XDC, [ADDR, other], 1_000, 1_999, async () => { /* nothing to do */ }); + + expect(requests).toHaveLength(1); + expect(requests[0].addresses).toEqual([ADDR, other]); + }); + + it("sends the chain's own index url, not a default", async () => { + const requests = scriptedWorker((req) => okCollect(req)); + + await fetchRange(XDC, [ADDR], 1_000, 1_999, async () => { /* nothing to do */ }); + + expect(requests[0].url).toBe(XDC.readers.hypersyncUrl); + }); +}); + +describe("a short collection is a failure, not a result", () => { + it("refuses a chunk whose nextBlock falls below the range it was asked for", async () => { + // Without this check a truncated range is indistinguishable from an empty one, and an empty + // one advances the frontier over blocks nobody read. + scriptedWorker((req) => ({ ...okCollect(req), nextBlock: req.toBlock - 10 })); + const seen: ChunkResult[] = []; + + const result = await fetchRange(XDC, [ADDR], 1_000, 1_999, async (c) => { seen.push(c); }); + + expect(result.complete).toBe(false); + expect(result.skipped).toEqual([[1_000, 1_999]]); + expect(result.chunksOk).toBe(0); + expect(seen, "a refused chunk must never reach the writer").toHaveLength(0); + expect(result.errors.join(" ")).toContain("SHORT_COLLECTION"); + }); + + it("reports EVERY skipped chunk, not the first one", async () => { + // Nine skipped chunks reported as three is a defect this project has already shipped once. + scriptedWorker(() => ({ ok: false, error: "simulated worker failure", ms: 1 })); + + const result = await fetchRange(XDC, [ADDR], 1_000, 1_000 + XDC.chunkBlocks * 3 - 1, + async () => { /* nothing to do */ }); + + expect(result.skipped).toHaveLength(3); + expect(result.chunksPlanned).toBe(3); + expect(result.chunksOk).toBe(0); + expect(result.complete).toBe(false); + }); + + it("bounds its retries by the configured count and then gives up on the chunk", async () => { + // Asserting "a retry happens" would be asserting the test environment, which pins + // HYPERSYNC_RETRIES to 1. The real property is that the count is BOUNDED and that exhausting + // it produces a recorded skip rather than an unbounded loop or a silent empty chunk. + let calls = 0; + setWorkerRunner(async () => { + calls += 1; + return { ok: false, error: "simulated persistent failure", ms: 1 }; + }); + + const result = await fetchRange(XDC, [ADDR], 1_000, 1_999, async () => { /* nothing to do */ }); + + expect(calls).toBe(CONFIG.HYPERSYNC_RETRIES); + expect(result.complete).toBe(false); + expect(result.skipped).toEqual([[1_000, 1_999]]); + }); +}); + +describe("what the reader tells the pipeline about a range", () => { + it("records a chunk with no logs as an empty chunk, which is a negative to confirm", async () => { + scriptedWorker((req) => okCollect(req)); + + const result = await fetchRange(XDC, [ADDR], 1_000, 1_999, async () => { /* nothing to do */ }); + + expect(result.emptyChunks).toEqual([[1_000, 1_999]]); + expect(result.logsSeen).toBe(0); + }); + + it("does not record a chunk that returned logs as empty", async () => { + scriptedWorker((req) => okCollect(req, [logAt(1_100, ADDR)])); + + const result = await fetchRange(XDC, [ADDR], 1_000, 1_999, async () => { /* nothing to do */ }); + + expect(result.emptyChunks).toEqual([]); + expect(result.logsSeen).toBe(1); + }); + + it("forwards the rollback guard the worker reported, which is half of SA-C23a", async () => { + // PR 71 fixed the worker dropping it. This asserts the reader still carries it up, because + // the status decision in pipeline.ts is now built on it. + const guard = { + blockNumber: 990, timestamp: 0, hash: hash32("rbg"), + firstBlockNumber: 990, firstParentHash: hash32("rbp"), + }; + scriptedWorker((req) => ({ ...okCollect(req), rollbackGuard: guard })); + + const result = await fetchRange(XDC, [ADDR], 1_000, 1_999, async () => { /* nothing to do */ }); + + expect(result.rollbackGuards).toEqual([guard]); + }); + + it("reports one source, because one index is one source however good it is", async () => { + scriptedWorker((req) => okCollect(req)); + + const result = await fetchRange(XDC, [ADDR], 1_000, 1_999, async () => { /* nothing to do */ }); + + expect(result.enumeratingSources).toBe(1); + expect(result.sourceKind).toBe("index"); + expect(result.sourceId).toContain("hypersync:"); + }); + + it("lowercases identifiers at the boundary, because two spellings of one hash are two keys", async () => { + scriptedWorker((req) => okCollect(req, [logAt(1_100, ADDR.toUpperCase().replace("0X", "0x"))])); + const seen: ChunkResult[] = []; + + await fetchRange(XDC, [ADDR], 1_000, 1_999, async (c) => { seen.push(c); }); + + expect(seen[0].logs[0].address).toBe(ADDR); + }); +}); + +describe("the chain tip is read, never guessed", () => { + it("returns the height the index reported", async () => { + scriptedWorker(() => ({ ok: true, height: 123_456, ms: 1 })); + + expect(await getChainTip(XDC)).toBe(123_456); + }); + + it("returns null rather than a guess when the index cannot answer", async () => { + // A guessed tip is how a range silently becomes shorter than the caller believes. + scriptedWorker(() => ({ ok: false, error: "simulated failure", ms: 1 })); + + expect(await getChainTip(XDC)).toBeNull(); + }); + + it("refuses a height that parses to NaN, because NaN IS a number", async () => { + scriptedWorker(() => ({ ok: true, height: Number.NaN, ms: 1 })); + + expect(await getChainTip(XDC)).toBeNull(); + }); +}); + +describe("a chain with no index is not served by this reader", () => { + it("reports Fuse as having no HyperSync index", () => { + expect(hasHypersync(FUSE)).toBe(false); + expect(hasHypersync(XDC)).toBe(true); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/oracle-verification.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/oracle-verification.test.ts new file mode 100644 index 0000000..d2bf8cc --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/oracle-verification.test.ts @@ -0,0 +1,508 @@ +/** + * oracle-verification.test.ts -- the Celo oracle, and what a verification result has to be able + * to say. + * + * THE DEFECT THESE GUARD, IN ONE SENTENCE. `runVerify` returned a boolean, so a run that compared + * 254 protocol days and matched every one, and a run that compared nothing at all, arrived at the + * CLI as the same value, and the CLI exited 0 for both. That is C4. It is the same shape as C2 one + * layer up: the type could not hold the distinction, so no amount of checking inside the function + * could produce it. + * + * THE OTHER HALF IS THE DAY KEY. Both UBIScheme contracts start their protocol day at NOON UTC -- + * measured, `periodStart()` modulo 86,400 is exactly 43,200 on Celo and on XDC. A comparison keyed + * on `DATE(block_timestamp)` therefore puts every claim made before noon on the wrong side of the + * boundary, and MEASURED on the real warehouse that is 764,706 of 2,649,450 XDC rows, 28.9 percent. + * It would not fail loudly. It would produce a plausible near-miss on every single day. + * + * WHY THERE IS A PURPOSE-BUILT WAREHOUSE STAND-IN HERE. The shared `BigQuerySimulator` models the + * MERGE semantics two write-path defects depend on and refuses any statement it does not model, + * which is the right behaviour and is why it is not extended here. What these tests depend on is a + * different single semantic: which protocol day a stored row is counted under. So the stand-in + * below computes the two reconciliation aggregates from rows, with the DAY KEY AS A PARAMETER, + * which is what makes the calendar key falsifiable rather than merely described. It answers only + * the statements it recognises and throws on anything else, for the same reason the shared + * simulator does: a plausible empty answer is a machine for manufacturing false greens. + */ + +import { describe, it, expect, beforeEach, afterEach } from "vitest"; +import { keccak256, toHex } from "viem"; +import { NETWORKS, ORACLES, oracleFor, oraclesFor } from "../../src/config.js"; +import { dayOf, dayWindow } from "../../src/oracle.js"; +import { runVerify, topic0Of } from "../../src/reconcile.js"; +import { ensureInfraTables } from "../../src/bq.js"; +import { readOnlyExitCode } from "../../src/outcome.js"; +import { setBigQueryClient, setRpcTransport, resetAdapters } from "../../src/adapters.js"; +import type { BigQueryClientLike } from "../../src/adapters.js"; +import { makeWireRecorder } from "../helpers/wire-recorder.js"; + +const CELO_UBISCHEME = "0x43d72ff17701b2da814620735c39c620ce0ea4a1"; +const CELO_PERIOD_START = 1_677_672_000; // MEASURED on chain: 2023-03-01T12:00:00Z +const XDC_PERIOD_START = 1_761_393_600; // MEASURED on chain: 2025-10-25T12:00:00Z +const UBICLAIMED = "UBIClaimed(address,uint256)"; + +/** Computed, never recalled. A recalled selector is a guess with four bytes of confidence. */ +const sel = (sig: string) => keccak256(toHex(sig)).slice(0, 10); +const SEL = { + periodStart: sel("periodStart()"), + currentDay: sel("currentDay()"), + getClaimerCount: sel("getClaimerCount(uint256)"), + getClaimAmount: sel("getClaimAmount(uint256)"), +}; +const word = (n: bigint | number) => BigInt(n).toString(16).padStart(64, "0"); +const hexWord = (n: bigint | number) => "0x" + word(n); + +// --------------------------------------------------------------------------- the day keys + +/** What the shipped SQL computes: DIV(UNIX_SECONDS(ts) - periodStart, 86400). */ +const protocolDayKey = (unixSeconds: number, periodStart: number) => dayOf(unixSeconds, periodStart); + +/** + * What a calendar key computes: whole UTC days since the calendar date periodStart falls on. + * This is the `DATE(block_timestamp)` shape, expressed so a test can run the comparison under it. + */ +const calendarDayKey = (unixSeconds: number, periodStart: number) => { + const midnightOfPeriodStart = Math.floor(periodStart / 86_400) * 86_400; + return Math.floor((unixSeconds - midnightOfPeriodStart) / 86_400); +}; + +// --------------------------------------------------------------------------- the stand-in + +interface StoredLog { tsSeconds: number; amountRaw: bigint; txHash: string; logIndex: number } + +interface WarehouseOptions { + rows: StoredLog[]; + periodStart: number; + /** Swap this for `calendarDayKey` to watch the comparison break. */ + dayKey: (unixSeconds: number, periodStart: number) => number; +} + +/** Rows loaded into OracleReconciliation, so the stored comparison is inspectable. */ +const recorded: Record[] = []; +/** Every statement the SHIPPED code emitted, so a test can assert on the real SQL. */ +const emittedSql: string[] = []; + +function warehouse(options: WarehouseOptions): BigQueryClientLike { + const key = (r: StoredLog) => options.dayKey(r.tsSeconds, options.periodStart); + return { + async query(request) { + const sql = request.query; + emittedSql.push(sql); + + if (/MIN\(block_timestamp\) AS lo/i.test(sql)) { + if (options.rows.length === 0) return [[{ lo: null, hi: null }]]; + const ts = options.rows.map((r) => r.tsSeconds); + return [[{ + lo: new Date(Math.min(...ts) * 1000).toISOString(), + hi: new Date(Math.max(...ts) * 1000).toISOString(), + }]]; + } + + if (/protocol_day/i.test(sql)) { + const p = (request.params ?? {}) as Record; + const byDay = new Map(); + for (const r of options.rows) { + const d = key(r); + if (d < Number(p.firstDay) || d > Number(p.lastDay)) continue; + const cur = byDay.get(d) ?? { n: 0, amount: 0n }; + byDay.set(d, { n: cur.n + 1, amount: cur.amount + r.amountRaw }); + } + return [[...byDay.entries()].map(([d, v]) => ({ + protocol_day: d, stored_rows: v.n, distinct_rows: v.n, + unreadable_rows: 0, amount_raw: v.amount.toString(), + }))]; + } + + if (/MAX\(block_timestamp\)\s+AS\s+max_ts/i.test(sql)) return [[{ max_ts: null }]]; + + throw new Error( + `STANDIN_UNRECOGNISED_STATEMENT: answering this with an empty result would manufacture a ` + + `false green. Statement:\n${sql}` + ); + }, + dataset() { + return { + table() { + return { + async load(source: string) { + // `recordReconciliation` writes newline-delimited JSON to a temp file and loads it. + const { readFileSync } = await import("node:fs"); + for (const line of readFileSync(source, "utf8").split("\n")) { + if (line.trim()) recorded.push(JSON.parse(line)); + } + return []; + }, + async getMetadata() { return [{}] as any; }, + }; + }, + }; + }, + }; +} + +/** + * A chain that answers exactly the four getters this unit reads, from a ledger the test states. + * Every Celo archive endpoint gets the same answer, which is what `consensusRead` requires. + */ +function chain(options: { periodStart: number; currentDay: number; ledger: Map }) { + return makeWireRecorder({ + answers: { + eth_blockNumber: () => "0x" + (30_000_000).toString(16), + eth_call: (params: unknown[]) => { + const data = String((params[0] as { data: string }).data); + if (data.startsWith(SEL.periodStart)) return hexWord(options.periodStart); + if (data.startsWith(SEL.currentDay)) return hexWord(options.currentDay); + const day = Number(BigInt("0x" + data.slice(10))); + const entry = options.ledger.get(day) ?? { claimers: 0, amountRaw: 0n }; + if (data.startsWith(SEL.getClaimerCount)) return hexWord(entry.claimers); + if (data.startsWith(SEL.getClaimAmount)) return hexWord(entry.amountRaw); + throw new Error(`unexpected eth_call data ${data}`); + }, + }, + }); +} + +/** Noon UTC on protocol day `d`, i.e. the exact instant the day opens. */ +const dayStart = (d: number, periodStart: number) => dayWindow(d, periodStart)[0]; + +beforeEach(() => { recorded.length = 0; emittedSql.length = 0; }); +afterEach(() => { resetAdapters(); setBigQueryClient(null); }); + +// ========================================================================================= +describe("the Celo oracle exists and is bound to what the contract actually says", () => { + it("resolves an oracle for Celo, which ORACLES could not do before", () => { + const celo = oracleFor(NETWORKS.CELO.chainId, CELO_UBISCHEME); + expect( + celo, + `Celo is half the ingestion scope and ORACLES held two entries, BOTH XDC. Without a Celo ` + + `entry no Celo figure can ever be reconciled against the chain, and a chain with no oracle ` + + `cannot return clean, so Celo verify would be permanently nonzero for a reason nobody could fix.` + ).toBeDefined(); + expect(celo!.kind).toBe("ubi_daily"); + expect(oraclesFor([NETWORKS.CELO]).length).toBeGreaterThan(0); + }); + + it("carries the periodStart the contract returns, to the second", () => { + const celo = oracleFor(NETWORKS.CELO.chainId, CELO_UBISCHEME)!; + expect(celo.periodStart).toBe(CELO_PERIOD_START); + expect(new Date(celo.periodStart * 1000).toISOString()).toBe("2023-03-01T12:00:00.000Z"); + }); + + it("puts every UBI oracle's day boundary at noon UTC, which is the whole reason the key matters", () => { + for (const o of ORACLES.filter((x) => x.kind === "ubi_daily")) { + expect( + o.periodStart % 86_400, + `${o.network.name} ${o.address} starts its protocol day ${o.periodStart % 86_400}s after ` + + `midnight UTC. Every UBIScheme in scope was MEASURED at exactly 43200, and a day boundary ` + + `taken from a config file rather than the contract is a claim about a config file.` + ).toBe(43_200); + } + }); + + it("binds on a topic0 computed from the signature, matching the shipped event surface", () => { + // The seed is an INDEPENDENT source for this value: it was recomputed from the verified ABI + // on 2,823 of 2,823 rows. Agreement between the computed selector and the seed is the check. + expect(topic0Of(UBICLAIMED)).toBe("0x89ed24731df6b066e4c5186901fffdba18cd9a10f07494aff900bdee260d1304"); + for (const o of ORACLES.filter((x) => x.kind === "ubi_daily")) { + expect(o.eventSignature).toBe(UBICLAIMED); + // claimer is the only indexed parameter, so amount is word 0 of log_data. + expect(o.amountWordIndex).toBe(0); + } + }); +}); + +// ========================================================================================= +describe("C4: a verification result says what was compared, not just whether it went well", () => { + it("returns clean ONLY after actually comparing something", async () => { + const day = 900; + const ledger = new Map([[day, { claimers: 2, amountRaw: 300n }]]); + setRpcTransport(chain({ periodStart: CELO_PERIOD_START, currentDay: 1000, ledger }).transport); + setBigQueryClient(warehouse({ + periodStart: CELO_PERIOD_START, + dayKey: protocolDayKey, + rows: [ + { tsSeconds: dayStart(day, CELO_PERIOD_START) + 60, amountRaw: 100n, txHash: "0xa", logIndex: 0 }, + { tsSeconds: dayStart(day, CELO_PERIOD_START) + 120, amountRaw: 200n, txHash: "0xb", logIndex: 0 }, + ], + })); + + const report = await runVerify({ mode: "verify", chains: ["CELO"], days: [day] }); + + expect(report.outcome).toBe("clean"); + expect(report.comparedUnits).toBe(1); + expect(report.matchedUnits).toBe(1); + expect(report.discrepantUnits).toBe(0); + expect(readOnlyExitCode(report.outcome)).toBe(0); + }); + + it("does not return clean when the contract holds a ledger and the warehouse holds nothing", async () => { + // This is the LIVE state of Celo in this warehouse: the oracle resolves, the contract answers, + // and not one claim row has been ingested. Before the fix, `reconcileDaily` refused to run at + // all without a warehouse day span, returned null, and the run still ended clean. + const day = 900; + const ledger = new Map([[day, { claimers: 11_743, amountRaw: 1_356_243_042_837_526_291_314_194n }]]); + setRpcTransport(chain({ periodStart: CELO_PERIOD_START, currentDay: 1000, ledger }).transport); + setBigQueryClient(warehouse({ periodStart: CELO_PERIOD_START, dayKey: protocolDayKey, rows: [] })); + + const report = await runVerify({ mode: "verify", chains: ["CELO"], days: [day] }); + + expect( + report.outcome, + `The contract says 11,743 people claimed on protocol day ${day} and the warehouse holds zero ` + + `rows. That is a finding, and an empty warehouse is a legitimate side of a comparison.` + ).toBe("finding"); + expect(report.comparedUnits).toBe(1); + expect(report.matchedUnits).toBe(0); + expect(report.discrepantUnits).toBe(1); + expect(report.checks[0].detail).toContain("0/1"); + expect(readOnlyExitCode(report.outcome)).toBe(1); + }); + + it("separates a day that disagrees from a day nobody could look at", async () => { + const day = 900; + const ledger = new Map([[day, { claimers: 3, amountRaw: 300n }]]); + setRpcTransport(chain({ periodStart: CELO_PERIOD_START, currentDay: 1000, ledger }).transport); + setBigQueryClient(warehouse({ + periodStart: CELO_PERIOD_START, + dayKey: protocolDayKey, + rows: [{ tsSeconds: dayStart(day, CELO_PERIOD_START) + 60, amountRaw: 100n, txHash: "0xa", logIndex: 0 }], + })); + + const report = await runVerify({ mode: "verify", chains: ["CELO"], days: [day] }); + + expect(report.outcome).toBe("finding"); + expect(report.discrepantUnits).toBe(1); + expect(report.unreadableUnits).toBe(0); + expect(report.checks[0].outcome).toBe("discrepant"); + }); + + it("counts a day the oracle could not be read as unreadable, which is not a pass and not a gap", async () => { + const day = 900; + // One endpoint answers and two fail, so `consensusRead` cannot reach two agreeing answers. + const recorder = makeWireRecorder({ + answers: { + eth_blockNumber: () => "0x" + (30_000_000).toString(16), + eth_call: (params: unknown[]) => { + const data = String((params[0] as { data: string }).data); + if (data.startsWith(SEL.periodStart)) return hexWord(CELO_PERIOD_START); + if (data.startsWith(SEL.currentDay)) return hexWord(1000); + return undefined; // no answer for the day getters + }, + }, + }); + setRpcTransport(recorder.transport); + setBigQueryClient(warehouse({ + periodStart: CELO_PERIOD_START, + dayKey: protocolDayKey, + rows: [{ tsSeconds: dayStart(day, CELO_PERIOD_START) + 60, amountRaw: 100n, txHash: "0xa", logIndex: 0 }], + })); + + const report = await runVerify({ mode: "verify", chains: ["CELO"], days: [day] }); + + expect( + report.outcome, + `A day the contract could not be read for is an unanswered question. Reporting it as clean ` + + `would be the same class of error as C4 itself: an absence presented as a result.` + ).not.toBe("clean"); + expect(report.unreadableUnits).toBe(1); + expect(report.matchedUnits).toBe(0); + expect(report.checks[0].outcome).toBe("unreadable"); + }); + + it("stores the per-day comparison so it can be queried afterwards", async () => { + const days = [900, 901]; + const ledger = new Map([ + [900, { claimers: 1, amountRaw: 100n }], + [901, { claimers: 5, amountRaw: 999n }], + ]); + setRpcTransport(chain({ periodStart: CELO_PERIOD_START, currentDay: 1000, ledger }).transport); + setBigQueryClient(warehouse({ + periodStart: CELO_PERIOD_START, + dayKey: protocolDayKey, + rows: [{ tsSeconds: dayStart(900, CELO_PERIOD_START) + 60, amountRaw: 100n, txHash: "0xa", logIndex: 0 }], + })); + + await runVerify({ mode: "verify", chains: ["CELO"], days }); + + expect(recorded.map((r) => r.protocol_day)).toEqual([900, 901]); + expect(recorded[0].verdict).toBe("exact"); + expect(recorded[1].verdict).toBe("missing"); + expect(recorded[1].count_gap).toBe(5); + // The amounts are carried as STRINGS, because a 24-digit raw value is past the point where a + // JavaScript number is exact and a reconciliation that is not exact is not a reconciliation. + expect(recorded[1].oracle_amount_raw).toBe("999"); + expect(recorded.every((r) => r.chain_id === NETWORKS.CELO.chainId)).toBe(true); + }); + + it("records an unreadable chain instead of letting it erase the whole run", async () => { + // A quorum failure on one chain used to throw out of `runVerify` and abort the command, so a + // completed comparison on another chain would be destroyed on the way out. MEASURED on Celo + // this session: two of three archive endpoints were unavailable at once and `pinBlock` + // refused, which is correct and must not also be fatal. + setRpcTransport(makeWireRecorder({ answers: { eth_blockNumber: () => undefined } }).transport); + setBigQueryClient(warehouse({ periodStart: CELO_PERIOD_START, dayKey: protocolDayKey, rows: [] })); + + const report = await runVerify({ mode: "verify", chains: ["CELO"], days: [900] }); + + expect(report.outcome).toBe("nothing_to_check"); + expect(report.unreadableUnits).toBe(1); + expect(report.checks[0].outcome).toBe("unreadable"); + expect(report.checks[0].detail).toContain("could not be read"); + expect(readOnlyExitCode(report.outcome)).toBe(2); + }); +}); + +// ========================================================================================= +describe("a dataset whose reconciliation table predates the chain dimension fails at startup", () => { + /** + * A dataset whose tables have exactly the columns the shipped DDL declares, except for the ones + * the test overrides. + * + * The schemas are DERIVED FROM THE DDL the code itself issues rather than transcribed here. A + * first version of this test hand-listed them, missed two columns on an unrelated table, and + * failed for a reason that had nothing to do with what it was testing -- and it would have + * broken again the next time a column was added. + */ + function datasetAsDeclared(overrides: Record): BigQueryClientLike { + const declared: Record = {}; + return { + async query(request) { + const m = /CREATE TABLE IF NOT EXISTS\s+(\S+)\s*\(([\s\S]*?)\n\s*\)/i.exec(request.query); + if (m) { + const tableId = m[1].replace(/`/g, "").split(".").pop()!; + declared[tableId] = m[2].split("\n") + .map((line) => /^\s*(\w+)\s+\w+/.exec(line)?.[1]) + .filter((c): c is string => !!c); + } + return [[]]; + }, + dataset() { + return { + table(tableId: string) { + return { + async load() { return []; }, + async getMetadata() { + const names = overrides[tableId] ?? declared[tableId] ?? []; + return [{ schema: { fields: names.map((name) => ({ name })) } }] as any; + }, + }; + }, + }; + }, + }; + } + + // The 14 columns the production copy actually carries, measured. Note `table_id` standing where + // `chain_id` and `contract_address` belong: it predates the second chain. + const LEGACY_RECONCILIATION = [ + "run_id", "network", "table_id", "protocol_day", "oracle_block", "oracle_count", + "oracle_amount_raw", "warehouse_stored", "warehouse_distinct", "warehouse_amount_raw", + "count_gap", "amount_gap_raw", "verdict", "checked_at", + ]; + + it("names the missing columns at startup rather than failing inside the load", async () => { + setBigQueryClient(datasetAsDeclared({ OracleReconciliation: LEGACY_RECONCILIATION })); + + await expect( + ensureInfraTables(), + `A create-if-absent cannot migrate a table that already exists, so a dataset carrying the ` + + `pre-chain-dimension reconciliation table keeps it forever. Without this check the run ` + + `reaches the load step -- after reading a year of contract state -- and fails naming a ` + + `column instead of the migration.` + ).rejects.toThrow(/SCHEMA_MISMATCH: OracleReconciliation has no column\(s\).*chain_id/); + }); + + it("passes on a dataset that carries the shape the DDL declares", async () => { + setBigQueryClient(datasetAsDeclared({})); + await expect(ensureInfraTables()).resolves.toBeUndefined(); + }); +}); + +// ========================================================================================= +describe("the protocol day is the contract's, not the calendar's", () => { + it("assigns a claim made before noon to a different day under each key", () => { + // 09:00 UTC on the calendar date that protocol day 900 opens. The protocol day that contains + // this instant opened at noon the PREVIOUS calendar date. + const beforeNoon = dayStart(900, CELO_PERIOD_START) - 3 * 3_600; + expect(protocolDayKey(beforeNoon, CELO_PERIOD_START)).toBe(899); + expect(calendarDayKey(beforeNoon, CELO_PERIOD_START)).toBe(900); + + const afterNoon = dayStart(900, CELO_PERIOD_START) + 3 * 3_600; + expect(protocolDayKey(afterNoon, CELO_PERIOD_START)).toBe(900); + expect(calendarDayKey(afterNoon, CELO_PERIOD_START)).toBe(900); + }); + + it("splits one protocol day across two calendar days on both chains in scope", () => { + for (const periodStart of [CELO_PERIOD_START, XDC_PERIOD_START]) { + const [open] = dayWindow(500, periodStart); + const beforeMidnight = open + 6 * 3_600; // 18:00 UTC, same calendar date + const afterMidnight = open + 18 * 3_600; // 06:00 UTC, the NEXT calendar date + expect(protocolDayKey(beforeMidnight, periodStart)).toBe(500); + expect(protocolDayKey(afterMidnight, periodStart)).toBe(500); + expect(new Date(beforeMidnight * 1000).toISOString().slice(0, 10)) + .not.toBe(new Date(afterMidnight * 1000).toISOString().slice(0, 10)); + } + }); + + it("RECONCILES EXACTLY on the protocol day key and FAILS on the calendar key, same rows", async () => { + // The discriminator. Two claims on protocol day 900, one either side of midnight UTC, which + // is the ordinary case rather than an edge: a protocol day always spans two calendar dates. + // The contract's own ledger says day 900 had two claimers and 300 raw units. + const open = dayStart(900, CELO_PERIOD_START); + const rows: StoredLog[] = [ + { tsSeconds: open + 6 * 3_600, amountRaw: 100n, txHash: "0xa", logIndex: 0 }, + { tsSeconds: open + 18 * 3_600, amountRaw: 200n, txHash: "0xb", logIndex: 0 }, + ]; + const ledger = new Map([[900, { claimers: 2, amountRaw: 300n }]]); + + setRpcTransport(chain({ periodStart: CELO_PERIOD_START, currentDay: 1000, ledger }).transport); + setBigQueryClient(warehouse({ periodStart: CELO_PERIOD_START, dayKey: protocolDayKey, rows })); + const onProtocolDay = await runVerify({ mode: "verify", chains: ["CELO"], days: [900] }); + + resetAdapters(); + setRpcTransport(chain({ periodStart: CELO_PERIOD_START, currentDay: 1000, ledger }).transport); + setBigQueryClient(warehouse({ periodStart: CELO_PERIOD_START, dayKey: calendarDayKey, rows })); + const onCalendarDay = await runVerify({ mode: "verify", chains: ["CELO"], days: [900] }); + + expect(onProtocolDay.outcome).toBe("clean"); + expect(onProtocolDay.matchedUnits).toBe(1); + + expect( + onCalendarDay.outcome, + `Keyed on the calendar date, the same two rows and the same contract ledger do NOT ` + + `reconcile: the claim made before midnight lands on one key and the claim made after it on ` + + `another, so day 900 reports a shortfall it does not have. If this assertion cannot be made ` + + `to fail on the calendar key, the keying under test is not the contract's.` + ).toBe("finding"); + expect(onCalendarDay.matchedUnits).toBe(0); + expect(onCalendarDay.discrepantUnits).toBe(1); + }); + + it("emits SQL that derives the day from periodStart, and never from the row's calendar date", async () => { + // The two tests above prove the SEMANTICS discriminate. This one binds that to the statement + // the SHIPPED code actually sends, so a future rewrite to `DATE(block_timestamp)` -- which + // would look tidier and read more naturally -- fails here instead of quietly producing a + // near-miss on every day. + const ledger = new Map([[900, { claimers: 1, amountRaw: 100n }]]); + setRpcTransport(chain({ periodStart: CELO_PERIOD_START, currentDay: 1000, ledger }).transport); + setBigQueryClient(warehouse({ + periodStart: CELO_PERIOD_START, + dayKey: protocolDayKey, + rows: [{ tsSeconds: dayStart(900, CELO_PERIOD_START) + 60, amountRaw: 100n, txHash: "0xa", logIndex: 0 }], + })); + + await runVerify({ mode: "verify", chains: ["CELO"], days: [900] }); + + const dayQuery = emittedSql.find((s) => /protocol_day/i.test(s)); + expect(dayQuery, "the reconciliation never issued its per-day aggregate").toBeDefined(); + expect( + dayQuery, + `The per-day aggregate must subtract periodStart before dividing into days. Without that ` + + `subtraction the key is a calendar day, and both contracts open their day at noon UTC.` + ).toMatch(/DIV\(UNIX_SECONDS\(\w*\.?block_timestamp\) - @periodStart, 86400\)/); + expect( + dayQuery, + `A DATE(block_timestamp) key silently reassigns every claim made before noon. MEASURED on ` + + `the real warehouse: 764,706 of 2,649,450 XDC rows, 28.9 percent.` + ).not.toMatch(/DATE\(\w*\.?block_timestamp\)/); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/plan-and-arguments.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/plan-and-arguments.test.ts new file mode 100644 index 0000000..bf15ed2 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/plan-and-arguments.test.ts @@ -0,0 +1,301 @@ +/** + * Plan mode and argument validation. Plan tasks 7, 8 and 9. + * + * TWO THINGS THIS FILE HAS TO PROVE, and they are different in kind. + * + * 1. That `plan` is genuinely PURE. Not "does not appear to touch the network" but "cannot": + * the BigQuery client and the RPC transport are both replaced with doubles that THROW on + * any use, and the plan is built anyway. A purity claim that rests on reading the code is + * the same class of evidence as a completeness claim that rests on a scan's own report. + * + * 2. That every argument shape plan task 7 names is REFUSED, each with its own assertion, and + * that each refusal carries exit code 2. A parser that rejects the wrong thing for the + * right reason still lets the defect through. + */ + +import { describe, it, expect, afterEach } from "vitest"; +import { parseArgs, CliUsageError } from "../../src/index.js"; +import { buildPlan, renderPlan, releaseScopeChains } from "../../src/plan.js"; +import { RELEASE_SCOPE_FREEZE } from "../../src/control-plane/releaseScope.js"; +import { RAW_LOGS_TABLE, TRANSACTIONS_TABLE, NETWORKS } from "../../src/config.js"; +import { MAX_CAPTURES_CEILING, MAX_CAPTURE_BLOCKS_CEILING } from "../../src/budget.js"; +import { setBigQueryClient, setRpcTransport, setReaderOverride, resetAdapters } from "../../src/adapters.js"; + +afterEach(() => resetAdapters()); + +/** Any use at all is a failure, so the double throws instead of answering. */ +const EXPLODING_BQ = { + query: () => { throw new Error("PLAN_MODE_TOUCHED_BIGQUERY"); }, + dataset: () => { throw new Error("PLAN_MODE_TOUCHED_BIGQUERY"); }, +} as any; + +const EXPLODING_RPC = (() => { throw new Error("PLAN_MODE_TOUCHED_THE_NETWORK"); }) as any; + +const EXPLODING_READER = (() => { throw new Error("PLAN_MODE_TOUCHED_A_CHAIN"); }) as any; + +function armTheTripwires(): void { + setBigQueryClient(EXPLODING_BQ); + setRpcTransport(EXPLODING_RPC); + setReaderOverride(EXPLODING_READER); +} + +describe("plan mode reads no chain and writes no BigQuery", () => { + it("builds a complete plan for an explicit range with every edge armed to throw", () => { + armTheTripwires(); + + const plan = buildPlan({ + mode: "backfill", + chains: ["XDC"], + addresses: ["0x22867567e2d80f2049200e25c6f31cb6ec2f0faf"], + fromBlock: 105_201_000, + toBlock: 105_201_500, + }); + + expect(plan.outcome).toBe("complete"); + expect(plan.exitCode).toBe(0); + expect(plan.contractsPlanned).toBe(1); + // One unit per grain. A refusal has to speak about both, so a plan does too. + expect(plan.units.map((u) => u.grain).sort()).toEqual([RAW_LOGS_TABLE, TRANSACTIONS_TABLE]); + for (const u of plan.units) { + expect(u.rangeResolved).toBe(true); + expect(u.fromBlock).toBe(105_201_000); + expect(u.toBlock).toBe(105_201_500); + expect(u.spanVerdict?.allowed).toBe(true); + } + expect(renderPlan(plan)).toMatch(/PLAN \(backfill\): COMPLETE, exit 0/); + }); + + it("plans a backfill with no --from from the contract's own creation block", () => { + armTheTripwires(); + + // R8: an absence claim's lower bound is contract creation, and that is knowable from the + // seed without reading anything. The END is not, so the plan is still incomplete and still + // exits nonzero. Half a resolvable range does not make a resolvable plan. + const plan = buildPlan({ + mode: "backfill", + chains: ["XDC"], + addresses: ["0x22867567e2d80f2049200e25c6f31cb6ec2f0faf"], + }); + + expect(plan.outcome).toBe("incomplete"); + expect(plan.units[0].fromBlock).toBeGreaterThan(0); + expect(plan.units[0].toBlock).toBeNull(); + expect(plan.units[0].rangeSource).toMatch(/start from the contract's creation block \d+/); + expect(plan.units[0].rangeSource).toMatch(/end at the chain tip minus \d+ finality block/); + }); + + it("calls an unresolvable range INCOMPLETE rather than guessing it", () => { + armTheTripwires(); + + // A daily run's start comes from the coverage ledger and its end from the chain tip. Plan + // mode reads neither, so the only honest answer is that it cannot say. + const plan = buildPlan({ + mode: "daily", + chains: ["XDC"], + addresses: ["0x22867567e2d80f2049200e25c6f31cb6ec2f0faf"], + }); + + expect(plan.outcome).toBe("incomplete"); + expect(plan.exitCode).toBe(1); + expect(plan.units.every((u) => !u.rangeResolved)).toBe(true); + expect(plan.units[0].fromBlock).toBeNull(); + expect(plan.units[0].rangeSource).toMatch(/coverage frontier, which plan mode does not read/); + expect(plan.refusals.join(" ")).toMatch(/cannot be resolved without reading/); + }); + + it("reports the budget verdict rather than the refusal's consequences", () => { + armTheTripwires(); + + // Every contract on every chain, against the default limit of 12. + const plan = buildPlan({ mode: "daily" }); + + expect(plan.outcome).toBe("refused"); + expect(plan.exitCode).toBe(2); + expect(plan.runSize?.allowed).toBe(false); + expect(plan.runSize?.requested).toBeGreaterThan(plan.runSize!.limit); + expect(plan.summary.totals.refused).toBe(plan.summary.totals.planned); + expect(plan.summary.totals.completed).toBe(0); + }); + + it("refuses an explicitly named span above the absolute ceiling", () => { + armTheTripwires(); + + // Naming a range raises the ordinary 30-day limit deliberately. It does not raise the + // absolute ceiling: a span this size is a genesis-to-head read of the deepest chain in the + // release, which is A5. Phase 3 made bare backfill illegal, so without this ceiling every + // backfill would be explicit and therefore unbounded. + const plan = buildPlan({ + mode: "backfill", + chains: ["XDC"], + addresses: ["0x22867567e2d80f2049200e25c6f31cb6ec2f0faf"], + fromBlock: 1, + toBlock: MAX_CAPTURE_BLOCKS_CEILING + 1, + }); + + expect(plan.outcome).toBe("refused"); + expect(plan.exitCode).toBe(2); + expect(plan.summary.totals.refused).toBe(2); + expect(plan.refusals.join(" ")).toMatch(/absolute ceiling/); + }); + + it("allows an explicitly named span below the ceiling even above the ordinary limit", () => { + armTheTripwires(); + + const xdc = NETWORKS.XDC; + const plan = buildPlan({ + mode: "backfill", + chains: ["XDC"], + addresses: ["0x22867567e2d80f2049200e25c6f31cb6ec2f0faf"], + fromBlock: 1, + // Comfortably above 30 days of XDC blocks, comfortably below the ceiling. + toBlock: 30 * xdc.blocksPerDay * 3, + }); + + expect(plan.outcome).toBe("complete"); + expect(plan.exitCode).toBe(0); + }); +}); + +describe("plan mode takes its chain list from the frozen release scope", () => { + it("reads the scope from the freeze module rather than a list of its own", () => { + expect(releaseScopeChains()).toEqual([...RELEASE_SCOPE_FREEZE.releaseChains]); + }); + + it("never treats a chain outside the frozen scope as usable", () => { + armTheTripwires(); + // A property, not a literal list: whatever the freeze says today, nothing outside it may be + // planned. Fuse was dropped from the release after the scope was first frozen, so a test + // asserting a fixed set of chains here would have to be edited when the seed catches up. + const plan = buildPlan({ mode: "daily", maxCaptures: MAX_CAPTURES_CEILING }); + const planned = new Set(plan.units.map((u) => u.network)); + for (const chain of planned) expect(releaseScopeChains()).toContain(chain); + }); + + it("refuses a configured chain the freeze excludes, with the decision record named", () => { + armTheTripwires(); + + // Narrow the scope to XDC alone and watch every other configured chain become unsupported. + // This is the path a scope change takes through this command, exercised rather than assumed. + const narrowed = { ...RELEASE_SCOPE_FREEZE, releaseChains: ["XDC"] as const }; + const plan = buildPlan({ mode: "daily", chains: ["CELO"] }, narrowed); + + expect(plan.outcome).toBe("unsupported"); + expect(plan.exitCode).toBe(2); + expect(plan.refusals.join(" ")).toMatch(/CELO is configured but is NOT in the release scope/); + expect(plan.refusals.join(" ")).toContain(RELEASE_SCOPE_FREEZE.decisionRecord); + }); + + it("treats every configured chain as usable when the scope is not frozen", () => { + armTheTripwires(); + + // The pre-freeze state, which is legal before a scope decision exists. It must not silently + // become "everything is out of scope", which is what an unguarded `includes` would do. + const unfrozen = { ...RELEASE_SCOPE_FREEZE, frozen: false }; + const plan = buildPlan({ mode: "daily", chains: ["CELO"], maxCaptures: 500 }, unfrozen); + + expect(plan.outcome).not.toBe("unsupported"); + expect(plan.contractsPlanned).toBeGreaterThan(0); + }); + + it("renders a refused and an unsupported plan without inventing numbers it does not have", () => { + armTheTripwires(); + + const unsupported = buildPlan({ mode: "daily", chains: ["SOLANA"] }); + const rendered = renderPlan(unsupported); + expect(rendered).toMatch(/UNSUPPORTED, exit 2/); + // No chains selected and no budget verdict exists, so neither is printed as a zero. + expect(rendered).toMatch(/chains selected: \(none\)/); + expect(rendered).not.toMatch(/run-size budget/); + + // And a plan long enough to be truncated says how many it left out rather than trailing off. + const big = buildPlan({ mode: "daily", maxCaptures: MAX_CAPTURES_CEILING }); + expect(big.units.length).toBeGreaterThan(40); + expect(renderPlan(big)).toMatch(/\.\.\. \d+ more unit\(s\)/); + }); +}); + +describe("arguments plan task 7 says must be refused", () => { + function usageError(argv: string[]): CliUsageError { + try { + parseArgs(argv); + } catch (e) { + return e as CliUsageError; + } + throw new Error(`parseArgs(${JSON.stringify(argv)}) did not throw`); + } + + it("refuses an unknown chain instead of selecting nothing", () => { + const e = usageError(["daily", "--chains=SOLANA"]); + expect(e.exitCode).toBe(2); + expect(e.message).toMatch(/Unknown chain\(s\): SOLANA/); + // The message names what IS configured, from the configuration, not from a list in the error. + for (const n of Object.values(NETWORKS)) expect(e.message).toContain(n.name); + }); + + it("refuses a one-sided block range on either side", () => { + expect(usageError(["daily", "--to=100"]).message).toMatch(/--to was given without --from/); + expect(usageError(["daily", "--from=100"]).message).toMatch(/--from was given without --to/); + expect(usageError(["daily", "--to=100"]).exitCode).toBe(2); + }); + + it("refuses a bare backfill, which is a full history wearing the name of a range read", () => { + const e = usageError(["backfill"]); + expect(e.exitCode).toBe(2); + expect(e.message).toMatch(/requires an explicit --from and --to/); + }); + + it("accepts a two-sided range and a known chain", () => { + const opts = parseArgs(["backfill", "--chains=XDC", "--from=1", "--to=2"]); + expect(opts.fromBlock).toBe(1); + expect(opts.toBlock).toBe(2); + }); + + it("keeps the existing rejections, which fire before the new ones", () => { + // Ordering matters: a reversed range and a non-numeric bound must still report themselves + // rather than being swallowed by the one-sided check that now sits below them. + expect(() => parseArgs(["backfill", "--from=200", "--to=100"])).toThrow(/below --from/); + expect(() => parseArgs(["backfill", "--from=abc"])).toThrow(/--from is not a number/); + expect(() => parseArgs(["nonsense"])).toThrow(CliUsageError); + expect(() => parseArgs(["daily", "--nope"])).toThrow(/Unrecognised argument/); + }); +}); + +describe("limits are positive safe integers with an explicit ceiling", () => { + function usageError(argv: string[]): CliUsageError { + try { + parseArgs(argv); + } catch (e) { + return e as CliUsageError; + } + throw new Error(`parseArgs(${JSON.stringify(argv)}) did not throw`); + } + + it("refuses a limit that would silently become NaN and disable the guard it raises", () => { + expect(usageError(["daily", "--max-captures=x"]).message).toMatch(/positive whole number/); + expect(usageError(["daily", "--max-capture-blocks=0"]).message).toMatch(/positive whole number/); + expect(usageError(["daily", "--max-captures=-1"]).message).toMatch(/positive whole number/); + }); + + it("refuses a limit above its stated ceiling", () => { + const e = usageError(["daily", `--max-captures=${MAX_CAPTURES_CEILING + 1}`]); + expect(e.exitCode).toBe(2); + expect(e.message).toMatch(/is above the maximum of/); + expect(usageError(["daily", `--max-capture-blocks=${MAX_CAPTURE_BLOCKS_CEILING + 1}`]).message) + .toMatch(/is above the maximum of/); + }); + + it("refuses a limit that is not a SAFE integer, which is not the same as not finite", () => { + // `Number.isFinite(9223372036854775807)` is true and the value is a DIFFERENT integer from + // the one typed. This project measured exactly that on 134 registry rows, so the check is + // safe-integer, not finite. + expect(usageError(["daily", "--max-captures=9223372036854775807"]).message) + .toMatch(/positive whole number|above the maximum/); + }); + + it("accepts a limit at the ceiling, so the bound is inclusive and stated", () => { + expect(parseArgs(["daily", `--max-captures=${MAX_CAPTURES_CEILING}`]).maxCaptures) + .toBe(MAX_CAPTURES_CEILING); + expect(parseArgs(["daily", `--max-capture-blocks=${MAX_CAPTURE_BLOCKS_CEILING}`]).maxCaptureBlocks) + .toBe(MAX_CAPTURE_BLOCKS_CEILING); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/reader-lists.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/reader-lists.test.ts new file mode 100644 index 0000000..33ce691 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/reader-lists.test.ts @@ -0,0 +1,62 @@ +/** + * reader-lists.test.ts -- the two questions an RPC endpoint can be asked about state, and why + * they are now two lists. + * + * THE MEASUREMENT THAT PRODUCED THIS. Celo's endpoints were qualified against DEEP historical + * state -- state old enough that a pruned node has discarded it -- and exactly one of three + * passed. Read as "Celo has one state endpoint", that makes the two-endpoint agreement rule + * unmeetable and turns a solved problem into a request to buy an archive endpoint. + * + * But nothing in this pipeline reads deep history. Every state read it performs is an `eth_call` + * at a RECENT pin, which a node that prunes deep history still answers correctly. Re-measured + * against the question actually being asked, across two separate OS processes on 2026-09-29, + * four free endpoints qualify. The endpoint was never missing; the list was answering the wrong + * question. + * + * The deep-archive list stays, stays at one endpoint for Celo, and stays recorded as a + * limitation. It is simply not on any path in use. + */ + +import { describe, it, expect } from "vitest"; +import { NETWORKS } from "../../src/config.js"; + +describe("the state reader lists are two lists, because they answer two questions", () => { + it("gives Celo four free recent-pin endpoints, which is what the two-endpoint rule needs", () => { + const state = NETWORKS.CELO.readers.stateRpcUrls; + expect( + state.length, + "the two-endpoint agreement rule needs at least two endpoints that answer eth_call" + ).toBeGreaterThanOrEqual(2); + expect(state).toContain("https://forno.celo.org"); + expect(state).toContain("https://celo.blockscout.com/api/eth-rpc"); + expect(state).toContain("https://rpc.ankr.com/celo"); + expect(state).toContain("https://1rpc.io/celo"); + }); + + it("keeps celo.drpc.org out of the state list, because it answers neither question", () => { + // Measured across two separate OS processes: eth_call 0 of 6, eth_blockNumber 2 of 6. It + // contributes errors rather than answers, and an endpoint that only ever fails makes + // agreement harder to reach rather than easier. + expect(NETWORKS.CELO.readers.stateRpcUrls).not.toContain("https://celo.drpc.org"); + expect(NETWORKS.CELO.readers.archiveRpcUrls).not.toContain("https://celo.drpc.org"); + }); + + it("keeps the deep-archive list narrow, and keeps its limitation recorded rather than hidden", () => { + // ankr serves a recent pin and holds NO state below Celo's L1-to-L2 migration at block + // 31,056,500, so it qualifies for one list and not the other. That is the whole reason the + // lists are separate, and widening the archive list to make a number look better would be + // the failure this split exists to prevent. + expect(NETWORKS.CELO.readers.archiveRpcUrls).toEqual(["https://forno.celo.org"]); + expect(NETWORKS.CELO.readers.notes).toMatch(/deep-archive list is\s+genuinely one endpoint/); + }); + + it("gives every chain a state list, so no chain silently falls back to the archive list", () => { + for (const [name, network] of Object.entries(NETWORKS)) { + expect( + network.readers.stateRpcUrls.length, + `${name} declares no state endpoints, so consensusRead would fall back to the ` + + `deep-archive list and re-inherit the defect this split removed.` + ).toBeGreaterThan(0); + } + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/reader-policy-and-batching.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/reader-policy-and-batching.test.ts new file mode 100644 index 0000000..e0993f0 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/reader-policy-and-batching.test.ts @@ -0,0 +1,653 @@ +/** + * Reader policy: batched capture, evidence grading, measured finality, and the rollback frontier. + * + * These cover the four defects this unit closed plus the two it was handed with no pinned test, + * `C6` and `H2`. Each one asserts the PROPERTY rather than the implementation, so a later rewrite + * that keeps the property keeps the test. + * + * The batching tests are the ones to read first. Closing `H2` naively -- widening the address + * list and nothing else -- trades a cost defect for a coverage defect, and a wrong coverage row + * is the more expensive of the two because a bill is visible and a silently wrong ledger is not. + */ + +import { describe, it, expect, afterEach } from "vitest"; +import { pinBlock } from "../../src/oracle.js"; +import { probeLogsPresent, confirmEmptyRange, MIN_INDEPENDENT_ENDPOINTS } from "../../src/rpc.js"; +import { projectChunk, projectFetchResult, unionRange, overlaps } from "../../src/batch.js"; +import { runPipeline } from "../../src/pipeline.js"; +import { computeResumePoint } from "../../src/coverage.js"; +import { NETWORKS } from "../../src/config.js"; +import { setRpcTransport, setBigQueryClient, setReaderOverride, resetAdapters } from "../../src/adapters.js"; +import { makeWireRecorder } from "../helpers/wire-recorder.js"; +import { BigQuerySimulator } from "../helpers/bq-simulator.js"; +import { RAW_LOGS_COLUMNS, TRANSACTIONS_COLUMNS, hash32, interval } from "../helpers/fixtures.js"; +import type { ChunkResult, FetchResult } from "../../src/types.js"; + +const CELO = NETWORKS.CELO; +const XDC = NETWORKS.XDC; +const FUSE = NETWORKS.FUSE; + +/** Two real XDC contracts from the shipped seed, with genuinely different creation blocks. */ +const AVATAR = "0x21eac3fe218307bee0463f77ebca3b50f452c0ce"; +const BULK_WHITELIST = "0xe8861a20452db53df685f1d9e6b7017de3db0e46"; + +afterEach(() => resetAdapters()); + +// --------------------------------------------------------------------------------------------- +// The projection. Pure, so the attribution rules can be asserted exactly rather than inferred +// from a warehouse afterwards. +// --------------------------------------------------------------------------------------------- + +function chunk(o: Partial = {}): ChunkResult { + return { + fromBlock: 1_000, toBlock: 1_999, ok: true, + logs: [], transactions: [], blocks: [], + nextBlock: 2_000, archiveHeight: 9_999, rollbackGuard: null, + sourceKind: "index", sourceId: "hypersync:xdc", attempts: [], ms: 1, + ...o, + }; +} + +function logOf(address: string, blockNumber: number, txSeed: string): any { + return { + blockNumber, blockHash: hash32(`b${blockNumber}`), transactionHash: hash32(txSeed), + transactionIndex: 0, logIndex: 0, address, data: "0x", topics: [hash32("t0")], removed: false, + }; +} + +function fetchOf(o: Partial = {}): FetchResult { + return { + fromBlock: 1_000, toBlock: 3_999, chunksPlanned: 3, chunksOk: 3, + skipped: [], errors: [], emptyChunks: [], logsSeen: 0, complete: true, + sourceKind: "index", sourceId: "hypersync:xdc", enumeratingSources: 1, + headAtCapture: 9_999, rollbackGuards: [], + ...o, + }; +} + +describe("H2: one batched read is projected back onto each contract", () => { + it("gives a contract only the logs its own address emitted", () => { + const batched = chunk({ + logs: [logOf(AVATAR, 1_100, "ta"), logOf(BULK_WHITELIST, 1_200, "tb"), logOf(AVATAR, 1_300, "tc")], + }); + + const mine = projectChunk(batched, { address: AVATAR, fromBlock: 1_000, toBlock: 1_999 }); + + expect(mine.logs).toHaveLength(2); + expect(mine.logs.every((l) => l.address === AVATAR)).toBe(true); + }); + + it("gives a contract only the blocks its own logs are in", () => { + const batched = chunk({ + logs: [logOf(AVATAR, 1_100, "ta"), logOf(BULK_WHITELIST, 1_200, "tb")], + blocks: [ + { number: 1_100, hash: hash32("b1100"), timestamp: 1_781_000_000 }, + { number: 1_200, hash: hash32("b1200"), timestamp: 1_781_000_100 }, + ], + }); + + const mine = projectChunk(batched, { address: AVATAR, fromBlock: 1_000, toBlock: 1_999 }); + + expect(mine.blocks.map((b) => b.number)).toEqual([1_100]); + }); + + it("gives a contract only the transactions its own logs point at", () => { + // The Transactions grain is defined as one row per transaction that produced at least one + // CAPTURED log. Copying the batch's transactions onto every member would make that definition + // false for every member but the one that emitted them. + const batched = chunk({ + logs: [logOf(AVATAR, 1_100, "ta"), logOf(BULK_WHITELIST, 1_200, "tb")], + transactions: [{ hash: hash32("ta"), blockNumber: 1_100 }, { hash: hash32("tb"), blockNumber: 1_200 }], + }); + + const mine = projectChunk(batched, { address: AVATAR, fromBlock: 1_000, toBlock: 1_999 }); + + expect(mine.transactions).toHaveLength(1); + expect(mine.transactions[0].hash).toBe(hash32("ta")); + }); + + it("withholds a log below the contract's own declared start", () => { + // The batched range is the UNION of the group, so a contract created later is read over + // blocks it never asked about. Attributing one of those to it would put a row in the table + // under a capture whose coverage row says that range was never read for it. + const batched = chunk({ logs: [logOf(BULK_WHITELIST, 1_100, "early")] }); + + const mine = projectChunk(batched, { address: BULK_WHITELIST, fromBlock: 1_500, toBlock: 1_999 }); + + expect(mine.logs).toHaveLength(0); + }); + + it("matches the address case-insensitively, because a reader may return either spelling", () => { + const batched = chunk({ logs: [logOf(AVATAR.toUpperCase().replace("0X", "0x"), 1_100, "ta")] }); + + const mine = projectChunk(batched, { address: AVATAR, fromBlock: 1_000, toBlock: 1_999 }); + + expect(mine.logs).toHaveLength(1); + }); + + it("reads the union of the group's ranges, not one range per contract", () => { + expect(unionRange([ + { address: AVATAR, fromBlock: 500, toBlock: 900 }, + { address: BULK_WHITELIST, fromBlock: 700, toBlock: 1_400 }, + ])).toEqual({ fromBlock: 500, toBlock: 1_400 }); + }); + + it("returns null for an empty group rather than an impossible range", () => { + expect(unionRange([])).toBeNull(); + }); +}); + +describe("H2: batching must not cost per-contract error attribution", () => { + const chunkRanges: [number, number][] = [[1_000, 1_999], [2_000, 2_999], [3_000, 3_999]]; + + it("attributes a failed chunk ONLY to the contracts whose range it overlaps", () => { + const fetch = fetchOf({ + skipped: [[3_000, 3_999]], + errors: ["chunk 3000..3999: every endpoint failed"], + complete: false, + }); + + const early = projectFetchResult( + fetch, { address: AVATAR, fromBlock: 1_000, toBlock: 2_999 }, chunkRanges, + { logsSeen: 4, emptyChunks: [] }); + const late = projectFetchResult( + fetch, { address: BULK_WHITELIST, fromBlock: 3_000, toBlock: 3_999 }, chunkRanges, + { logsSeen: 0, emptyChunks: [[3_000, 3_999]] }); + + expect(early.complete, "a failure outside a contract's range does not make it incomplete").toBe(true); + expect(early.skipped).toEqual([]); + expect(early.errors).toEqual([]); + + expect(late.complete, "a failure inside a contract's range is not excused by another's success").toBe(false); + expect(late.skipped).toEqual([[3_000, 3_999]]); + expect(late.errors).toHaveLength(1); + }); + + it("counts only the chunks that overlap a contract as planned for it", () => { + const one = projectFetchResult( + fetchOf(), { address: AVATAR, fromBlock: 1_000, toBlock: 1_999 }, chunkRanges, + { logsSeen: 0, emptyChunks: [] }); + + expect(one.chunksPlanned, "a contract created late did not have the whole chain's chunks planned for it").toBe(1); + expect(one.chunksOk).toBe(1); + }); + + it("clips a skipped range to the contract's own interval", () => { + // A skip recorded outside the contract's range reads downstream as a hole in ground the + // contract never claimed to cover. + const projected = projectFetchResult( + fetchOf({ skipped: [[1_000, 3_999]], complete: false }), + { address: AVATAR, fromBlock: 2_500, toBlock: 3_200 }, chunkRanges, + { logsSeen: 0, emptyChunks: [] }); + + expect(projected.skipped).toEqual([[2_500, 3_200]]); + }); + + it("keeps an error that names no range, rather than dropping it silently", () => { + // An error count that reaches zero because an error could not be attributed is the exact + // shape this project keeps finding: an absence produced by the instrument, not the chain. + const projected = projectFetchResult( + fetchOf({ errors: ["HS_SPAWN failed, no range known"] }), + { address: AVATAR, fromBlock: 1_000, toBlock: 1_999 }, chunkRanges, + { logsSeen: 0, emptyChunks: [] }); + + expect(projected.errors).toEqual(["HS_SPAWN failed, no range known"]); + }); + + it("carries a rollback guard to every contract, because it is a fact about the chain", () => { + const guard = { + blockNumber: 900, timestamp: 0, hash: hash32("rbg"), + firstBlockNumber: 900, firstParentHash: hash32("rbp"), + }; + const projected = projectFetchResult( + fetchOf({ rollbackGuards: [guard] }), + { address: AVATAR, fromBlock: 1_000, toBlock: 1_999 }, chunkRanges, + { logsSeen: 0, emptyChunks: [] }); + + expect(projected.rollbackGuards).toEqual([guard]); + }); + + it("takes logsSeen and emptyChunks per contract, never from the batch", () => { + // A batched chunk full of another contract's logs is not empty for the batch and IS empty for + // this contract, and it is this contract that has to confirm that negative. + const projected = projectFetchResult( + fetchOf({ logsSeen: 40 }), + { address: AVATAR, fromBlock: 1_000, toBlock: 1_999 }, chunkRanges, + { logsSeen: 0, emptyChunks: [[1_000, 1_999]] }); + + expect(projected.logsSeen).toBe(0); + expect(projected.emptyChunks).toEqual([[1_000, 1_999]]); + }); + + it("treats touching intervals as overlapping and disjoint ones as not", () => { + expect(overlaps(100, 200, 200, 300)).toBe(true); + expect(overlaps(100, 200, 201, 300)).toBe(false); + }); +}); + +describe("H2: the pipeline issues ONE read for a chain, not one per contract", () => { + function simulator() { + const sim = new BigQuerySimulator(); + sim.defineTable("RawLogs", RAW_LOGS_COLUMNS, []); + sim.defineTable("Transactions", TRANSACTIONS_COLUMNS, []); + setBigQueryClient(sim); + return sim; + } + + it("calls the reader once with every address, and writes a coverage row per contract", async () => { + const reads: { addresses: string[]; from: number; to: number }[] = []; + setReaderOverride(async (_n, addresses, from, to, onChunk) => { + reads.push({ addresses: [...addresses], from, to }); + await onChunk(chunk({ + fromBlock: from, toBlock: to, + logs: [logOf(AVATAR, from, "ta")], + transactions: [{ + hash: hash32("ta"), blockNumber: from, blockHash: hash32(`b${from}`), transactionIndex: 0, + from: "0x0000000000000000000000000000000000000001", to: null, value: "0", nonce: "0", + gas: "21000", gasUsed: "21000", effectiveGasPrice: "1", input: "0x", kind: 2, + status: 1, contractAddress: null, + }], + blocks: [{ number: from, hash: hash32(`b${from}`), timestamp: 1_781_000_000 }], + archiveHeight: to + 100, + })); + return fetchOf({ + fromBlock: from, toBlock: to, chunksPlanned: 1, chunksOk: 1, logsSeen: 1, + headAtCapture: to + 100, + }); + }); + const sim = simulator(); + + await runPipeline({ + mode: "backfill", chains: ["XDC"], addresses: [AVATAR, BULK_WHITELIST], + fromBlock: 100_000_000, toBlock: 100_000_010, + }); + + expect(reads, "two contracts must produce ONE read, which is the whole of H2").toHaveLength(1); + expect(reads[0].addresses.map((a) => a.toLowerCase()).sort()) + .toEqual([AVATAR, BULK_WHITELIST].sort()); + + const coverage = sim.tables.get("IngestionCoverage")?.rows ?? []; + const rawRows = coverage.filter((r) => r.target_table === "RawLogs"); + expect(rawRows.map((r) => r.contract_address).sort(), "one RawLogs coverage row per contract") + .toEqual([AVATAR, BULK_WHITELIST].sort()); + expect(coverage.filter((r) => r.target_table === "Transactions")) + .toHaveLength(2); + }); + + it("gives the emitting contract the rows and the other one an honest zero", async () => { + // Both contracts were read. Only one emitted. The other's coverage row must say it was read + // and found nothing, which is a different fact from not having been read at all. + setReaderOverride(async (_n, _a, from, to, onChunk) => { + await onChunk(chunk({ + fromBlock: from, toBlock: to, + logs: [logOf(AVATAR, from, "ta")], + transactions: [{ + hash: hash32("ta"), blockNumber: from, blockHash: hash32(`b${from}`), transactionIndex: 0, + from: "0x0000000000000000000000000000000000000001", to: null, value: "0", nonce: "0", + gas: "21000", gasUsed: "21000", effectiveGasPrice: "1", input: "0x", kind: 2, + status: 1, contractAddress: null, + }], + blocks: [{ number: from, hash: hash32(`b${from}`), timestamp: 1_781_000_000 }], + archiveHeight: to + 100, + })); + return fetchOf({ + fromBlock: from, toBlock: to, chunksPlanned: 1, chunksOk: 1, logsSeen: 1, + headAtCapture: to + 100, + }); + }); + const sim = simulator(); + + await runPipeline({ + mode: "backfill", chains: ["XDC"], addresses: [AVATAR, BULK_WHITELIST], + fromBlock: 100_000_000, toBlock: 100_000_010, + }); + + const coverage = sim.tables.get("IngestionCoverage")?.rows ?? []; + const avatar = coverage.find((r) => r.target_table === "RawLogs" && r.contract_address === AVATAR); + const other = coverage.find((r) => r.target_table === "RawLogs" && r.contract_address === BULK_WHITELIST); + + expect(Number(avatar?.logs_seen)).toBe(1); + expect(Number(avatar?.rows_inserted)).toBe(1); + expect(Number(other?.logs_seen), "the batch's logs must not leak onto a contract that emitted none").toBe(0); + expect(Number(other?.rows_inserted)).toBe(0); + + const written = sim.tables.get("RawLogs")?.rows ?? []; + expect(written.map((r) => r.contract_address)).toEqual([AVATAR]); + }); + + it("records the failure against every contract when the batched read fails outright", async () => { + // The read covered them all, so it failed for them all. Recording it against only whichever + // contract was being written when it threw leaves the rest with rows in the table and nothing + // saying anybody looked, which is the one state the coverage ledger exists to prevent. + setReaderOverride(async () => { throw new Error("HS_SPAWN simulated"); }); + const sim = simulator(); + + const result = await runPipeline({ + mode: "backfill", chains: ["XDC"], addresses: [AVATAR, BULK_WHITELIST], + fromBlock: 100_000_000, toBlock: 100_000_010, + }); + + const coverage = sim.tables.get("IngestionCoverage")?.rows ?? []; + const failed = coverage.filter((r) => r.target_table === "RawLogs" && r.status === "incomplete"); + expect(failed.map((r) => r.contract_address).sort()).toEqual([AVATAR, BULK_WHITELIST].sort()); + expect(result.failed, "a failed batch must reach the exit code once per contract").toBeGreaterThanOrEqual(2); + }); +}); + +// --------------------------------------------------------------------------------------------- +// SA-C8, the pin margin. +// --------------------------------------------------------------------------------------------- + +describe("SA-C8: the pin margin comes from the chain's own measurement", () => { + function headRecorder(head: number) { + const recorder = makeWireRecorder({ answers: { eth_blockNumber: "0x" + head.toString(16) } }); + setRpcTransport(recorder.transport); + return recorder; + } + + it("uses each chain's measured finality, so two chains pin differently", async () => { + const head = 40_000_000; + headRecorder(head); + + const celo = await pinBlock(CELO); + const xdc = await pinBlock(XDC); + + expect(head - (celo.value ?? head)).toBe(CELO.finality.blocks); + expect(head - (xdc.value ?? head)).toBe(XDC.finality.blocks); + expect(CELO.finality.blocks).not.toBe(XDC.finality.blocks); + }); + + it("refuses a caller's margin that is NARROWER than the measurement, and says so", async () => { + const head = 40_000_000; + headRecorder(head); + + const pin = await pinBlock(CELO, 5); + + expect(head - (pin.value ?? head), "a 5-block pin on Celo sits inside the reorg window") + .toBe(CELO.finality.blocks); + expect(pin.errors.join(" ")).toContain("inside CELO's measured finality"); + }); + + it("honours a caller's margin that is WIDER, because further behind head is always safe", async () => { + const head = 40_000_000; + headRecorder(head); + + const pin = await pinBlock(CELO, CELO.finality.blocks + 1_000); + + expect(head - (pin.value ?? head)).toBe(CELO.finality.blocks + 1_000); + }); +}); + +// --------------------------------------------------------------------------------------------- +// SA-C8 and C6, the reader's evidence. +// --------------------------------------------------------------------------------------------- + +describe("SA-C8 and C6: a log scan's answer carries what it is worth as evidence", () => { + const ADDR = "0x" + "11".repeat(20); + + it("confirms an empty range when two independent endpoints each cover it and find nothing", async () => { + // The fix is not "always refuse". Genuine corroboration still confirms, which is what keeps + // an honest empty range from blocking the frontier forever. + setRpcTransport(makeWireRecorder({ answers: { eth_getLogs: [] } }).transport); + + const result = await confirmEmptyRange(FUSE, [ADDR], 1_000, 1_100); + + expect(FUSE.readers.rpcUrls.length).toBeGreaterThanOrEqual(MIN_INDEPENDENT_ENDPOINTS); + expect(result.confirmed).toBe(true); + expect(result.evidence.grade).toBe("corroborated_absence"); + }); + + it("never renders a sentence claiming more sources than answered", async () => { + setRpcTransport(makeWireRecorder({ + answers: { eth_getLogs: [] }, + failWith: { "https://fuse.liquify.com": 500 }, + }).transport); + + const result = await confirmEmptyRange(FUSE, [ADDR], 1_000, 1_100); + + expect(result.reason).not.toContain("two sources agree"); + expect(result.reason).toContain("1 of 2 endpoint(s)"); + }); + + it("still refuses to call a corroborated absence ADMISSIBLE, because R7 admits no exception", async () => { + setRpcTransport(makeWireRecorder({ answers: { eth_getLogs: [] } }).transport); + + const result = await confirmEmptyRange(FUSE, [ADDR], 1_000, 1_100); + + expect(result.confirmed).toBe(true); + expect(result.evidence.admissibleAsAbsence).toBe(false); + expect(result.evidence.admissibleAsRefutation).toBe(false); + }); + + it("grades a find as a refutation, which is the one claim a log scan can support", async () => { + setRpcTransport(makeWireRecorder({ + answers: { eth_getLogs: [logOf(ADDR, 1_050, "found")] }, + }).transport); + + const result = await confirmEmptyRange(FUSE, [ADDR], 1_000, 1_100); + + expect(result.confirmed).toBe(false); + expect(result.evidence.grade).toBe("refutation"); + expect(result.evidence.admissibleAsRefutation).toBe(true); + expect(result.reason).toContain("REFUTED"); + }); + + it("grades a range no endpoint could cover as no clean answer, not as an absence", async () => { + setRpcTransport(makeWireRecorder({ + answers: { eth_getLogs: [] }, + failWith: { "https://rpc.fuse.io": 500, "https://fuse.liquify.com": 500 }, + }).transport); + + const result = await confirmEmptyRange(FUSE, [ADDR], 1_000, 1_100); + + expect(result.evidence.grade).toBe("no_clean_answer"); + expect(result.evidence.cleanEndpoints).toBe(0); + }); +}); + +describe("SA-C8: an endpoint answering zero is distinguishable from one answering with rows", () => { + const ADDR = "0x" + "11".repeat(20); + + it("counts zero answers per endpoint, separately from that endpoint's failures", async () => { + // The old tally was { found, failures } summed across endpoints, in which an endpoint + // answering zero and one answering with rows are the same reading. That is the exact signal a + // false zero produces, so it was the one signal the tally could not carry. + setRpcTransport(makeWireRecorder({ + answers: { + eth_getLogs: (_p: unknown[], url: string) => + url === "https://rpc.fuse.io" ? [logOf(ADDR, 1_050, "real")] : [], + }, + }).transport); + + const probe = await probeLogsPresent(FUSE, [ADDR], 1_000, 1_100); + + const answering = probe.perEndpoint.find((e) => e.url === "https://rpc.fuse.io")!; + const silent = probe.perEndpoint.find((e) => e.url === "https://fuse.liquify.com")!; + + expect(answering.nonZeroAnswers).toBe(1); + expect(answering.zeroAnswers).toBe(0); + expect(silent.zeroAnswers).toBe(1); + expect(silent.nonZeroAnswers).toBe(0); + expect(silent.failures, "a zero is an ANSWER and must never be counted as a failure").toBe(0); + }); + + it("names the endpoint whose zero is contradicted by another endpoint's find", async () => { + setRpcTransport(makeWireRecorder({ + answers: { + eth_getLogs: (_p: unknown[], url: string) => + url === "https://rpc.fuse.io" ? [logOf(ADDR, 1_050, "real")] : [], + }, + }).transport); + + const probe = await probeLogsPresent(FUSE, [ADDR], 1_000, 1_100); + + expect(probe.falseZeroSuspects, "a false zero caught in the act is named, not averaged away") + .toEqual(["https://fuse.liquify.com"]); + }); + + it("raises no suspect when every endpoint agrees the range is empty", async () => { + setRpcTransport(makeWireRecorder({ answers: { eth_getLogs: [] } }).transport); + + const probe = await probeLogsPresent(FUSE, [ADDR], 1_000, 1_100); + + expect(probe.falseZeroSuspects).toEqual([]); + expect(Object.values(probe.zeroLogAnswers)).toEqual([1, 1]); + }); + + it("keeps errors out of the zero tally entirely", async () => { + setRpcTransport(makeWireRecorder({ + answers: { eth_getLogs: [] }, + failWith: { "https://fuse.liquify.com": 500 }, + }).transport); + + const probe = await probeLogsPresent(FUSE, [ADDR], 1_000, 1_100); + + const failing = probe.perEndpoint.find((e) => e.url === "https://fuse.liquify.com")!; + expect(failing.failures).toBe(1); + expect(failing.zeroAnswers, "an endpoint that errored did not answer zero").toBe(0); + }); +}); + +describe("C6: the grade travels to the ledger, not just to the call site that refused it", () => { + it("writes the evidence grade and an honest confirmation label onto the coverage row", async () => { + // A judgement made in a conditional is made only there. This is the consumer: the coverage + // row carries both what the reader concluded and the grade it concluded it under, so a reader + // of the warehouse can see WHY a range is not settled without re-running anything. + setRpcTransport(makeWireRecorder({ + answers: { eth_getLogs: [], eth_blockNumber: "0x" + (100_000_500).toString(16) }, + failWith: { "https://xdc.public-rpc.com": 500, "https://rpc.xdcrpc.com": 500 }, + }).transport); + setReaderOverride(async (_n, _a, from, to, onChunk) => { + await onChunk(chunk({ fromBlock: from, toBlock: to, logs: [], archiveHeight: to + 100 })); + return fetchOf({ + fromBlock: from, toBlock: to, chunksPlanned: 1, chunksOk: 1, logsSeen: 0, + emptyChunks: [[from, to]], headAtCapture: to + 100, + }); + }); + const sim = new BigQuerySimulator(); + sim.defineTable("RawLogs", RAW_LOGS_COLUMNS, []); + sim.defineTable("Transactions", TRANSACTIONS_COLUMNS, []); + setBigQueryClient(sim); + + await runPipeline({ + mode: "backfill", chains: ["XDC"], addresses: [AVATAR], + fromBlock: 100_000_000, toBlock: 100_000_010, + }); + + const row = (sim.tables.get("IngestionCoverage")?.rows ?? []) + .find((r) => r.target_table === "RawLogs"); + + expect(row?.confirmation_result).toBe("uncorroborated"); + expect(String(row?.error_message)).toContain("EVIDENCE_GRADES: single_source_absence"); + expect(row?.status, "an uncorroborated empty range is not settled ground").not.toBe("complete"); + expect(row?.assurance, "and it cannot be graded as confirmed").toBe("C"); + }); +}); + +// --------------------------------------------------------------------------------------------- +// SA-C23a, the rollback frontier. +// --------------------------------------------------------------------------------------------- + +describe("SA-C23a: a rollback guard holds the resume frontier, it does not just annotate it", () => { + it("does not let the frontier move past a rollback-eligible capture", () => { + // This is the half that matters. A status nothing reads is a note with a different name, and + // `isClean` is the one thing that decides whether the next run looks at a range again. + const resume = computeResumePoint( + [interval(1_000, 1_999), interval(2_000, 2_999, { status: "rollback_eligible" })], + 1_000); + + expect(resume.resumeAt).toBe(1_999); + expect(resume.coveredUpTo).toBe(1_999); + }); + + it("moves the frontier over the same range once the capture is clean", () => { + // The discrimination: identical intervals, one status different, and the frontier moves. + // Without this the first test would pass on a frontier that never moves at all. + const resume = computeResumePoint( + [interval(1_000, 1_999), interval(2_000, 2_999)], + 1_000); + + expect(resume.resumeAt).toBe(2_999); + }); + + it("records rollback_eligible rather than complete, and the reason with it", async () => { + setReaderOverride(async (_n, _a, from, to, onChunk) => { + await onChunk(chunk({ + fromBlock: from, toBlock: to, + logs: [logOf(AVATAR, from, "ta")], + transactions: [{ + hash: hash32("ta"), blockNumber: from, blockHash: hash32(`b${from}`), transactionIndex: 0, + from: "0x0000000000000000000000000000000000000001", to: null, value: "0", nonce: "0", + gas: "21000", gasUsed: "21000", effectiveGasPrice: "1", input: "0x", kind: 2, + status: 1, contractAddress: null, + }], + blocks: [{ number: from, hash: hash32(`b${from}`), timestamp: 1_781_000_000 }], + archiveHeight: to + 100, + })); + return fetchOf({ + fromBlock: from, toBlock: to, chunksPlanned: 1, chunksOk: 1, logsSeen: 1, + headAtCapture: to + 100, + rollbackGuards: [{ + blockNumber: from - 10, timestamp: 0, hash: hash32("rbg"), + firstBlockNumber: from - 10, firstParentHash: hash32("rbp"), + }], + }); + }); + const sim = new BigQuerySimulator(); + sim.defineTable("RawLogs", RAW_LOGS_COLUMNS, []); + sim.defineTable("Transactions", TRANSACTIONS_COLUMNS, []); + setBigQueryClient(sim); + + await runPipeline({ + mode: "backfill", chains: ["XDC"], addresses: [AVATAR], + fromBlock: 100_000_000, toBlock: 100_000_010, + }); + + const rows = (sim.tables.get("IngestionCoverage")?.rows ?? []) + .filter((r) => r.contract_address === AVATAR); + + expect(rows.map((r) => r.status)).toEqual(["rollback_eligible", "rollback_eligible"]); + expect(String(rows[0].error_message)).toContain("ROLLBACK_GUARD"); + }); + + it("leaves a guard that holds only settled blocks alone", async () => { + // The discrimination for the status half: a guard whose first held block is ABOVE the + // capture's start says nothing about this range, and must not hold it. + setReaderOverride(async (_n, _a, from, to, onChunk) => { + await onChunk(chunk({ + fromBlock: from, toBlock: to, + logs: [logOf(AVATAR, from, "ta")], + transactions: [{ + hash: hash32("ta"), blockNumber: from, blockHash: hash32(`b${from}`), transactionIndex: 0, + from: "0x0000000000000000000000000000000000000001", to: null, value: "0", nonce: "0", + gas: "21000", gasUsed: "21000", effectiveGasPrice: "1", input: "0x", kind: 2, + status: 1, contractAddress: null, + }], + blocks: [{ number: from, hash: hash32(`b${from}`), timestamp: 1_781_000_000 }], + archiveHeight: to + 100, + })); + return fetchOf({ + fromBlock: from, toBlock: to, chunksPlanned: 1, chunksOk: 1, logsSeen: 1, + headAtCapture: to + 100, + rollbackGuards: [{ + blockNumber: to + 50, timestamp: 0, hash: hash32("rbg"), + firstBlockNumber: to + 50, firstParentHash: hash32("rbp"), + }], + }); + }); + const sim = new BigQuerySimulator(); + sim.defineTable("RawLogs", RAW_LOGS_COLUMNS, []); + sim.defineTable("Transactions", TRANSACTIONS_COLUMNS, []); + setBigQueryClient(sim); + + await runPipeline({ + mode: "backfill", chains: ["XDC"], addresses: [AVATAR], + fromBlock: 100_000_000, toBlock: 100_000_010, + }); + + const row = (sim.tables.get("IngestionCoverage")?.rows ?? []) + .find((r) => r.target_table === "RawLogs"); + + expect(row?.status).toBe("complete"); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/reader-regression-guards.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/reader-regression-guards.test.ts new file mode 100644 index 0000000..abab1c5 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/reader-regression-guards.test.ts @@ -0,0 +1,206 @@ +/** + * GREEN regression guards for Stage A defects PR 71 already repaired. + * + * WHY THESE ARE GREEN AND NOT RED, stated plainly because the plan lists them among the + * regressions Phase 1 must turn red. Plan Section 5 task 4 names six carried Stage A defects. + * They were established against the Stage A verification library at `specs/_lib/lib.mjs`. The + * shipping pipeline in the integrated candidate does not have them: PR 71 independently repaired + * the same shapes, and each repair is verified below by exercising the code rather than by + * reading its comments. + * + * A defect that is already fixed cannot be made red for its intended reason, and coordination's + * own rule is that a test which passes whether or not the defect is present is worthless. So + * each one becomes what it can honestly be: a guard that fails the moment the fix is undone. + * Phase 6 owns the repair of anything still outstanding, and what IS still outstanding is red in + * `test/known-failures/reader-evidence.test.ts`. + * + * The split between this file and that one is a finding in the Phase 1 report, not a quiet + * narrowing of scope. + */ + +import { describe, it, expect, afterEach } from "vitest"; +import { readFileSync } from "fs"; +import { fileURLToPath } from "url"; +import { dirname, join } from "path"; +import { rpcFetchRange } from "../../src/reader.js"; +import { NETWORKS } from "../../src/config.js"; +import { setRpcTransport, resetAdapters } from "../../src/adapters.js"; +import { makeWireRecorder } from "../helpers/wire-recorder.js"; +import { hash32 } from "../helpers/fixtures.js"; + +const HERE = dirname(fileURLToPath(import.meta.url)); +const SRC = join(HERE, "..", "..", "src"); + +const ETH = NETWORKS.ETHEREUM; + +afterEach(() => resetAdapters()); + +/** One log and its block and transaction, enough for a chunk to hydrate cleanly. */ +function oneLogAt(block: number) { + return { + blockNumber: "0x" + block.toString(16), + blockHash: hash32("bh"), + transactionHash: hash32("tx"), + transactionIndex: "0x0", + logIndex: "0x0", + address: "0x" + "11".repeat(20), + data: "0x", + topics: [hash32("t0")], + removed: false, + }; +} + +describe("SA-C7: verification and hydration calls name a block, never `latest`", () => { + it("sends a hex block number on eth_getBlockByNumber and never the string latest", async () => { + const block = 21_000_000; + const recorder = makeWireRecorder({ + answers: { + eth_blockNumber: "0x" + (block + 500).toString(16), + eth_getLogs: [oneLogAt(block)], + eth_getBlockByNumber: { + number: "0x" + block.toString(16), hash: hash32("bh"), timestamp: "0x6800_0000".replace("_", ""), + }, + eth_getTransactionByHash: { + hash: hash32("tx"), blockNumber: "0x" + block.toString(16), blockHash: hash32("bh"), + transactionIndex: "0x0", from: "0x" + "22".repeat(20), to: "0x" + "11".repeat(20), + value: "0x0", nonce: "0x1", gas: "0x5208", input: "0x", type: "0x2", + }, + eth_getTransactionReceipt: { + status: "0x1", gasUsed: "0x5208", effectiveGasPrice: "0x1", contractAddress: null, + }, + }, + }); + setRpcTransport(recorder.transport); + + await rpcFetchRange(ETH, ["0x" + "11".repeat(20)], block, block + 10, async () => {}); + + const blockCalls = recorder.of("eth_getBlockByNumber"); + expect(blockCalls.length).toBeGreaterThan(0); + for (const call of blockCalls) { + expect(call.params[0], "a pinned read must name a numeric block").toMatch(/^0x[0-9a-f]+$/); + expect(call.body).not.toContain("latest"); + expect(call.body).not.toContain("pending"); + } + + // Every log query is bounded by explicit hex block numbers too. + for (const call of recorder.of("eth_getLogs")) { + const filter = call.params[0] as { fromBlock: string; toBlock: string }; + expect(filter.fromBlock).toMatch(/^0x[0-9a-f]+$/); + expect(filter.toBlock).toMatch(/^0x[0-9a-f]+$/); + } + }); + + it("sends eth_getTransactionReceipt exactly one parameter, the transaction hash", async () => { + const block = 21_000_000; + const recorder = makeWireRecorder({ + answers: { + eth_blockNumber: "0x" + (block + 500).toString(16), + eth_getLogs: [oneLogAt(block)], + eth_getBlockByNumber: { number: "0x" + block.toString(16), hash: hash32("bh"), timestamp: "0x68000000" }, + eth_getTransactionByHash: { + hash: hash32("tx"), blockNumber: "0x" + block.toString(16), blockHash: hash32("bh"), + transactionIndex: "0x0", from: "0x" + "22".repeat(20), to: "0x" + "11".repeat(20), + value: "0x0", nonce: "0x1", gas: "0x5208", input: "0x", type: "0x2", + }, + eth_getTransactionReceipt: { + status: "0x1", gasUsed: "0x5208", effectiveGasPrice: "0x1", contractAddress: null, + }, + }, + }); + setRpcTransport(recorder.transport); + + await rpcFetchRange(ETH, ["0x" + "11".repeat(20)], block, block + 10, async () => {}); + + const receipts = recorder.of("eth_getTransactionReceipt"); + expect(receipts.length).toBeGreaterThan(0); + for (const call of receipts) { + // A second parameter here is not merely redundant: the method takes one, and an endpoint + // that validates its arity rejects the whole call, which renders as a missing receipt. + expect(call.params).toHaveLength(1); + expect(call.params[0]).toMatch(/^0x[0-9a-f]{64}$/); + } + }); +}); + +describe("SA-C8: every skipped chunk is reported, not a sample of them", () => { + it("reports all nine skipped chunks when every endpoint fails on every one", async () => { + // Nine chunks, both endpoints failing every time. The Stage A library tallied only the first + // three per (pass, endpoint) and reported three gaps where nine chunks had failed. + const recorder = makeWireRecorder({ + answers: { eth_blockNumber: "0x1400000" }, + failWith: { + "https://eth.blockscout.com/api/eth-rpc": 500, + "https://gateway.tenderly.co/public/mainnet": 500, + }, + }); + setRpcTransport(recorder.transport); + + const chunk = ETH.chunkBlocks; + const from = 1_000_000; + const to = from + chunk * 9 - 1; + + const result = await rpcFetchRange(ETH, ["0x" + "11".repeat(20)], from, to, async () => {}); + + expect(result.chunksPlanned).toBe(9); + expect(result.skipped).toHaveLength(9); + expect(result.complete).toBe(false); + // Errors are counted separately from results, so an all-failure run is never an empty answer. + expect(result.errors.length).toBeGreaterThanOrEqual(9); + expect(result.logsSeen).toBe(0); + }); +}); + +describe("SA-C23a: finality and the rollback guard are wired, not assumed", () => { + it("carries a measured per-chain finality depth with its source, never a bare 64 on Celo", () => { + // A2 measured Celo's finalized tag 1,187 to 1,930 blocks behind head. The predecessor held 64. + expect(NETWORKS.CELO.finality.blocks).toBeGreaterThanOrEqual(1_187); + expect(NETWORKS.CELO.finality.source).toMatch(/\S/); + + for (const network of Object.values(NETWORKS)) { + expect(network.finality.blocks, `${network.name} must declare a positive margin`).toBeGreaterThan(0); + expect( + network.finality.source, + `${network.name} must record where its finality figure came from, so it is checkable` + ).toMatch(/\S/); + // The one chain with no finality tag must say so rather than imply a measurement. + if (!network.finality.publishesFinalizedTag) { + expect(network.finality.source).toMatch(/not a measurement|time budget/i); + } + } + }); + + it("requests the rollback guard from the index client and forwards it to the caller", () => { + // Asserted on the worker source because the client itself cannot run here: it is a native + // module driven in a child process against a live index. What is checkable without one is + // that the worker reads the field and puts it in the message, which is the half that was + // dropped. + const worker = readFileSync(join(SRC, "hs-worker.mjs"), "utf8"); + expect(worker).toMatch(/rollbackGuard:\s*res\.rollbackGuard/); + expect(worker).toMatch(/nextBlock:/); + + const hypersync = readFileSync(join(SRC, "hypersync.ts"), "utf8"); + expect(hypersync).toMatch(/rollbackGuards\.push/); + }); +}); + +describe("SA-C8: convergence is calibrated from a measured rate, not a fixed pass count", () => { + it("derives the pass count k from the measured miss rate p", async () => { + const { __testing } = await import("../../src/calibrate.js"); + expect(__testing, "calibrate.ts must expose its summariser for this assertion").toBeDefined(); + + // p measured at 0.7, which is what this project actually measured on one endpoint in one + // afternoon. A five-pass rule stops falsely about one time in six at that rate. The modal + // answer is the full count; the short answers vary, which is what a false zero and a partial + // read actually look like next to each other. + const short = __testing.summarise("src", "CELO", 1, 100, [10, 10, 10, 0, 1, 2, 3, 4, 5, 6], 0); + expect(short.modeAnswer).toBe(10); + expect(short.p).toBeCloseTo(0.7, 5); + expect(short.kForOnePercent).toBe(Math.ceil(Math.log(0.01) / Math.log(0.7))); + expect(short.kForOnePercent).toBeGreaterThan(5); + + // Zero short answers is a fact about the session, reported with its n, not a property. + const clean = __testing.summarise("src", "CELO", 1, 100, [10, 10, 10], 0); + expect(clean.p).toBe(0); + expect(clean.verdict).toMatch(/fact about this session/i); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/run-ledger.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/run-ledger.test.ts new file mode 100644 index 0000000..de150b7 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/run-ledger.test.ts @@ -0,0 +1,394 @@ +/** + * The nonrecursive job-ledger contract. Plan Phase 3, task 12, and its two RED/GREEN checks. + * + * THE TWO CHECKS THE PLAN NAMES, in its own words: + * + * "Force the successful terminalizer query result unavailable, then reconstruct the exact + * snapshot solely from canonical_terminal_row_v1 plus successful parent/full-child metadata + * and one affected DML row. Assert byte-identical row/hash, zero tabledata.list, zero Storage + * Read, zero replacement jobs.insert and zero additional query jobs." + * + * "Cancel once immediately after the COMMIT child succeeds but before the trailing no-FROM + * SELECT completes. The parent may be cancelled/failed and the result absent; recovery must + * recognize the successful COMMIT plus one-row DML, reconstruct the exact snapshot, close + * normally and submit zero replacement terminalizers. A sibling fixture cancelled before + * COMMIT must prove rollback before one linked retry; an ambiguous/missing COMMIT status must + * stop rather than guess." + * + * HOW THE "ZERO CALLS" HALF IS PROVEN, and why it is proven rather than asserted. Recovery is + * handed a client whose every method THROWS. If reconstruction touched BigQuery in any way the + * test would fail with that client's own error, not with a count. A counter that nobody + * increments reads the same as a call that never happened, which is the failure shape this + * project keeps finding. + */ + +import { describe, it, expect } from "vitest"; +import { readFileSync } from "fs"; +import { setBigQueryClient, resetAdapters } from "../../src/adapters.js"; +import { + JobLedger, LedgerError, JOB_STAGES, + base32EncodeNoPad, base32DecodeNoPad, planHashLabel, planHashLabelMatches, + validateJobLabels, uuidVersion, deterministicChildRunId, + canonicalJson, sha256Hex, terminalRowHash, buildTerminalizerIntent, reconstructTerminalRow, + decideRecovery, isTerminal, ROW_HASH_FIELD, RECEIPT_CAP_BYTES, + type CanonicalTerminalRow, type SubmitIntent, type TerminalizerJobEvidence, type TypedValue, +} from "../../src/run-ledger.js"; + +/** The plan's own SHA-256, which is what a real writer binds to. */ +const PLAN_HASH_HEX = "9dcde225459127c4da2beadf9094fd894fe193010f39cb70c0753dd874853e26"; +const RELEASE_SHA = "17b82df3c2cd24c5601a541b44b3a2a80f09c292"; +const RUN_V7 = "0199a3c4-5d6e-7f80-8123-456789abcdef"; +const RUN_V5 = "0199a3c4-5d6e-5f80-8123-456789abcdef"; +const RUN_V4 = "0199a3c4-5d6e-4f80-8123-456789abcdef"; + +function intent(jobId: string, stage: (typeof JOB_STAGES)[number] = "merge"): SubmitIntent { + return { + jobId, location: "US", principal: "pipeline@example.invalid", + statementClass: "MERGE", targets: ["BlockchainEvents.RawLogs"], + templateHash: sha256Hex("template"), submittedAt: "2026-09-28T00:00:00.000Z", + stage, parentJobId: null, + }; +} + +function row(overrides: Record = {}): CanonicalTerminalRow { + return { + version: "canonical_terminal_row_v1", + runId: RUN_V7, + fields: { + run_id: { type: "STRING", value: RUN_V7 }, + execution_status: { type: "STRING", value: "completed" }, + units_planned: { type: "INT64", value: 3 }, + units_completed: { type: "INT64", value: 3 }, + units_refused: { type: "INT64", value: 0 }, + work_jobs_terminal: { type: "BOOL", value: true }, + terminalized_at: { type: "TIMESTAMP", value: "2026-09-28T01:00:00.000Z" }, + closure_receipt_uri: { type: "STRING", value: "sandbox/receipts/run/closure.json" }, + bigquery_job_ledger: { type: "JSON", value: "[]" }, + // Present and explicitly null. A missing key and a null key are the same in JSON, and + // recovery has to reproduce the row byte for byte. + parent_run_id: { type: "STRING", value: null }, + error_message: { type: "STRING", value: null }, + [ROW_HASH_FIELD]: { type: "STRING", value: null }, + ...overrides, + }, + }; +} + +describe("label encoding refuses anything that merely looks right", () => { + it("round-trips a 32-byte hash through 52 characters of lowercase base32", () => { + const label = planHashLabel(PLAN_HASH_HEX); + expect(label).toHaveLength(52); + expect(label).toMatch(/^[a-z2-7]{52}$/); + expect(Buffer.from(base32DecodeNoPad(label)).toString("hex")).toBe(PLAN_HASH_HEX); + }); + + it("compares by DECODED BYTES, so a truncation is not a match", () => { + const label = planHashLabel(PLAN_HASH_HEX); + expect(planHashLabelMatches(label, PLAN_HASH_HEX)).toBe(true); + // A prefix of the right label. A prefix comparison would accept this, and a prefix comparison + // has already produced a false finding in this project by comparing padded uint256 values. + expect(planHashLabelMatches(label.slice(0, 40), PLAN_HASH_HEX)).toBe(false); + // One character different, same length. + const flipped = (label[0] === "a" ? "b" : "a") + label.slice(1); + expect(planHashLabelMatches(flipped, PLAN_HASH_HEX)).toBe(false); + expect(planHashLabelMatches("not base32 at all!", PLAN_HASH_HEX)).toBe(false); + }); + + it("refuses a plan hash that is not 64 lowercase hex characters", () => { + expect(() => planHashLabel(PLAN_HASH_HEX.toUpperCase())).toThrow(/PLAN_HASH_SHAPE/); + expect(() => planHashLabel(PLAN_HASH_HEX.slice(0, 63))).toThrow(/PLAN_HASH_SHAPE/); + }); + + it("encodes the empty input and short inputs without padding", () => { + expect(base32EncodeNoPad(Uint8Array.from([]))).toBe(""); + expect(Buffer.from(base32DecodeNoPad(base32EncodeNoPad(Uint8Array.from([1, 2, 3])))) + .toString("hex")).toBe("010203"); + }); +}); + +describe("a run id carries a claim about what kind of run it is, and the claim is checked", () => { + const ctx = { isRootedA5Child: false, canonicalPlanHashHex: PLAN_HASH_HEX }; + const labels = (over: Partial> = {}) => ({ + run_id: RUN_V7, stage: "merge", release_sha: RELEASE_SHA, + plan_hash: planHashLabel(PLAN_HASH_HEX), ...over, + }); + + it("accepts a well-formed ordinary parent run", () => { + expect(validateJobLabels(labels(), ctx)).toEqual([]); + }); + + it("refuses a UUIDv5 outside the authenticated A5 child path", () => { + const v = validateJobLabels(labels({ run_id: RUN_V5 }), ctx); + expect(v.map((x) => x.key)).toContain("run_id"); + expect(v[0].reason).toMatch(/must be UUIDv7, not v5/); + expect(v[0].reason).toMatch(/outside the authenticated A5 child path refuses/); + }); + + it("refuses a UUIDv7 A5 child, which is the mirror-image mistake", () => { + const v = validateJobLabels(labels(), { ...ctx, isRootedA5Child: true }); + expect(v[0].reason).toMatch(/must be the deterministic UUIDv5/); + }); + + it("accepts a UUIDv5 on the A5 child path and nowhere else", () => { + expect(validateJobLabels(labels({ run_id: RUN_V5 }), { ...ctx, isRootedA5Child: true })).toEqual([]); + }); + + it("refuses every other UUID version, an unknown stage and a bad release SHA", () => { + expect(validateJobLabels(labels({ run_id: RUN_V4 }), ctx)[0].reason).toMatch(/not v4/); + expect(validateJobLabels(labels({ stage: "whatever" }), ctx).map((x) => x.key)).toContain("stage"); + expect(validateJobLabels(labels({ release_sha: "ABCDEF" }), ctx).map((x) => x.key)) + .toContain("release_sha"); + }); + + it("refuses a value outside BigQuery's label alphabet or over 63 characters", () => { + const v = validateJobLabels(labels({ stage: "MERGE" }), ctx); + expect(v.some((x) => x.reason.includes("63-character limit") || x.reason.includes("alphabet"))) + .toBe(true); + // The canonical hex hash is 64 characters, which is why the base32 form exists at all. + expect(PLAN_HASH_HEX.length).toBe(64); + expect(planHashLabel(PLAN_HASH_HEX).length).toBeLessThanOrEqual(63); + }); + + it("reports every violation in one pass rather than the first", () => { + const v = validateJobLabels( + { run_id: "nope", stage: "nope", release_sha: "nope", plan_hash: "nope" }, ctx); + expect(v.map((x) => x.key).sort()).toEqual(["plan_hash", "release_sha", "run_id", "stage"]); + }); +}); + +describe("the deterministic A5 child id is recomputable byte for byte", () => { + const ns = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"; + const parts = { + parentRunId: RUN_V7, manifestSetId: "manifest-1", approvalRevisionOrZero: 0, + childPlanHash: sha256Hex("child-plan"), globalOrControlOrdinal: 3, attempt: 1, + }; + + it("produces a UUIDv5 and the same one every time", () => { + const a = deterministicChildRunId(ns, parts); + expect(uuidVersion(a)).toBe(5); + expect(deterministicChildRunId(ns, parts)).toBe(a); + }); + + it("changes when any single component of the canonical tuple changes", () => { + const base = deterministicChildRunId(ns, parts); + expect(deterministicChildRunId(ns, { ...parts, attempt: 2 })).not.toBe(base); + expect(deterministicChildRunId(ns, { ...parts, globalOrControlOrdinal: 4 })).not.toBe(base); + expect(deterministicChildRunId(ns, { ...parts, manifestSetId: "manifest-2" })).not.toBe(base); + // A delimiter collision would make these two tuples render identically. They must not. + expect(deterministicChildRunId(ns, { ...parts, manifestSetId: "manifest", approvalRevisionOrZero: 10 })) + .not.toBe(deterministicChildRunId(ns, { ...parts, manifestSetId: "manifest-1", approvalRevisionOrZero: 0 })); + }); + + it("refuses a parent that is not a UUIDv7", () => { + expect(() => deterministicChildRunId(ns, { ...parts, parentRunId: RUN_V5 })) + .toThrow(/A5_CHILD_PARENT/); + }); +}); + +describe("the ledger is append-only and NEVER contains its own terminalizer", () => { + it("refuses a terminalizer submit intent outright", () => { + const ledger = new JobLedger(RUN_V7); + expect(() => ledger.appendSubmitIntent(intent("job-t", "terminalizer"))) + .toThrow(LedgerError); + expect(() => ledger.appendSubmitIntent(intent("job-t", "terminalizer"))) + .toThrow(/LEDGER_RECURSION/); + }); + + it("refuses a terminal state for a job it never authorised", () => { + const ledger = new JobLedger(RUN_V7); + expect(() => ledger.appendJobTerminal({ + jobId: "ghost", state: "DONE", errorMessage: null, transactionId: null, affectedRows: 1, + })).toThrow(/LEDGER_NO_INTENT/); + }); + + it("refuses a nonterminal state and a duplicate intent", () => { + const ledger = new JobLedger(RUN_V7); + ledger.appendSubmitIntent(intent("job-1")); + expect(() => ledger.appendSubmitIntent(intent("job-1"))).toThrow(/LEDGER_DUPLICATE_INTENT/); + expect(() => ledger.appendJobTerminal({ + jobId: "job-1", state: "RUNNING", errorMessage: null, transactionId: null, affectedRows: null, + })).toThrow(/LEDGER_NOT_TERMINAL/); + expect(isTerminal("RUNNING")).toBe(false); + expect(["DONE", "FAILED", "CANCELLED"].every(isTerminal as any)).toBe(true); + }); + + it("is not terminal while a generated child the Jobs API knows about is unledgered", () => { + const ledger = new JobLedger(RUN_V7); + ledger.appendSubmitIntent(intent("parent-1")); + ledger.appendJobTerminal({ + jobId: "parent-1", state: "DONE", errorMessage: null, transactionId: "tx1", affectedRows: 1, + }); + + // Parent status alone is insufficient: a multi-statement script's generated children are + // separate jobs and the Jobs API is where they surface. + expect(ledger.workJobsTerminal(["parent-1"])).toBe(true); + expect(ledger.workJobsTerminal(["parent-1", "parent-1_child_0"])).toBe(false); + expect(ledger.reconcile(["parent-1", "parent-1_child_0"]).unledgered).toEqual(["parent-1_child_0"]); + }); + + it("is not terminal while an authorised job has not reported", () => { + const ledger = new JobLedger(RUN_V7); + ledger.appendSubmitIntent(intent("job-1")); + ledger.appendSubmitIntent(intent("job-2")); + ledger.appendJobTerminal({ + jobId: "job-1", state: "DONE", errorMessage: null, transactionId: null, affectedRows: 1, + }); + expect(ledger.reconcile(["job-1", "job-2"]).nonterminal).toEqual(["job-2"]); + expect(ledger.workJobsTerminal(["job-1", "job-2"])).toBe(false); + }); + + it("hashes to a value that moves when the ledger does", () => { + const ledger = new JobLedger(RUN_V7); + const before = ledger.hash(); + ledger.appendSubmitIntent(intent("job-1")); + expect(ledger.hash()).not.toBe(before); + }); +}); + +describe("canonical_terminal_row_v1 hashes the same from either code path", () => { + it("is insensitive to key insertion order and sensitive to every value", () => { + const a = row(); + const reordered: CanonicalTerminalRow = { + version: a.version, runId: a.runId, + fields: Object.fromEntries(Object.entries(a.fields).reverse()), + }; + // Recovery builds the row from the stored intent and the original built it from live + // counters. Those ARE two different code paths, and the whole proof rests on them agreeing. + expect(terminalRowHash(reordered)).toBe(terminalRowHash(a)); + expect(terminalRowHash(row({ units_completed: { type: "INT64", value: 4 } }))) + .not.toBe(terminalRowHash(a)); + }); + + it("excludes the hash field itself rather than blanking it", () => { + const withNull = row(); + const withoutKey: CanonicalTerminalRow = { + ...withNull, + fields: Object.fromEntries( + Object.entries(withNull.fields).filter(([k]) => k !== ROW_HASH_FIELD)), + }; + expect(terminalRowHash(withoutKey)).toBe(terminalRowHash(withNull)); + // And a populated hash field must not change the hash either, or a row could never be + // verified after it was written. + const populated = row({ [ROW_HASH_FIELD]: { type: "STRING", value: "deadbeef" } }); + expect(terminalRowHash(populated)).toBe(terminalRowHash(withNull)); + }); + + it("distinguishes an absent field from a null one in the canonical form", () => { + const withNull = canonicalJson({ a: 1, b: null }); + const withoutB = canonicalJson({ a: 1 }); + expect(withNull).not.toBe(withoutB); + }); + + it("refuses an intent over the 256 KiB receipt cap instead of truncating it", () => { + const huge = row({ bigquery_job_ledger: { type: "JSON", value: "x".repeat(RECEIPT_CAP_BYTES) } }); + expect(() => buildTerminalizerIntent({ + terminalizerJobId: "t-1", runId: RUN_V7, row: huge, ledgerHash: sha256Hex("l"), + terminalizedAt: "2026-09-28T01:00:00.000Z", closureReceiptUri: "sandbox/c.json", + })).toThrow(/RECEIPT_TOO_LARGE/); + }); + + it("refuses an intent whose row already claims a hash", () => { + expect(() => buildTerminalizerIntent({ + terminalizerJobId: "t-1", runId: RUN_V7, + row: row({ [ROW_HASH_FIELD]: { type: "STRING", value: "preset" } }), + ledgerHash: sha256Hex("l"), + terminalizedAt: "2026-09-28T01:00:00.000Z", closureReceiptUri: "sandbox/c.json", + })).toThrow(/ROW_HASH_PRESET/); + }); +}); + +describe("recovery after the terminalizer result is gone", () => { + const theIntent = buildTerminalizerIntent({ + terminalizerJobId: "t-1", runId: RUN_V7, row: row(), ledgerHash: sha256Hex("ledger"), + terminalizedAt: "2026-09-28T01:00:00.000Z", + closureReceiptUri: "sandbox/receipts/run/closure.json", + }); + + const evidence = (over: Partial = {}): TerminalizerJobEvidence => ({ + parentState: "DONE", dmlChildState: "DONE", dmlChildAffectedRows: 1, + commitChildState: "DONE", trailingSelectState: "DONE", + resultAvailable: true, rollbackProven: false, ...over, + }); + + it("reads the existing result when everything succeeded and it is still there", () => { + expect(decideRecovery(evidence()).action).toBe("read_existing_result"); + }); + + it("reconstructs the EXACT row from the intent alone when the result has expired", () => { + const decision = decideRecovery(evidence({ resultAvailable: false })); + expect(decision.action).toBe("reconstruct_from_intent"); + + const { row: rebuilt, rowHash } = reconstructTerminalRow(theIntent); + + // Byte-identical, which is the plan's word. Not "equivalent", not "the same fields". + expect(rowHash).toBe(theIntent.rowHash); + expect(rebuilt.fields[ROW_HASH_FIELD]).toEqual({ type: "STRING", value: theIntent.rowHash }); + expect(canonicalJson({ ...rebuilt, fields: { ...rebuilt.fields, [ROW_HASH_FIELD]: { type: "STRING", value: null } } })) + .toBe(canonicalJson(theIntent.row)); + }); + + it("reconstructs with zero BigQuery access of any kind, proven two ways", () => { + // ONE: the only route to a client in this codebase is `getBigQueryClient()`, so an installed + // client whose every member throws is a real tripwire. If reconstruction reached BigQuery for + // a tabledata.list, a Storage Read session, a replacement jobs.insert or any additional query + // job, this fails with that client's own error rather than with a count of zero. + setBigQueryClient({ + query: () => { throw new Error("RECOVERY_TOUCHED_BIGQUERY"); }, + dataset: () => { throw new Error("RECOVERY_TOUCHED_BIGQUERY"); }, + } as any); + try { + const { rowHash, row: rebuilt } = reconstructTerminalRow(theIntent); + expect(rowHash).toBe(theIntent.rowHash); + expect(rebuilt.runId).toBe(RUN_V7); + } finally { + resetAdapters(); + } + + // TWO: the tripwire only covers what the module could reach at runtime on this path, so the + // structural claim is checked directly. `run-ledger.ts` imports node's crypto and nothing + // else. A module that cannot see a client cannot call one on any path, not just this one. + const source = readFileSync(new URL("../../src/run-ledger.ts", import.meta.url), "utf8"); + const imports = [...source.matchAll(/^import .*?from "([^"]+)";/gm)].map((m) => m[1]); + expect(imports).toEqual(["crypto"]); + }); + + it("treats the COMMIT child as authoritative even when the parent was cancelled", () => { + // The plan's fixture: cancel immediately after COMMIT succeeds and before the trailing SELECT + // completes. The parent may be cancelled and the result absent, and the run still closed. + const decision = decideRecovery(evidence({ + parentState: "CANCELLED", trailingSelectState: "MISSING", resultAvailable: false, + })); + expect(decision.action).toBe("reconstruct_from_intent"); + expect(decision.reason).toMatch(/NO replacement terminalizer is submitted/); + }); + + it("allows exactly one linked retry when rollback is PROVEN", () => { + const decision = decideRecovery(evidence({ + commitChildState: "CANCELLED", trailingSelectState: "MISSING", + resultAvailable: false, rollbackProven: true, + })); + expect(decision.action).toBe("retry_linked_recovery"); + }); + + it("stops rather than guessing when the COMMIT status is ambiguous or missing", () => { + for (const state of ["UNKNOWN", "MISSING"] as const) { + const decision = decideRecovery(evidence({ + commitChildState: state, resultAvailable: false, rollbackProven: false, + })); + expect(decision.action, state).toBe("stop"); + expect(decision.reason).toMatch(/two terminal rows|Ambiguity stops|not proven/); + } + }); + + it("stops when a COMMIT succeeded over a broken prefix or the wrong number of rows", () => { + expect(decideRecovery(evidence({ dmlChildState: "MISSING" })).action).toBe("stop"); + expect(decideRecovery(evidence({ dmlChildAffectedRows: 2 })).action).toBe("stop"); + expect(decideRecovery(evidence({ dmlChildAffectedRows: 0 })).reason) + .toMatch(/not exactly 1/); + }); + + it("refuses to reconstruct a row whose hash does not match its intent", () => { + const tampered = { ...theIntent, rowHash: sha256Hex("something else") }; + expect(() => reconstructTerminalRow(tampered)).toThrow(/ROW_HASH_MISMATCH/); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/sandbox-guard.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/sandbox-guard.test.ts new file mode 100644 index 0000000..ba2d278 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/sandbox-guard.test.ts @@ -0,0 +1,198 @@ +/** + * The sandbox guard, tested as a control rather than as a helper. + * + * The question each test answers is "what does this refuse", not "does the happy path work". A + * convenience wrapper and a control are indistinguishable while nothing goes wrong; they differ + * only at the moment something does. + */ + +import { describe, it, expect, beforeEach, afterEach } from "vitest"; +import { + PROTECTED_DATASETS, SANDBOX_PURPOSE_LABEL, SandboxRefusal, + isProtectedDataset, assertNotProtectedDataset, sandboxDatasetId, purposeLabelValue, + createSandbox, dropSandbox, withSandbox, setDatasetAdmin, + type DatasetAdmin, type CreateDatasetOptions, +} from "../../src/sandbox.js"; + +/** An in-memory project. Records every call so a test can assert what did NOT happen. */ +class FakeAdmin implements DatasetAdmin { + datasets = new Map>(); + readonly deletes: string[] = []; + readonly creates: string[] = []; + listThrows: Error | null = null; + + constructor(seed: string[] = []) { + for (const id of seed) this.datasets.set(id, {}); + } + + async listDatasets(): Promise { + if (this.listThrows) throw this.listThrows; + return [...this.datasets.keys()].sort(); + } + + async createDataset(datasetId: string, options: CreateDatasetOptions): Promise { + this.creates.push(datasetId); + this.datasets.set(datasetId, options.labels); + } + + async labelsOf(datasetId: string): Promise | null> { + return this.datasets.get(datasetId) ?? null; + } + + async deleteDataset(datasetId: string): Promise { + this.deletes.push(datasetId); + this.datasets.delete(datasetId); + } +} + +let admin: FakeAdmin; + +beforeEach(() => { + admin = new FakeAdmin(["BlockchainEvents", "Staging", "Semantic", "Marts", "dev_sandbox"]); + setDatasetAdmin(admin); +}); + +afterEach(() => setDatasetAdmin(null)); + +describe("the refusal is by hard-coded name, not by configuration", () => { + it("names BlockchainEvents in the source and refuses it", () => { + expect(PROTECTED_DATASETS).toContain("BlockchainEvents"); + expect(isProtectedDataset("BlockchainEvents")).toBe(true); + expect(() => assertNotProtectedDataset("BlockchainEvents", "test")).toThrow(SandboxRefusal); + }); + + it("refuses every dbt layer built on production too", () => { + for (const name of ["Staging", "Semantic", "Marts"]) { + expect(() => assertNotProtectedDataset(name, "test")).toThrow(SandboxRefusal); + } + }); + + it("refuses regardless of casing, because a dataset id comparison is not case sensitive here", () => { + expect(() => assertNotProtectedDataset("blockchainevents", "test")).toThrow(SandboxRefusal); + expect(() => assertNotProtectedDataset(" BLOCKCHAINEVENTS ", "test")).toThrow(SandboxRefusal); + }); + + it("refuses to CREATE a sandbox named BlockchainEvents, and writes nothing while refusing", async () => { + // config.ts defaults DATASET_ID to BlockchainEvents, so this is the exact shape of the + // accident: a caller that forgets one environment variable asks for production by name. + await expect(createSandbox({ purpose: "unit-03-test", datasetId: "BlockchainEvents" })) + .rejects.toThrow(/protected dataset/); + expect(admin.creates).toEqual([]); + }); + + it("refuses to DELETE BlockchainEvents even when handed a handle that claims it is a sandbox", async () => { + await expect(dropSandbox({ + datasetId: "BlockchainEvents", + purposeLabel: "unit-03-test", + location: "US", + createdAt: new Date().toISOString(), + })).rejects.toThrow(/protected dataset/); + expect(admin.deletes).toEqual([]); + }); + + it("lets an ordinary sandbox name through, so the refusal discriminates", () => { + expect(isProtectedDataset("sbx_unit03_coverage_20260929T014230Z_q3bywk")).toBe(false); + expect(() => assertNotProtectedDataset("sbx_unit03_coverage", "test")).not.toThrow(); + }); +}); + +describe("a sandbox must be uniquely named and purpose-labelled", () => { + it("refuses a name that already exists rather than reusing it", async () => { + await expect(createSandbox({ purpose: "unit-03-test", datasetId: "dev_sandbox" })) + .rejects.toThrow(/already exists/); + expect(admin.creates).toEqual([]); + }); + + it("refuses when the listing that would prove uniqueness fails", async () => { + admin.listThrows = new Error("listing unavailable"); + await expect(createSandbox({ purpose: "unit-03-test" })).rejects.toThrow("listing unavailable"); + expect(admin.creates).toEqual([]); + }); + + it("generates a legal, unique, self-describing dataset id", () => { + const id = sandboxDatasetId("unit-03 coverage", new Date("2026-09-29T01:42:30.123Z"), "q3bywk"); + expect(id).toBe("sbx_unit_03_coverage_20260929T014230Z_q3bywk"); + expect(id).toMatch(/^[A-Za-z0-9_]+$/); + }); + + it("carries the purpose label at creation", async () => { + const handle = await createSandbox({ purpose: "unit-03-coverage" }); + expect(admin.datasets.get(handle.datasetId)).toEqual({ [SANDBOX_PURPOSE_LABEL]: "unit-03-coverage" }); + }); + + it("refuses a purpose that cannot become a legal label", () => { + expect(() => purposeLabelValue("!!")).toThrow(SandboxRefusal); + expect(purposeLabelValue("Unit 03 Coverage")).toBe("unit-03-coverage"); + }); +}); + +describe("cleanup checks the label first and proves absence by listing", () => { + it("deletes only after reading the label back off the live dataset", async () => { + const handle = await createSandbox({ purpose: "unit-03-coverage" }); + const result = await dropSandbox(handle); + + expect(result.labelChecked).toBe("unit-03-coverage"); + expect(admin.deletes).toEqual([handle.datasetId]); + expect(result.provenAbsent).toBe(true); + expect(result.datasetsAfter).not.toContain(handle.datasetId); + }); + + it("refuses to delete when the live label disagrees with the handle", async () => { + const handle = await createSandbox({ purpose: "unit-03-coverage" }); + // Something else now occupies the name. The handle is a claim; the label is the evidence. + admin.datasets.set(handle.datasetId, { [SANDBOX_PURPOSE_LABEL]: "someone-elses-work" }); + + await expect(dropSandbox(handle)).rejects.toThrow(/not provably the one this run created/); + expect(admin.deletes).toEqual([]); + }); + + it("refuses to delete a dataset carrying no purpose label at all", async () => { + // The two leftover datasets in this project carry no labels, which is why neither could be + // judged disposable. An unlabelled dataset is never this run's to remove. + const handle = await createSandbox({ purpose: "unit-03-coverage" }); + admin.datasets.set(handle.datasetId, {}); + + await expect(dropSandbox(handle)).rejects.toThrow(/purpose=\(none\)/); + expect(admin.deletes).toEqual([]); + }); + + it("reports NOT proven absent when the delete succeeds and the listing still shows it", async () => { + // A cleanup receipt in this corpus is known wrong at least once. The listing decides, not + // the delete call's return value. + const handle = await createSandbox({ purpose: "unit-03-coverage" }); + admin.deleteDataset = async (id: string) => { admin.deletes.push(id); }; + + const result = await dropSandbox(handle); + expect(admin.deletes).toEqual([handle.datasetId]); + expect(result.provenAbsent).toBe(false); + expect(result.detail).toMatch(/still present/); + }); + + it("treats an already-absent dataset as nothing to do, not as a failure", async () => { + const handle = await createSandbox({ purpose: "unit-03-coverage" }); + admin.datasets.delete(handle.datasetId); + + const result = await dropSandbox(handle); + expect(result.provenAbsent).toBe(true); + expect(result.labelChecked).toBeNull(); + expect(admin.deletes).toEqual([]); + }); +}); + +describe("withSandbox cleans up on both paths", () => { + it("drops the sandbox after the work succeeds", async () => { + const { result, cleanup } = await withSandbox({ purpose: "unit-03-coverage" }, async (h) => h.datasetId); + expect(admin.datasets.has(result)).toBe(false); + expect(cleanup.provenAbsent).toBe(true); + }); + + it("drops the sandbox when the work throws, and still raises the original error", async () => { + await expect( + withSandbox({ purpose: "unit-03-coverage" }, async () => { throw new Error("the work failed"); }) + ).rejects.toThrow("the work failed"); + + expect(admin.creates).toHaveLength(1); + expect(admin.deletes).toEqual(admin.creates); + expect([...admin.datasets.keys()]).not.toContain(admin.creates[0]); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/transaction-grain-guards.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/transaction-grain-guards.test.ts new file mode 100644 index 0000000..016d1b1 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/transaction-grain-guards.test.ts @@ -0,0 +1,155 @@ +/** + * Green guards for the transaction grain, mirroring the H5 red tests. + * + * The H5 fixtures live in the known-failures suite, which the default suite and its coverage run + * never execute. A fix whose only exercise is a RED suite is one config change away from being + * unexercised, and the branch it added would sit uncovered in the module it changed. So the same + * behaviour is asserted here, green, in the suite that runs on every push. + * + * Same pattern as `reader-regression-guards.test.ts`: a guard is not a duplicate of a red test, + * it is the thing that keeps the red test from being the only witness. + */ + +import { describe, it, expect, beforeEach, afterEach } from "vitest"; +import { runPipeline } from "../../src/pipeline.js"; +import { setBigQueryClient, setReaderOverride, resetAdapters } from "../../src/adapters.js"; +import { BigQuerySimulator } from "../helpers/bq-simulator.js"; +import { hash32, RAW_LOGS_COLUMNS, TRANSACTIONS_COLUMNS } from "../helpers/fixtures.js"; +import { RAW_LOGS_TABLE, TRANSACTIONS_TABLE } from "../../src/config.js"; + +const ADDRESS = "0x22867567e2d80f2049200e25c6f31cb6ec2f0faf"; + +/** Two logs, two distinct transaction hashes, and only ONE transaction returned. */ +function chunk(transactions: unknown[]) { + return { + fromBlock: 1_000, toBlock: 1_010, ok: true, + logs: [ + { + blockNumber: 1_000, blockHash: hash32("bh1"), transactionHash: hash32("tx1"), + transactionIndex: 0, logIndex: 0, address: ADDRESS, + data: "0x", topics: [hash32("t0")], removed: false, + }, + { + blockNumber: 1_001, blockHash: hash32("bh2"), transactionHash: hash32("tx2"), + transactionIndex: 0, logIndex: 0, address: ADDRESS, + data: "0x", topics: [hash32("t0")], removed: false, + }, + ], + transactions, + blocks: [ + { number: 1_000, hash: hash32("bh1"), timestamp: 1_781_000_000 }, + { number: 1_001, hash: hash32("bh2"), timestamp: 1_781_000_005 }, + ], + nextBlock: 1_011, archiveHeight: 2_000, rollbackGuard: null, + sourceKind: "index" as const, sourceId: "hypersync:xdc", attempts: [], ms: 0, + }; +} + +function transaction(name: string, blockNumber: number, blockHash: string) { + return { + hash: hash32(name), blockNumber, blockHash, transactionIndex: 0, + from: "0x0000000000000000000000000000000000000001", to: null, value: "0", nonce: "0", + gas: "21000", gasUsed: "21000", effectiveGasPrice: "1", input: "0x", kind: 2, status: 1, + contractAddress: null, + }; +} + +let sim: BigQuerySimulator; + +beforeEach(() => { + sim = new BigQuerySimulator(); + sim.defineTable("RawLogs", RAW_LOGS_COLUMNS, []); + sim.defineTable("Transactions", TRANSACTIONS_COLUMNS, []); + setBigQueryClient(sim); +}); + +afterEach(() => resetAdapters()); + +function reader(transactions: unknown[]) { + setReaderOverride(async (_n, _a, from, to, onChunk) => { + await onChunk(chunk(transactions) as any); + return { + fromBlock: from, toBlock: to, chunksPlanned: 1, chunksOk: 1, + skipped: [], errors: [], emptyChunks: [], logsSeen: 2, complete: true, + sourceKind: "index", sourceId: "hypersync:xdc", enumeratingSources: 1, + headAtCapture: 2_000, rollbackGuards: [], + }; + }); +} + +const backfill = () => runPipeline({ + mode: "backfill", chains: ["XDC"], addresses: [ADDRESS], fromBlock: 1_000, toBlock: 1_010, +}); + +const coverageRows = () => sim.tables.get("IngestionCoverage")?.rows ?? []; + +describe("the transaction grain carries its own verdict", () => { + it("marks ONLY the Transactions row incomplete when a transaction is missing", async () => { + reader([transaction("tx1", 1_000, hash32("bh1"))]); + await backfill(); + + const rows = coverageRows(); + expect(rows.find((r) => r.target_table === TRANSACTIONS_TABLE)?.status).toBe("incomplete"); + // The log range genuinely completed. Marking it incomplete would be the opposite error and + // would stall the resume point over a defect in a different grain. + expect(rows.find((r) => r.target_table === RAW_LOGS_TABLE)?.status).toBe("complete"); + }); + + it("says in the row WHY, rather than leaving a status with no account of itself", async () => { + reader([transaction("tx1", 1_000, hash32("bh1"))]); + await backfill(); + + const tx = coverageRows().find((r) => r.target_table === TRANSACTIONS_TABLE); + expect(tx?.error_message).toContain("MISSING_TRANSACTIONS: 1"); + expect(tx?.error_message).toContain("NOT complete for the transaction grain"); + }); + + it("reaches the run counters, so the command cannot exit zero", async () => { + reader([transaction("tx1", 1_000, hash32("bh1"))]); + const result = await backfill(); + + expect(result.failed).toBeGreaterThan(0); + expect(result.summary.totals.incomplete).toBe(1); + expect(result.summary.byGrain.get(TRANSACTIONS_TABLE)).toMatchObject({ incomplete: 1, completed: 0 }); + expect(result.summary.byGrain.get(RAW_LOGS_TABLE)).toMatchObject({ completed: 1, incomplete: 0 }); + }); + + it("names the grain in the outcome, not just the contract", async () => { + reader([transaction("tx1", 1_000, hash32("bh1"))]); + const result = await backfill(); + + const problem = result.summary.problems[0]; + expect(problem.grain).toBe(TRANSACTIONS_TABLE); + expect(problem.detail).toMatch(/transaction\(s\) pointed at by a captured log were not returned/); + }); + + it("DISCRIMINATES: both grains complete when every transaction comes back", async () => { + // Without this the tests above would also pass on a build that marks the transaction grain + // incomplete unconditionally, which is a different defect with the same green ticks. + reader([transaction("tx1", 1_000, hash32("bh1")), transaction("tx2", 1_001, hash32("bh2"))]); + const result = await backfill(); + + const rows = coverageRows(); + expect(rows.find((r) => r.target_table === TRANSACTIONS_TABLE)?.status).toBe("complete"); + expect(rows.find((r) => r.target_table === TRANSACTIONS_TABLE)?.error_message).toBe(""); + expect(result.failed).toBe(0); + expect(result.summary.totals.completed).toBe(2); + }); + + it("records two rows and two outcomes, one per grain", async () => { + reader([transaction("tx1", 1_000, hash32("bh1")), transaction("tx2", 1_001, hash32("bh2"))]); + const result = await backfill(); + + expect(coverageRows().map((r) => r.target_table).sort()).toEqual([RAW_LOGS_TABLE, TRANSACTIONS_TABLE]); + expect(result.summary.units.map((u) => u.grain).sort()).toEqual([RAW_LOGS_TABLE, TRANSACTIONS_TABLE]); + }); + + it("keeps totalRows meaning RawLogs rows merged, not logs plus transactions", async () => { + // It is persisted as `totalRowsMerged`. Adding the transaction rows to it would change what a + // shipped column means rather than report a new fact. + reader([transaction("tx1", 1_000, hash32("bh1")), transaction("tx2", 1_001, hash32("bh2"))]); + const result = await backfill(); + + expect(result.totalRows).toBe(2); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/test/unit/write-safety.test.ts b/projects/onchain-analytics/pipeline-v5/test/unit/write-safety.test.ts new file mode 100644 index 0000000..590f5f3 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/test/unit/write-safety.test.ts @@ -0,0 +1,440 @@ +/** + * write-safety.test.ts -- the controls that stand between this pipeline and a duplicated or + * runaway write. + * + * FOUR SUBJECTS, each of which exists because its absence was measured on this system. + * + * THE CROSS-PROCESS LEASE. `C1`: two captures of one range ran at once, both exited 0, and + * RawLogs held 149 rows over 102 keys. The lease excludes the second writer. + * + * THE COVERAGE CONSEQUENCE OF A REFUSAL, which is the half a row count cannot show. The + * original incident was invisible because BOTH processes wrote a coverage row saying + * `complete`. A correct row count with two `complete` rows is not a fix. So the refusal has to + * travel: refused write, thrown capture, `incomplete` coverage, nonzero exit. + * + * THE COST CEILING. `maximumBytesBilled` on every statement, attached at the one chokepoint + * every statement passes through, because a ceiling that jobs can be written without is a + * convention rather than a control. + * + * THE STAGING SPLIT. Staging tables are created and dropped, so they must not live in the + * dataset holding production rows -- otherwise the writer identity needs `tables.delete` on + * the production raw layer, which is one of the permissions this system is built to keep + * revoked. + * + * The two-OS-process reproduction is NOT here, deliberately: everything below runs in one + * process, and within-process repetition has already produced a wrong conclusion on this + * project. It lives in `test/integration/two-process-merge.gate.ts`, which needs a credential. + */ + +import { describe, it, expect, afterEach } from "vitest"; +import { mkdtempSync, rmSync, existsSync, readFileSync, writeFileSync, readdirSync } from "fs"; +import { tmpdir, hostname } from "os"; +import { join } from "path"; +import { stageAndMerge, bqQuery } from "../../src/bq.js"; +import { runPipeline } from "../../src/pipeline.js"; +import { + CONFIG, RAW_LOGS_TABLE, RAW_LOGS_SCHEMA, MERGE_KEYS, + stagingTableName, assertStagingIsSeparate, +} from "../../src/config.js"; +import { windowForRows } from "../../src/window.js"; +import { fileWriteLock, leaseFileName } from "../../src/writelock.js"; +import { setBigQueryClient, setWriteLock, setReaderOverride, resetAdapters } from "../../src/adapters.js"; +import { BigQuerySimulator } from "../helpers/bq-simulator.js"; +import { rawLogRow, RAW_LOGS_COLUMNS, C1_RANGE, XDC_CHAIN_ID, hash32 } from "../helpers/fixtures.js"; + +const KEY = MERGE_KEYS[RAW_LOGS_TABLE]; +const tempDirs: string[] = []; + +function lockDir(): string { + const dir = mkdtempSync(join(tmpdir(), "gd-writelock-test-")); + tempDirs.push(dir); + return dir; +} + +afterEach(() => { + resetAdapters(); + for (const d of tempDirs.splice(0)) rmSync(d, { recursive: true, force: true }); +}); + +function simulator(): BigQuerySimulator { + const sim = new BigQuerySimulator(); + sim.defineTable(RAW_LOGS_TABLE, RAW_LOGS_COLUMNS, []); + setBigQueryClient(sim); + return sim; +} + +describe("the cross-process write lease", () => { + it("admits one holder at a time and refuses the second when it will not wait", async () => { + const lock = fileWriteLock({ dir: lockDir(), waitMs: 0, pollMs: 1 }); + + const first = await lock.acquire(RAW_LOGS_TABLE, null); + expect(first, "the first caller must be admitted").not.toBeNull(); + + // waitMs 0 means the second caller does not queue; it is told no. That is what turns a + // losing writer into a nonzero exit instead of a duplicate row. + const second = await lock.acquire(RAW_LOGS_TABLE, null); + expect(second, "a held lease must refuse rather than admit a second writer").toBeNull(); + + await first!.release(); + + const third = await lock.acquire(RAW_LOGS_TABLE, null); + expect(third, "a released lease must be acquirable again").not.toBeNull(); + await third!.release(); + }); + + it("waits for a held lease rather than refusing, when it is given time", async () => { + const lock = fileWriteLock({ dir: lockDir(), waitMs: 5_000, pollMs: 5 }); + + const first = await lock.acquire(RAW_LOGS_TABLE, null); + let secondAdmittedAt = 0; + const waiter = lock.acquire(RAW_LOGS_TABLE, null).then((h) => { + secondAdmittedAt = Date.now(); + return h; + }); + + await new Promise((r) => setTimeout(r, 60)); + const releasedAt = Date.now(); + await first!.release(); + + const second = await waiter; + expect(second, "a waiter given time must be admitted, not refused").not.toBeNull(); + expect( + secondAdmittedAt, + "the waiter must not have been admitted before the holder let go" + ).toBeGreaterThanOrEqual(releasedAt); + await second!.release(); + }); + + it("holds the lease per table, so an unrelated table is not blocked", async () => { + const lock = fileWriteLock({ dir: lockDir(), waitMs: 0, pollMs: 1 }); + const logs = await lock.acquire(RAW_LOGS_TABLE, null); + const txs = await lock.acquire("Transactions", null); + + expect(logs).not.toBeNull(); + expect(txs, "a different table is a different lease").not.toBeNull(); + await logs!.release(); + await txs!.release(); + }); + + it("reclaims a lease whose holder is no longer running, without waiting out the expiry", async () => { + const dir = lockDir(); + // A pid that cannot be running: the killed-mid-MERGE case. Without liveness detection this + // lease would block every later run for a full expiry period, which is how a crash turns + // into an unwritable table -- and the expiry cannot simply be shortened, because reclaiming + // a lease that is merely slow reintroduces the concurrent write. + const dead = { + token: "stale-token", pid: 0x7fffffff, host: hostname(), + tableId: RAW_LOGS_TABLE, acquiredAt: new Date().toISOString(), window: null, + }; + writeFileSync( + join(dir, leaseFileName(CONFIG.GCP_PROJECT_ID, CONFIG.DATASET_ID, RAW_LOGS_TABLE)), + JSON.stringify(dead) + ); + + const lock = fileWriteLock({ dir, waitMs: 0, pollMs: 1, staleMs: 60 * 60_000 }); + const handle = await lock.acquire(RAW_LOGS_TABLE, null); + + expect( + handle, + "a lease held by a dead process must be reclaimed at once, not held until it expires" + ).not.toBeNull(); + await handle!.release(); + }); + + it("reclaims a lease that has passed its expiry even when the holder cannot be asked about", async () => { + const dir = lockDir(); + const foreign = { + token: "old-token", pid: 1, host: "some-other-machine", + tableId: RAW_LOGS_TABLE, acquiredAt: new Date(Date.now() - 10 * 60_000).toISOString(), + window: null, + }; + writeFileSync( + join(dir, leaseFileName(CONFIG.GCP_PROJECT_ID, CONFIG.DATASET_ID, RAW_LOGS_TABLE)), + JSON.stringify(foreign) + ); + + const handle = await fileWriteLock({ dir, waitMs: 0, pollMs: 1, staleMs: 60_000 }) + .acquire(RAW_LOGS_TABLE, null); + expect(handle, "a lease older than its expiry is abandoned").not.toBeNull(); + await handle!.release(); + }); + + it("will not delete a lease that was reclaimed from it, which would admit a third writer", async () => { + const dir = lockDir(); + const path = join(dir, leaseFileName(CONFIG.GCP_PROJECT_ID, CONFIG.DATASET_ID, RAW_LOGS_TABLE)); + const lock = fileWriteLock({ dir, waitMs: 0, pollMs: 1 }); + + const mine = await lock.acquire(RAW_LOGS_TABLE, null); + // Somebody else reclaimed it as stale while this holder was still running. Releasing by + // unlinking the path would delete THEIR lease. + const theirs = { ...JSON.parse(readFileSync(path, "utf8")), token: "someone-elses-token" }; + writeFileSync(path, JSON.stringify(theirs)); + + await mine!.release(); + + expect(existsSync(path), "the other holder's lease must survive our release").toBe(true); + expect(JSON.parse(readFileSync(path, "utf8")).token).toBe("someone-elses-token"); + }); + + it("names the lease by dataset, so a sandbox write does not contend with production", () => { + const production = leaseFileName("gooddollar", "BlockchainEvents", RAW_LOGS_TABLE); + const sandbox = leaseFileName("gooddollar", "sbx_unit06_20260929Z_ab12cd", RAW_LOGS_TABLE); + expect(production).not.toBe(sandbox); + }); +}); + +describe("a refused write does not leave a capture looking complete", () => { + const ADDRESS = "0x22867567e2d80f2049200e25c6f31cb6ec2f0faf"; + + /** + * A reader that returns one log and reports the range fully read. + * + * `complete: true` and an empty `rollbackGuards` are load-bearing rather than boilerplate: + * `pipeline.ts` derives status from them first, so a fixture that omitted either would record + * `incomplete` for a reason that has nothing to do with the write lock, and the refusal test + * above it would pass while proving nothing. The discrimination case below is what catches + * that, and it caught exactly this. + */ + function readerReturningOneLog(): void { + setReaderOverride(async (_n, _addresses, from, to, onChunk) => { + await onChunk({ + fromBlock: from, toBlock: to, + logs: [{ + address: ADDRESS, blockNumber: from, blockHash: hash32(`b${from}`), + transactionHash: hash32(`t${from}`), transactionIndex: 0, logIndex: 0, + topics: [hash32("topic0")], data: "0x", removed: false, + }], + transactions: [], blocks: [{ number: from, hash: hash32(`b${from}`), timestamp: 1_781_000_000 }], + sourceKind: "index", sourceId: "hypersync:xdc.hypersync.xyz", archiveHeight: to + 100, + } as any); + return { + fromBlock: from, toBlock: to, chunksPlanned: 1, chunksOk: 1, logsSeen: 1, + skipped: [], errors: [], emptyChunks: [], complete: true, + sourceKind: "index", sourceId: "hypersync:xdc.hypersync.xyz", + enumeratingSources: 1, headAtCapture: to + 100, rollbackGuards: [], + } as any; + }); + } + + const runOneCapture = () => runPipeline({ + mode: "backfill", chains: ["XDC"], addresses: [ADDRESS], + fromBlock: 100_000_000, toBlock: 100_000_010, + }); + + /** + * `C1`'s third clause, which is the one that made the original incident invisible. + * + * Both processes exited 0 and both wrote `complete`. A correct row count with two `complete` + * coverage rows is a failed fix, so the refusal has to be visible in the ledger and not only + * in the table. This drives the real capture path with a lock that refuses. + */ + it("records incomplete, never complete, when the write lock refuses", async () => { + const sim = simulator(); + setWriteLock({ acquire: async () => null }); + readerReturningOneLog(); + + await runOneCapture(); + + const coverage = sim.tables.get("IngestionCoverage")?.rows ?? []; + expect(coverage.length, "a refused write must still leave a coverage row").toBeGreaterThan(0); + + const complete = coverage.filter((r) => r.status === "complete"); + expect( + complete.length, + `A refused writer recorded ${complete.length} coverage row(s) as complete. That is the ` + + `exact shape of the original incident: the rows were wrong and the ledger said they were ` + + `fine. A refusal must never read as a clean capture.` + ).toBe(0); + + // Asserted on the RawLogs grain by name. The transaction grain returns its own `incomplete` + // whenever a captured log points at a transaction the reader did not return, which it does + // here -- so `some row says incomplete` would have passed with the lock removed entirely. + const logsRow = coverage.find((r) => r.target_table === RAW_LOGS_TABLE); + expect(logsRow, "the RawLogs grain must have a coverage row").toBeDefined(); + expect(logsRow!.status).toBe("incomplete"); + expect( + String(logsRow!.error_message ?? ""), + "the coverage row must name the refusal, so the cause is queryable rather than inferred" + ).toContain("WRITE_LOCK_REFUSED"); + }); + + it("DISCRIMINATION: the same capture with a granting lock records complete", async () => { + const sim = simulator(); + setWriteLock({ acquire: async () => ({ release: async () => {} }) }); + readerReturningOneLog(); + + await runOneCapture(); + + // If this ever fails, the test above proves nothing: it would be reporting "not complete" + // for a reason that has nothing to do with the lock. + const coverage = sim.tables.get("IngestionCoverage")?.rows ?? []; + const logsRow = coverage.find((r) => r.target_table === RAW_LOGS_TABLE); + expect( + logsRow?.status, + `The identical capture with a GRANTING lock did not record the RawLogs grain complete, so ` + + `the refusal test above is not measuring the lock. Statuses seen: ` + + `${coverage.map((r) => `${r.target_table}=${r.status}`).join(", ") || "(none)"}.` + ).toBe("complete"); + expect( + String(logsRow?.error_message ?? ""), + "a granted lock must leave no refusal note behind" + ).not.toContain("WRITE_LOCK_REFUSED"); + }); +}); + +describe("the per-job cost ceiling", () => { + it("puts maximumBytesBilled on every statement, because they all pass one chokepoint", async () => { + const seen: (string | undefined)[] = []; + setBigQueryClient({ + query: async (req: any) => { seen.push(req.maximumBytesBilled); return [[]]; }, + dataset: () => ({ table: () => ({ load: async () => [{}], getMetadata: async () => [{}] }) }), + } as any); + + await bqQuery("SELECT 1"); + await bqQuery("DELETE FROM x WHERE y = @z", { z: 1 }, { z: "INT64" }); + + expect(seen).toHaveLength(2); + for (const v of seen) { + expect(v, "a statement with no ceiling is an unbounded bill").toBe( + String(CONFIG.MAX_BYTES_BILLED_PER_JOB) + ); + } + }); + + it("sends the ceiling as a string, because the REST field is an int64", async () => { + let captured: any; + setBigQueryClient({ + query: async (req: any) => { captured = req.maximumBytesBilled; return [[]]; }, + dataset: () => ({ table: () => ({ load: async () => [{}], getMetadata: async () => [{}] }) }), + } as any); + + await bqQuery("SELECT 1"); + expect(typeof captured).toBe("string"); + expect(Number(captured)).toBe(10 * 1024 * 1024 * 1024); + }); + + it("does not retry a refusal, because the same statement is refused identically every time", async () => { + let attempts = 0; + setBigQueryClient({ + query: async () => { + attempts += 1; + throw new Error( + "Query exceeded limit for bytes billed: 10737418240. 21474836480 or higher required." + ); + }, + dataset: () => ({ table: () => ({ load: async () => [{}], getMetadata: async () => [{}] }) }), + } as any); + + await expect(bqQuery("SELECT * FROM enormous")).rejects.toThrow(/exceeded limit for bytes billed/); + expect( + attempts, + `A refusal was attempted ${attempts} times. Retrying a cost refusal cannot succeed and only ` + + `delays the error behind ${CONFIG.BQ_RETRIES} backoffs.` + ).toBe(1); + }); +}); + +describe("the staging split", () => { + it("composes a staging name from the staging dataset, not the production one", () => { + const name = stagingTableName("_staging_RawLogs_abc123"); + expect(name).toContain(CONFIG.STAGING_DATASET_ID); + expect( + name.includes(`.${CONFIG.DATASET_ID}.`), + "a staging table inside the production dataset is the defect this split removes" + ).toBe(false); + }); + + it("refuses to compose a staging name at all if the two datasets are configured the same", () => { + const original = CONFIG.STAGING_DATASET_ID; + try { + (CONFIG as any).STAGING_DATASET_ID = CONFIG.DATASET_ID; + expect(() => assertStagingIsSeparate()).toThrow(/STAGING_NOT_SEPARATE/); + expect(() => stagingTableName("_staging_RawLogs_abc123")).toThrow(/STAGING_NOT_SEPARATE/); + } finally { + (CONFIG as any).STAGING_DATASET_ID = original; + } + }); + + it("creates, reads and drops the staging table in the staging dataset during a real merge", async () => { + const sim = simulator(); + const rows = Array.from({ length: 3 }, (_, i) => + rawLogRow({ blockNumber: C1_RANGE.from + i, txHash: hash32(`split-${i}`), logIndex: 0, chainId: XDC_CHAIN_ID }) + ); + // The simulator records the dataset each handle was opened against, so "which dataset did + // the load go to" is answerable rather than inferred from the SQL text alone. + await stageAndMerge(RAW_LOGS_TABLE, rows, RAW_LOGS_SCHEMA, "run-split", windowForRows(rows, 1)!); + + const stagingRefs = sim.statements + .filter((s) => /_staging_/.test(s.sql)) + .map((s) => s.sql); + expect(stagingRefs.length, "the merge must reference a staging table").toBeGreaterThan(0); + + for (const sql of stagingRefs) { + for (const ref of sql.match(/`[^`]*_staging_[^`]*`/g) ?? []) { + expect( + ref, + `Staging reference ${ref} resolves into the production dataset. Every staging create, ` + + `read and drop must route to ${CONFIG.STAGING_DATASET_ID}.` + ).toContain(`.${CONFIG.STAGING_DATASET_ID}.`); + } + } + + const dropped = sim.statements.filter((s) => s.kind === "drop"); + expect(dropped.length, "the staging table must be dropped").toBeGreaterThan(0); + expect(dropped[0].sql).toContain(`.${CONFIG.STAGING_DATASET_ID}.`); + expect(sim.rowsOf(RAW_LOGS_TABLE)).toHaveLength(3); + }); + + it("leaves no lease files behind after a merge", async () => { + const dir = lockDir(); + setWriteLock(fileWriteLock({ dir, waitMs: 1_000, pollMs: 5 })); + const sim = simulator(); + const rows = [rawLogRow({ blockNumber: C1_RANGE.from, txHash: hash32("lease"), logIndex: 0, chainId: XDC_CHAIN_ID })]; + + await stageAndMerge(RAW_LOGS_TABLE, rows, RAW_LOGS_SCHEMA, "run-lease", windowForRows(rows, 1)!); + + expect(sim.rowsOf(RAW_LOGS_TABLE)).toHaveLength(1); + expect( + readdirSync(dir), + "a lease that outlives its merge blocks the next run" + ).toHaveLength(0); + }); + + it("releases the lease even when the merge throws", async () => { + const dir = lockDir(); + setWriteLock(fileWriteLock({ dir, waitMs: 1_000, pollMs: 5 })); + const sim = new BigQuerySimulator(); + // No RawLogs defined, so `liveColumns` throws part way through the write path. + setBigQueryClient(sim); + const rows = [rawLogRow({ blockNumber: C1_RANGE.from, txHash: hash32("throw"), logIndex: 0, chainId: XDC_CHAIN_ID })]; + + await expect( + stageAndMerge(RAW_LOGS_TABLE, rows, RAW_LOGS_SCHEMA, "run-throw", windowForRows(rows, 1)!) + ).rejects.toThrow(); + + expect( + readdirSync(dir), + "a lease held by a failed merge would block every later run" + ).toHaveLength(0); + }); +}); + +describe("the merge key is checked, not assumed", () => { + it("reports a phantom row rather than leaving a duplicate silent", async () => { + const sim = simulator(); + const key = { txHash: hash32("dup"), logIndex: 0, chainId: XDC_CHAIN_ID }; + sim.defineTable(RAW_LOGS_TABLE, RAW_LOGS_COLUMNS, [ + rawLogRow({ ...key, blockNumber: 105_100_000, blockTimestamp: "2026-05-02T00:00:00.000Z" }), + rawLogRow({ ...key, blockNumber: 105_100_000, blockTimestamp: "2026-08-05T00:00:00.000Z" }), + ]); + + const { verifyMergeKeyUniqueness } = await import("../../src/bq.js"); + const result = await verifyMergeKeyUniqueness(RAW_LOGS_TABLE, XDC_CHAIN_ID); + + expect(result.ok).toBe(false); + expect(result.report.storedRows).toBe(2); + expect(result.report.distinctKeys).toBe(1); + expect(result.report.phantomRows).toBe(1); + expect(sim.distinctKeys(RAW_LOGS_TABLE, KEY).size).toBe(1); + }); +}); diff --git a/projects/onchain-analytics/pipeline-v5/tsconfig.json b/projects/onchain-analytics/pipeline-v5/tsconfig.json index e7fe927..963c87d 100644 --- a/projects/onchain-analytics/pipeline-v5/tsconfig.json +++ b/projects/onchain-analytics/pipeline-v5/tsconfig.json @@ -7,11 +7,11 @@ "esModuleInterop": true, "skipLibCheck": true, "outDir": "dist", - "rootDir": "src", "declaration": true, "resolveJsonModule": true, - "forceConsistentCasingInFileNames": true + "forceConsistentCasingInFileNames": true, + "noEmit": true }, - "include": ["src/**/*.ts"], - "exclude": ["node_modules", "dist"] + "include": ["src/**/*.ts", "test/**/*.ts", "vitest.config.ts", "vitest.known-failures.config.ts"], + "exclude": ["node_modules", "dist", "coverage"] } diff --git a/projects/onchain-analytics/pipeline-v5/vitest.config.ts b/projects/onchain-analytics/pipeline-v5/vitest.config.ts new file mode 100644 index 0000000..b88b689 --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/vitest.config.ts @@ -0,0 +1,41 @@ +import { defineConfig } from "vitest/config"; + +/** + * The DEFAULT suite. What `npm test` runs and what a pull request must pass. + * + * It deliberately EXCLUDES `test/known-failures/`, which holds the reproduced production defects. + * Those are red by design until the phase that owns each one fixes it, so including them here + * would make the release command permanently red for reasons a contributor cannot act on. + * + * The release command is `npm run verify:local`, and it runs BOTH. That is the arrangement plan + * Section 5 asks for: the harness is green, the known failures stay red, and the command that + * decides whether the candidate is releasable cannot be green while any of them is. + */ +export default defineConfig({ + test: { + include: ["test/unit/**/*.test.ts", "test/integration/**/*.test.ts"], + exclude: ["node_modules/**", "dist/**", "test/known-failures/**"], + environment: "node", + // Establishes a fake, credential-free environment before any src/ module is imported. + // config.ts exits the process on a missing ENVIO_API_TOKEN, so without this nothing imports. + setupFiles: ["test/setup/env.ts"], + // Adapters in `src/adapters.ts` are module-level holders, so two files mutating them at once + // would make the result depend on scheduling. One file at a time removes that entirely. + fileParallelism: false, + testTimeout: 20_000, + reporters: ["default"], + coverage: { + provider: "v8", + reporter: ["text-summary", "json-summary", "lcov"], + reportsDirectory: "coverage", + include: ["src/**/*.ts"], + // hs-worker.mjs is a child process entry point that only runs under a real HyperSync + // client, and index.ts's `main` is the process wrapper the tests deliberately do not start. + exclude: ["src/**/*.d.ts"], + // Phase 1 fixes nothing, so it is not held to the plan's 80 and 90 percent thresholds. + // The instrument is proven to work and the baseline is recorded; the phase that first + // fixes production code turns these on. + thresholds: undefined, + }, + }, +}); diff --git a/projects/onchain-analytics/pipeline-v5/vitest.known-failures.config.ts b/projects/onchain-analytics/pipeline-v5/vitest.known-failures.config.ts new file mode 100644 index 0000000..33e8f6e --- /dev/null +++ b/projects/onchain-analytics/pipeline-v5/vitest.known-failures.config.ts @@ -0,0 +1,25 @@ +import { defineConfig } from "vitest/config"; + +/** + * The KNOWN-FAILURES suite. Every reproduced production defect, as an executable test. + * + * EVERY TEST IN HERE IS EXPECTED TO FAIL, and that is the point. Each one names the finding it + * reproduces, the source line that causes it and the phase that owns the fix. None of them is + * skipped, none is marked `todo`, and none is wrapped in an expectation that inverts it, because + * a suite that passes while the defect is present proves nothing. + * + * A test leaves this suite when the phase that owns it makes it pass, at which point it moves to + * `test/unit` or `test/integration` and travels with the fix. Until then the release command sees + * this suite fail and refuses to call the candidate releasable. + */ +export default defineConfig({ + test: { + include: ["test/known-failures/**/*.test.ts"], + exclude: ["node_modules/**", "dist/**"], + environment: "node", + setupFiles: ["test/setup/env.ts"], + fileParallelism: false, + testTimeout: 20_000, + reporters: ["default"], + }, +}); diff --git a/projects/onchain-analytics/scripts/ops/bq-metadata-client.mjs b/projects/onchain-analytics/scripts/ops/bq-metadata-client.mjs new file mode 100644 index 0000000..dea844a --- /dev/null +++ b/projects/onchain-analytics/scripts/ops/bq-metadata-client.mjs @@ -0,0 +1,83 @@ +// Read-only BigQuery metadata client. +// +// This module can issue HTTP GET requests to the BigQuery metadata endpoints and nothing else. +// It has no query, job, insert, patch or delete path, and it contains no SQL. That is deliberate: +// the state manifest that operations tooling depends on must be impossible to turn into a writer, +// whatever a caller passes it. +// +// Authentication uses Application Default Credentials through the gcloud CLI. No key file is read +// and no token is written to disk or to stdout. + +import { execFileSync } from 'node:child_process'; + +const GET_ONLY_ENDPOINTS = [ + /^https:\/\/bigquery\.googleapis\.com\/bigquery\/v2\/projects\/[\w.-]+\/datasets(\?.*)?$/, + /^https:\/\/bigquery\.googleapis\.com\/bigquery\/v2\/projects\/[\w.-]+\/datasets\/[\w$-]+$/, + /^https:\/\/bigquery\.googleapis\.com\/bigquery\/v2\/projects\/[\w.-]+\/datasets\/[\w$-]+\/tables(\?.*)?$/, + /^https:\/\/bigquery\.googleapis\.com\/bigquery\/v2\/projects\/[\w.-]+\/datasets\/[\w$-]+\/tables\/[\w$-]+(\?.*)?$/, +]; + +let cachedToken = null; + +function accessToken() { + if (cachedToken) return cachedToken; + cachedToken = execFileSync( + process.env.COMSPEC || 'cmd.exe', + ['/c', 'gcloud', 'auth', 'application-default', 'print-access-token'], + { encoding: 'utf8', timeout: 180_000 } + ).trim(); + if (!cachedToken || cachedToken.length < 40) { + throw new Error('No access token was returned by gcloud. Run: gcloud auth application-default login'); + } + return cachedToken; +} + +/** + * Issues one GET against an allowlisted BigQuery metadata endpoint. + * Returns { ok, status, json, errorMessage }. An HTTP error never throws, so a caller can count + * errors separately from results instead of mistaking a failure for an empty answer. + */ +export async function get(url, { timeoutMs = 120_000 } = {}) { + if (!GET_ONLY_ENDPOINTS.some((pattern) => pattern.test(url))) { + throw new Error(`Refused: ${url} is not a BigQuery metadata endpoint on the read-only allowlist.`); + } + const controller = new AbortController(); + const timer = setTimeout(() => controller.abort(), timeoutMs); + try { + const res = await fetch(url, { + method: 'GET', + headers: { Authorization: `Bearer ${accessToken()}` }, + signal: controller.signal, + }); + const text = await res.text(); + let json; + try { json = JSON.parse(text); } catch { json = { raw: text.slice(0, 2000) }; } + return { + ok: res.ok, + status: res.status, + json, + errorMessage: res.ok ? null : (json?.error?.message ?? text.slice(0, 400)), + }; + } catch (e) { + return { ok: false, status: 0, json: null, errorMessage: `${e.name}: ${e.message}` }; + } finally { + clearTimeout(timer); + } +} + +export function listDatasetsUrl(project) { + return `https://bigquery.googleapis.com/bigquery/v2/projects/${project}/datasets?all=true&maxResults=1000`; +} + +export function datasetUrl(project, dataset) { + return `https://bigquery.googleapis.com/bigquery/v2/projects/${project}/datasets/${dataset}`; +} + +export function listTablesUrl(project, dataset, pageToken) { + const base = `https://bigquery.googleapis.com/bigquery/v2/projects/${project}/datasets/${dataset}/tables?maxResults=1000`; + return pageToken ? `${base}&pageToken=${encodeURIComponent(pageToken)}` : base; +} + +export function tableUrl(project, dataset, table) { + return `https://bigquery.googleapis.com/bigquery/v2/projects/${project}/datasets/${dataset}/tables/${table}`; +} diff --git a/projects/onchain-analytics/scripts/ops/diff-bq-manifest.mjs b/projects/onchain-analytics/scripts/ops/diff-bq-manifest.mjs new file mode 100644 index 0000000..70876d1 --- /dev/null +++ b/projects/onchain-analytics/scripts/ops/diff-bq-manifest.mjs @@ -0,0 +1,152 @@ +#!/usr/bin/env node +// Compares two BigQuery state manifests produced by generate-bq-manifest.mjs. +// +// Answers one question: What changed in the warehouse between these two readings? It reports +// added, removed and altered datasets and tables, and for an altered table it names the exact +// fields that moved rather than printing two large objects side by side. +// +// Usage: +// node diff-bq-manifest.mjs --baseline before.json --current after.json +// node diff-bq-manifest.mjs --baseline before.json --current after.json --out diff.json +// +// Exit codes: 0 when the two payloads are identical, 2 when they differ, 1 on a usage or read +// error. A nonzero exit from a scheduled comparison means someone or something changed the +// warehouse outside the intended path. + +import { readFileSync, writeFileSync, mkdirSync } from 'node:fs'; +import { dirname } from 'node:path'; + +function parseArgs(argv) { + const args = { baseline: null, current: null, out: null }; + for (let i = 0; i < argv.length; i += 1) { + const flag = argv[i]; + if (flag === '--baseline') args.baseline = argv[++i]; + else if (flag === '--current') args.current = argv[++i]; + else if (flag === '--out') args.out = argv[++i]; + else throw new Error(`Unknown argument: ${flag}`); + } + if (!args.baseline || !args.current) throw new Error('--baseline and --current are both required'); + return args; +} + +function load(path) { + const parsed = JSON.parse(readFileSync(path, 'utf8')); + if (!parsed.payload) throw new Error(`${path} has no payload. It was not produced by generate-bq-manifest.mjs.`); + return parsed; +} + +/** Field-level comparison of two flat-ish objects, ignoring the nested tables map. */ +function compareFields(before, after, skip = []) { + const changes = []; + const keys = new Set([...Object.keys(before ?? {}), ...Object.keys(after ?? {})]); + for (const key of keys) { + if (skip.includes(key)) continue; + const b = JSON.stringify(before?.[key] ?? null); + const a = JSON.stringify(after?.[key] ?? null); + if (b !== a) changes.push({ field: key, baseline: JSON.parse(b), current: JSON.parse(a) }); + } + return changes; +} + +function diffTables(baselineTables, currentTables) { + const added = []; + const removed = []; + const changed = []; + const ids = new Set([...Object.keys(baselineTables ?? {}), ...Object.keys(currentTables ?? {})]); + for (const id of [...ids].sort()) { + const b = baselineTables?.[id]; + const a = currentTables?.[id]; + if (!b) { added.push(id); continue; } + if (!a) { removed.push(id); continue; } + // schema_fields is already summarised by schema_sha256; comparing it twice only adds noise. + const fieldChanges = compareFields(b, a, ['schema_fields']); + if (fieldChanges.length > 0) changed.push({ table_id: id, changes: fieldChanges }); + } + return { added, removed, changed }; +} + +function main() { + const args = parseArgs(process.argv.slice(2)); + const baseline = load(args.baseline); + const current = load(args.current); + + const identical = baseline.payload_sha256 === current.payload_sha256; + + const datasetIds = new Set([ + ...Object.keys(baseline.payload.datasets ?? {}), + ...Object.keys(current.payload.datasets ?? {}), + ]); + + const datasetsAdded = []; + const datasetsRemoved = []; + const datasetChanges = []; + + for (const id of [...datasetIds].sort()) { + const b = baseline.payload.datasets?.[id]; + const a = current.payload.datasets?.[id]; + if (!b) { datasetsAdded.push(id); continue; } + if (!a) { datasetsRemoved.push(id); continue; } + const propertyChanges = compareFields(b, a, ['tables']); + const tableDiff = diffTables(b.tables, a.tables); + const anything = propertyChanges.length > 0 + || tableDiff.added.length > 0 || tableDiff.removed.length > 0 || tableDiff.changed.length > 0; + if (anything) { + datasetChanges.push({ dataset_id: id, property_changes: propertyChanges, tables: tableDiff }); + } + } + + const report = { + compared_at_utc: new Date().toISOString(), + baseline: { + path: args.baseline, + generated_at_utc: baseline.generated_at_utc, + payload_sha256: baseline.payload_sha256, + error_count: baseline.error_count, + }, + current: { + path: args.current, + generated_at_utc: current.generated_at_utc, + payload_sha256: current.payload_sha256, + error_count: current.error_count, + }, + identical, + datasets_added: datasetsAdded, + datasets_removed: datasetsRemoved, + dataset_changes: datasetChanges, + }; + + if (args.out) { + mkdirSync(dirname(args.out), { recursive: true }); + writeFileSync(args.out, `${JSON.stringify(report, null, 2)}\n`); + } + + console.log(`baseline sha256 : ${baseline.payload_sha256}`); + console.log(`current sha256 : ${current.payload_sha256}`); + console.log(`identical : ${identical}`); + console.log(`datasets added : ${datasetsAdded.length}`); + console.log(`datasets removed: ${datasetsRemoved.length}`); + console.log(`datasets changed: ${datasetChanges.length}`); + for (const d of datasetChanges) { + console.log(` ${d.dataset_id}: ${d.property_changes.length} property changes, ` + + `${d.tables.added.length} tables added, ${d.tables.removed.length} removed, ${d.tables.changed.length} altered`); + for (const t of d.tables.changed) { + console.log(` ${t.table_id}: ${t.changes.map((c) => c.field).join(', ')}`); + } + } + if (args.out) console.log(`written : ${args.out}`); + + // A baseline or current reading that itself had errors is incomplete, so a clean comparison + // between two incomplete readings must not be reported as proof that nothing changed. + if (baseline.error_count > 0 || current.error_count > 0) { + console.log('WARNING: at least one manifest was generated with errors and is incomplete.'); + } + + process.exit(identical ? 0 : 2); +} + +try { + main(); +} catch (e) { + console.error(`FAILED: ${e.message}`); + process.exit(1); +} diff --git a/projects/onchain-analytics/scripts/ops/generate-bq-manifest.mjs b/projects/onchain-analytics/scripts/ops/generate-bq-manifest.mjs new file mode 100644 index 0000000..bfb236c --- /dev/null +++ b/projects/onchain-analytics/scripts/ops/generate-bq-manifest.mjs @@ -0,0 +1,253 @@ +#!/usr/bin/env node +// Generates a deterministic state manifest for one or more BigQuery datasets. +// +// The manifest is the reference an operator diffs against to answer one question in a single +// command: Has anything in the warehouse changed that nobody intended to change? It records +// structure, storage and governance metadata for every table, materialized view and view. +// +// It is metadata only. No query job is submitted, no table data is read and no byte is billed. +// +// Usage: +// node generate-bq-manifest.mjs --project gooddollar --dataset BlockchainEvents --out manifest.json +// node generate-bq-manifest.mjs --project gooddollar --all-datasets --out manifest.json +// +// Exit codes: 0 when every requested dataset was read with zero errors, 1 otherwise. A nonzero +// exit means the manifest is incomplete and must not be used as a baseline. + +import { createHash } from 'node:crypto'; +import { writeFileSync, mkdirSync } from 'node:fs'; +import { dirname } from 'node:path'; +import { get, listDatasetsUrl, datasetUrl, listTablesUrl, tableUrl } from './bq-metadata-client.mjs'; + +const MANIFEST_SCHEMA_VERSION = 1; + +function parseArgs(argv) { + const args = { project: null, datasets: [], allDatasets: false, out: null }; + for (let i = 0; i < argv.length; i += 1) { + const flag = argv[i]; + if (flag === '--project') args.project = argv[++i]; + else if (flag === '--dataset') args.datasets.push(argv[++i]); + else if (flag === '--all-datasets') args.allDatasets = true; + else if (flag === '--out') args.out = argv[++i]; + else throw new Error(`Unknown argument: ${flag}`); + } + if (!args.project) throw new Error('--project is required'); + if (!args.out) throw new Error('--out is required'); + if (!args.allDatasets && args.datasets.length === 0) { + throw new Error('Pass at least one --dataset, or --all-datasets'); + } + return args; +} + +/** Canonical JSON: object keys sorted recursively, so a hash depends on content and not on order. */ +function canonical(value) { + if (Array.isArray(value)) return value.map(canonical); + if (value && typeof value === 'object') { + return Object.fromEntries(Object.keys(value).sort().map((k) => [k, canonical(value[k])])); + } + return value; +} + +function sha256(value) { + return createHash('sha256').update(JSON.stringify(canonical(value))).digest('hex'); +} + +function epochMsToIso(ms) { + if (ms === undefined || ms === null) return null; + const n = Number(ms); + return Number.isFinite(n) ? new Date(n).toISOString() : null; +} + +/** Flattens a BigQuery schema to a stable, comparable field list including nested records. */ +function flattenSchema(fields, prefix = '') { + const out = []; + for (const f of fields ?? []) { + const path = prefix ? `${prefix}.${f.name}` : f.name; + out.push({ + path, + type: f.type ?? null, + mode: f.mode ?? 'NULLABLE', + has_description: Boolean(f.description), + description_sha256: f.description ? sha256(f.description) : null, + precision: f.precision ?? null, + scale: f.scale ?? null, + max_length: f.maxLength ?? null, + }); + if (f.fields) out.push(...flattenSchema(f.fields, path)); + } + return out; +} + +function summariseTable(meta) { + const fields = flattenSchema(meta.schema?.fields); + return { + table_id: meta.tableReference?.tableId ?? null, + type: meta.type ?? null, + creation_time_utc: epochMsToIso(meta.creationTime), + last_modified_time_utc: epochMsToIso(meta.lastModifiedTime), + expiration_time_utc: epochMsToIso(meta.expirationTime), + has_expiration: Boolean(meta.expirationTime), + num_rows: meta.numRows !== undefined ? Number(meta.numRows) : null, + num_bytes: meta.numBytes !== undefined ? Number(meta.numBytes) : null, + num_long_term_bytes: meta.numLongTermBytes !== undefined ? Number(meta.numLongTermBytes) : null, + num_active_logical_bytes: meta.numActiveLogicalBytes !== undefined ? Number(meta.numActiveLogicalBytes) : null, + num_total_partitions: meta.numPartitions !== undefined ? Number(meta.numPartitions) : null, + location: meta.location ?? null, + partitioning: meta.timePartitioning + ? { + kind: 'time', + type: meta.timePartitioning.type ?? null, + field: meta.timePartitioning.field ?? null, + expiration_ms: meta.timePartitioning.expirationMs !== undefined + ? Number(meta.timePartitioning.expirationMs) : null, + require_partition_filter: meta.timePartitioning.requirePartitionFilter ?? null, + } + : meta.rangePartitioning + ? { kind: 'range', field: meta.rangePartitioning.field ?? null, range: meta.rangePartitioning.range ?? null } + : { kind: 'none' }, + require_partition_filter: meta.requirePartitionFilter ?? null, + clustering_fields: meta.clustering?.fields ?? null, + labels: meta.labels ?? null, + column_count: fields.length, + schema_sha256: sha256(fields), + schema_fields: fields, + description_sha256: meta.description ? sha256(meta.description) : null, + has_description: Boolean(meta.description), + view_definition_sha256: meta.view?.query ? sha256(meta.view.query) : null, + materialized_view_definition_sha256: meta.materializedView?.query ? sha256(meta.materializedView.query) : null, + materialized_view_enable_refresh: meta.materializedView?.enableRefresh ?? null, + materialized_view_refresh_interval_ms: meta.materializedView?.refreshIntervalMs !== undefined + ? Number(meta.materializedView.refreshIntervalMs) : null, + default_collation: meta.defaultCollation ?? null, + encryption_kms_key: meta.encryptionConfiguration?.kmsKeyName ?? null, + streaming_buffer_present: Boolean(meta.streamingBuffer), + }; +} + +function summariseDataset(meta) { + return { + dataset_id: meta.datasetReference?.datasetId ?? null, + location: meta.location ?? null, + creation_time_utc: epochMsToIso(meta.creationTime), + last_modified_time_utc: epochMsToIso(meta.lastModifiedTime), + default_table_expiration_ms: meta.defaultTableExpirationMs !== undefined && meta.defaultTableExpirationMs !== null + ? Number(meta.defaultTableExpirationMs) : null, + default_partition_expiration_ms: meta.defaultPartitionExpirationMs !== undefined && meta.defaultPartitionExpirationMs !== null + ? Number(meta.defaultPartitionExpirationMs) : null, + labels: meta.labels ?? null, + description_sha256: meta.description ? sha256(meta.description) : null, + storage_billing_model: meta.storageBillingModel ?? null, + max_time_travel_hours: meta.maxTimeTravelHours !== undefined ? Number(meta.maxTimeTravelHours) : null, + access_entries: (meta.access ?? []) + .map((a) => ({ + role: a.role ?? null, + user_by_email: a.userByEmail ?? null, + group_by_email: a.groupByEmail ?? null, + special_group: a.specialGroup ?? null, + iam_member: a.iamMember ?? null, + view: a.view ? `${a.view.projectId}.${a.view.datasetId}.${a.view.tableId}` : null, + routine: a.routine ? `${a.routine.projectId}.${a.routine.datasetId}.${a.routine.routineId}` : null, + dataset: a.dataset ? `${a.dataset.dataset?.datasetId}` : null, + })) + .sort((x, y) => JSON.stringify(x).localeCompare(JSON.stringify(y))), + }; +} + +async function listTableIds(project, dataset, errors) { + const ids = []; + let pageToken; + do { + const res = await get(listTablesUrl(project, dataset, pageToken)); + if (!res.ok) { + errors.push({ where: `tables.list ${dataset}`, status: res.status, message: res.errorMessage }); + return ids; + } + for (const t of res.json?.tables ?? []) { + const id = t.tableReference?.tableId; + if (id) ids.push(id); + } + pageToken = res.json?.nextPageToken; + } while (pageToken); + return ids.sort(); +} + +async function main() { + const args = parseArgs(process.argv.slice(2)); + const errors = []; + + let datasetIds = args.datasets; + if (args.allDatasets) { + const res = await get(listDatasetsUrl(args.project)); + if (!res.ok) { + errors.push({ where: 'datasets.list', status: res.status, message: res.errorMessage }); + } else { + datasetIds = (res.json?.datasets ?? []) + .map((d) => d.datasetReference?.datasetId) + .filter(Boolean) + .sort(); + } + } + + const datasets = {}; + for (const datasetId of datasetIds) { + const dsRes = await get(datasetUrl(args.project, datasetId)); + if (!dsRes.ok) { + errors.push({ where: `datasets.get ${datasetId}`, status: dsRes.status, message: dsRes.errorMessage }); + continue; + } + const tableIds = await listTableIds(args.project, datasetId, errors); + const tables = {}; + for (const tableId of tableIds) { + const tRes = await get(tableUrl(args.project, datasetId, tableId)); + if (!tRes.ok) { + errors.push({ where: `tables.get ${datasetId}.${tableId}`, status: tRes.status, message: tRes.errorMessage }); + continue; + } + tables[tableId] = summariseTable(tRes.json); + } + datasets[datasetId] = { + ...summariseDataset(dsRes.json), + table_count: Object.keys(tables).length, + table_ids_listed: tableIds.length, + tables, + }; + } + + // The payload is what a diff compares. Everything volatile about this particular run stays + // outside it, so re-running the generator against an unchanged warehouse produces no diff. + const payload = { + manifest_schema_version: MANIFEST_SCHEMA_VERSION, + project: args.project, + datasets, + }; + + const manifest = { + generated_at_utc: new Date().toISOString(), + generator: 'scripts/ops/generate-bq-manifest.mjs', + access_mode: 'metadata read only, no query job submitted', + requested_datasets: args.allDatasets ? 'all' : args.datasets, + error_count: errors.length, + errors, + payload_sha256: sha256(payload), + payload, + }; + + mkdirSync(dirname(args.out), { recursive: true }); + writeFileSync(args.out, `${JSON.stringify(manifest, null, 2)}\n`); + + const tableTotal = Object.values(datasets).reduce((n, d) => n + d.table_count, 0); + console.log(`project : ${args.project}`); + console.log(`datasets : ${Object.keys(datasets).length}`); + console.log(`tables : ${tableTotal}`); + console.log(`payload sha256 : ${manifest.payload_sha256}`); + console.log(`error count : ${errors.length}`); + for (const e of errors) console.log(` error ${e.where}: ${e.status} ${e.message}`); + console.log(`written : ${args.out}`); + + process.exit(errors.length === 0 ? 0 : 1); +} + +main().catch((e) => { + console.error(`FAILED: ${e.message}`); + process.exit(1); +}); diff --git a/projects/onchain-analytics/warehouse/L1/08_PipelineRunsOutcome_v1.sql b/projects/onchain-analytics/warehouse/L1/08_PipelineRunsOutcome_v1.sql new file mode 100644 index 0000000..6d136b3 --- /dev/null +++ b/projects/onchain-analytics/warehouse/L1/08_PipelineRunsOutcome_v1.sql @@ -0,0 +1,112 @@ +-- 08_PipelineRunsOutcome_v1.sql +-- +-- DO NOT RUN. This file is a migration DEFINITION, not a deployment step. +-- +-- That banner is load bearing and it is the FIRST thing in this file on purpose. +-- `scripts/deploy-warehouse.ps1` executes every .sql file in this folder in filename order unless +-- its first twenty lines carry `DO NOT RUN` or `NOT THE LIVE SHAPE`. That bootstrap script is the +-- readiness audit's finding C3, it is owned by Phase 8, and it is not fixed yet. Adding a file +-- here without this banner would hand a live migration to a script that is already known to run +-- things nobody asked it to run. The banner is the only control that exists today, so this file +-- carries it, and it is not a substitute for fixing C3. +-- +-- ONE STATEMENT. ADDITIVE ONLY. NOT APPLIED BY THIS PHASE. +-- +-- WHAT THIS IS. The remediation plan's Phase 3 task 11 migration: the columns that let a +-- PipelineRuns row say what a run actually did, rather than carrying two counters that were +-- incremented separately from the outcomes they claim to describe. +-- +-- WHY IT EXISTS. The readiness audit's finding C2 has two runtime receipts and both end the same +-- way. A bare `daily` planned 142 targets against a limit of 12, logged REFUSED, read nothing, +-- and persisted ZERO planned and ZERO failed captures. An XDC backfill requested 12,394,045 +-- blocks against a limit of 1,296,000, wrote one refusal row, and persisted ONE planned and ONE +-- successful capture. In both cases the run record agreed with the exit code and both were wrong, +-- because the only shapes available were "succeeded" and "failed" and a refusal is neither. These +-- columns are the vocabulary that was missing. +-- +-- SAFETY PROPERTIES, each one deliberate. +-- +-- * Every clause is ADD COLUMN IF NOT EXISTS. There is no DROP, no ALTER COLUMN, no rename and +-- no data movement anywhere in this file. Running it twice is a no-op. This matters here +-- specifically: `04_L0Contract_v3.sql` carries three unconditional DROP TABLE statements and +-- one of them was executed against production by accident in this project's own history. +-- * One statement in one file, per plan section 1.2. Nothing extracts a fragment of this file +-- by delimiter or string slicing: the incident above was caused by exactly that, on a CRLF +-- file where the delimiter search returned -1 and took the rest of the file with it. +-- * `host` and `pipeline_version` are REUSED for runner identity and release version. Plan task +-- 11 says so explicitly and forbids adding aliases for them, so neither appears below. +-- * Adding a column to a BigQuery table rewrites no rows and scans no bytes. Existing rows read +-- NULL for every column below, which is correct: those runs genuinely did not record this. +-- +-- WHO APPLIES IT. Not this change. The migration is rehearsed against a sandbox dataset and +-- applied to production only inside an authorised additive-DDL window. What lands here is the +-- definition plus the code that reads and writes it, and `ensureInfraTables` asserts every +-- column at startup so a dataset that has not had this applied fails immediately, naming this +-- file, instead of failing at the INSERT after a whole run has already happened. +-- +-- TARGET. Substitute the dataset deliberately. This file names no project so it cannot be run +-- against production by copy-paste alone. + +ALTER TABLE `${PROJECT}.${DATASET}.PipelineRuns` + -- The outcome model. `execution_status` is the word form of the exit code, because exit 2 does + -- not distinguish a refusal from a crash and those need different responses. + ADD COLUMN IF NOT EXISTS execution_status STRING + OPTIONS(description="completed, partial, refused, unsupported, empty or failed. Never plain success: a refused run and a clean run must not share a word."), + ADD COLUMN IF NOT EXISTS units_planned INT64 + OPTIONS(description="Work units this run intended, recorded BEFORE any guard ran. A globally refused run has a real planned count here; that number does not exist after the refusal."), + ADD COLUMN IF NOT EXISTS units_attempted INT64 + OPTIONS(description="Units the pipeline actually tried to read. planned minus attempted is exactly the work this run declined."), + ADD COLUMN IF NOT EXISTS units_completed INT64 + OPTIONS(description="Units that finished their whole range. The only value that is success."), + ADD COLUMN IF NOT EXISTS units_noop INT64 + OPTIONS(description="Units whose range was empty by arithmetic. Not work, and not a completion: a run of pure no-ops exits nonzero."), + ADD COLUMN IF NOT EXISTS units_refused INT64 + OPTIONS(description="Units a budget guard declined before reading. The range is unread and recorded as unread in IngestionCoverage with status refused_budget."), + ADD COLUMN IF NOT EXISTS units_unsupported INT64 + OPTIONS(description="Units this pipeline cannot do: no reader for the chain, chain outside the frozen release scope, or an address the control plane does not know."), + ADD COLUMN IF NOT EXISTS units_failed INT64 + OPTIONS(description="Units that ran and did not finish, whether they threw or returned an incomplete range."), + ADD COLUMN IF NOT EXISTS outcome_counts_by_grain JSON + OPTIONS(description="The same counters per target grain, RawLogs and Transactions separately, plus RawLogs+Transactions for run-level parent units. Reconciles exactly to the units_ columns."), + ADD COLUMN IF NOT EXISTS release_sha STRING + OPTIONS(description="40-character lowercase Git SHA of the release that produced this run. NULL until a release process sets it; a hash invented by the program it is supposed to bind would bind nothing."), + ADD COLUMN IF NOT EXISTS plan_hash STRING + OPTIONS(description="64-character lowercase hex SHA-256 of the remediation plan this writer is bound to, per plan section 1.1."), + + -- The child-plan lineage. A run may be a child of another run's plan, and the readiness audit's + -- reconciliation requirement is that a parent's outcome be derivable from its children rather + -- than asserted alongside them. + ADD COLUMN IF NOT EXISTS parent_run_id STRING + OPTIONS(description="The run that planned this one. NULL for an ordinary top-level run."), + ADD COLUMN IF NOT EXISTS child_plan_stage STRING + OPTIONS(description="Fixed lowercase stage enum this child belongs to."), + ADD COLUMN IF NOT EXISTS child_plan_root_hash STRING + OPTIONS(description="Hash of the whole plan tree this child was derived from."), + ADD COLUMN IF NOT EXISTS child_plan_hash STRING + OPTIONS(description="Hash of this child's own plan. Part of the canonical input to a deterministic child run id."), + ADD COLUMN IF NOT EXISTS child_ordinal INT64 + OPTIONS(description="Position of this child in the global plan ordering."), + ADD COLUMN IF NOT EXISTS stage_child_ordinal INT64 + OPTIONS(description="Position of this child within its own stage."), + ADD COLUMN IF NOT EXISTS stage_child_count INT64 + OPTIONS(description="How many children the stage declared, so a missing child is detectable without a scan."), + + -- The job ledger and the closure chain. Written by the mutation broker and the terminalizer in + -- later phases; defined here because plan task 11 fixes the column set and forbids Phase 8 from + -- redefining it. + ADD COLUMN IF NOT EXISTS bigquery_job_ledger JSON + OPTIONS(description="Every WORK job this run submitted, with its submit intent and terminal state. The terminalizer is never in its own ledger."), + ADD COLUMN IF NOT EXISTS job_ledger_hash STRING + OPTIONS(description="Hash over the complete ledger, computed before terminalization."), + ADD COLUMN IF NOT EXISTS work_jobs_terminal BOOL + OPTIONS(description="True only when every parent and generated child work job reached a terminal state. Parent status alone is insufficient."), + ADD COLUMN IF NOT EXISTS terminalizer_job_id STRING + OPTIONS(description="The single committed terminalizer attempt. Once a terminalized row exists, no second terminalizer patches it."), + ADD COLUMN IF NOT EXISTS closure_status STRING + OPTIONS(description="terminalized, closed or closure_invalidated. terminalized is provisional and never means closed."), + ADD COLUMN IF NOT EXISTS terminalized_at TIMESTAMP + OPTIONS(description="Predetermined at intent creation and passed in as a typed parameter. The terminalizer may not call CURRENT_TIMESTAMP()."), + ADD COLUMN IF NOT EXISTS terminalized_row_hash STRING + OPTIONS(description="Hash over the canonical final fields excluding this field itself, so a recovered row can be proven byte-identical to the intended one."), + ADD COLUMN IF NOT EXISTS closure_receipt_uri STRING + OPTIONS(description="Predetermined URI of the closure object. That object alone makes a run closed.");