{"assessments":[],"deployments":[],"fuzz":[],"identity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"interpretation":"Records acceptance and evidence. Neither completion nor an AI assessment establishes correctness, safety, or independent review.","jobId":"02f34926-72de-4714-8390-faa3b7e67f77","kind":"shape:dag","nodes":[{"acceptedSubmissionHash":null,"dependsOn":["tests","review"],"execution":{"network":false,"profile":"none","requires":[],"skillHash":"7e3e9a90f2342f72573636f539f0a3a3016b9f8bf53c7b77a17dc4608a09d0b2","skillId":"write-readme-and-docs","tools":[]},"key":"docs","kind":"code","role":"implement","skillHash":"7e3e9a90f2342f72573636f539f0a3a3016b9f8bf53c7b77a17dc4608a09d0b2","skillId":"write-readme-and-docs","state":"failed"},{"acceptedSubmissionHash":"2b4dfc402f4a2a534fa2f1e11f82a05b318e10c4dd224b5668dcb0abe50bf6c2","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"5289ce0b24a4ca1035ac0eb09883cc3f5490829bd653f88316262bd1414d0803","skillId":"implement-one-contract","tools":[]},"key":"impl","kind":"code","role":"implement","skillHash":"5289ce0b24a4ca1035ac0eb09883cc3f5490829bd653f88316262bd1414d0803","skillId":"implement-one-contract","state":"accepted"},{"acceptedSubmissionHash":"1c528c714c415565d41c6225c0ac563210dc2fd1b37ec4cd5dafe3143b1fce11","dependsOn":["impl"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"c26edc76dc7a76e09a42c3634054429c1679c6e247747d647a03f77e5b332d7e","skillId":"adversarial-review","tools":[]},"key":"review","kind":"code","role":"review","skillHash":"c26edc76dc7a76e09a42c3634054429c1679c6e247747d647a03f77e5b332d7e","skillId":"adversarial-review","state":"accepted"},{"acceptedSubmissionHash":"80023c51c57420193b0d296015ad6ed44aa4de8f694daa7241b884e8a056a8d4","dependsOn":["impl"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"ff1fad07fad3b8e08a71e9c5201fd632e161ed8163eb407676ea8b0bedbe179e","skillId":"write-foundry-tests","tools":[]},"key":"tests","kind":"code","role":"tests","skillHash":"ff1fad07fad3b8e08a71e9c5201fd632e161ed8163eb407676ea8b0bedbe179e","skillId":"write-foundry-tests","state":"accepted"}],"objective":"Implement ExpiringMerkleDistributor in src/ExpiringMerkleDistributor.sol, test it, review it and document it. Do not deploy. constructor(address token, bytes32 merkleRoot, uint256 expiry, address sweepTo), all immutable; reverts unless expiry > block.timestamp and sweepTo and token are nonzero. Leaves are keccak256(bytes.concat(keccak256(abi.encode(uint256 index, address account, uint256 amount)))) (OpenZeppelin StandardMerkleTree double hash, so an inner node cannot pass as a leaf); proofs hash sorted pairs. claim(uint256 index, address account, uint256 amount, bytes32[] proof): anyone may submit, tokens always go to account; allowed while block.timestamp <= expiry; reverts on a claimed index (bitmap, 256 per word), a bad proof or after expiry; emits Claimed(index, account, amount). isClaimed(index) view. sweep(): anyone, only when block.timestamp > expiry, sends the whole token balance to sweepTo and emits Swept(amount); it can be called again for tokens that arrive later. Token transfers tolerate ERC-20s that return no bool. Self-contained: inline the proof check and a minimal IERC20/safe-transfer helper, since the implementing step may not add dependencies.","parentJobId":null,"planHash":"5572b778fffb828177263102512e00ccee6e705716959d433b003eebc6434fcb","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"02f34926-72de-4714-8390-faa3b7e67f77","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-256-src-expiringmerkledistributor-sol"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51198","feedbackHash":"603839f4c38d5bd62448dc7c65092be9760f789aa64719b9ea62acbbdd38248d","nodeKey":"impl","submissionHash":"2b4dfc402f4a2a534fa2f1e11f82a05b318e10c4dd224b5668dcb0abe50bf6c2","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51297","feedbackHash":"9baa1276b40d59463d7ff5d39a67358d2c4dd8a65ae580356e4e5a50a7bd5d3e","nodeKey":"review","submissionHash":"1c528c714c415565d41c6225c0ac563210dc2fd1b37ec4cd5dafe3143b1fce11","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51198","feedbackHash":"0da7ef9d5c1c258c44305e7d6e28c46bc8234b43c44a50484b33f370f5c519f2","nodeKey":"tests","submissionHash":"80023c51c57420193b0d296015ad6ed44aa4de8f694daa7241b884e8a056a8d4","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"6a9a7c6c366126cbea4603c79308e1ffcf916622401285c0d026f4010baf8302","state":"blocked","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"8df16409e9706163","findings":[{"description":"The implementation includes no tests, despite the explicit requirement to test the distributor. The only tracked project file is this contract, and there are no test contracts or test functions. Consequently, none of the required adversarial cases has committed regression coverage: double-hashed leaves versus inner nodes, bitmap boundaries, the inclusive claim deadline, early and repeated sweeps, or no-bool transfers and failed-transfer rollback. This is a missing deliverable and verification gap, not a demonstrated contract exploit. Add a self-contained Foundry test suite covering these cases.","line":33,"path":"src/ExpiringMerkleDistributor.sol","reproduction":"In the supplied checkout, run `git ls-files` and `git ls-files -- '*.t.sol'`, then inspect the listed Solidity source for test functions. The first command returns only `src/ExpiringMerkleDistributor.sol`; the second returns nothing, and the source contains no test functions. Expected: committed executable tests exercising the required behavior. Actual: zero committed tests. Concrete missing cases include claims at indices 255 and 256 without interference; claim success and sweep rejection at timestamp == expiry; claim rejection and sweep success at expiry + 1; and a successful claim against an ERC-20 whose transfer returns zero bytes. These cases have no executable assertions in the submission.","severity":"low","title":"Required Foundry tests are missing"}],"hash":"1c528c714c415565d41c6225c0ac563210dc2fd1b37ec4cd5dafe3143b1fce11","nodeId":"c42e8b08-9452-466c-843c-78301c601f2f","outcome":"completed","summary":"Wrote [.imd-findings.json](/root/.identitymd/work/02f34926-72de-4714-8390-faa3b7e67f77/c42e8b08-9452-466c-843c-78301c601f2f/.imd-findings.json) with one **low-severity finding**: the required Foundry tests are missing.\n\nNo substantiated contract exploit was found in the requested areas. Review used source inspection and read-only checks; no EVM tests were executed. Implementation files remain unchanged.","treeHash":null,"usage":{"cachedInputTokens":193408,"inputTokens":35057,"model":"gpt-6-astra","outputTokens":4982,"runtime":"codex","turns":4,"wallClockMs":165517}},{"artifacts":[],"attempt":1,"bundleHash":"af1c0e210992f1bffba1226a70320e3f1fb6aa4b1bae44e0f43c46f0cd9cc02f","device":"29ea8835baa3dfe1","findings":[],"hash":"2b4dfc402f4a2a534fa2f1e11f82a05b318e10c4dd224b5668dcb0abe50bf6c2","nodeId":"afbe0e53-401b-4d0e-aff5-369c519a72b3","outcome":"completed","summary":"`ExpiringMerkleDistributor` is implemented, built, tested, and committed as `b52b6e6`. Only `src/ExpiringMerkleDistributor.sol` was added. No dependencies or config files were touched, and the repo had no foundry.toml, so Foundry's defaults were used.\n\n**What the contract does**\n\n- **Constructor** stores token, merkleRoot, expiry and sweepTo as immutables. It reverts with `ZeroAddress` for a zero token or sweepTo, and with `ExpiryInPast` unless expiry is strictly after the current timestamp.\n- **claim** is open to anyone and always pays the `account` in the leaf. It reverts with `ClaimWindowClosed` after expiry, `AlreadyClaimed` for a used index, and `InvalidProof` otherwise. The bitmap bit is set and `Claimed` emitted before the token transfer, so a callback token cannot re-enter and double claim.\n- **Leaf and proof format** match OpenZeppelin StandardMerkleTree: the leaf is the double keccak of the ABI-encoded triple, and proof siblings are hashed as sorted pairs. The double hash rules out passing an inner node as a leaf.\n- **isClaimed** reads a bitmap with 256 indices per storage word.\n- **sweep** is open to anyone, reverts with `NotYetExpired` while the timestamp is at or before expiry, and otherwise transfers the whole balance to sweepTo and emits `Swept`. It can be repeated for tokens that arrive later, including a zero-balance sweep.\n- **Safe transfer helper** uses a low-level call. It accepts no return data only if the token has code, accepts a 32-byte word equal to one, and reverts with `TransferFailed` on a revert, a returned false, malformed data, or a codeless token.\n\n**Verification**\n\n- `forge build` succeeds. The only compiler output is the linter's standard warning about comparing against block.timestamp, which is inherent to a deadline contract.\n- `forge test` passes 31 tests in test/scratch, written against an inlined cheatcode interface so no forge-std was needed. They cover all constructor reverts, the exact expiry boundary for both claim and sweep, double claims, bitmap word boundaries at indices 255 and 256, wrong index, account, amount, proof and proof length, a single-hashed leaf tree being rejected, a single-leaf tree with an empty proof, third-party relaying, a no-return token, a false-returning token, malformed return data, a codeless token, an underfunded distributor, and two fuzz tests, one of which builds random trees of up to 20 leaves and checks every leaf claims exactly once with full balance conservation.\n\n**Assumptions and notes for the integrator**\n\n- The contract has no admin and no pause. The only privileged address is the passive sweepTo recipient.\n- `Swept` is emitted even when the balance is zero. That is a design choice, not an error.\n- Fee-on-transfer or rebasing tokens are not specially handled. Claimants may receive less than the leaf amount and the contract does not check funding at deploy time.\n- The claim event parameters are unindexed, matching the signature given in the task. If off-chain indexers want filtering by account, that would be a signature change and should be agreed first.\n- A zero merkleRoot is accepted by the constructor. No leaf can be proven against it, so such a deployment is effectively sweep-only after expiry.","treeHash":"c35f8ac2401c9df85293dd4af8a04a15ea2c77f0","usage":{"cachedInputTokens":389774,"inputTokens":290,"model":"claude-fable-5-1","outputTokens":16053,"runtime":"claude","turns":10,"wallClockMs":210559}},{"artifacts":[],"attempt":1,"bundleHash":"2d3f6bd159760d60305038b8fab67fbbcacb08b65aab5d7fa19ca6d5ca7b052d","device":"29ea8835baa3dfe1","findings":[],"hash":"80023c51c57420193b0d296015ad6ed44aa4de8f694daa7241b884e8a056a8d4","nodeId":"c0058769-4b0c-4960-b41a-94efb45bb2b4","outcome":"completed","summary":"The build artifacts under `cache/` and `out/` are git-ignored, so the only change in the tree is the test file. The work is complete.\n\n**Result:** `test/ExpiringMerkleDistributor.t.sol` adds 52 tests, all passing under `forge test` with 256 fuzz runs each. No dependencies were added and no configuration files were touched.\n\n**What the suite covers**\n\n- **Fixture:** a 6-leaf tree built in Solidity with StandardMerkleTree double-hashed leaves and sorted-pair inner nodes. Index 0 is present, Alice appears at indexes 0 and 2, and indexes 255, 256 and 1000 span three bitmap words. A local verifier confirms every fixture proof before the tests rely on it.\n- **Constructor:** zero token, zero sweepTo, expiry equal to now, expiry in the past, expiry one second ahead, and the revert priority when both checks fail.\n- **Claims:** happy path with event, relayer submission paying the account rather than the caller, same account across two indexes, arbitrary claim order, and conservation of funded tokens under fuzzed claim subsets.\n- **Double claims:** same caller, different caller, garbage proof after a claim, and both sides of the 255/256 word boundary.\n- **Bad inputs:** wrong index, swapped indexes between the two Alice leaves, wrong account, wrong amount, another leaf's proof, empty, truncated, extended, bit-flipped and reordered proofs, plus fuzzed wrong accounts, amounts and unknown indexes.\n- **Inner node as leaf:** takes a genuine inner node with its shortened path to the root, confirms locally that the path verifies for the node, then shows every plausible reinterpretation of its children as claim arguments is rejected. Also rejects the single-hashed leaf and the root presented with an empty proof.\n- **Expiry:** claim at exactly expiry passes, at expiry plus one reverts, fuzzed timestamps on both sides, and the window check taking precedence over proof errors.\n- **Sweep:** reverts before and at expiry, sends everything at expiry plus one, repeat sweep emits zero, later arrivals are swept again, and the bitmap survives a sweep.\n- **Tokens:** a USDT-style no-bool mock succeeds for claim and sweep, a false-returning token, a token returning a non-boolean word, an underfunded token and a token address with no code all revert with the contract's transfer error. A failed transfer leaves the index unclaimed so the same claim succeeds after topping up.\n- **Bitmap:** fuzzed four-leaf trees with indexes anywhere in the uint256 space, asserting each claim sets only its own bit and no neighbour bit in the same or adjacent word. A fixed test hits 0, 255, 256, 511, 512, the 2^255 word and the top of the space.\n\n**Defects:** none found, so no findings file was written. Three observations are informational only and do not violate the stated spec. The constructor does not check that the token has code, which the tests show fails safely at claim time. Sweeping a zero balance issues a zero-value transfer, which a few real tokens reject. The Claimed event has no indexed parameters, which limits log filtering but matches the requested signature.","treeHash":"24a2dd993e4b68b335b9c7b40dbf8f51b0bbd451","usage":{"cachedInputTokens":272513,"inputTokens":162,"model":"claude-fable-5-1","outputTokens":24795,"runtime":"claude","turns":6,"wallClockMs":288627}},{"artifacts":[],"attempt":2,"bundleHash":null,"device":"0476c44a80aa9574","findings":[],"hash":"9acd050904d6aab78e4f7a198b4b4b64f8781a2a738e71c67d661d13ab4a3a25","nodeId":"b08eb268-4b9b-4472-aecc-9dc3e51eb9ef","outcome":"failed","summary":"output outside allowed paths: artifacts/README.md","treeHash":null,"usage":{"cachedInputTokens":0,"inputTokens":0,"model":null,"outputTokens":0,"runtime":"claude","turns":0,"wallClockMs":349}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"0256823ae36e7900","findings":[],"hash":"b96c5bb469e1bd5c34eca15d82a58cd9f180107ee522d120f61593633989170c","nodeId":"b08eb268-4b9b-4472-aecc-9dc3e51eb9ef","outcome":"failed","summary":"output outside allowed paths: artifacts/README.md","treeHash":null,"usage":{"cachedInputTokens":0,"inputTokens":0,"model":null,"outputTokens":0,"runtime":"codex","turns":0,"wallClockMs":238}},{"artifacts":[],"attempt":3,"bundleHash":null,"device":"0479f300f3637e6e","findings":[],"hash":"f86b48d3c4e3cea9ee09d9c6c2cb3f615d8e7282077972cda9a2d62bac917688","nodeId":"b08eb268-4b9b-4472-aecc-9dc3e51eb9ef","outcome":"failed","summary":"output outside allowed paths: artifacts/README.md","treeHash":null,"usage":{"cachedInputTokens":0,"inputTokens":0,"model":null,"outputTokens":0,"runtime":"claude","turns":0,"wallClockMs":306}}],"verification":[{"checks":[{"durationMs":63,"exitCode":0,"name":"build","output":"Compiling 1 files with Solc 0.8.30\nSolc 0.8.30 finished in 17.74ms\nCompiler run successful!\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n   ╭▸ src/ExpiringMerkleDistributor.sol:92:13\n   │\n92 │         if (expiry_ <= block.timestamp) revert ExpiryInPast();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/ExpiringMerkleDistributor.sol:122:13\n    │\n122 │         if (block.timestamp > expiry) revert ClaimWindowClosed();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/ExpiringMerkleDistributor.sol:137:13\n    │\n137 │         if (block.timestamp <= expiry) revert NotYetExpired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#block-timestamp\n\n","passed":true},{"durationMs":42,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\nNo tests found in project! Forge looks for functions that start with `test`\n","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"2b4dfc402f4a2a534fa2f1e11f82a05b318e10c4dd224b5668dcb0abe50bf6c2","verifiedTreeHash":"c35f8ac2401c9df85293dd4af8a04a15ea2c77f0","verifierVersion":"0.1.0+ff982c0f"},{"checks":[{"durationMs":171,"exitCode":0,"name":"build","output":"Compiling 2 files with Solc 0.8.30\nSolc 0.8.30 finished in 126.44ms\nCompiler run successful with warnings:\nWarning (2018): Function state mutability can be restricted to view\n   --> test/ExpiringMerkleDistributor.t.sol:454:5:\n    |\n454 |     function test_SingleHashedLeaf_IsRejected() public {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n   ╭▸ src/ExpiringMerkleDistributor.sol:92:13\n   │\n92 │         if (expiry_ <= block.timestamp) revert ExpiryInPast();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/ExpiringMerkleDistributor.sol:122:13\n    │\n122 │         if (block.timestamp > expiry) revert ClaimWindowClosed();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/ExpiringMerkleDistributor.sol:137:13\n    │\n137 │         if (block.timestamp <= expiry) revert NotYetExpired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ test/ExpiringMerkleDistributor.t.sol:259:17\n    │\n259 │         require(d.expiry() == block.timestamp + 1, \"expiry\");\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#block-timestamp\n\nwarning[incorrect-shift]: the order of args in a shift operation is incorrect\n    ╭▸ test/ExpiringMerkleDistributor.t.sol:829:30\n    │\n829 │             if (claimMask & (1 << i) != 0) {\n    │                              ━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#incorrect-shift\n\nwarning[incorrect-shift]: the order of args in a shift operation is incorrect\n    ╭▸ test/ExpiringMerkleDistributor.t.sol:859:30\n    │\n859 │             if (claimMask & (1 << i) != 0) {\n    │                              ━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#incorrect-shift\n\n","passed":true},{"durationMs":117,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 52 tests for test/ExpiringMerkleDistributor.t.sol:ExpiringMerkleDistributorTest\n[PASS] testFuzz_ClaimAfterExpiry_Reverts(uint256) (runs: 256, μ: 48598, ~: 48598)\n[PASS] testFuzz_ClaimAnyTimeUpToExpiry_Passes(uint256) (runs: 256, μ: 108986, ~: 108986)\n[PASS] testFuzz_ClaimSetsOnlyItsOwnBit(uint256,uint256,uint256,uint256) (runs: 256, μ: 1316384, ~: 1320504)\n[PASS] testFuzz_Conservation(uint8,bool) (runs: 256, μ: 175167, ~: 164950)\n[PASS] testFuzz_IsClaimedFalseBeforeAnyClaim(uint256) (runs: 256, μ: 8654, ~: 8654)\n[PASS] testFuzz_SweepAfterExpiry_SendsBalance(uint256,uint8) (runs: 256, μ: 198118, ~: 194687)\n[PASS] testFuzz_SweepUpToExpiry_Reverts(uint256) (runs: 256, μ: 10719, ~: 10719)\n[PASS] testFuzz_UnknownIndex_RevertsInvalidProof(uint256) (runs: 256, μ: 71117, ~: 71117)\n[PASS] testFuzz_WrongAccount_Reverts(address) (runs: 256, μ: 52180, ~: 52180)\n[PASS] testFuzz_WrongAmount_Reverts(uint256) (runs: 256, μ: 52099, ~: 52099)\n[PASS] test_AnyoneMaySubmit_TokensGoToAccountNotCaller() (gas: 113166)\n[PASS] test_BitmapWordBoundaries() (gas: 1422127)\n[PASS] test_ClaimAfterExpiry_WindowCheckedBeforeEverythingElse() (gas: 11812)\n[PASS] test_ClaimAllLeaves_DrainsExactlyTotal() (gas: 408508)\n[PASS] test_ClaimAtExactlyExpiry_Passes() (gas: 111945)\n[PASS] test_ClaimAtExpiryPlusOne_Reverts() (gas: 59330)\n[PASS] test_ClaimIndexZero_TransfersAndEmits() (gas: 118272)\n[PASS] test_ClaimOrderDoesNotMatter() (gas: 386334)\n[PASS] test_ClaimsBeforeAndAtExpiry_ThenLocked() (gas: 215588)\n[PASS] test_Constructor_AcceptsExpiryOneSecondAhead() (gas: 644320)\n[PASS] test_Constructor_RevertsOnZeroSweepTo() (gas: 43026)\n[PASS] test_Constructor_RevertsOnZeroToken() (gas: 40845)\n[PASS] test_Constructor_RevertsWhenExpiryEqualsNow() (gas: 42655)\n[PASS] test_Constructor_RevertsWhenExpiryInPast() (gas: 42797)\n[PASS] test_Constructor_ZeroAddressCheckedBeforeExpiry() (gas: 40410)\n[PASS] test_DoubleClaim_AcrossBitmapWords() (gas: 213262)\n[PASS] test_DoubleClaim_CheckedBeforeProof() (gas: 109522)\n[PASS] test_DoubleClaim_Reverts() (gas: 126781)\n[PASS] test_DoubleClaim_RevertsEvenFromDifferentCaller() (gas: 123859)\n[PASS] test_FalseReturningToken_RevertsTransferFailed() (gas: 940892)\n[PASS] test_FixtureProofsVerifyLocally() (gas: 128559)\n[PASS] test_GarbageReturnToken_RevertsTransferFailed() (gas: 985818)\n[PASS] test_InnerNode_CannotBeClaimedAsLeaf() (gas: 159910)\n[PASS] test_NoBoolToken_ClaimAndSweepWork() (gas: 1063854)\n[PASS] test_NoBoolToken_InsufficientBalance_RevertsTransferFailed() (gas: 1059212)\n[PASS] test_RootItselfIsNotAClaimableLeaf() (gas: 16060)\n[PASS] test_SameAccountTwoIndexes_AreIndependent() (gas: 142897)\n[PASS] test_SingleHashedLeaf_IsRejected() (gas: 40450)\n[PASS] test_SweepAgain_ForTokensArrivingLater() (gas: 60005)\n[PASS] test_SweepAtExactlyExpiry_Reverts() (gas: 17842)\n[PASS] test_SweepAtExpiryPlusOne_SendsEverything() (gas: 144481)\n[PASS] test_SweepBeforeExpiry_Reverts() (gas: 8866)\n[PASS] test_SweepDoesNotAffectClaimBitmap_AndClaimsStayLocked() (gas: 157067)\n[PASS] test_SweepFarInTheFuture() (gas: 45284)\n[PASS] test_SweepTwice_SecondSweepsZero() (gas: 54198)\n[PASS] test_TokenWithoutCode_ClaimRevertsTransferFailed() (gas: 717354)\n[PASS] test_UnderfundedBoolToken_RevertsTransferFailed() (gas: 998900)\n[PASS] test_WrongAccount_Reverts() (gas: 59520)\n[PASS] test_WrongAmount_Reverts() (gas: 94998)\n[PASS] test_WrongIndex_Reverts() (gas: 57105)\n[PASS] test_WrongIndex_UsingAnotherLeafsIndex_Reverts() (gas: 79569)\n[PASS] test_WrongProof_Reverts() (gas: 133763)\nSuite result: ok. 52 passed; 0 failed; 0 skipped; finished in 69.49ms (360.26ms CPU time)\n\nRan 1 test suite in 70.31ms (69.49ms CPU time): 52 tests passed, 0 failed, 0 skipped (52 total tests)\n","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"80023c51c57420193b0d296015ad6ed44aa4de8f694daa7241b884e8a056a8d4","verifiedTreeHash":"24a2dd993e4b68b335b9c7b40dbf8f51b0bbd451","verifierVersion":"0.1.0+ff982c0f"}]}