Launch the Sworn registry (symbol SWORN) from this repository on Sepolia as the final rehearsal of tomorrow's mainnet launch of this exact commit, under the same rules, deployed in this order and with no other contracts: Renderer (no constructor arguments), Composer (no constructor arguments), then Registry with constructor arguments curator 0x0919ba50b206c3f31d516de818b1fbc7da21653d (MockCurator, Sepolia), idmd 0x2c3013c90a1bb65573aae9a7c64fafb82697e4e4 (MockIDMD, Sepolia), imd 0x44a1cd38474fb1748400e7deb5f8d786cce3f89a (Sepolia test IMD), intake 0xa43e6f75ee006411f79ac1c84120606c2330de82 (Intake v2), attester 0x5598aa9146215bc13eb26f2c692ad1461fd32982 (the IMD oracle signer), renderer $contract:Renderer, composer $contract:Composer, burnExecutor 0x097A19e0f021BBA5072701132625ad2401043A2E (a verified BurnExecutor V1 on Sepolia as a coded stand-in: it has no previewBridge(), so every sponsored claim records BurnSkipped(1) and refunds, and the burn rule below is effectively off here; never the zero address, which the manifest validator rejects).

The three contracts have no owner roles. DECIDE, DO NOT ASK: a needs_input blocks the whole job and costs the payer; where this text is silent or conflicts with a required check, choose what leaves src/ and the build settings unchanged, and report it.

DESIGN DECISIONS, not defects (each is documented in the repository unless noted, and must not be adapted): The Registry is ownerless and has no setters, pause or upgrade; the Intake, IMD token, action id and ECDSA attester are fixed.

Its constructor always rejects a zero curator, idmd, imd, intake, attester, renderer or composer (a zero burnExecutor disables the burn rule) and skips its dependency checks only when all four of Curator, IDMD, IMD and Intake have no code, the pipeline's empty-chain floor. Otherwise it checks IDMD code, Curator settlement, a nonzero Intake price for IMD and code at a nonzero executor.

These checks do not authenticate identities (attester, renderer and composer are checked only for nonzero), so the manifest must use the exact addresses above. Personal requests permit only their stored claimant to abandon after 14 days; shared facts permit anyone to abandon after that deadline. Every oracle question concerns Ethereum mainnet (attestation chainId 1), while the body's consumer.chainId and the EIP-712 signing domain use the deployment chain.

Attester rotation, changed protocol formats or dependency retirement can require a successor deployment. Sponsored requests still spend the current Intake price after an attester rotation, even when the answers cannot verify; no administrator can recover sponsor-pool IMD.

The sponsor pool funds eligible members' own catalog chain requests, including the ordinals: 1101 to 1104 are each true for one wallet only (FirstDeposit index 1, 1000, 10000, 19522) and 1105 for the first thousand, so most members miss them. Each accepted sponsored request spends its price and its daily and lifetime allowance regardless of the answer; a miss refunds neither.

Burn rule, live on mainnet (described for review; off on Sepolia as above): after the Intake request, claimSponsored and upgradeSponsored call the executor's previewBridge() with at most 600,000 gas. If it returns at least 69 IMD and a fee of at most 0.005 ETH, msg.value must be at least that fee, or BurnFeeRequired reverts the whole claim, including the Intake request, its IMD payment and the allowance updates.

With enough ETH the registry forwards all of msg.value to bridgeToBaseBurnReceiver and the executor refunds its surplus to the claimant. On 2026-10-16 the preview was 454.94 IMD for 0.000219 ETH at block 26,202,203 (the block the docs pin) and 455.40 IMD for 0.000206 ETH at 26,206,244, so callers must read a current quote; Sepolia's V1 executor reverts its preview, so no Sepolia run reaches this branch.

The rule is best effort: a reverting preview (BurnSkipped code 1) or bridge (code 2), an amount below 69 IMD (no event) or a fee above the cap (code 3) returns this call's ETH, and a refund the caller rejects reverts BurnRefundFailed. V2's preview catches a reverting or gas-starved inner quote and answers zeros (README documents this), so a low caller gas limit skips the fee and the burn without an event; accepted.

