{"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":"56ea39f1-953e-4b7f-b394-8077f4a817a8","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"1a686540ff085d02474f46b3662fcc067f1920db91237d26a707fc060e92d456","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_economics","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"5258625edb575e4be32caa1055e2f5560c374ac674dbd1f21f91a41ccff07561","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_flow","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"53b924bac1dbe5a274a395f7314fff90d0a9d60998964dcd62d580d2e87003da","dependsOn":["build_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"af3aa01159bbf354f621cafa5c0006f6169e0938a8b015be508b7377dbf165bc","skillId":"audit-judge","tools":[]},"key":"audit_judge","kind":"code","role":"review","skillHash":"af3aa01159bbf354f621cafa5c0006f6169e0938a8b015be508b7377dbf165bc","skillId":"audit-judge","state":"accepted"},{"acceptedSubmissionHash":"73f088c013b63b23a7c95ac91d1f7588284bfc60a0c2d75561f74e4abf1df687","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_math","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"e6e8b32f8fa4ccfe168eab71ba5b435af37d96d93a6e18eac6647b5b3bd6fe88","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_permissions","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"62d4815ed2ae4ba3d98d72302f00e782d8abb02b2b328c9b05f041a22696824d","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"6b8d2c2ebd3301cff2be8edb1e1cc6ba65c858c02fe7247be81722b969842265","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"6b8d2c2ebd3301cff2be8edb1e1cc6ba65c858c02fe7247be81722b969842265","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":"9957484c6b365f2a1e9661bb8ddeb835dbe58f156b9fe81ecf3bedab8ed66229","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"c0f441f28b3656e58ccdc0ada79b30cdf3e3d712f7a9b0441536585dca2958cb","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"4c76766b00591dfe982fe85d3de589fdb2f810e5137c301155d1c5e36a1d3b23","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"4c76766b00591dfe982fe85d3de589fdb2f810e5137c301155d1c5e36a1d3b23","skillId":"write-foundry-tests","state":"accepted"}],"objective":"A custom token: Quantum Canary (CANARY).\nToken name: Quantum Canary\nToken symbol: CANARY\nToken supply: 1,000,000,000 with 18 decimals, all minted once to the deployer in the constructor.","parentJobId":null,"planHash":"b43d43155aa8d360ccacadcf18844acad90f24285a8719c53878e7606aed3876","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"56ea39f1-953e-4b7f-b394-8077f4a817a8","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1797-quantum-canary"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51163","feedbackHash":"1e582954418bc097651f16cd3bb22adb33cca3bf244adce9477c183553d8e6be","nodeKey":"audit_economics","submissionHash":"1a686540ff085d02474f46b3662fcc067f1920db91237d26a707fc060e92d456","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51231","feedbackHash":"effca6e917daefcd73256ed8f6664eb0a86d0d957bc9c395caee8e45abb1d08e","nodeKey":"audit_flow","submissionHash":"5258625edb575e4be32caa1055e2f5560c374ac674dbd1f21f91a41ccff07561","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51291","feedbackHash":"79b1aad3b8adf5cf2b8208b3527b0ff8f25e9d0db64d6d2e0ec9d379bf13a34d","nodeKey":"audit_judge","submissionHash":"53b924bac1dbe5a274a395f7314fff90d0a9d60998964dcd62d580d2e87003da","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51169","feedbackHash":"62f4b2e2e4796b07a895ffc3d228b1b6f712be94f475b0eb809c0e8a6e64275b","nodeKey":"audit_math","submissionHash":"73f088c013b63b23a7c95ac91d1f7588284bfc60a0c2d75561f74e4abf1df687","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"50939","feedbackHash":"9635df5f0cdbf4345e330f7df850c8b69fa09a5df86f42332071e79274eefb46","nodeKey":"audit_permissions","submissionHash":"e6e8b32f8fa4ccfe168eab71ba5b435af37d96d93a6e18eac6647b5b3bd6fe88","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52196","feedbackHash":"c217a897eb829661e63a511b91a23a675d90964416c6998a97c171479a8e2033","nodeKey":"build_contract_project","submissionHash":"62d4815ed2ae4ba3d98d72302f00e782d8abb02b2b328c9b05f041a22696824d","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51125","feedbackHash":"212bc46daa542bf8f87739ce897c17a9fe8e7f41a2f437c0fe9386f061022dc0","nodeKey":"manifest","submissionHash":"9957484c6b365f2a1e9661bb8ddeb835dbe58f156b9fe81ecf3bedab8ed66229","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52197","feedbackHash":"7eab343d869095b420365d91797d0e92f9c8bce81c93d4f30f3c5df4c573daf3","nodeKey":"write_foundry_tests","submissionHash":"c0f441f28b3656e58ccdc0ada79b30cdf3e3d712f7a9b0441536585dca2958cb","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"1994fa321753e0fc13ae9b05ed39c4da96bc2e5ae9253cbf71d74b812b69024a","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"8af9903f4ad1eed0","findings":[],"hash":"1a686540ff085d02474f46b3662fcc067f1920db91237d26a707fc060e92d456","nodeId":"af436c94-e8c0-4d13-9761-e70f3b4f980d","outcome":"completed","summary":"The findings file is in place and is excluded from git by the repository's own exclude rule, which is expected for this review's output. The scratch directory is removed and no source file changed. Nothing further is needed.\n\n**Review complete: no defects found in the economics area.**\n\nQuantum Canary is a plain OpenZeppelin v5.0.2 ERC-20 with one constructor mint of 1e27 units to the immediate deployer. There is nothing in it for the Economic Security, Invariant or Flow Gap guides to break, and I confirmed that rather than assumed it.\n\nWhat I verified:\n\n- **Supply conservation.** The only writer of total supply is the constructor's single mint. The ABI exposes no mint, burn, burnFrom, owner or upgrade surface, and 22 common admin selectors revert from both the deployer and a stranger.\n- **Launch flows move exactly.** The 10 percent swarm share, a full claim out of the distributor, an 80 percent pool seed and the remainder transfer all arrive whole. A buy and sell round trip through a pool-manager stand-in leaves exact balances, and an unlimited allowance is not decremented.\n- **Boundaries.** Zero-value transfers from empty accounts succeed, self-transfers conserve, transfer to the zero address reverts, and over-balance or over-allowance by one wei reverts atomically.\n- **Deployer binding.** The mint goes to the CREATE2 caller, not tx.origin, so the factory receives the supply.\n- **Periphery.** The runtime has no DELEGATECALL, CALLCODE, SELFDESTRUCT, CREATE or external CALL. No receive or fallback exists.\n- **Dependency integrity.** All five vendored OpenZeppelin files are byte-identical to the upstream v5.0.2 release archive and match DEPENDENCIES.json.\n- **Static-analysis lead.** The aderyn large-literal note is the readable expression of exactly one billion tokens at 18 decimals and is not a defect.\n\nThe project's own 31 tests pass, and my 7 scratch probes passed before I removed them. The protected launch harness could not be run here because it imports v4-core and floor contracts absent from this tree, so I mirrored its token-level checks instead. The judge's independent harness remains the authority on the pool seed and swap legs.\n\nOutput written to `.imd-findings.json` with an empty findings list and nine coverage rows: the three entry points all hold, plus six invariant and dependency rows.","treeHash":null,"usage":{"cachedInputTokens":1112329,"inputTokens":642,"model":"claude-fable-5-1","outputTokens":14039,"runtime":"claude","turns":21,"wallClockMs":213234}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"1507f63d3f1b973a","findings":[{"citation":"resolved","description":"QuantumCanary inherits OpenZeppelin v5.0.2 ERC20 unchanged. approve(spender, value) overwrites the allowance (ERC20._approve, lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol:291 `_allowances[owner][spender] = value;`). OpenZeppelin v5 deliberately ships no increaseAllowance/decreaseAllowance, and the token adds none, so a holder who lowers an existing non-zero allowance can be front-run by the spender, who then spends old + new. This is the well-known ERC-20 property, not a deviation from the brief (which asks for ordinary ERC-20 behaviour with no custom rules), and README.md lines 129-132 already tell holders to revoke to zero first. Reported at info so the judge has it on record; it does not need a code change to meet the requested design. If the author wants an in-code mitigation, adding increaseAllowance/decreaseAllowance wrappers around _approve would preserve all other behaviour.","line":8,"path":"src/QuantumCanary.sol","reproduction":"State: alice holds 200e18 CANARY. 1) alice: approve(bob, 100e18). 2) alice broadcasts approve(bob, 50e18) intending to lower it. 3) bob sees it in the mempool and front-runs: transferFrom(alice, bob, 100e18) -> succeeds, allowance 0. 4) alice's approve(bob, 50e18) mines -> allowance 50e18. 5) bob: transferFrom(alice, bob, 50e18) -> succeeds. Result: bob holds 150e18, alice 50e18; alice intended bob to be able to take at most 100e18 (or 50e18). Verified with a Foundry test on this tree (test_ApproveRaceSpends150: final balanceOf(bob) == 150e18).","severity":"info","snippet":"contract QuantumCanary is ERC20 {","title":"Standard ERC-20 allowance replacement race is present and unmitigated in code (inherent to the requested plain ERC-20; documented in README)"}],"hash":"5258625edb575e4be32caa1055e2f5560c374ac674dbd1f21f91a41ccff07561","nodeId":"5c0a0c3a-86d5-4262-92a4-fc472135c226","outcome":"completed","summary":"The review is complete. The findings file is valid JSON, the snippet matches line 8 of the source exactly, and `git status --porcelain` is empty apart from the required output file.\n\n**Outcome: no defects found in the assigned area.** One info-level note is recorded so the judge has it on file.\n\n**What was checked**\n\n- **Execution trace.** All three state-changing entry points traced through OpenZeppelin v5.0.2 to `_update`. Zero-address, insufficient balance and insufficient allowance paths revert with exact values. Unchecked arithmetic is safe because every subtraction is bounded by a prior check and supply is fixed. Rollback on failed `transferFrom` leaves allowance intact. No callbacks, fees, hooks or external calls exist.\n- **Periphery.** Every vendored OpenZeppelin file matches the recorded sha256 and is byte-identical to the upstream v5.0.2 tag fetched independently. `Context._msgSender` returns `msg.sender` with no meta-transaction indirection.\n- **First principles.** The only assumption is that the immediate deployer is the factory, which the launch harness guarantees via CREATE2. Supply is exactly 1e27 minted once. The ABI exposes no mint, burn, pause, blacklist, owner, initializer or fallback. Runtime contains no DELEGATECALL, CALLCODE or SELFDESTRUCT. Plain ETH, value-bearing calls and unknown selectors all revert.\n- **Launch floor.** Name, symbol, decimals, contract identifier length and whole-amount transfers all satisfy the protected test expectations.\n- **Static leads.** The aderyn large-literal note is a compile-time constant equal to 1e27. Slither reported nothing.\n\n**Verification runs**\n\n| Check | Result |\n| --- | --- |\n| `forge build` | ok |\n| Project suite with README seed | 31 passed, 0 failed |\n| Scratch edge tests (ETH, unknown selector, allowance race, max allowance, token-as-holder) | 5 passed |\n| `forge fmt --check` | ok |\n\n**Recorded note (info).** The standard ERC-20 allowance replacement race is present because the token adds no increase/decrease allowance helpers. The reproduction is a concrete two-approval sequence where the spender takes 150 instead of 100. It is inherent to the plain ERC-20 the brief asks for and the README already documents the mitigation, so it is reported at info and does not call for a code change.\n\n**Coverage.** Ten rows written: all three listed entry points, the constructor mint, and six invariants. Nothing was left unreached. The scratch test directory was deleted after use.","treeHash":null,"usage":{"cachedInputTokens":822495,"inputTokens":354,"model":"claude-fable-5-1","outputTokens":13677,"runtime":"claude","turns":28,"wallClockMs":201209}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"bd7adba3a8045853","findings":[{"citation":"resolved","description":"Merged from audit_permissions and audit_flow (same root cause, reported twice). QuantumCanary inherits OpenZeppelin v5.0.2 ERC20 unchanged. approve() calls _approve(), which overwrites the allowance (lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol:291 `_allowances[owner][spender] = value;`), and transferFrom() spends whatever allowance is current at execution time (_spendAllowance, ERC20.sol:305-315). OpenZeppelin v5 ships no increaseAllowance/decreaseAllowance and the token adds none, so a holder lowering a non-zero allowance can be front-run by the spender, who then spends old + new. This is the well-known EIP-20 property of the exact interface the brief asks for (a fixed-supply ERC-20 with no custom rules), not an implementation error; README.md lines 129-132 already tell holders to revoke to zero and wait before setting a replacement. Recorded at info so the trust assumption is on file. It does not block the launch and needs no change to meet the requested design; adding increaseAllowance/decreaseAllowance wrappers would be a scope decision for the requester.","line":8,"path":"src/QuantumCanary.sol","reproduction":"Reproduced with a scratch Foundry test on this tree (test/scratch/Review.t.sol::test_ApproveRaceSpends150, passed, not kept). State: alice holds 200e18 CANARY. 1) alice: approve(bob, 100e18). 2) alice intends to lower to 50e18 and broadcasts approve(bob, 50e18). 3) bob front-runs: transferFrom(alice, bob, 100e18) -> succeeds, allowance(alice,bob) == 0. 4) alice's approve(bob, 50e18) mines -> allowance == 50e18. 5) bob: transferFrom(alice, bob, 50e18) -> succeeds. Expected by alice: bob moves at most 100e18 (or 50e18). Actual: balanceOf(bob) == 150e18, balanceOf(alice) == 50e18, allowance == 0.","severity":"info","snippet":"contract QuantumCanary is ERC20 {","title":"Standard ERC-20 allowance replacement race (approve overwrites; transferFrom spends the live value) — inherent to the requested plain ERC-20, documented in README, no code change required"}],"hash":"53b924bac1dbe5a274a395f7314fff90d0a9d60998964dcd62d580d2e87003da","nodeId":"1eeca170-417b-44f3-b4ed-3bdaff017cbe","outcome":"completed","summary":"Review complete. The report is in `.imd-findings.json` at the repository root, and the tree is otherwise unchanged (the scratch test was removed).\n\n**Outcome:** no defects. Quantum Canary is an unmodified OpenZeppelin v5.0.2 ERC20 whose constructor mints the full supply once to msg.sender, with no admin, mint, burn, pause or fee paths.\n\n**Specialist findings:** the two info-level reports from audit_permissions and audit_flow describe the same root cause, the standard ERC-20 allowance replacement race. I merged them into one info finding and reproduced it with a scratch Foundry test on this tree. The sequence approve 100, front-run transferFrom 100, approve 50, transferFrom 50 leaves the spender with 150e18. This is an inherent property of the plain ERC-20 the brief asks for, the README already documents the revoke-first workaround, and it does not block the launch. audit_math, audit_economics and the test writer reported nothing, and I found nothing they missed.\n\n**What I verified myself:**\n- All three entry points (approve, transfer, transferFrom) hold. Each traced through the OpenZeppelin code for guards, state writes and revert paths, and confirmed by the 47 existing tests plus my scratch tests.\n- Supply, decimals, name and symbol match the manifest exactly. Creation code 2,645 bytes, runtime 1,752 bytes, both well under the limits. No DELEGATECALL, CALLCODE or SELFDESTRUCT in the runtime bytecode. No constructor arguments, so CREATE2 deployment needs nothing the manifest does not give.\n- launch.json uses only schema keys, lowercase addresses, correct types, and a 13-character contract name.\n- The protected tests could not be run here because they import Uniswap v4-core and floor sources absent from this tree. I checked each property they assert by hand against the code.\n\nCoverage record answers all 3 listed entry points as `holds`, plus 4 invariant rows.","treeHash":null,"usage":{"cachedInputTokens":474923,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":7587,"runtime":"claude","turns":11,"wallClockMs":139353}},{"artifacts":[],"attempt":1,"bundleHash":"4055bf2dc74f69b921faef79df1a73b5ed792becbc738b6e6f5c72227c002330","device":"9b84a1e2e2a9ac5e","findings":[],"hash":"62d4815ed2ae4ba3d98d72302f00e782d8abb02b2b328c9b05f041a22696824d","nodeId":"f8e2b9ed-89ed-4d30-a566-763a8eefd737","outcome":"completed","summary":"Implemented Quantum Canary (CANARY): 1,000,000,000 tokens with 18 decimals, minted once to the deployer. No later minting or administrative controls.\n\nIncluded vendored dependencies, success/failure tests, fuzz and invariant tests, and deployment documentation in `README.md`.\n\nValidation passed:\n\n- `forge build`\n- `forge test` — 31 passed using the specified fuzz seed\n- `forge fmt --check`","treeHash":"4e71cd0591f6ab4d146232b958a63b4dd3c4a01b","usage":{"cachedInputTokens":443904,"inputTokens":52319,"model":"gpt-6-astra","outputTokens":15278,"runtime":"codex","turns":5,"wallClockMs":374779}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"3987a51ff810f3b9","findings":[],"hash":"66f8277925746c0dc47676b1a52dddb799ed3a936e09d9685937490d1fe0501b","nodeId":"3cc4199f-7edd-47a6-b4c2-769a29b75534","outcome":"failed","summary":"Credit balance is too low","treeHash":null,"usage":{"cachedInputTokens":0,"inputTokens":0,"model":null,"outputTokens":0,"runtime":"claude","turns":1,"wallClockMs":4566}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"87804e27e9c9f85a","findings":[],"hash":"73f088c013b63b23a7c95ac91d1f7588284bfc60a0c2d75561f74e4abf1df687","nodeId":"58abae21-baf9-43ef-9b8e-608c90d610c4","outcome":"completed","summary":"The review is complete. The findings file holds an empty list and a full coverage record. No source file was changed and the scratch test is removed.\n\n**Result: no defects in the math precision, boundary or numerical gap areas.**\n\nWhat I checked:\n\n- **The contract** is a single-file OpenZeppelin v5.0.2 ERC-20 with one constructor mint and no overrides. Every vendored library file hashes to the value recorded in DEPENDENCIES.json, so the arithmetic under review is upstream's unmodified code.\n- **Math precision.** The supply constant is a compile-time literal expression and evaluates exactly to ten to the twenty-seventh, matching the manifest string. There is no division, no cast, no scaling and no fee formula anywhere in the token, so there is nothing to round or truncate. The aderyn large-literal lead is a style note only.\n- **Boundary.** The token makes no external calls, has no receive or fallback, decodes no bytes, and its only sentinel branches are the library's zero-address reverts. I probed 1 wei, full balance, self-transfer, max allowance minus one, max-uint amounts and ETH sends; each behaved as specified.\n- **Numerical gap.** The launch split of the supply by basis points divides with no remainder and cannot overflow, so the factory's ten percent, pool share and remainder flows move exact amounts. The sum-of-balances invariant held across the project's stateful fuzz campaign with zero reverts.\n\nCoverage rows mark all three entry points as holding, plus four invariant and boundary rows. The existing 31-test suite passes with the project's recorded seed.","treeHash":null,"usage":{"cachedInputTokens":567151,"inputTokens":226,"model":"claude-fable-5-1","outputTokens":7245,"runtime":"claude","turns":21,"wallClockMs":138145}},{"artifacts":[],"attempt":1,"bundleHash":"6642f652c5beae2e107cade28287cf840308b34048624d0f21cb2c32d1bc6827","device":"42dc54b22317eb81","findings":[],"hash":"9957484c6b365f2a1e9661bb8ddeb835dbe58f156b9fe81ecf3bedab8ed66229","nodeId":"d950a536-7fe1-487c-b7f6-f99adc5ac7ef","outcome":"completed","summary":"Created [launch.json](/home/worker/.identitymd/work/56ea39f1-953e-4b7f-b394-8077f4a817a8/d950a536-7fe1-487c-b7f6-f99adc5ac7ef/launch.json) matching the accepted constructor, exact supply, pool settings, and economics.\n\n`forge build` succeeded; all 31 local tests passed with the supplied fuzz seed. Only `launch.json` changed outside permitted scratch artifacts.","treeHash":"f3b8ecd8aed8d01a7cb6239ec037b14f596ec07a","usage":{"cachedInputTokens":220032,"inputTokens":24449,"model":"gpt-6-astra","outputTokens":2410,"runtime":"codex","turns":3,"wallClockMs":63150}},{"artifacts":[],"attempt":1,"bundleHash":"994cb2fdb3a450612fe73accd1999a61cbe2521aafd2a2c99f0798704f506e50","device":"b3450b02f80aa5c2","findings":[],"hash":"c0f441f28b3656e58ccdc0ada79b30cdf3e3d712f7a9b0441536585dca2958cb","nodeId":"9edd6feb-c84a-40d3-bda7-53486a040c59","outcome":"completed","summary":"Added 16 adversarial unit/fuzz tests and expanded stateful invariants to cover failed calls, rollback, and allowance changes. All changes are within `test/`.\n\nVerified offline with the required seed: `forge build` and `forge test` pass—47 reported tests, 10,000 fuzz cases, and 32,768 invariant calls.\n\nNo implementation defects found in the tested behavior.","treeHash":"5907e368b59a59d68930a359b38b2ea957c1a778","usage":{"cachedInputTokens":771712,"inputTokens":72696,"model":"gpt-6-astra","outputTokens":14333,"runtime":"codex","turns":6,"wallClockMs":344244}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"72b617d4b615473a","findings":[{"citation":"resolved","description":"Asymmetry guide, pair approve <-> pull. QuantumCanary inherits OpenZeppelin v5.0.2 ERC20.approve unchanged (lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol:132-136), which overwrites the allowance with the new value, and ERC20.transferFrom (ERC20.sol:154-159), which spends whatever allowance is current at execution time. Because approve replaces rather than adjusts, and the pull side reads the live value, a spender who observes a pending replacement approval can spend the old allowance before it lands and the new allowance after it lands. This is the well-known EIP-20 allowance race; it is a property of the standard interface the brief asked for, not an implementation error. The token exposes no increaseAllowance/decreaseAllowance (removed from OpenZeppelin v5 core) and no permit, so holders have only the revoke-then-set workaround, which the README already recommends (README.md lines 129-132). Reported as information so the trust assumption is on record; adding allowance-adjusting functions would be a scope decision for the requester, not a fix the current design requires. Access-control and trust-gap lenses find nothing further: the only authorizations in the contract are holder-over-own-balance and spender-over-allowance, both enforced consistently on every write path to _balances and _allowances.","line":8,"path":"src/QuantumCanary.sol","reproduction":"State: owner holds 1000 CANARY; owner has approved spender for 100e18. Owner submits approve(spender, 50e18) intending to lower the limit. Sequence that executes: (1) spender front-runs with transferFrom(owner, sink, 100e18) -> succeeds, allowance becomes 0; (2) owner's approve(spender, 50e18) lands -> allowance becomes 50e18; (3) spender calls transferFrom(owner, sink, 50e18) -> succeeds. Expected by the owner: at most 100e18 (or 50e18) ever moved. Actual: 150e18 moved; balanceOf(sink) == 150e18, allowance(owner, spender) == 0. Verified with a scratch Foundry test (test/scratch/ApproveRace.t.sol, not kept) that passed on this tree with exactly these calls.","severity":"info","snippet":"contract QuantumCanary is ERC20 {","title":"Standard ERC-20 approve-replacement race between approve and transferFrom (inherent to the standard, documented by the author; no code change required by the brief)"}],"hash":"e6e8b32f8fa4ccfe168eab71ba5b435af37d96d93a6e18eac6647b5b3bd6fe88","nodeId":"3cc4199f-7edd-47a6-b4c2-769a29b75534","outcome":"completed","summary":"The review is complete. The findings file is at the repository root, the scratch test is removed, and no project file was changed.\n\n**Outcome.** The Quantum Canary token has no access-control, trust-gap or asymmetry defect. It is a bare OpenZeppelin v5.0.2 ERC-20 whose constructor mints the whole supply to the deployer. I recorded one informational note and no defects.\n\n**What I checked and how**\n\n- **Permission model.** The compiled ABI exposes exactly three state-changing functions: approve, transfer and transferFrom. There is no owner, role, modifier, initializer, pause, blacklist, mint, burn, receive or fallback. Every write to balances or allowances is guarded by the caller's own identity or an allowance it was granted. The deployer has no power after the mint.\n- **Asymmetry.** The approve/transferFrom pair and the transfer/transferFrom pair share the same zero-address and balance checks. The mint branch of the internal update hook is unreachable after construction because transfers reject a zero sender.\n- **Trust gap.** With no privileged actor and no economic formula beyond exact transfer, nothing exists at the access, economics and asymmetry seam.\n- **Launch floor.** Transfers move exactly the requested amount, so the swarm share, claims, seed and swaps arrive whole. Supply equals 10^27 minor units, which I computed with a tool. Decimals are 18. The contract identifier is 13 characters. The runtime contains no DELEGATECALL, CALLCODE or SELFDESTRUCT.\n- **Dependencies.** The five vendored OpenZeppelin files match the hashes in DEPENDENCIES.json, and I read the ERC20 and Context sources line by line against upstream v5.\n- **Tooling.** I ran the project's full suite with its pinned fuzz seed. All 31 tests passed, including the 8,192-call invariant campaign. The aderyn large-numeric-literal lead is a style note; the literal is correct.\n\n**The one informational finding.** The inherited approve overwrites the allowance, so the standard EIP-20 replacement race applies. A spender holding a 100-token allowance who sees a pending approve for 50 can pull 100 first and 50 afterwards, moving 150. I confirmed the sequence with a scratch Foundry test. The README already documents this and recommends revoke-then-set. It is a property of the standard the brief requested, not an implementation error, and I said so in the report. Adding allowance-adjusting functions would be a scope decision for the requester.\n\n**Coverage.** All three listed entry points have rows: approve is marked `finding` pointing at the info note, transfer and transferFrom are `holds`. Seven further rows cover the constructor, the absence of privileged entry points, the opcode invariant, both protected launch tests, dependency integrity and the static-analysis lead. Nothing is `unreached`.\n\n**What I did not do.** I did not run the protected launch harness itself, since it needs the network's factory and PoolManager fixtures and environment variables that are not in this tree. I reasoned about its assertions against the source instead. No file other than .imd-findings.json remains changed.","treeHash":null,"usage":{"cachedInputTokens":811799,"inputTokens":258,"model":"claude-fable-5-1","outputTokens":16654,"runtime":"claude","turns":32,"wallClockMs":277051}}],"verification":[{"checks":[{"durationMs":1126,"exitCode":0,"name":"build","output":"Compiling 27 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.05s\nCompiler run successful!\n","passed":true},{"durationMs":2898,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 30 tests for test/QuantumCanary.t.sol:QuantumCanaryTest\n[PASS] testFuzz_RevertWhenTransferExceedsBalance(uint256,uint256) (runs: 512, μ: 126993, ~: 127190)\nLogs:\n  Bound result 96391289594184064056792947\n  Bound result 1\n\n[PASS] testFuzz_RevertWhenTransferFromExceedsAllowance(uint256,uint256) (runs: 512, μ: 133275, ~: 133903)\nLogs:\n  Bound result 20037\n  Bound result 1\n\n[PASS] testFuzz_TransferConservesSupply(address,uint256) (runs: 512, μ: 92630, ~: 93183)\nLogs:\n  Bound result 870255072977986814846544068\n\n[PASS] testFuzz_TransferFromAccountsExactly(uint256,uint256) (runs: 512, μ: 162388, ~: 164843)\nLogs:\n  Bound result 316713255890617588747320210\n  Bound result 290050646968058696746219977\n\n[PASS] test_ApproveEmitsEventAndCanBeReplacedAndRevoked() (gas: 196053)\n[PASS] test_ConstructorEmitsExactlyOneMint() (gas: 9729)\n[PASS] test_Create2MintsEverythingToFactory() (gas: 305467)\n[PASS] test_DeployerCannotSpendHolderBalanceWithoutApproval() (gas: 158044)\n[PASS] test_InfiniteAllowanceIsNotDecremented() (gas: 214775)\n[PASS] test_LaunchDistributionClaimAndPoolTransfersAreExact() (gas: 644313)\n[PASS] test_MetadataAndInitialSupply() (gas: 97189)\n[PASS] test_NoMintBurnOrAdministrativeEntrypoints() (gas: 1548037)\n[PASS] test_RevertWhenApproveZeroSpender() (gas: 37650)\n[PASS] test_RevertWhenDifferentSpenderUsesApproval() (gas: 105229)\n[PASS] test_RevertWhenTransferExceedsBalance() (gas: 67737)\n[PASS] test_RevertWhenTransferFromExceedsAllowance() (gas: 115791)\n[PASS] test_RevertWhenTransferFromExceedsBalanceRollsBackAllowance() (gas: 188800)\n[PASS] test_RevertWhenTransferFromHasNoApproval() (gas: 57799)\n[PASS] test_RevertWhenTransferFromToZeroRollsBackAllowance() (gas: 114222)\n[PASS] test_RevertWhenTransferFromZeroAddress() (gas: 52602)\n[PASS] test_RevertWhenTransferIsUint256Max() (gas: 42471)\n[PASS] test_RevertWhenTransferToZeroIncludingZeroAmount() (gas: 71993)\n[PASS] test_RuntimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 1038073)\n[PASS] test_SelfTransferFromConsumesAllowanceWithoutChangingBalance() (gas: 103332)\n[PASS] test_SelfTransferPreservesBalance() (gas: 51451)\n[PASS] test_TransferDoesNotCallRecipient() (gas: 173933)\n[PASS] test_TransferEntireSupplyEmitsEvent() (gas: 88747)\n[PASS] test_TransferFromEmitsTransferAndConsumesFiniteAllowance() (gas: 242018)\n[PASS] test_ZeroTransferFromEmptyAccountEmitsEvent() (gas: 73474)\n[PASS] test_ZeroTransferFromNeedsNoAllowance() (gas: 81544)\nSuite result: ok. 30 passed; 0 failed; 0 skipped; finished in 65.64ms (141.09ms CPU time)\n\nRan 1 test for test/QuantumCanary.invariant.t.sol:QuantumCanaryInvariantTest\n[PASS]\nQuantumCanaryInvariantTest invariants:\n[PASS] invariant_AllowancesMatchModel\n[PASS] invariant_SupplyAndBalancesMatchModel\n QuantumCanaryInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭---------------+-------------+-------+---------+----------╮\n| Contract      | Selector    | Calls | Reverts | Discards |\n+==========================================================+\n| CanaryHandler | move        | 2698  | 0       | 0        |\n|---------------+-------------+-------+---------+----------|\n| CanaryHandler | setApproval | 2761  | 0       | 0        |\n|---------------+-------------+-------+---------+----------|\n| CanaryHandler | spend       | 2733  | 0       | 0        |\n╰---------------+-------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 13\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 6\n  Bound result 0\n  Bound result 302\n  Bound result 0\n  Bound result 4219891686517860825325\n  Bound result 5050\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 7\n  Bound result 3\n  Bound result 4252\n  Bound result 0\n  Bound result 23000000000000000000\n  Bound result 8945703828313612313\n  Bound result 5091\n  Bound result 0\n  Bound result 3097\n  Bound result 2489322667531008815556\n  Bound result 238464469610362846875\n  Bound result 0\n  Bound result 999999999999999999999999999\n  Bound result 4219891686517860825326\n  Bound result 309\n  Bound result 0\n  Bound result 378\n  Bound result 0\n  Bound result 2\n  Bound result 28\n  Bound result 0\n  Bound result 244\n  Bound result 0\n  Bound result 3\n  Bound result 4251\n  Bound result 0\n  Bound result 3346\n  Bound result 2000000000000000000\n  Bound result 0\n  Bound result 3605\n  Bound result 14\n  Bound result 255\n  Bound result 2000000000000000000\n  Bound result 5405284865889580569\n  Bound result 1211\n  Bound result 10000000000000000000\n  Bound result 9\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.79s (2.79s CPU time)\n\nRan 2 test suites in 2.79s (2.86s CPU time): 31 tests passed, 0 failed, 0 skipped (31 total tests)\n","passed":true},{"durationMs":53,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"QuantumCanary.approve(address,uint256)\",\"QuantumCanary.transfer(address,uint256)\",\"QuantumCanary.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":3,\"DEPENDENCIES.json\":56,\"README.md\":141,\"foundry.toml\":21,\"remappings.txt\":2,\"src/QuantumCanary.sol\":16,\"test/QuantumCanary.invariant.t.sol\":105,\"test/QuantumCanary.t.sol\":422},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":427,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":222,"exitCode":0,"name":"aderyn","output":"[low] large-numeric-literal at src/QuantumCanary.sol:10: Large Numeric Literal","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"62d4815ed2ae4ba3d98d72302f00e782d8abb02b2b328c9b05f041a22696824d","verifiedTreeHash":"4e71cd0591f6ab4d146232b958a63b4dd3c4a01b","verifierVersion":"0.1.0+aca6c688"},{"checks":[{"durationMs":1062,"exitCode":0,"name":"build","output":"Compiling 27 files with Solc 0.8.26\nSolc 0.8.26 finished in 994.20ms\nCompiler run successful!\n","passed":true},{"durationMs":2470,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 30 tests for test/QuantumCanary.t.sol:QuantumCanaryTest\n[PASS] testFuzz_RevertWhenTransferExceedsBalance(uint256,uint256) (runs: 512, μ: 126993, ~: 127190)\nLogs:\n  Bound result 564954674858365718841458599\n  Bound result 30696137957665862\n\n[PASS] testFuzz_RevertWhenTransferFromExceedsAllowance(uint256,uint256) (runs: 512, μ: 133275, ~: 133903)\nLogs:\n  Bound result 20037\n  Bound result 1\n\n[PASS] testFuzz_TransferConservesSupply(address,uint256) (runs: 512, μ: 92630, ~: 93183)\nLogs:\n  Bound result 38723\n\n[PASS] testFuzz_TransferFromAccountsExactly(uint256,uint256) (runs: 512, μ: 162388, ~: 164843)\nLogs:\n  Bound result 564954674858365718841458599\n  Bound result 30696137957665862\n\n[PASS] test_ApproveEmitsEventAndCanBeReplacedAndRevoked() (gas: 196053)\n[PASS] test_ConstructorEmitsExactlyOneMint() (gas: 9729)\n[PASS] test_Create2MintsEverythingToFactory() (gas: 305467)\n[PASS] test_DeployerCannotSpendHolderBalanceWithoutApproval() (gas: 158044)\n[PASS] test_InfiniteAllowanceIsNotDecremented() (gas: 214775)\n[PASS] test_LaunchDistributionClaimAndPoolTransfersAreExact() (gas: 644313)\n[PASS] test_MetadataAndInitialSupply() (gas: 97189)\n[PASS] test_NoMintBurnOrAdministrativeEntrypoints() (gas: 1548037)\n[PASS] test_RevertWhenApproveZeroSpender() (gas: 37650)\n[PASS] test_RevertWhenDifferentSpenderUsesApproval() (gas: 105229)\n[PASS] test_RevertWhenTransferExceedsBalance() (gas: 67737)\n[PASS] test_RevertWhenTransferFromExceedsAllowance() (gas: 115791)\n[PASS] test_RevertWhenTransferFromExceedsBalanceRollsBackAllowance() (gas: 188800)\n[PASS] test_RevertWhenTransferFromHasNoApproval() (gas: 57799)\n[PASS] test_RevertWhenTransferFromToZeroRollsBackAllowance() (gas: 114222)\n[PASS] test_RevertWhenTransferFromZeroAddress() (gas: 52602)\n[PASS] test_RevertWhenTransferIsUint256Max() (gas: 42471)\n[PASS] test_RevertWhenTransferToZeroIncludingZeroAmount() (gas: 71993)\n[PASS] test_RuntimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 1038073)\n[PASS] test_SelfTransferFromConsumesAllowanceWithoutChangingBalance() (gas: 103332)\n[PASS] test_SelfTransferPreservesBalance() (gas: 51451)\n[PASS] test_TransferDoesNotCallRecipient() (gas: 173933)\n[PASS] test_TransferEntireSupplyEmitsEvent() (gas: 88747)\n[PASS] test_TransferFromEmitsTransferAndConsumesFiniteAllowance() (gas: 242018)\n[PASS] test_ZeroTransferFromEmptyAccountEmitsEvent() (gas: 73474)\n[PASS] test_ZeroTransferFromNeedsNoAllowance() (gas: 81544)\nSuite result: ok. 30 passed; 0 failed; 0 skipped; finished in 15.39ms (71.90ms CPU time)\n\nRan 1 test for test/QuantumCanary.invariant.t.sol:QuantumCanaryInvariantTest\n[PASS]\nQuantumCanaryInvariantTest invariants:\n[PASS] invariant_AllowancesMatchModel\n[PASS] invariant_SupplyAndBalancesMatchModel\n QuantumCanaryInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭---------------+-------------+-------+---------+----------╮\n| Contract      | Selector    | Calls | Reverts | Discards |\n+==========================================================+\n| CanaryHandler | move        | 2698  | 0       | 0        |\n|---------------+-------------+-------+---------+----------|\n| CanaryHandler | setApproval | 2761  | 0       | 0        |\n|---------------+-------------+-------+---------+----------|\n| CanaryHandler | spend       | 2733  | 0       | 0        |\n╰---------------+-------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 13\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 6\n  Bound result 0\n  Bound result 302\n  Bound result 0\n  Bound result 4219891686517860825325\n  Bound result 5050\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 7\n  Bound result 3\n  Bound result 4252\n  Bound result 0\n  Bound result 23000000000000000000\n  Bound result 8945703828313612313\n  Bound result 5091\n  Bound result 0\n  Bound result 3097\n  Bound result 2489322667531008815556\n  Bound result 238464469610362846875\n  Bound result 0\n  Bound result 999999999999999999999999999\n  Bound result 4219891686517860825326\n  Bound result 309\n  Bound result 0\n  Bound result 378\n  Bound result 0\n  Bound result 2\n  Bound result 28\n  Bound result 0\n  Bound result 244\n  Bound result 0\n  Bound result 3\n  Bound result 4251\n  Bound result 0\n  Bound result 3346\n  Bound result 2000000000000000000\n  Bound result 0\n  Bound result 3605\n  Bound result 14\n  Bound result 255\n  Bound result 2000000000000000000\n  Bound result 5405284865889580569\n  Bound result 1211\n  Bound result 10000000000000000000\n  Bound result 9\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.39s (2.39s CPU time)\n\nRan 2 test suites in 2.39s (2.41s CPU time): 31 tests passed, 0 failed, 0 skipped (31 total tests)\n","passed":true},{"durationMs":40,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"QuantumCanary.approve(address,uint256)\",\"QuantumCanary.transfer(address,uint256)\",\"QuantumCanary.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":3,\"DEPENDENCIES.json\":56,\"README.md\":141,\"foundry.toml\":21,\"launch.json\":24,\"remappings.txt\":2,\"src/QuantumCanary.sol\":16,\"test/QuantumCanary.invariant.t.sol\":105,\"test/QuantumCanary.t.sol\":422},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"9957484c6b365f2a1e9661bb8ddeb835dbe58f156b9fe81ecf3bedab8ed66229","verifiedTreeHash":"f3b8ecd8aed8d01a7cb6239ec037b14f596ec07a","verifierVersion":"0.1.0+aca6c688"},{"checks":[{"durationMs":1376,"exitCode":0,"name":"build","output":"Compiling 28 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.31s\nCompiler run successful!\n","passed":true},{"durationMs":10708,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 30 tests for test/QuantumCanary.t.sol:QuantumCanaryTest\n[PASS] testFuzz_RevertWhenTransferExceedsBalance(uint256,uint256) (runs: 1000, μ: 127038, ~: 127250)\nLogs:\n  Bound result 175656830\n  Bound result 22773414242813303540500481882251705933246265404694107469705691902970\n\n[PASS] testFuzz_RevertWhenTransferFromExceedsAllowance(uint256,uint256) (runs: 1000, μ: 133398, ~: 133921)\nLogs:\n  Bound result 175656830\n  Bound result 37693411037663072392790800\n\n[PASS] testFuzz_TransferConservesSupply(address,uint256) (runs: 1000, μ: 93439, ~: 93638)\nLogs:\n  Bound result 92099065868801101615243674641254490526466807820\n  Bound result 630862040959681551284364410\n\n[PASS] testFuzz_TransferFromAccountsExactly(uint256,uint256) (runs: 1000, μ: 162861, ~: 164851)\nLogs:\n  Bound result 175656830\n  Bound result 68815338\n\n[PASS] test_ApproveEmitsEventAndCanBeReplacedAndRevoked() (gas: 196053)\n[PASS] test_ConstructorEmitsExactlyOneMint() (gas: 9729)\n[PASS] test_Create2MintsEverythingToFactory() (gas: 305467)\n[PASS] test_DeployerCannotSpendHolderBalanceWithoutApproval() (gas: 158044)\n[PASS] test_InfiniteAllowanceIsNotDecremented() (gas: 214775)\n[PASS] test_LaunchDistributionClaimAndPoolTransfersAreExact() (gas: 644313)\n[PASS] test_MetadataAndInitialSupply() (gas: 97189)\n[PASS] test_NoMintBurnOrAdministrativeEntrypoints() (gas: 1548037)\n[PASS] test_RevertWhenApproveZeroSpender() (gas: 37650)\n[PASS] test_RevertWhenDifferentSpenderUsesApproval() (gas: 105229)\n[PASS] test_RevertWhenTransferExceedsBalance() (gas: 67737)\n[PASS] test_RevertWhenTransferFromExceedsAllowance() (gas: 115791)\n[PASS] test_RevertWhenTransferFromExceedsBalanceRollsBackAllowance() (gas: 188800)\n[PASS] test_RevertWhenTransferFromHasNoApproval() (gas: 57799)\n[PASS] test_RevertWhenTransferFromToZeroRollsBackAllowance() (gas: 114222)\n[PASS] test_RevertWhenTransferFromZeroAddress() (gas: 52602)\n[PASS] test_RevertWhenTransferIsUint256Max() (gas: 42471)\n[PASS] test_RevertWhenTransferToZeroIncludingZeroAmount() (gas: 71993)\n[PASS] test_RuntimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 1038073)\n[PASS] test_SelfTransferFromConsumesAllowanceWithoutChangingBalance() (gas: 103332)\n[PASS] test_SelfTransferPreservesBalance() (gas: 51451)\n[PASS] test_TransferDoesNotCallRecipient() (gas: 173933)\n[PASS] test_TransferEntireSupplyEmitsEvent() (gas: 88747)\n[PASS] test_TransferFromEmitsTransferAndConsumesFiniteAllowance() (gas: 242018)\n[PASS] test_ZeroTransferFromEmptyAccountEmitsEvent() (gas: 73474)\n[PASS] test_ZeroTransferFromNeedsNoAllowance() (gas: 81544)\nSuite result: ok. 30 passed; 0 failed; 0 skipped; finished in 97.88ms (338.95ms CPU time)\n\nRan 16 tests for test/QuantumCanary.adversarial.t.sol:QuantumCanaryAdversarialTest\n[PASS] testFuzz_ApprovalReplacementIsExactAndIsolated(uint256,uint256,uint256,uint256) (runs: 1000, μ: 411135, ~: 414372)\nLogs:\n  Bound result 13026823627941314556454338\n  Bound result 361036740745707301345\n\n[PASS] testFuzz_InsufficientBalancePreservesFiniteOrInfiniteAllowance(uint256,uint256,bool) (runs: 1000, μ: 311187, ~: 310045)\nLogs:\n  Bound result 8675\n  Bound result 19391\n\n[PASS] testFuzz_InvalidReceiverRollsBackApprovalConsumption(uint256,bool) (runs: 1000, μ: 230475, ~: 230987)\nLogs:\n  Bound result 156069476675464967579648681\n\n[PASS] testFuzz_RevokingUnlimitedApprovalStopsSpendingAndAllowsReapproval(uint256) (runs: 1000, μ: 364457, ~: 364265)\nLogs:\n  Bound result 410546659282126423423224222\n\n[PASS] testFuzz_SplitDelegatedTransfersMatchOneTransfer(uint256,uint256,uint256) (runs: 1000, μ: 382093, ~: 383060)\nLogs:\n  Bound result 394677974760473559963419229\n  Bound result 19144\n  Bound result 115792089237316195423570985008687907853269984665640169361488823534353166201563\n\n[PASS] testFuzz_TransferRoundTripPreservesBalancesAndApprovals(uint256,uint256,uint256) (runs: 1000, μ: 300808, ~: 302708)\nLogs:\n  Bound result 403778302529502593643743801\n  Bound result 6027154263\n\n[PASS] test_ApprovalCannotBeRedelegatedForAnotherOwnersBalance() (gas: 308640)\n[PASS] test_ExhaustedAllowanceCannotBeReusedAfterBalanceRefill() (gas: 262636)\n[PASS] test_InfiniteApprovalCannotSpendEmptyBalanceAndSurvivesRefill() (gas: 305524)\n[PASS] test_MaxMinusOneIsFiniteAllowance() (gas: 158287)\n[PASS] test_OneWeiRoundTrip() (gas: 143031)\n[PASS] test_ReplacingInfiniteApprovalWithFiniteAllowanceRestrictsSpender() (gas: 201371)\n[PASS] test_SelfTransfersCannotBypassBalanceChecks() (gas: 147070)\n[PASS] test_TransactionOriginDoesNotAuthorizeTransfers() (gas: 176754)\n[PASS] test_TransferFromByOwnerRequiresItsOwnApproval() (gas: 209967)\n[PASS] test_ZeroAmountDoesNotPermitInvalidRecipientOrSpender() (gas: 157327)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 100.72ms (586.95ms CPU time)\n\nRan 1 test for test/QuantumCanary.invariant.t.sol:QuantumCanaryInvariantTest\n[PASS]\nQuantumCanaryInvariantTest invariants:\n[PASS] invariant_AllowancesMatchModel\n[PASS] invariant_MetadataRemainsUnchanged\n[PASS] invariant_SupplyAndBalancesMatchModel\n QuantumCanaryInvariantTest invariants (runs: 256, calls: 32768, reverts: 0)\n\n╭---------------+--------------------+-------+---------+----------╮\n| Contract      | Selector           | Calls | Reverts | Discards |\n+=================================================================+\n| CanaryHandler | approveZeroSpender | 3705  | 0       | 0        |\n|---------------+--------------------+-------+---------+----------|\n| CanaryHandler | move               | 3700  | 0       | 0        |\n|---------------+--------------------+-------+---------+----------|\n| CanaryHandler | moveOverBalance    | 3680  | 0       | 0        |\n|---------------+--------------------+-------+---------+----------|\n| CanaryHandler | moveToZero         | 3500  | 0       | 0        |\n|---------------+--------------------+-------+---------+----------|\n| CanaryHandler | revoke             | 3714  | 0       | 0        |\n|---------------+--------------------+-------+---------+----------|\n| CanaryHandler | setApproval        | 3607  | 0       | 0        |\n|---------------+--------------------+-------+---------+----------|\n| CanaryHandler | spend              | 3636  | 0       | 0        |\n|---------------+--------------------+-------+---------+----------|\n| CanaryHandler | spendOverLimit     | 3601  | 0       | 0        |\n|---------------+--------------------+-------+---------+----------|\n| CanaryHandler | spendToZero        | 3625  | 0       | 0        |\n╰---------------+--------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 972\n  Bound result 6\n  Bound result 2\n  Bound result 7035\n  Bound result 1000000000000000001\n  Bound result 4112\n  Bound result 0\n  Bound result 8802\n  Bound result 0\n  Bound result 115792089237316195423570985008687907853269984665640314039457584007913129640190\n  Bound result 12\n  Bound result 115792089237316195423570985008687907853269984665640314039457584007913129648992\n  Bound result 17\n  Bound result 249999999999999999999999999\n  Bound result 6092\n  Bound result 0\n  Bound result 105362823889908130039955150271907670513939361344\n  Bound result 383\n  Bound result 0\n  Bound result 0\n  Bound result 250000000000000000000000001\n  Bound result 7967\n  Bound result 408447\n  Bound result 11\n  Bound result 235088932295952765193120012\n  Bound result 0\n  Bound result 115792089237316195423570985008687907853269984665640314039457584007913129636409\n  Bound result 4612610438491586626365\n  Bound result 621\n  Bound result 727\n  Bound result 115792089237316195423570985008687907853269984665640314039458584007913129634989\n  Bound result 9159\n  Bound result 0\n  Bound result 0\n  Bound result 155906675876966425375459303\n  Bound result 333652565763958\n  Bound result 2\n  Bound result 16\n  Bound result 0\n  Bound result 224366944168214732452960210763282627922846\n  Bound result 115792089237316195423570985008687907853269984665640314039457584007913129655743\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 249999999999999999999987087\n  Bound result 0\n  Bound result 115792089237316195423570985008687907853269984665640314039457584007913129664511\n  Bound result 0\n  Bound result 115792089237316195423570985008687907853269984665640314039457584007913129641500\n  Bound result 0\n  Bound result 1040149169511226808075553526197763808084569910820\n  Bound result 721\n  Bound result 5\n  Bound result 6000000000000000000\n  Bound result 115792089237316195423570985008687907853269984665640314039457584007913740237947\n  Bound result 10\n  Bound result 2\n  Bound result 0\n  Bound result 6292\n  Bound result 1568554953934128596692684326816947635387250719488312310897154\n  Bound result 18\n  Bound result 115792089237316195423570985008687907853269984665640314039457584007913129655965\n  Bound result 358\n  Bound result 4344\n  Bound result 115792089237316195423570985008687907853269984665640314039457584007913129635666\n  Bound result 6763\n  Bound result 0\n  Bound result 7015\n  Bound result 107251982667401971660626546\n  Bound result 2000000000000000000\n  Bound result 3850\n  Bound result 216689617534149619523230185\n  Bound result 2547099622207555204098714981\n  Bound result 0\n  Bound result 0\n  Bound result 3000000000000000000\n  Bound result 6000000000000000000\n  Bound result 4028195770509850143987\n  Bound result 2626\n  Bound result 1311\n  Bound result 115792089237316195423570985008687907853269984665640564039457584007913129635833\n  Bound result 0\n  Bound result 903\n  Bound result 156\n  Bound result 129188991451649388589488711\n  Bound result 23000000000000000000\n  Bound result 0\n  Bound result 0\n  Bound result 0\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 10.63s (10.63s CPU time)\n\nRan 3 test suites in 10.63s (10.83s CPU time): 47 tests passed, 0 failed, 0 skipped (47 total tests)\n","passed":true},{"durationMs":49,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"QuantumCanary.approve(address,uint256)\",\"QuantumCanary.transfer(address,uint256)\",\"QuantumCanary.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":3,\"DEPENDENCIES.json\":56,\"README.md\":141,\"foundry.toml\":21,\"remappings.txt\":2,\"src/QuantumCanary.sol\":16,\"test/QuantumCanary.adversarial.t.sol\":353,\"test/QuantumCanary.invariant.t.sol\":198,\"test/QuantumCanary.t.sol\":423,\"test/README.md\":44},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"c0f441f28b3656e58ccdc0ada79b30cdf3e3d712f7a9b0441536585dca2958cb","verifiedTreeHash":"5907e368b59a59d68930a359b38b2ea957c1a778","verifierVersion":"0.1.0+aca6c688"}]}