{"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":"75567c33-db2d-4dff-83ad-80ee34a7b148","kind":"impl_tests_review","nodes":[{"acceptedSubmissionHash":"b4ec30b4e5e22bef37721b0bcf41ff2e6066eb110aa191157eabcf54a5e9eaf6","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"d37537abb20af46832b24602788d7895021ecaac20c6934313dc4f8aba4ad047","skillId":"implement-contract","tools":[]},"key":"impl","kind":"code","role":"implement","skillHash":"d37537abb20af46832b24602788d7895021ecaac20c6934313dc4f8aba4ad047","skillId":"implement-contract","state":"accepted"},{"acceptedSubmissionHash":"efd356ddfe00b2575c04de1df4f88f03e1134ee1ed97c4b7e09e7f4f13bee382","dependsOn":["impl","tests"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"cde70111c1a3be5c45749e6d44960baf641ca60fa1734f1238369ce6eb372db1","dependsOn":["impl","tests","manifest"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"6b037a7b6601e883cf8a906c1520c0624817d42d8310b65c2f43679204608af3","skillId":"adversarial-review","tools":[]},"key":"review","kind":"code","role":"review","skillHash":"6b037a7b6601e883cf8a906c1520c0624817d42d8310b65c2f43679204608af3","skillId":"adversarial-review","state":"accepted"},{"acceptedSubmissionHash":"eb56aba2308c6794cf128e8ba7d705a9fd9165c8346f1aef5a83e52839674b83","dependsOn":["impl"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","tools":[]},"key":"tests","kind":"code","role":"tests","skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","state":"accepted"}],"objective":"Memecoin Cemetery: a tokenless contract on Ethereum mainnet where dead ERC-20 tokens get a tombstone and an epitaph, but only if nobody holding the token objects. No token, no fees, no owner, no upgrade, no ETH accepted.\n\nContract MemecoinCemetery:\n- dig(address token, string calldata epitaph): opens a 30-day wake for an ERC-20 (epitaph max 140 bytes; one open wake or grave per token). Emits WakeOpened(token, digger, epitaph, endsAt).\n- itLives(address token): during the wake, any account holding at least 0.1% of the token's totalSupply (checked with balanceOf/totalSupply at call time) can call this to cancel the burial. Emits Resurrected(token, holder). The token can be dug again after 30 days.\n- seal(address token): after the wake ends with no successful itLives, anyone seals the grave. Emits Buried(token, epitaph, digger, sealedAt). A sealed grave is permanent.\n- graveOf(address) view returns (state: None/Wake/Buried, digger, epitaph, endsAt or sealedAt); graveCount() view.\n- Must tolerate non-standard tokens: wrap balanceOf/totalSupply in try/catch; a token whose calls revert cannot be dug.\n\nAcceptance: Foundry tests with mock ERC-20s for dig, itLives by a 0.1% holder (and rejection below 0.1%), seal only after the wake, permanence of sealed graves, re-dig cooldown, epitaph length limit, reverting-token handling, ETH rejected; NatSpec everywhere; verified source.","parentJobId":null,"planHash":"bcc5f1f96e151f247b42f56c1e903a21b16e66fdad1ff8a6a59f983edc43f78c","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"75567c33-db2d-4dff-83ad-80ee34a7b148","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-852-memecoincemetery"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51357","feedbackHash":"c7e6736d8a9d8bf94e19787de9029e5004b0b203e7abe8adb9cbe1798c24235b","nodeKey":"impl","submissionHash":"b4ec30b4e5e22bef37721b0bcf41ff2e6066eb110aa191157eabcf54a5e9eaf6","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52113","feedbackHash":"098dc69e5c572a041991db3a0cfabdc091b7197c361ad3e5afbd74c2172b6faf","nodeKey":"manifest","submissionHash":"efd356ddfe00b2575c04de1df4f88f03e1134ee1ed97c4b7e09e7f4f13bee382","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51435","feedbackHash":"18c8912044ad32b7c5fe53a18e5e3f126c049fc717bcc6acc15c973d9b2b83c5","nodeKey":"review","submissionHash":"cde70111c1a3be5c45749e6d44960baf641ca60fa1734f1238369ce6eb372db1","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52095","feedbackHash":"9d5129658900426c23544fc43621f17da3353d2c721bdeac2cf10fe3cf144cb1","nodeKey":"tests","submissionHash":"eb56aba2308c6794cf128e8ba7d705a9fd9165c8346f1aef5a83e52839674b83","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"46c257fe3db015e4459760247bdc6fc07119d7f82394334989977d4c926bd9b7","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":"2ede1ea78948137ad713727bc71168852d846f25cdca629c21474c78f9bfa20a","device":"7eb57f222fe63696","findings":[],"hash":"b4ec30b4e5e22bef37721b0bcf41ff2e6066eb110aa191157eabcf54a5e9eaf6","nodeId":"7c6104f2-91b1-46f9-b632-8503f14e9c54","outcome":"completed","summary":"Implemented [MemecoinCemetery.sol](/root/.identitymd/work/75567c33-db2d-4dff-83ad-80ee34a7b148/7c6104f2-91b1-46f9-b632-8503f14e9c54/src/MemecoinCemetery.sol) with the required lifecycle, token checks, ETH rejection, and NatSpec.\n\n`forge build` succeeds. All 32 scratch tests pass, including fuzz and deployment checks. No configuration or dependencies changed.\n\nExplorer source verification remains pending deployment.","treeHash":"a2f6260b2a97af077f84e22cb425c849f22ed378","usage":{"cachedInputTokens":229632,"inputTokens":41581,"model":"gpt-6-astra","outputTokens":12203,"runtime":"codex","turns":5,"wallClockMs":290202}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"5fdca4f96f37a80d","findings":[{"citation":"resolved","description":"The try/catch only catches reverts raised inside the token. If the token's call succeeds but returns fewer than 32 bytes (for example a contract with an empty fallback, or one that returns 31 bytes), Solidity's return-data decoding reverts in the cemetery itself, outside the catch clause, with zero bytes of revert data. The spec requirement that such a token 'cannot be dug' still holds, and the @dev comment on _readToken acknowledges the path, but callers and front-ends get an undiagnosable empty revert rather than the documented TokenReadFailed error. The same applies to itLives. Not a security issue; purely an error-reporting gap. A fix would be to perform the reads with a low-level staticcall and check returndata length, or to accept the behaviour and document it in the error NatSpec.","line":168,"path":"src/MemecoinCemetery.sol","reproduction":"Deploy `contract T { fallback() external {} }`. Call `cemetery.dig(address(T), \"x\")`. Expected (per the TokenReadFailed NatSpec 'A token's totalSupply or balanceOf call reverted'): revert with selector TokenReadFailed (0x...). Actual: revert with 0 bytes of data (trace: `EmptyReturnToken::fallback() [staticcall] -> Stop`, then `MemecoinCemetery::dig -> [Revert] EvmError: Revert`, revert data length 0). The existing test test_DigRejectsMalformedTokenReads uses a bare vm.expectRevert() for modes 2 and 3, which is why this difference is not visible in the suite.","severity":"info","snippet":"        try ICemeteryToken(token).totalSupply() returns (uint256 currentSupply) {","title":"ABI-decode failures on token reads escape the try/catch and surface as an empty revert instead of TokenReadFailed"},{"citation":"resolved","description":"Eligibility is the caller's live balance at call time with no holding period or snapshot. Any account that can obtain 0.1% of supply for one transaction (flash swap from a DEX pool, a loan from a friendly whale, or simply transferring tokens between its own wallets) can call itLives and return the tokens in the same transaction. This matches the brief ('checked with balanceOf/totalSupply at call time') and is documented in the contract-level @dev, so it is not a defect against the requested design. It is recorded so the requester consciously accepts that 'nobody holding the token objects' can be satisfied by a non-holder with transient access to tokens. Mitigations (snapshots, holding periods, per-address objection cooldowns) would change the agreed design and need a scope decision.","line":121,"path":"src/MemecoinCemetery.sol","reproduction":"Token with totalSupply 1_000_000e18; dig(token). In one transaction: transfer 1_000e18 (exactly 0.1%) to contract F, F calls cemetery.itLives(token), F transfers the 1_000e18 back. Expected under the brief: itLives succeeds and the wake is cancelled; actual: same (verified in a scratch test: graveOf(token).state == None afterwards and F's final balance == 0). Listed for awareness only.","severity":"info","snippet":"        (uint256 supply, uint256 balance) = _readToken(token, msg.sender);","title":"Scope observation: a momentary (flash-borrowed) 0.1% balance is sufficient to cancel a wake"},{"citation":"resolved","description":"The brief says a holder of 'at least 0.1% of the token's totalSupply' can object. For a token whose totalSupply() returns 0, 0.1% of 0 is 0, so a strict reading would let any account with a nonzero (or even zero) balance object. The implementation instead rejects every objection and lets such tokens be buried unopposed. This is a reasonable and explicitly documented choice (@dev on itLives: 'Requires a nonzero supply') and a zero-supply token is genuinely dead, but a broken token that reports supply 0 while still holding real balances (some proxies with uninitialised supply, or tokens that mis-track supply) cannot be defended by its holders. The existing test test_SupplyBecomingZeroRejectsObjection only covers balance == 0; the balance > 0 case is untested.","line":124,"path":"src/MemecoinCemetery.sol","reproduction":"Mock token: setSupply(0); setBalance(HOLDER, 1000). dig(token); vm.prank(HOLDER); itLives(token). Expected under a literal reading of the brief: objection succeeds (1000 >= 0.1% of 0); actual: revert InsufficientBalance and the wake remains sealable after 30 days. Not a security defect; a design/scope question for the requester.","severity":"info","snippet":"        if (supply == 0 || balance < minimumBalance) revert InsufficientBalance();","title":"Scope observation: when totalSupply reports zero, no account can object regardless of its balance"}],"hash":"cde70111c1a3be5c45749e6d44960baf641ca60fa1734f1238369ce6eb372db1","nodeId":"e972e2eb-e619-4943-9fbc-8cb9563519f7","outcome":"completed","summary":"The review is complete. No tracked files were changed, and `.imd-findings.json` holds the result.\n\n**Verdict: no defects found that warrant a revision.** The implementation matches the brief, and the test suite covers every acceptance item. I traced all three state-changing entry points and re-ran the full suite, including the stateful invariant campaign, plus scratch probes of my own.\n\nWhat I checked and found correct:\n\n- **dig** enforces the 140-byte limit, one record per token, the exact 30-day cooldown boundary after a resurrection, a code-size check, and both token reads via STATICCALL. State writes are atomic on revert.\n- **itLives** uses a ceiling threshold equal to `balance * 1000 >= supply` without overflow at maximum supply. It rejects at and after the deadline, deletes the record, and starts the cooldown. Token callbacks cannot mutate cemetery state.\n- **seal** does not read the token, so a broken token cannot block burial. Buried graves are permanent and counted exactly once.\n- **No ETH path**: the ABI has no receive, fallback, or payable function. The runtime is 5247 bytes with no DELEGATECALL, CALLCODE, or SELFDESTRUCT, so the protected deployment test should pass.\n- The static-analysis leads (literal 1000, unchecked return from the validating read in dig) are style only, not defects.\n\nThree info-level observations are recorded with reproductions, none blocking:\n\n1. A token that returns empty or short data from totalSupply or balanceOf reverts with zero bytes of revert data rather than the documented custom error. The try/catch does not cover ABI decoding failures. The spec requirement that such a token cannot be dug still holds.\n2. A momentary 0.1% balance, such as a flash swap returned in the same transaction, is enough to cancel a wake. The brief explicitly asks for balances checked at call time, so this is a scope note, not a defect.\n3. When totalSupply reports zero, no account can object regardless of its balance. This is documented in the NatSpec and is a reasonable reading of the brief, but the tests only cover the zero-balance case.\n\nOne configuration note outside the author's scope: there is no foundry.toml, so the compiled metadata uses the default ipfs bytecode hash rather than the recommended none. That is a config-file concern for whoever owns the launch policy, not a code finding.","treeHash":null,"usage":{"cachedInputTokens":643888,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":20163,"runtime":"claude","turns":18,"wallClockMs":298546}},{"artifacts":[],"attempt":1,"bundleHash":"30bd4ace2a7549b50a0f0eb5135afc4da57fed367e33ae3f41d3eb353ac6cb0b","device":"8310b806f0fcfbea","findings":[],"hash":"eb56aba2308c6794cf128e8ba7d705a9fd9165c8346f1aef5a83e52839674b83","nodeId":"aff1f4a1-87b9-40f2-bb23-af92d941debd","outcome":"completed","summary":"Added [test/MemecoinCemetery.t.sol](/home/imd14/.identitymd/work/75567c33-db2d-4dff-83ad-80ee34a7b148/aff1f4a1-87b9-40f2-bb23-af92d941debd/test/MemecoinCemetery.t.sol) with lifecycle, failure-path, fuzz, and invariant coverage.\n\nOffline verification passed: `forge build` and all 36 tests, including 16,384 invariant calls. No reproducible defects found. Only the allowed deliverable file changed.","treeHash":"82e3ebd7cbcc969e1e7d08f1dbb91a146d6b86f2","usage":{"cachedInputTokens":413440,"inputTokens":55954,"model":"gpt-6-astra","outputTokens":16248,"runtime":"codex","turns":5,"wallClockMs":395102}},{"artifacts":[],"attempt":1,"bundleHash":"1083722dbf6ac4dcd47aa8ea57ae5455a4a6e81dee90110a01cec33262350d52","device":"92352b60f8e93ddd","findings":[],"hash":"efd356ddfe00b2575c04de1df4f88f03e1134ee1ed97c4b7e09e7f4f13bee382","nodeId":"1ff989d2-2fb0-4898-a6e6-36e783822238","outcome":"completed","summary":"Created [launch.json](/home/imd-worker-33/.identitymd/work/75567c33-db2d-4dff-83ad-80ee34a7b148/1ff989d2-2fb0-4898-a6e6-36e783822238/launch.json) listing only `MemecoinCemetery` with empty constructor arguments.\n\nValidated the manifest structure and constructor ABI. `forge build` succeeded; all 36 tests passed. Only `launch.json` is a submission change.","treeHash":"29b10a8e66bf97f24b724c1d84b0ca2ed0effc33","usage":{"cachedInputTokens":127360,"inputTokens":19866,"model":"gpt-6-astra","outputTokens":1783,"runtime":"codex","turns":3,"wallClockMs":52834}}],"verification":[{"checks":[{"durationMs":79,"exitCode":0,"name":"build","output":"Compiling 1 files with Solc 0.8.26\nSolc 0.8.26 finished in 29.25ms\nCompiler run successful!\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MemecoinCemetery.sol:101:13\n    │\n101 │         if (block.timestamp < _digAfter[token]) revert CooldownActive();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MemecoinCemetery.sol:119:13\n    │\n119 │         if (block.timestamp >= grave.timestamp) revert WakeEnded();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MemecoinCemetery.sol:138:13\n    │\n138 │         if (block.timestamp < grave.timestamp) revert WakeNotEnded();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\n","passed":true},{"durationMs":68,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\nWarning: No tests found in project! Forge looks for functions that start with `test`\n","passed":true},{"durationMs":25,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MemecoinCemetery.dig(address,string)\",\"MemecoinCemetery.itLives(address)\",\"MemecoinCemetery.seal(address)\"],\"files\":{\"src/MemecoinCemetery.sol\":179},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":385,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":297,"exitCode":0,"name":"aderyn","output":"[low] literal-instead-of-constant at src/MemecoinCemetery.sol:123: Literal Instead of Constant (2 places)\n[low] unchecked-return at src/MemecoinCemetery.sol:104: Unchecked Return","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"b4ec30b4e5e22bef37721b0bcf41ff2e6066eb110aa191157eabcf54a5e9eaf6","verifiedTreeHash":"a2f6260b2a97af077f84e22cb425c849f22ed378","verifierVersion":"0.1.0+7471272e"},{"checks":[{"durationMs":242,"exitCode":0,"name":"build","output":"Compiling 2 files with Solc 0.8.26\nSolc 0.8.26 finished in 170.22ms\nCompiler run successful!\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MemecoinCemetery.sol:101:13\n    │\n101 │         if (block.timestamp < _digAfter[token]) revert CooldownActive();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MemecoinCemetery.sol:119:13\n    │\n119 │         if (block.timestamp >= grave.timestamp) revert WakeEnded();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MemecoinCemetery.sol:138:13\n    │\n138 │         if (block.timestamp < grave.timestamp) revert WakeNotEnded();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\n","passed":true},{"durationMs":1627,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 13 tests for test/MemecoinCemetery.t.sol:MemecoinCemeteryLifecycleTest\n[PASS] test_BelowThresholdAndNonholderCannotObject() (gas: 334603)\n[PASS] test_DigByNonholderEmitsWakeOpened() (gas: 175761)\n[PASS] test_DuplicateDigCannotReplaceWakeEvenAfterExpiry() (gas: 220155)\n[PASS] test_ExactThresholdHolderResurrectsAndEmits() (gas: 329636)\n[PASS] test_InitialState() (gas: 45179)\n[PASS] test_LateSealUsesActualTimestamp() (gas: 231756)\n[PASS] test_LifecycleCallsRequireAnExistingWake() (gas: 78751)\n[PASS] test_MultipleTokensHaveIndependentRecordsAndCooldowns() (gas: 1516767)\n[PASS] test_ObjectionAtLastSecond() (gas: 236855)\n[PASS] test_ObjectionRejectedAtAndAfterDeadline() (gas: 240864)\n[PASS] test_RedigCooldownAndRepeatedResurrection() (gas: 755869)\n[PASS] test_SealBoundaryAndBuriedEvent() (gas: 285415)\n[PASS] test_SealedGraveIsPermanent() (gas: 431889)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 39.82ms (8.12ms CPU time)\n\nRan 22 tests for test/MemecoinCemetery.t.sol:MemecoinCemeteryEdgeTest\n[PASS] testFuzz_ArbitraryHolderEligibility(uint256,uint256) (runs: 1000, μ: 261053, ~: 266985)\n[PASS] testFuzz_EpitaphBytes(bytes) (runs: 1000, μ: 169034, ~: 159587)\n[PASS] testFuzz_ThresholdRoundsUpWithoutOverflow(uint256) (runs: 1000, μ: 707805, ~: 708062)\n[PASS] test_DigRejectsMalformedTokenReads() (gas: 2227883)\n[PASS] test_DigRejectsNonTokenContract() (gas: 47503)\n[PASS] test_DigRejectsRevertingBalance() (gas: 277007)\n[PASS] test_DigRejectsRevertingSupply() (gas: 273101)\n[PASS] test_DigRejectsZeroAddressAndEOA() (gas: 100174)\n[PASS] test_ETHRejectedAtEveryEntryPoint() (gas: 538306)\n[PASS] test_EmptyEpitaphRoundTrip() (gas: 184822)\n[PASS] test_Epitaph141BytesRejectedThenValidDigSucceeds() (gas: 205980)\n[PASS] test_FormerHolderCannotUseOpeningBalance() (gas: 253980)\n[PASS] test_MaximumEpitaphRoundTrip() (gas: 385215)\n[PASS] test_ObjectionReadFailuresAreAtomicAndRecoverable() (gas: 839942)\n[PASS] test_ObjectionReadsCurrentBalanceOfCaller() (gas: 324181)\n[PASS] test_ObjectionReadsCurrentSupply() (gas: 364074)\n[PASS] test_SealDoesNotReadBrokenToken() (gas: 275989)\n[PASS] test_SupplyBecomingZeroRejectsObjection() (gas: 225959)\n[PASS] test_ThresholdArithmeticEdges() (gas: 4946114)\n[PASS] test_TokenReadsEnforceStaticCallbacks() (gas: 928746)\n[PASS] test_UnicodeEpitaphUsesByteLength() (gas: 318880)\n[PASS] test_ZeroSupplyCanBeBuriedWithoutZeroBalanceObjection() (gas: 273981)\nSuite result: ok. 22 passed; 0 failed; 0 skipped; finished in 40.75ms (131.73ms CPU time)\n\nRan 1 test for test/MemecoinCemetery.t.sol:MemecoinCemeteryInvariantTest\n[PASS] invariant_RecordsCountAndPermanenceMatchModel() (runs: 256, calls: 16384, reverts: 0)\n\n╭--------------------------+-------------+-------+---------+----------╮\n| Contract                 | Selector    | Calls | Reverts | Discards |\n+=====================================================================+\n| CemeteryLifecycleHandler | advanceTime | 3300  | 0       | 0        |\n|--------------------------+-------------+-------+---------+----------|\n| CemeteryLifecycleHandler | dig         | 3273  | 0       | 0        |\n|--------------------------+-------------+-------+---------+----------|\n| CemeteryLifecycleHandler | object      | 3217  | 0       | 0        |\n|--------------------------+-------------+-------+---------+----------|\n| CemeteryLifecycleHandler | seal        | 3315  | 0       | 0        |\n|--------------------------+-------------+-------+---------+----------|\n| CemeteryLifecycleHandler | sendETH     | 3279  | 0       | 0        |\n╰--------------------------+-------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.58s (1.57s CPU time)\n\nRan 3 test suites in 1.58s (1.66s CPU time): 36 tests passed, 0 failed, 0 skipped (36 total tests)\n","passed":true},{"durationMs":27,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MemecoinCemetery.dig(address,string)\",\"MemecoinCemetery.itLives(address)\",\"MemecoinCemetery.seal(address)\"],\"files\":{\"src/MemecoinCemetery.sol\":179,\"test/MemecoinCemetery.t.sol\":906},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"eb56aba2308c6794cf128e8ba7d705a9fd9165c8346f1aef5a83e52839674b83","verifiedTreeHash":"82e3ebd7cbcc969e1e7d08f1dbb91a146d6b86f2","verifierVersion":"0.1.0+7471272e"},{"checks":[{"durationMs":216,"exitCode":0,"name":"build","output":"Compiling 2 files with Solc 0.8.26\nSolc 0.8.26 finished in 157.65ms\nCompiler run successful!\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MemecoinCemetery.sol:101:13\n    │\n101 │         if (block.timestamp < _digAfter[token]) revert CooldownActive();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MemecoinCemetery.sol:119:13\n    │\n119 │         if (block.timestamp >= grave.timestamp) revert WakeEnded();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MemecoinCemetery.sol:138:13\n    │\n138 │         if (block.timestamp < grave.timestamp) revert WakeNotEnded();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\n","passed":true},{"durationMs":1567,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 13 tests for test/MemecoinCemetery.t.sol:MemecoinCemeteryLifecycleTest\n[PASS] test_BelowThresholdAndNonholderCannotObject() (gas: 334603)\n[PASS] test_DigByNonholderEmitsWakeOpened() (gas: 175761)\n[PASS] test_DuplicateDigCannotReplaceWakeEvenAfterExpiry() (gas: 220155)\n[PASS] test_ExactThresholdHolderResurrectsAndEmits() (gas: 329636)\n[PASS] test_InitialState() (gas: 45179)\n[PASS] test_LateSealUsesActualTimestamp() (gas: 231756)\n[PASS] test_LifecycleCallsRequireAnExistingWake() (gas: 78751)\n[PASS] test_MultipleTokensHaveIndependentRecordsAndCooldowns() (gas: 1516767)\n[PASS] test_ObjectionAtLastSecond() (gas: 236855)\n[PASS] test_ObjectionRejectedAtAndAfterDeadline() (gas: 240864)\n[PASS] test_RedigCooldownAndRepeatedResurrection() (gas: 755869)\n[PASS] test_SealBoundaryAndBuriedEvent() (gas: 285415)\n[PASS] test_SealedGraveIsPermanent() (gas: 431889)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 40.12ms (8.63ms CPU time)\n\nRan 22 tests for test/MemecoinCemetery.t.sol:MemecoinCemeteryEdgeTest\n[PASS] testFuzz_ArbitraryHolderEligibility(uint256,uint256) (runs: 1000, μ: 261078, ~: 266985)\n[PASS] testFuzz_EpitaphBytes(bytes) (runs: 1000, μ: 168259, ~: 159587)\n[PASS] testFuzz_ThresholdRoundsUpWithoutOverflow(uint256) (runs: 1000, μ: 707803, ~: 708040)\n[PASS] test_DigRejectsMalformedTokenReads() (gas: 2227883)\n[PASS] test_DigRejectsNonTokenContract() (gas: 47503)\n[PASS] test_DigRejectsRevertingBalance() (gas: 277007)\n[PASS] test_DigRejectsRevertingSupply() (gas: 273101)\n[PASS] test_DigRejectsZeroAddressAndEOA() (gas: 100174)\n[PASS] test_ETHRejectedAtEveryEntryPoint() (gas: 538306)\n[PASS] test_EmptyEpitaphRoundTrip() (gas: 184822)\n[PASS] test_Epitaph141BytesRejectedThenValidDigSucceeds() (gas: 205980)\n[PASS] test_FormerHolderCannotUseOpeningBalance() (gas: 253980)\n[PASS] test_MaximumEpitaphRoundTrip() (gas: 385215)\n[PASS] test_ObjectionReadFailuresAreAtomicAndRecoverable() (gas: 839942)\n[PASS] test_ObjectionReadsCurrentBalanceOfCaller() (gas: 324181)\n[PASS] test_ObjectionReadsCurrentSupply() (gas: 364074)\n[PASS] test_SealDoesNotReadBrokenToken() (gas: 275989)\n[PASS] test_SupplyBecomingZeroRejectsObjection() (gas: 225959)\n[PASS] test_ThresholdArithmeticEdges() (gas: 4946114)\n[PASS] test_TokenReadsEnforceStaticCallbacks() (gas: 928746)\n[PASS] test_UnicodeEpitaphUsesByteLength() (gas: 318880)\n[PASS] test_ZeroSupplyCanBeBuriedWithoutZeroBalanceObjection() (gas: 273981)\nSuite result: ok. 22 passed; 0 failed; 0 skipped; finished in 46.86ms (133.69ms CPU time)\n\nRan 1 test for test/MemecoinCemetery.t.sol:MemecoinCemeteryInvariantTest\n[PASS] invariant_RecordsCountAndPermanenceMatchModel() (runs: 256, calls: 16384, reverts: 0)\n\n╭--------------------------+-------------+-------+---------+----------╮\n| Contract                 | Selector    | Calls | Reverts | Discards |\n+=====================================================================+\n| CemeteryLifecycleHandler | advanceTime | 3318  | 0       | 0        |\n|--------------------------+-------------+-------+---------+----------|\n| CemeteryLifecycleHandler | dig         | 3270  | 0       | 0        |\n|--------------------------+-------------+-------+---------+----------|\n| CemeteryLifecycleHandler | object      | 3246  | 0       | 0        |\n|--------------------------+-------------+-------+---------+----------|\n| CemeteryLifecycleHandler | seal        | 3283  | 0       | 0        |\n|--------------------------+-------------+-------+---------+----------|\n| CemeteryLifecycleHandler | sendETH     | 3267  | 0       | 0        |\n╰--------------------------+-------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.51s (1.51s CPU time)\n\nRan 3 test suites in 1.52s (1.60s CPU time): 36 tests passed, 0 failed, 0 skipped (36 total tests)\n","passed":true},{"durationMs":23,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MemecoinCemetery.dig(address,string)\",\"MemecoinCemetery.itLives(address)\",\"MemecoinCemetery.seal(address)\"],\"files\":{\"launch.json\":10,\"src/MemecoinCemetery.sol\":179,\"test/MemecoinCemetery.t.sol\":906},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"efd356ddfe00b2575c04de1df4f88f03e1134ee1ed97c4b7e09e7f4f13bee382","verifiedTreeHash":"29b10a8e66bf97f24b724c1d84b0ca2ed0effc33","verifierVersion":"0.1.0+7471272e"}]}