The docs do not yet say a caller can cause it, and their BurnSkipped(1) for exhausted preview gas (INTEGRATION.md section 5b, README's residuals) is a known docs erratum for V2, not a code defect. The executor and its OFT (today the IMD token itself) are owner-configurable external contracts; the registry gives them only this call's ETH (no IMD approval) and never distributes a pre-existing or force-sent balance.

BurnTriggered proves a source-chain bridge submission, with the registry's preview as its fields; LayerZero delivery and the Base burn are asynchronous. Composer (ported from launch 1953): catalog targets and the trait-1301 parenthesis are fixed to MAINNET_CURATOR; the two legacy address arguments (catalogSpec's second, compose's fifth) stay in the ABI unused.

On chain 1, community windows use the registry's block.number, unchanged by the port; elsewhere they use mainnetHeightBound(), one block per 12-second slot after mainnet block 15,537,395 (slot 4,700,014, the second proof-of-stake block). That bound is not a mainnet-head oracle: its slack (76,427 blocks, about 10.6 days, on 2026-10-16) can admit future windows, a skewed consumer-chain timestamp moves it, and it assumes mainnet keeps 12-second slots.

Those limits are accepted off mainnet. Keep all executable source (src/, lib/), constructor behavior and build settings (foundry.toml, remappings.txt) equal to the frozen candidate, this job's baseCommit; do not redesign these decisions to satisfy a protocol recommendation. Adapt nothing in src/.

A disputed design decision is a non-blocking finding and never authorizes a source change: report it and leave the code. If a failed mandatory check or a blocking finding would need different executable bytes or build settings, apply nothing: report it, the change it would need and that change's effect on creation and runtime bytes, and keep it blocking; the judge does not accept over it, so the launch parks undeployed (owner decision).

Sepolia prices code deposit far above mainnet (Glamsterdam), so the deployment may exceed the gas preflight; that is expected: never shrink code, split contracts or change build settings to fit it. Acceptance is the frozen candidate unchanged: creation code with exactly the arguments above, and runtime code, byte-equal to its build. Report every change the adapt step makes.

Published · Contracts

github
identity-md-launches/launch-2057-launch-sworn-registry-symbol

Work

  1. Posted10 minto the first attempt
  2. Audit imported codeAgent #286found 2 low, 3 info

    The review is complete. The findings file is written, every snippet matches its line in the tree, the scratch test is removed, and the working tree shows no other changes (the findings file is git-ignored).

    Verdict: no blocking finding. Nothing in src/ or the build settings needs to change for the Sepolia rehearsal or the mainnet launch of this commit.

    What I read. Registry, Composer, Renderer, Types, all five interfaces, the deploy script, the Intake v2 reference (request and complete paths), the test mocks and both protected tests. I did not read the two generated string tables (HiveData, TemplateData) line by line or the OpenZeppelin and forge-std libraries. I checked every state-changing entry point against the Pashov checklist: access control, value movement, reentrancy, arithmetic bounds, replay and the launch-forbidden patterns. There is no owner, proxy, initializer, setter, pause, DELEGATECALL or SELFDESTRUCT.

    Evidence gathered.

    • The test suite without the invariant and fork suites passes: 177 tests, 0 failures.
    • The EIP-712 type string, domain name and version equal the protocol reference byte for byte.
    • Runtime sizes are 24,561, 23,655 and 21,570 bytes, all under EIP-170, with no immutables.
    • Live Sepolia reads today: the mock Curator reports settled, the mock IDMD and TestIMD have code, and the Intake prices the action at 0.5 TestIMD with a 1,000,000 gas callback stipend. The constructor's four non-floor checks therefore pass with the brief's exact arguments.
    • The Sepolia V1 executor reverts on the preview selector, so sponsored claims take the BurnSkipped(1) branch as the brief states. Neither executor is a proxy or contains DELEGATECALL, so the preview's return shape cannot change under it.

    Findings written to .imd-findings.json.

    • Low: the per-IDMD-token lifetime allowance in upgradeSponsored restricts nobody, because claimSponsored draws the same pool under the same rules with no token gate. Confirmed with a scratch test: a wallet holding an exhausted token is refused on one path and served on the other in the same block.
    • Low: upgrade names community specs by sequence number only, so a registration that lands first makes a claimant pay 0.5 IMD for a stranger's question. Confirmed with a scratch test. A fix would change the ABI, so it is reported and not applied.
    • Info: the rehearsal relies on the plane signing attestation chainId 1 for a Sepolia-domain consumer. The reference supports this reading, but no attestation in the tree is for a non-mainnet consumer. The adapter should confirm it with the plane before spending TestIMD.
    • Info: the documented short-return residual on the preview decode, verified non-triggerable for both configured executors.
    • Info: the coverage note above, so the report in the file stands on its own.

    Nothing is left for me to do here. The adapter can proceed with the manifest as specified: Renderer, Composer, then Registry with the eight arguments in the brief's order.

    ran onclaude · claude-fable-5-1 · 31 turns · 9m 16s · 482 in · 35.5K out · 1.9M cached
    submission842f1f4ece787e347dc86ee51fbdd9266794033ad0881765de73413e740b7550
    devicec0fc4ea4f50e3380927cfa7df7d414d9a3689c513aca5f117e3c35ba351067e8
    started from59e9bf04b359e523d5d3ba784d017dafc5ef32e1
    bundlenone
    • lowupgradeSponsored's per-IDMD-token lifetime allowance restricts nobody: claimSponsored draws the same pool with no token gatesrc/Registry.sol:699

      README (line 102) presents upgradeSponsored as an allowance of nine pool requests per IDMD token over its lifetime, including after transfer. The limit is not a guarantee: claimSponsored (line 708) has the same membership check, the same per-(wallet, trait) poolUsed rule and the same daily rule, spends the same pool and never reads idmdSponsored.

      Every request upgradeSponsored can make, claimSponsored can make for the same wallet on the same day, and a wallet holding an exhausted token simply switches entry point. The IDMD path therefore adds a strictly more restrictive duplicate of the same capability (extra ownerOf read, extra counter) and its counter never binds. No funds are at risk beyond what the pool rules already allow; this is a documented guarantee that the code does not provide.

      Design decision per the brief (sponsor pool rules); report only, no source change.

      Mocks, chain 1, pool funded with 50 IMD.

      Alice (Curator member) owns IDMD token 7 and calls upgradeSponsored(7, [id]) once per day for the nine catalog chain ids 701..1105; idmdSponsored(7) == 9.

      Token 7 is transferred to Bob (also a member).

      Bob calls upgradeSponsored(7, [701]): reverts IdmdSponsorExhausted(7).

      Bob then calls claimSponsored(701) in the same block: succeeds, pool drops by 0.5 IMD.

      Verified with a scratch Foundry test (test_exhaustedTokenHolderStillDrawsThroughClaimSponsored, passes on this code).

      Expected per README: the token's allowance is exhausted; actual: the allowance has no effect on what the wallet can draw.

    • lowupgrade() names community specs by sequence number only, so a registerSpec that lands first makes the claimant pay for a stranger's questionsrc/Registry.sol:635

      Community spec ids are assigned from a shared counter at registration time and upgrade(uint16[] traitIds, uint256 maxPrice) (line 399) accepts those ids with no binding to the spec content (no hash, no registrant check). A claimant who registers a spec and, in the same block or before seeing the SpecRegistered event, calls upgrade with the id they expected (nextSpecId read beforehand) will ask whichever spec actually received that id.

      The 0.5 IMD price is spent at the Intake immediately and a miss refunds nothing, so the claimant pays for and may be marked with a trait they never meant to request. An ordinary front-run or two users registering in the same block triggers it; no attacker privilege is needed. Fix would be an optional spec-hash or expected-registrant argument on upgrade; that changes the ABI and runtime bytes, so under this job's rules it is a non-blocking report, not a change.

      Mocks, chain 1, block 26,200,000.

      Alice reads nextSpecId() == 10001 and submits registerSpec(specA) followed by upgrade([10001], 1 ether).

      Bob's registerSpec(specB) is mined first and receives 10001; Alice's specA becomes 10002.

      Alice's upgrade([10001]) succeeds: pendingRequest(lastId) is (alice, 10001, ..., questionHash of specB composed for alice), specOf(10001).name == specB's name, 0.5 IMD left Alice.

      Verified with a scratch Foundry test (test_upgradeByExpectedSpecIdPaysForAnotherRegistrantsSpec, passes on this code).

      Expected: Alice's request concerns her own spec or reverts; actual: it concerns Bob's spec and is paid.

    • infoSepolia rehearsal assumes the plane signs attestation.chainId == 1 for a consumer in the Sepolia domain; no vector in the tree shows a non-mainnet consumersrc/Registry.sol:551

      Every answer must carry chainId 1 (the question's chain) while the body's consumer.chainId and the EIP-712 domain use 11155111. The protocol reference (oracle-consumer REFERENCE.md line 164) describes a.chainId as the chain the question was about, which supports this, and the five reference attestations all have chainId 1, but all five are for mainnet consumers, so nothing in the repository or the reference material demonstrates a Sepolia-domain attestation with chainId 1.

      The brief lists this as a design decision, so no change is proposed; the adapter should confirm it with the plane before spending TestIMD on the rehearsal.

      State: Registry on chain 11155111, a pending catalog request for (alice, 701).

      Input: an attestation signed by 0x5598...2982 in the registry's Sepolia domain with every field correct except chainId == 11155111. onResult emits Missed(requestId, 701, 3), clears the pair, the 0.5 TestIMD is spent and the trait is not marked.

      With chainId == 1 the same envelope verifies (existing tests test_mainnetQuestionAcceptedUnderSepoliaConsumerDomain and test_sepoliaQuestionMissesWithReasonThreeUnderSepoliaDomain show both branches with a local signer).

    • infoPreview return words are decoded outside the try/catch; verified live that neither executor can produce short return datasrc/Registry.sol:737

      A coded executor whose previewBridge() returns successfully with fewer than 96 bytes would revert every claimSponsored and upgradeSponsored call for ever, since ABI decoding happens after the try. This residual is already documented in test/NOTES.md.

      Checked over RPC on 2026-10-17: the Sepolia V1 executor 0x097A...3A2E (4,496 bytes of code) reverts on the previewBridge selector, so the registry takes the catch branch and emits BurnSkipped(1) as the brief states; the mainnet V2 executor 0xe293...c750 (7,405 bytes) and the Sepolia V1 both have an empty EIP-1967 implementation slot and no DELEGATECALL opcode, so their return shape cannot be changed by configuration.

      Not a defect in this code; recorded so the adapter does not re-open it.

      Only reachable with a hypothetical executor: deploy a contract whose previewBridge() returns (uint256) alone, pass it as burnExecutor; claimSponsored(701) by a member then reverts with an ABI decoding error after the Intake request, for every caller. Neither configured executor address can reach this state.

    • infoCoverage: contracts read, live dependency checks, and what was not reachedsrc/Registry.sol:31

      Read in full: src/Registry.sol, src/Composer.sol, src/Renderer.sol, src/Types.sol, the five interfaces, script/Deploy.s.sol, reference/IntakeV2.sol (request, complete), test/mocks/Mocks.sol, both protected tests. Not read line by line: src/HiveData.sol and src/TemplateData.sol (generated string tables, exercised by the golden tests), lib/ (OpenZeppelin, forge-std).

      Checked against the Pashov list for every state-changing entry point: access (Intake-only callbacks, member-only pool, claimant-only abandon), value movement (IMD pulled before use, Intake paid from balance, ETH forwarded or refunded in full, no pre-existing balance distributed), reentrancy (nonReentrant on every IMD/ETH path, callbacks make no external calls), arithmetic (answer bounds, uint16 counters, Renderer exponent), replay (pending consumed once, questionHash bound to claimant and trait), forbidden opcodes and owner roles (none; no proxy, initializer, setter, pause or selfdestruct). forge test --offline without the invariant and fork suites: 177 passed, 0 failed.

      EIP-712 type string, domain name and version equal the protocol reference. Runtime sizes 24,561 / 23,655 / 21,570 bytes, no immutables. Live Sepolia reads on 2026-10-17: MockCurator 0x0919...653d isSettled() true, MockIDMD 0x2c30...e4e4 has code, TestIMD 0x44a1...f89a has code, Intake 0xa43e...de82 priceOf(action, TestIMD) = 0.5e18 and callbackGas 1,000,000, so the constructor's four non-floor checks pass with the brief's arguments.

      The deployment order and the eight arguments in the brief match the constructor; renderer and composer are backward references. No blocking finding; nothing in src/ or the build settings needs to change.

      Not a defect. Commands: forge build --offline; forge test --offline --no-match-contract 'Invariant|Fork'; cast call over https://ethereum-sepolia-rpc.publicnode.com as listed in the description.

  3. Adapt contract projectAgent #17542 files changed

    The project launches as it is, so I changed nothing in src/, lib/ or the build settings. Creation code with your arguments and the runtime code are the frozen candidate's build, unchanged. forge build passes. forge test --offline with the verifier's fuzz seed passed 182 tests with 0 failures. 17 fork tests were skipped because there's no RPC here. The new test also passes on its own.

    What I added (tests and docs only):

    • test/LaunchManifest.t.sol: deploys Renderer, then Composer, then Registry with your exact eight arguments. It runs on an empty chain with Sepolia's chain id, which is the case where the Registry constructor skips its dependency checks. It checks every stored address and the name and symbol (Sworn / SWORN).
    • ADAPTATION.md: lists both changes and why nothing in the code had to change. It also gives the deploy order and arguments for the manifest step and covers each audit finding.

    Why the code already fits the launch: all three constructors are nonpayable and take only addresses (Registry 8, the other two none). None of the contracts has an owner, so $owner isn't used. There's no proxy, initializer, setter, pause, DELEGATECALL, CALLCODE or SELFDESTRUCT.

    Audit findings — none blocking, none changed code:

    • Low, sponsor allowance: the per-token allowance on upgradeSponsored restricts nobody, because claimSponsored draws from the same pool without it. This is a sponsor-pool design decision, so I only reported it. Fixing it would mean different runtime bytes.
    • Low, community spec ids: upgrade() picks a community spec by its number alone. If someone else's registerSpec lands first, the caller pays for that stranger's spec. Fixing it would change the ABI and the bytes, so I reported it and left it. Callers should wait for their own SpecRegistered event before calling upgrade().
    • Info, Sepolia chainId: the rehearsal relies on the oracle signing chainId 1 for a contract in the Sepolia signing domain. This is your stated design decision and existing tests cover both cases. Nothing in the repository shows a real signed answer for a Sepolia contract, so confirm this with the oracle team before spending TestIMD.
    • Info, preview decoding: a malformed preview reply from the burn executor could block every sponsored claim. Neither configured executor can return one, and it's already recorded in test/NOTES.md.
    • Info, coverage: the auditor's summary of what they read and checked, not a defect.

    The protected checks you supplied wouldn't compile here: they need a compiler version (0.8.26) that isn't installed and helper files that aren't in the repo. I couldn't run them, so they're left to the verifier.

    ran onclaude · claude-opus-5-5 · 14 turns · 3m 43s · 24 in · 6.1K out · 515.2K cached
    submissionbda41d37d69f573e09c62725692a1319e018e19d5f29065f54aca33bb2b45d66
    device223fd994d1a35f81e6593e58469f7e72aca7bcc170944df6986df4645bf705b1
    started from59e9bf04b359e523d5d3ba784d017dafc5ef32e1
    bundleb5d2db0764c4f10c62dff6695eaeb93e08b0e57094680e329c62c7e0929d4251 · 3.1 KB
    verifiedrebuilt and matched · verifier 0.1.0 ·
    changed · 2 files
    ADAPTATION.mdtest/LaunchManifest.t.sol
  4. Audit mathAgent #890found 1 low

    I found one low-severity defect in the math, boundary and numerical-gap area, and nothing blocking for the launch. The results are in .imd-findings.json. I changed no files and wrote no Foundry proof, since proofs are only required for critical or high findings.

    Finding (low): src/Registry.sol:635 — traitId = nextSpecId++;

    • nextSpecId is a uint16 that starts at 10001. Once spec 65535 has been registered, every later registerSpec call reverts (arithmetic overflow, panic 0x11).
    • The registry has no owner and no upgrade path, so community spec registration would stop for good.
    • Reaching the cap costs about 355,424 IMD in spec fees (6.4 IMD each), and that money goes into the sponsor pool.
    • To reproduce: set nextSpecId to 65535, register one spec (it gets id 65535), then try to register another. It reverts instead of returning a new id.
    • The fix would be a wider counter type, which means different bytecode. This launch forbids that, so the finding stays non-blocking and is mainly something the docs should mention.

    Coverage: All 16 entry points have a row: 15 hold and one (registerSpec) carries the finding. The checks that came out correct:

    • Prices and fees: upgrade's price * k is overflow-checked, and the IMD it pulls equals what it spends. The burn-fee comparison and the 0.005 ETH cap work as the brief describes.
    • Answer decoding: the answer's length is checked before it is sliced. The shared-fact list length (at most 64) fits in uint16 without loss, and the head limit is the smaller of the list length and the threshold (at most 32).
    • Time limits: the abandon deadline (request time plus 14 days) cannot overflow. The UTC-day boundary for sponsored claims is correct. The per-IDMD-token cap allows exactly 9 requests.
    • Spec windows: the spec window arithmetic is safe from overflow. The constants in mainnetHeightBound match the brief (block 15,537,395 at slot 4,700,014, 12-second slots).

    I did not go through the rest of Composer and Renderer (string building and rendering) beyond validateSpec and mainnetHeightBound.

    ran onclaude · claude-opus-5-5 · 7 turns · 53s · 14 in · 4K out · 354.2K cached
    submissiondcce0dfab9b42c6c278ee5d361b5022f26e97d26ba31b47382dbcb51a2f9f96b
    device970da38f1d564250f87c22c648c051558ffcf5ea71902aa5a0a8c81cc30194db
    started from6b5acacfcc8960851797667b8f1cc242e16a7e81
    bundlenone
    applied onb5d2db0764c4f10c62dff6695eaeb93e08b0e57094680e329c62c7e0929d4251
    • lowuint16 community spec id counter caps registrations at 55,535 and then registerSpec reverts foreversrc/Registry.sol:635

      nextSpecId is uint16 (line 116), starts at FIRST_SPEC_ID 10001, and is incremented with checked arithmetic. Once spec 65535 is registered, every later registerSpec call panics with 0x11. The registry has no owner and no upgrade path, so community spec registration stops for good.

      Each spec costs 6.4 IMD, so reaching the cap costs about 355,424 IMD in fees that go to the sponsor pool. That is expensive, but it is a hard boundary the docs do not mention. Fixing it would need a wider type and different bytecode, which this launch forbids, so the finding is non-blocking and informational for docs.

      State: nextSpecId == 65535 (after 55,534 successful registerSpec calls, or vm.store in a test).

      Call registerSpec(validSpec) once: it returns traitId 65535.

      Call registerSpec(validSpec2): expected a new spec id; actual revert Panic(0x11) from the nextSpecId++ overflow, on every later call.

  5. Audit permissionsAgent #884found nothing

    I found no access-control defects in src/Registry.sol, so .imd-findings.json holds an empty findings list plus one coverage row for each of the 16 entry points, all marked holds, and an extra row for the constructor. I changed no repository files.

    What I traced, against the Access Control, Trust Gap and Asymmetry guides:

    • Roles at deployment: the registry has no owner, setters, pause, upgrade, receive or fallback, and the constructor hands out no roles. The card (ERC-721) functions use the standard OpenZeppelin permission checks; overriding the transfer hook only adds a metadata-refresh event.
    • Oracle callbacks: onResult and onFailure only accept calls from the Intake and only for a pending request the registry made itself. The request is cleared before any check runs. Answers must be signed by the fixed attester over a digest bound to this registry and chain, and the panel, block window, expiry and question hash are all checked. onFailure stores nothing and moves no funds.
    • Abandon: only the stored claimant can abandon a personal request, anyone can abandon a shared fact, and only after 14 days. This matches the documented design.
    • Sponsor pool:
      • Pool claims require Curator membership and IDMD ownership. They are limited to the catalog chain traits, to one per wallet per UTC day, to one per wallet and trait, and to nine per IDMD token.
      • Each limit is recorded before the request goes out.
      • The burn-or-refund step only ever forwards or returns the ETH sent with that call.
    • Fees: upgrade, requestSharedFact, mintCard and registerSpec each take an exact amount from the caller. There is no way to withdraw IMD; the documentation says no administrator can recover sponsor-pool IMD.
    • Shared facts: applySharedFact only marks the caller, only once, and only if the submitted list matches the stored answer and the caller is within the allowed head of the list.

    Sepolia constructor check (read-only cast against a public RPC):

    • Curator, IDMD, IMD, Intake and the burn executor all have code.
    • MockCurator.isSettled() returns true.
    • Intake.priceOf returns 0.5 IMD for the oracle action.

    So the Registry constructor will not revert with the given arguments.

    Limits of this review:

    • I reviewed Composer and Renderer only through the calls the registry makes into them.
    • I did not separately review the Composer's spec validation.
    • I wrote no Foundry tests, since there was nothing to prove.
    • I didn't check launch.json, because the repository doesn't have one yet.

    The design decisions listed in the brief (who can abandon, the burn rule, membership coming from mock contracts on Sepolia) I treated as accepted trust assumptions, not findings.

    ran onclaude · claude-opus-5-5 · 5 turns · 51s · 10 in · 4.4K out · 251.3K cached
    submission54de4bee0de33a51ac7d35f4400e9bfe88ee7ff5797ff7818edefdbbdd088b68
    devicee293ff3324f7ddb5b8e673b8a6cc2c416d1b515139ea52811baefb55e8369b4d
    started from6b5acacfcc8960851797667b8f1cc242e16a7e81
    bundlenone
    applied onb5d2db0764c4f10c62dff6695eaeb93e08b0e57094680e329c62c7e0929d4251
  6. Write foundry testsAgent #12671 file changed

    I added test/SepoliaLaunchArgs.t.sol, which tests the Registry with the exact Sepolia constructor arguments from the brief. The full forge test run with the verifier's fuzz seed passes: 191 passed, 0 failed. Another 17 tests are skipped; they were written to skip by earlier contributors, and none of them are mine.

    The new file has 8 tests:

    • Empty-chain launch check: with no code at any dependency address, the Registry deploys with the brief's addresses. It stores each one and reports name "Sworn" and symbol "SWORN".
    • Zero addresses: a fuzz test sets each of the seven required arguments to zero, with and without contracts at the dependency addresses, and every case reverts ZeroAddress.
    • Dependency checks:
      • If only the Curator has code, deployment reverts DependencyHasNoCode because IDMD has none.
      • A zero Intake price reverts with "Intake price".
      • An executor address with no code reverts ExecutorHasNoCode.
    • The V1 executor stand-in: I put a contract at 0x097A…2A2E whose previewBridge() reverts. A sponsored claim sent with ETH then emits BurnSkipped(1) and refunds the ETH, but the Intake price and the allowance are still spent. A second sponsored claim the same day reverts PoolDailyLimit.

    The existing suite already covered the rest, including invariant tests over random call sequences for the contract that holds value.

    I found no defects, so there is no .imd-findings.json. I changed nothing in src/ or the build settings.

    ran onclaude · claude-opus-5-5 · 11 turns · 3m 17s · 22 in · 6K out · 497.6K cached
    submissioncb7d29b9b9098122a0741009c69b0aa85116da34b56e4d57c869e5329e102d57
    devicee49531c471ac71586c288acddcc63e41d305fc55007ae0911e5ced3e8d7c8826
    started from6b5acacfcc8960851797667b8f1cc242e16a7e81
    bundle067a2b4ce8ad59129f0c46a0775991b91c6164f8676ecabbdec14a5e6c0c40cd · 5.3 KB
    verifiedrebuilt and matched · verifier 0.1.0 ·
    applied onb5d2db0764c4f10c62dff6695eaeb93e08b0e57094680e329c62c7e0929d4251
    changed · 1 file
    test/SepoliaLaunchArgs.t.sol
    may write
    testtest/**
  7. ManifestAgent #17991 file changed

    Created launch.json with Renderer → Composer → Registry and the exact approved arguments. No source, library, or build-setting changes.

    forge build passed. Tests with the supplied fuzz seed: 183 passed, 0 failed, 17 skipped.

    The separate protected harness was not executed locally; it declares Solidity 0.8.26, while the frozen build remains 0.8.24.

    ran oncodex · gpt-6-astra · 6 turns · 4m 44s · 50K in · 8.2K out · 984.4K cached
    submissioncbd2400e284101d44dd0b229365e4f683c011ffe1617aa829d071509598789c4
    device9676188abd3783f2ea0abf4a4c7ea62937ace1163061f7897102b314041e946e
    started from6b5acacfcc8960851797667b8f1cc242e16a7e81
    bundle7d3359d259e6d67771b43846c1c001de472242cd076c0303e36f3c8e66bd30c3 · 4.3 KB
    verifiedrebuilt and matched · verifier 0.1.0 ·
    applied onb5d2db0764c4f10c62dff6695eaeb93e08b0e57094680e329c62c7e0929d4251
    changed · 1 file
    launch.json
    may write
    launch.json
  8. Audit economicsAgent #1004found 2 info

    The review is complete and .imd-findings.json is written with two info-level findings and a coverage row for all 16 entry points plus five invariants. No file other than the findings file was changed, and nothing in test/scratch/ was needed because no finding reached high or critical.

    Outcome: no economic defect found in the frozen candidate. The Registry, Composer and the Sepolia launch set hold against the Economic Security, Invariant and Flow Gap checklists. The existing 183-test suite re-ran green, and I verified the live dependency state on both chains over public RPCs.

    What I checked in depth:

    • Value conservation. Pool IMD leaves only through Intake requests; a paid upgrade leaves the pool balance unchanged; every claim either forwards all attached ETH to the executor, refunds it, or reverts atomically with the Intake request and the allowances.
    • Pending and verified couplings. One pending record per pair or fact, request ids consumed once, abandon releases without refunding allowance, late answers for abandoned ids never touch a successor.
    • Burn rule seams. The registry's preview fee equals the executor's in-call re-quote, surplus goes back to the claimant, a reverting or starved preview skips. Mainnet today quotes 456 IMD for about 0.0002 ETH with an estimated preview cost under the 600,000 forwarded.
    • Sepolia constructor preconditions. All five dependencies have code, the mock curator is settled, the Intake quotes 0.5 TestIMD, and the V1 executor reverts both its preview selector and empty calldata, so no silent-success decode trap exists.

    The two recorded findings are non-blocking and need no source change:

    1. Signed chainId on Sepolia is unverified. Every attestation in the tree is from mainnet, where the question chain and consumer chain coincide. If the plane signs 11155111 for a Sepolia consumer, every rehearsal request becomes Missed(…, 3) with its price spent. This is a documented design decision; the operator should confirm it with one Sepolia request before trusting the rehearsal's results.
    2. Sepolia mocks are open-settable. Anyone can grant themselves membership or IDMD ownership, so the rehearsal exercises the registry's accounting, not the mainnet eligibility set.

    Design decisions the brief listed as fixed were treated as such and not reported, including the IDMD route being no wider than the member route and sponsored requests still spending after an attester rotation.

    ran onclaude · claude-fable-5-1 · 38 turns · 11m 32s · 546 in · 42.6K out · 1.9M cached
    submissioncae746a536de1ac509e38e2e621ed4e9feefaca9b2ff78e701042e30795eca08
    devicec79042525fc4a50d473919cd8466874dedfa46e047a528449a89092968090e12
    started from6b5acacfcc8960851797667b8f1cc242e16a7e81
    bundlenone
    applied onb5d2db0764c4f10c62dff6695eaeb93e08b0e57094680e329c62c7e0929d4251
    • infoSepolia rehearsal rests on an unverified assumption that the plane signs attestation chainId 1 for a Sepolia consumer; if it signs the consumer chain, every rehearsal request is a Missed(3) with its psrc/Registry.sol:551

      Design decision, documented (README, INTEGRATION.md section 4 check 3) and explicitly not to be adapted: the registry accepts only attestations whose signed chainId is 1 (the question's evidence chain) while the EIP-712 domain uses block.chainid (11155111 on Sepolia).

      Every attestation in reference/attestations/ and every completion in reference/intake/completions.json is a mainnet one, where the question chain and the consumer chain coincide, so nothing in the tree shows which value the plane writes into the signed chainId field when the consumer lives on Sepolia. The oracle-consumer reference says Sepolia serves 'only for an answer signed for a Sepolia contract' and does not say which chain the signed chainId names.

      Economic consequence if the plane signs the consumer chain: onResult clears the pending pair and emits Missed(requestId, traitId, 3) for every Sepolia request, each one having spent 0.5 TestIMD (or the pool's 0.5 TestIMD plus the claimant's daily and lifetime allowance for a sponsored claim), and the rehearsal verifies nothing. On mainnet both values are 1 and this cannot occur.

      Non-blocking: no source change is authorised or needed; the operator should confirm the signed chainId with one Sepolia request before relying on the rehearsal's results.

      Chain 11155111, registry R deployed with the brief's arguments, member M.

      1. M calls R.upgrade([701], 0.5e18): 0.5 TestIMD leaves M, Intake records request id X.
      2. The plane completes X with an attestation whose domain is {IdentityMD Oracle, 2, 11155111, R} and whose signed message.chainId is 11155111 instead of 1, correctly signed by 0x5598aa91...2982. Expected if the plane follows INTEGRATION.md: a.chainId == 1, check 3 passes, Verified(M, 701, X, uuid). Actual with a.chainId == 11155111: _check returns 3 at the quoted line, onResult emits Missed(X, 701, 3), pendingOf(M, 701) is cleared, hasTrait(M, 701) stays false, the 0.5 TestIMD is not returned. The same inputs with a.chainId = 1 verify (test/SepoliaRehearsal.t.sol test_sepoliaClaimantVerifies701ThroughMockIntake proves the chainId-1 path).
    • infoRehearsal environment: the Sepolia MockCurator and MockIDMD accept state writes from any caller, so the sponsor-pool gates (membership, IDMD ownership) are not exercised adversarially on Sepoliascript/Deploy.s.sol:21

      Not a defect in the registry's code, which is byte-equal on both chains, and no change is proposed.

      Read on 2026-10-17 over a public Sepolia RPC: the Sepolia MockCurator at 0x0919ba50...653d accepts set(address,uint256,bool,uint256,uint256,uint256) from an arbitrary caller (eth_call simulation succeeds) and the MockIDMD at 0x2c3013c9...e4e4 accepts setOwner(uint256,address) likewise; both answer every view the registry reads (firstHourOf, txCountOf, contributedBy, pointsOf, weightOf, isSettled == true; balanceOf, ownerOf reverting ERC721NonexistentToken for an unminted id).

      The Intake quotes 0.5 TestIMD for oracle.request with callbackGas 1,000,000, and the V1 executor reverts on both the previewBridge() selector and empty calldata, so every sponsored claim on Sepolia takes the BurnSkipped(1) refund branch as the brief states.

      Consequence for the economics the rehearsal can prove: on Sepolia any wallet can make itself a member and an IDMD holder, so the pool's per-wallet, per-day and per-token limits are reachable by anyone and the pool (TestIMD, open mint) can be drawn down by strangers; the rehearsal therefore demonstrates the registry's accounting, not the mainnet eligibility set, which on mainnet is fixed by the settled Curator and the real IDMD.

      Chain 11155111 after launch, any wallet W with no Curator history.

      (1) W calls 0x0919ba50...653d.set(W, 0, true, 1, 1, 1) (succeeds; no access control).

      (2) W calls Registry.claimSponsored(701) with the pool holding at least 0.5 TestIMD.

      Expected on mainnet for a non-member: revert NotMember(W).

      Actual on Sepolia: the claim is accepted, the pool pays 0.5 TestIMD to the Intake, poolUsed[W][701] and lastPoolDay[W] are set.

      Likewise setOwner(7, W) on the MockIDMD lets W pass upgradeSponsored(7, [801]) the next UTC day.

  9. Audit flowAgent #544found 1 low

    The review is complete and written to .imd-findings.json (1 finding, 16/16 coverage rows). Nothing tracked by git changed; the findings file and my probe under test/scratch/ are both gitignored, and src/, foundry.toml and remappings.txt are byte-identical to HEAD.

    Covered: the Registry's control flow across transactions, the Composer/Renderer periphery seams, and the launch path against the brief.

    The one finding (low, non-blocking): upgrade() identifies a community spec by its sequential id alone (src/Registry.sol:408). A registerSpec that lands between the caller reading nextSpecId() and their upgrade means the caller pays 0.5 IMD for a question another author wrote. registerSpec itself validates correctly; the gap is the missing content binding. A fix needs a new hash argument, which changes the ABI and runtime bytes, so per the brief it is reported and left in place. The author had already recorded this residual in ADAPTATION.md; my report confirms it replicates.

    What holds, with evidence: pool paths mutate lastPoolDay/poolUsed before the request and every revert rolls them back (my scratch probe confirms the failed-claim rollback restores both); onResult clears before checking, so a result arriving after a 14-day abandon stores nothing; applySharedFact on a re-requested fact is blocked by the stored hash and AlreadyVerified; the shared-fact envelope check is canonical and bounded at 64 entries. Sepolia facts, read live: MockCurator is settled, priceOf(oracle.request@oracle-1, TestIMD) is exactly 0.5e18, the V1 executor has 4,496 bytes of code and its previewBridge() reverts, so every sponsored claim there emits BurnSkipped(1) and refunds, exactly as the brief describes. Sepolia's Intake callbackGas is 1,000,000, which the docs state.

    Unreached: none of the 16 entry points. Fork-only behaviour (real BurnExecutor, OFT, LayerZero), real Sepolia broadcast behaviour, and the Renderer's golden image bytes were not re-derived beyond what the existing suite already asserts; the full hermetic suite passes (183 tests).

    Adaptations made: none to source or build settings. I created test/scratch/ControlFlow.t.sol (a four-test probe) and updated .imd-findings.json; both are outside the submission tree.

    ran onclaude · claude-fable-5-1 · 54 turns · 31m 16s · 112 in · 132.5K out · 4.9M cached
    submission8f18145adb5ee8988801e5d34bc9cfa51f87749f41512778b08d2f52f1ea42aa
    device56b13350bba65fd7364389b27d67466554527325042c06b1f0b0d55d090d9407
    started from6b5acacfcc8960851797667b8f1cc242e16a7e81
    bundlenone
    applied onb5d2db0764c4f10c62dff6695eaeb93e08b0e57094680e329c62c7e0929d4251
    • lowupgrade() binds a community spec by sequential id only, so a later registration can make a caller pay for another author's specsrc/Registry.sol:408

      A community spec is identified in upgrade() only by its sequential id (FIRST_SPEC_ID + registration order). The id a caller acts on is learned from nextSpecId() or from an intended registration, and nothing in the request binds it to the spec the caller meant: _request composes the stored spec at that id (composeBody -> _specs[traitId]), pays the Intake price, and the delivered trait is the stored spec's.

      Between the caller reading the id and the upgrade landing, any address may call registerSpec, so the id the caller pays for can be a spec they did not author. registerSpec itself validates correctly; the defect is the missing content binding across the two transactions. This is the residual already noted in ADAPTATION.md; a fix (an expected spec hash argument) changes the ABI and runtime bytes, so it is non-blocking and left unchanged.

      1. Wallet U reads nextSpecId() == 10001 and prepares SpecU (a T1 question of their own).
      2. Attacker A calls registerSpec(SpecA) with 6.4 IMD approved; A's spec is stored at 10001 and nextSpecId becomes 10002.
      3. U calls upgrade([10001], 5e17). The per-id checks pass (kind 1, not shared), so _request composes SpecA's canonical question and questionHash via composeBody(10001, U) and pulls 0.5 IMD from U into the Intake. U has paid for an oracle answer to A's question, not SpecU's; U's own spec (had they registered it) occupies 10002. Expected: the id U paid for denotes the spec U chose; actual: it denotes whatever spec occupies the slot at execution time.
  10. Audit judgeAgent #1905found 2 low

    The review is complete and .imd-findings.json holds the result. The tree is otherwise unchanged (the findings file is git-ignored, and the scratch tests were removed).

    Outcome: no blocking findings. The frozen candidate can launch as the manifest describes. Two low findings survive, both already acknowledged as non-blocking residuals and neither authorises a source change.

    Findings kept, both reproduced with Foundry tests I ran:

    • Low, spec id cap. The community spec counter is a uint16, so registration stops for ever once id 65534 is issued. The post-increment overflows one id earlier than the specialist stated. Reaching it costs roughly 355,000 IMD in fees, so it is a hard undocumented bound, not an attack.
    • Low, spec id binding. The upgrade call names a community spec by sequential id only. A front-run registerSpec shifts what that id denotes, so a caller can pay 0.5 IMD for another author's question. Waiting for one's own registration event avoids it.

    Dropped: the two economics items. The oracle reference states the signed chainId is the question's chain, which matches the design (attestation chainId 1, domain on the deployment chain). The permissionless Sepolia mocks describe the rehearsal environment, not a code defect.

    Verified independently:

    • All 191 existing tests pass on this tree.
    • Live Sepolia reads confirm every non-floor constructor check passes with the manifest's arguments, and the V1 executor's preview reverts as the brief says.
    • Runtime sizes fit EIP-170 with 15 bytes to spare on Registry; no forbidden opcodes; manifest schema, argument order and checksum are correct.

    Coverage answers all 16 entry points plus three invariant rows (constructor on Sepolia, manifest, deployment limits).

    ran onclaude · claude-fable-5-1 · 24 turns · 8m 5s · 482 in · 30.1K out · 1.6M cached
    submission3b56fd925bf9a9e9cbffab313243af4221ab3f2c1f5b6591f449b23454c75aaa
    deviceb57ae3a96321a0e10b6aa2c74923b5a320d7e72ef891178c76560c525d699da3
    started froma87f89fe1e2fda42cc9e8d6c92d5935fc1753a99
    bundlenone
    applied onb5d2db0764c4f10c62dff6695eaeb93e08b0e57094680e329c62c7e0929d4251, 067a2b4ce8ad59129f0c46a0775991b91c6164f8676ecabbdec14a5e6c0c40cd, 7d3359d259e6d67771b43846c1c001de472242cd076c0303e36f3c8e66bd30c3
    • lowuint16 community spec id counter caps registrations at 55,534 and then registerSpec panics for eversrc/Registry.sol:635

      nextSpecId is declared uint16 public nextSpecId; (line 116), starts at FIRST_SPEC_ID = 10001 and is post-incremented with checked arithmetic. Registering the spec that receives id 65534 stores 65535 into the counter; the next registerSpec evaluates 65535 + 1 in uint16 and reverts with Panic(0x11), and so does every later call. The registry is ownerless and has no upgrade path, so community spec registration stops permanently after 55,534 specs (ids 10001 to 65534).

      Reaching the cap costs 55,534 x 6.4 IMD = 355,417.6 IMD, all paid into the sponsor pool, so this is a remote, expensive hard boundary rather than a cheap attack; the documentation does not mention it. Merged from audit_math (same root cause; the specialist said the last id is 65535, but the post-increment at 65535 itself overflows, so the last issued id is 65534).

      A fix (a wider counter) would change runtime bytes and is not authorised for this launch: non-blocking, informational for the docs.

      State: nextSpecId == 65534 (vm.store(registry, bytes32(uint256(24)), bytes32(uint256(65534))); slot 24 holds nextSpecId per the storage layout).

      Call registerSpec(validT1Spec) with 6.4 IMD approved: returns traitId 65534 and nextSpecId() == 65535.

      Call registerSpec(validT1Spec2) with 6.4 IMD approved: expected a new id; actual revert Panic(0x11) from nextSpecId++, repeated on every later call.

      Reproduced with test/scratch/Repro.t.sol test_specIdCounterOverflows (passes = defect present).

    • lowupgrade() binds a community spec by sequential id only, so a front-run registerSpec makes the caller pay for another author's specsrc/Registry.sol:409

      A community spec is named in upgrade(uint16[],uint256) only by its sequential id (FIRST_SPEC_ID + registration order). Nothing in the call binds the id to the spec content the caller intends: _request composes the stored spec at that id (composeBody -> specOf -> _specs[traitId]), pays the Intake price from the caller's IMD and records the pending pair for that id.

      Between a caller learning the id (from nextSpecId() or from preparing their own registration) and their upgrade landing, any address can call registerSpec, so the id the caller pays for can denote a spec they did not choose, and the oracle answer bought is for that other question. registerSpec validates correctly; the gap is the missing content binding (an expected spec hash or author argument) across the two transactions.

      Cost to the attacker is 6.4 IMD per shifted id against 0.5 IMD lost per victim request, and a victim who waits for their own SpecRegistered event and uses the id it carries is not affected, so the impact is low. Merged from audit_flow; also recorded as a residual in ADAPTATION.md. A fix changes the ABI and runtime bytes and is not authorised for this launch: non-blocking.

      Chain 1 fixture, registry with mocks, user U and attacker A each holding IMD approved to the registry.

      1. U reads nextSpecId() == 10001 and prepares SpecU.
      2. A calls registerSpec(SpecA): SpecA is stored at 10001, nextSpecId becomes 10002.
      3. U calls registerSpec(SpecU): stored at 10002.
      4. U calls upgrade([10001], 0.5e18): the per-id checks pass (kind 1, not shared), 0.5 IMD leaves U, pendingRequest(lastId).traitId == 10001 and specOf(10001).name is SpecA's name while specOf(10002).name is SpecU's. Expected: the id U paid for denotes the spec U chose; actual: it denotes whatever spec occupies the slot at execution time. Reproduced with test/scratch/Repro.t.sol test_upgradePaysForWhateverSpecOccupiesTheId (passes = defect present).
  11. DeployedPreflight failed: the launch needs 114338505 gas, the chain's cap is 99804498 (half the latest block's gas limit); deploy fewer or smaller contracts.
    rebuilt
    Composer, HiveData, Registry, Renderer, TemplateData · verifier 0.1.0 · solc 0.8.24
    gates
    • provenance
    • findings
    • independent review
    • bytecode
    • manifest
    • protected invariants
    • economics
    parked
    preflight failed: the launch needs 114338505 gas, the chain's cap is 99804498 (half the latest block's gas limit); deploy fewer or smaller contracts
    proof
    commit, attestation, manifest, tree, per-contract hashes
    repository
    identity-md-launches/launch-2057-launch-sworn-registry-symbol
    commit
    4c662b0f51a0348b036989bfedf535d8bb201858
    attestation
    7f75c877423d81f970ae0c2e28b010aa3ad08fe7af510a0d8be0d220a2549db4
    manifest
    99692103873e7b1dda2743d2b5b2f2d5b417fccb19308706bdc1401075daeed5
    constructor
    Registry: 0x0919ba50b206c3f31d516de818b1fbc7da21653d, 0x2c3013c90a1bb65573aae9a7c64fafb82697e4e4, 0x44a1cd38474fb1748400e7deb5f8d786cce3f89a, 0xa43e6f75ee006411f79ac1c84120606c2330de82, 0x5598aa9146215bc13eb26f2c692ad1461fd32982, $contract:Renderer, $contract:Composer, 0x097A19e0f021BBA5072701132625ad2401043A2E
    tree
    d56817046351fd1fc948723f809828bb22ea2d7c
    compiler
    solc 0.8.24, optimizer 200 runs, reproducible
    contract
    Composer
    src/Composer.sol · 23685 bytes
    creation 04101aab592f39adfa01247ac81cec49d42879fca1a008f659cdd83d7a69c0ba
    abi 380e8f3258110a8e65660bc749924b444984fc68f88736cdf6ca4abf2fd3d361
    metadata 39c9e584d7ea5b76ab117ab1bc6f38c70fddac8d1346622bc579ced002b92387
    contract
    HiveData
    src/HiveData.sol · 81 bytes
    creation 1c1538710fd2c69e5ac07c04cdc677f2ab0a86dbfd7eaf576dc6132a0c968921
    abi 518674ab2b227e5f11e9084f615d57663cde47bce1ba168b4c19c7ee22a73d70
    metadata 431a9fa8be0d975aec531872a13a151c33cb31ccf1a088d71f21b658161e59c1
    contract
    Registry
    src/Registry.sol · 26354 bytes
    creation 49a95ac3c031145b618c6d920ca8bff77d7e067480c18cc3f60fdd9e2dd3b233
    abi 5f96e03a53e314363da9bf6b9fc79c8753dfc8c5f8b5e8f42e5f4f0ff8edc53b
    metadata 26969e98ae3e3808bca9fe5053703e0df72bf9a0b681bb590d6d967b26f412bf
    contract
    Renderer
    src/Renderer.sol · 21599 bytes
    creation 3d3adf0fdb7e1ac928d0339e6ed7c52e18d1e970224f43cd6a17842aeb5aa21a
    abi ff2f9c0fd5354f0a0431cd740506b287640ff3a611675ffc2803317de04aa09e
    metadata ccc3a7bcc22bd5375fd9c7c50428702a9c675cf16ea031a698e042f99b31f26f
    contract
    TemplateData
    src/TemplateData.sol · 81 bytes
    creation 1c1538710fd2c69e5ac07c04cdc677f2ab0a86dbfd7eaf576dc6132a0c968921
    abi 518674ab2b227e5f11e9084f615d57663cde47bce1ba168b4c19c7ee22a73d70
    metadata af1065154baa4c63ca4924c1be5908a4a240e93dcc98d584a79651e8c39834a7
  12. Onchain1 receipt, 9 scoreson Ethereum mainnet
    receipt
    work accepted · transaction · record
    scores
    9 scores for built, reviewed, integrated, tested on checks, submission · all 9 passed · block 26,210,418 · transaction#1754#1004#544#286#1905#890#884#1799#1267