{"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":"d9ddabf9-a52c-4e65-bc66-2d311a524d9e","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"e0d924599c4bc849a2af839b5d5166cda3bb1b54084641ea7aed2211f73cca94","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":"c4c28508f17c36ccbb814e547465e94926c7ed93a48691bfdc9c015593ff59e2","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":"8033173bdc20adfafcc569495f4b690e0b2b3d7525a07078cfb1148a16ac4a70","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":"9926d97e74bce886242bdb7076bf3f7fa3255332a85856be4d359ced9d83e5a5","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":"e65e4f99da3453a5d00d607eb7ccfefdb65235930619fe116f2b1ebef1046ec7","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":"0a474b7af190601f11cd30b9f27a9eb41abae6587855cd9a7e62f1182ab8dbd6","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"d59561da3b378461b7c749f6bd5084477d44993aa94972ddea90f542535751df","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"d59561da3b378461b7c749f6bd5084477d44993aa94972ddea90f542535751df","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":"4b3b4aab251614a76fdfc305c6d5eca14de8a23d7614210508d7306f7ccf878f","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"964913ba429aef9d7937ac41db44729023b8352cd903fb9a6002c8e68edef5da","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: Ink Global Market (INK).\nToken name: Ink Global Market\nToken symbol: INK\nToken supply: 1,000,000,000 with 18 decimals, all minted once to the deployer in the constructor.","parentJobId":null,"planHash":"60cf39fdf0a93739b9f232d6f7400f15bbdfcfe52fab46aa7952990c3cd0504f","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"d9ddabf9-a52c-4e65-bc66-2d311a524d9e","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-2120-ink-global-market"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51203","feedbackHash":"ab412d5b498db3455a32a35cd5df5d942a2ad394e092bee2b7ef68d9a07d80d8","nodeKey":"audit_economics","submissionHash":"e0d924599c4bc849a2af839b5d5166cda3bb1b54084641ea7aed2211f73cca94","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52590","feedbackHash":"a8c4318907066b07e77c78954ee188432951be6cf6d48eb07832eddb1a3abf5c","nodeKey":"audit_flow","submissionHash":"c4c28508f17c36ccbb814e547465e94926c7ed93a48691bfdc9c015593ff59e2","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52599","feedbackHash":"b43b676fd12b27391c5105e98e2546ad78c8853f0f5ceefafac50203e4711513","nodeKey":"audit_judge","submissionHash":"8033173bdc20adfafcc569495f4b690e0b2b3d7525a07078cfb1148a16ac4a70","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52158","feedbackHash":"6d341ebaaf48e13da0b53c86a0be390e4c66852650ec4fb892c8c2e18b2cc5bf","nodeKey":"audit_math","submissionHash":"9926d97e74bce886242bdb7076bf3f7fa3255332a85856be4d359ced9d83e5a5","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"50994","feedbackHash":"a519ecb659d80df35494bbd8c3222066ff9242815bfe62b00914ff12a57dffd2","nodeKey":"audit_permissions","submissionHash":"e65e4f99da3453a5d00d607eb7ccfefdb65235930619fe116f2b1ebef1046ec7","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51197","feedbackHash":"29f1d1e8ac4d6e5c64557510ba891e92c8baa98a0d659aee9131c5c61cb7a7a8","nodeKey":"build_contract_project","submissionHash":"0a474b7af190601f11cd30b9f27a9eb41abae6587855cd9a7e62f1182ab8dbd6","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"50904","feedbackHash":"5e024b3ca0a87cded57b953ec622918a3ccaff4074e3d03bcb0a78aedf4c1438","nodeKey":"manifest","submissionHash":"4b3b4aab251614a76fdfc305c6d5eca14de8a23d7614210508d7306f7ccf878f","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52262","feedbackHash":"46427e3b1df5e6dd026cc6bd5cb8ce84be70b76207a11d32e3f44198d86940fb","nodeKey":"write_foundry_tests","submissionHash":"964913ba429aef9d7937ac41db44729023b8352cd903fb9a6002c8e68edef5da","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"c2fa8796673c81bf33de3c0fb523f7ae9bca7b73d4615de88f910e582cdb5044","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":"cf8ae8ce2f58301ae17ef6e079e5c972d7cb7891b3c3cad99b8818034a86a716","device":"f2d7eadae2a3cfdf","findings":[],"hash":"0a474b7af190601f11cd30b9f27a9eb41abae6587855cd9a7e62f1182ab8dbd6","nodeId":"02849393-d5d0-43de-8b49-9545fe8ac3dd","outcome":"completed","summary":"Implemented Ink Global Market (INK): 18 decimals, 1 billion tokens minted once to the deployer, with no administrative powers.\n\nIncluded offline dependencies, deployment documentation, and 31 passing tests covering success, failure, fuzz, and invariant cases.\n\n`forge build`, `forge test` with the required seed, and `forge fmt --check` all pass.","treeHash":"75d0cdff3733040b62afe88620bde4b88ccbde2a","usage":{"cachedInputTokens":292352,"inputTokens":42976,"model":"gpt-6-astra","outputTokens":13717,"runtime":"codex","turns":5,"wallClockMs":328161}},{"artifacts":[],"attempt":1,"bundleHash":"951786266ed30cc69dec494b04526021578b85e6845a60f5db62b5d95523f0ce","device":"dbfcf48f94822fd7","findings":[],"hash":"4b3b4aab251614a76fdfc305c6d5eca14de8a23d7614210508d7306f7ccf878f","nodeId":"fa2d8a4f-3959-4b83-bf31-909ac0df0f5c","outcome":"completed","summary":"Done. `launch.json` is written and is the only changed file.\n\n**What the manifest says**\n- Kind is `custom_token`. The token entry names the Solidity contract `InkToken` with name \"Ink Global Market\", symbol INK, 18 decimals, an empty constructorArgs list (the constructor takes no parameters) and totalSupply `1000000000000000000000000000`, which is exactly what the constructor mints to msg.sender.\n- The contracts list is empty. The accepted tree has only the token, no application contracts, initialization calls or libraries.\n- The pool block uses the IMD pair address, fee 12500, tick spacing 60 and the one-to-one sqrtPriceX96 from the launch reference.\n- The economics object is copied verbatim from the job.\n- Notes describe the token's behavior in about 1,050 characters, including that the swarm's share is the factory's and that initialPrice is provenance only.\n\n**Checks**\n- A small script in the repository confirmed the manifest has only the schema's top-level keys, the economics match the job byte for byte, and the supply is one billion times ten to the eighteenth.\n- `forge build` compiled cleanly, and `forge test` with the verifier's fuzz seed passed all 31 tests in both suites.\n- `git status` shows `launch.json` as the only new or changed file.","treeHash":"d66db7d451aebe0b5a87a3f2dede8ec6e1a9c63c","usage":{"cachedInputTokens":183559,"inputTokens":130,"model":"claude-fable-5-1","outputTokens":2575,"runtime":"claude","turns":8,"wallClockMs":52331}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"a315ee4cb81c640c","findings":[{"citation":"resolved","description":"Merged from audit_flow (the only specialist to report it; audit_permissions, audit_math, audit_economics and write_foundry_tests reported nothing). Reproduced against the code: `approve` writes the new allowance unconditionally (`_allowances[owner][spender] = value` at ERC20.sol:280), so a holder lowering a nonzero allowance can be front-run by the spender, who spends the old allowance and then the new one. This is the ERC-20 standard's own property, unchanged in OpenZeppelin v5.4.0 (which deliberately dropped increaseAllowance/decreaseAllowance), and the token inherits the vendored implementation byte-for-byte (verified: all six vendored files are identical to upstream commit c64a1edb67b6e3f4a15cca8909c9482ad33a02b0). README.md lines 101-103 already document the revoke-first mitigation. None of the launch flows (factory transfer to the distributor, PoolManager seed, remainder forward, claims, swaps) rely on allowance adjustment. Kept at info as a holder trust assumption for the record; it does not require a revision.","line":120,"path":"vendor/openzeppelin/contracts/token/ERC20/ERC20.sol","reproduction":"Scratch Foundry test (test/scratch, not kept) run with `forge test --match-path test/scratch/ApproveRace.t.sol`, passed. State: deploy InkToken; transfer 1000 to holder H. H calls approve(S, 100). Sequence: (1) S calls transferFrom(H, A, 100) before H's lowering tx lands: allowance 100 >= 100, 100 tokens move to A, allowance -> 0. (2) H's approve(S, 50) executes: allowance -> 50. (3) S calls transferFrom(H, A, 50): succeeds. Expected by H: at most 100 spendable. Actual: balanceOf(A) == 150, allowance(H,S) == 0. Mitigation needing no code change: approve(S, 0), wait for inclusion, then approve(S, 50).","severity":"info","snippet":"    function approve(address spender, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, value);\n        return true;\n    }","title":"Standard ERC-20 approve ordering race: a spender can consume both the old and the new allowance (inherent ERC-20 design, documented in README; no code change required)"}],"hash":"8033173bdc20adfafcc569495f4b690e0b2b3d7525a07078cfb1148a16ac4a70","nodeId":"77f5258f-c3cd-4be4-b389-14f34c0ea5ca","outcome":"completed","summary":"The review is complete and the findings file is written. The git working tree reports no tracked changes, and the findings file was read back successfully.\n\n**Outcome: no defects found.** The token is a 17-line fixed-supply ERC-20 that inherits unmodified OpenZeppelin v5.4.0 and mints the full supply once to the deployer. The one specialist finding was reproduced and kept at info level. Nothing blocks the launch.\n\n**What I verified against the code**\n\n- The constructor mints exactly 1e27 units to msg.sender with no arguments, matching the manifest's supply, name, symbol and 18 decimals.\n- The compiled ABI exposes only approve, transfer and transferFrom as state-changing functions. There is no mint, burn, owner, pause, blacklist, upgrade, receive or fallback, so supply cannot grow and no privileged hand can move or freeze a balance.\n- I scanned the runtime bytecode by opcode. It contains no DELEGATECALL, CALLCODE, SELFDESTRUCT, CALL, STATICCALL or CREATE. Sizes are far under the deployment limits.\n- All six vendored OpenZeppelin files are byte-identical to the upstream commit named in PROVENANCE.md, and their SHA-256 hashes match the file's claims.\n- The project builds cleanly, the format check passes, and the 61-test suite including both stateful invariants passes with the README's fuzz seed.\n- Slither reported nothing. Aderyn's large-numeric-literal lead is the supply constant itself and is correct.\n\n**Specialist findings settled**\n\n- The audit_flow approve ordering race reproduces. I confirmed it with a scratch test in which a spender front-runs a lowering approve and moves 150 tokens where the holder intended at most 100. It is inherent to the ERC-20 standard, is already documented in the README with the revoke-first mitigation, and affects no launch flow. Kept at info with the reproduction and marked as needing no code change.\n- The other four areas reported nothing, so there were no duplicates to merge.\n\n**Coverage record** answers all three entry points plus five invariant rows: constructor allocation, fixed supply, opcode and size limits, vendored dependency integrity, and the static-analysis leads. The scratch test directory was removed so the tree is unchanged apart from the findings file.","treeHash":null,"usage":{"cachedInputTokens":363276,"inputTokens":194,"model":"claude-fable-5-1","outputTokens":9237,"runtime":"claude","turns":22,"wallClockMs":133058}},{"artifacts":[],"attempt":1,"bundleHash":"14092e4ab3d144ffd151b2e0ddb767a661b5420ce89cea745acfc31c03bd2833","device":"28e346843ec15530","findings":[],"hash":"964913ba429aef9d7937ac41db44729023b8352cd903fb9a6002c8e68edef5da","nodeId":"42f4ff8b-dc6a-48a2-a5f3-4cad899539a7","outcome":"completed","summary":"I added two test files on top of the existing suite. With the verifier's fuzz seed, `forge build` succeeds and `forge test` passes all 61 tests: the 31 that were already there plus 30 new ones.\n\n**`test/InkTokenEdgeCases.t.sol`** (29 tests, 9 of them fuzz tests):\n- **Supply and deployment:** the supply is exactly 10^27 smallest units. When a factory deploys the token through CREATE2, the token lands at the predicted address and the factory gets the whole supply; `tx.origin` gets nothing. Deploying again with the same salt reverts, and two separate deployments keep separate supplies. The 10% / 80% / remainder launch split moves exactly.\n- **Zero addresses:** every case reverts with its exact error: sending from address(0), approving from address(0), `transferFrom` with address(0) as owner, and (fuzzed over any amount) sending to address(0) or approving address(0) as spender.\n- **Boundaries:**\n  - transferring the maximum uint256 amount reverts cleanly, and so does sending one wei more than the balance;\n  - an allowance of max − 1 counts as a normal limited allowance: it goes down when spent and still caps spending;\n  - an unlimited allowance still can't move more than the balance;\n  - an allowance belongs to one owner and one spender only, and a spent allowance can't be reused;\n  - an owner can approve itself;\n  - tokens sent to the token contract stay there and nobody can move them out.\n- **Events:** `transferFrom` emits only a `Transfer` event, not an `Approval`. Failed calls emit nothing.\n- **Unknown functions:** any call to a function the token doesn't have reverts and changes nothing, whether it comes from the deployer or anyone else. Empty or too-short call data also reverts.\n- **Fuzzed properties:** sending tokens to another holder and back adds up correctly, nobody can spend more than they hold, an unlimited allowance never goes down, and approving again always replaces the old allowance.\n\n**`test/InkTokenFailurePathInvariant.t.sol`** is a second invariant test, set to 256 runs of 64 calls each in the file itself. The existing invariant test only made valid calls. This one mixes valid calls with invalid ones in random order:\n- sending or spending more than the balance or the allowance;\n- sending to address(0), approving address(0) as spender;\n- calling functions the token doesn't have.\n\nEach invalid call must revert with the exact expected error and leave balances and allowances unchanged. The token contract itself is one of the recipients. After every sequence it checks that:\n- balances and allowances match a separately kept record of what they should be;\n- the balances add up to the full supply, which never changes;\n- no invalid call ever succeeded;\n- the token contract's own balance can only grow.\n\nA final check fails the run if no invalid calls were made, so the test can't pass without checking anything.\n\nTo make sure the new tests can actually fail, I temporarily changed the token so `transferFrom` didn't use up allowances. All the new invariants and several unit tests failed. I then restored `src/InkToken.sol`; only the two new test files are changed.\n\nI found no defects, so there is no `.imd-findings.json`. The token is the standard OpenZeppelin v5.4.0 ERC-20, and its vendored files match the checksums listed in the repository. I didn't commit anything.","treeHash":"a025485c139513a3975b3c875e06b0526e9461c5","usage":{"cachedInputTokens":693547,"inputTokens":26,"model":"claude-opus-5-5","outputTokens":20622,"runtime":"claude","turns":16,"wallClockMs":208251}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"4dd67dae195771b6","findings":[],"hash":"9926d97e74bce886242bdb7076bf3f7fa3255332a85856be4d359ced9d83e5a5","nodeId":"37ee6185-14f6-45f3-9c31-41dc050bb8aa","outcome":"completed","summary":"The review is complete. The findings file is written and the working tree is unchanged.\n\n**Result: no defects found in the math area.** `.imd-findings.json` holds an empty findings list and nine coverage rows, one for each of the three listed entry points plus the invariants and boundaries I checked.\n\n**What the code is.** `src/InkToken.sol` is 17 lines: it inherits the unmodified OpenZeppelin v5.4.0 ERC-20 and mints a compile-time constant of exactly 10^27 units to the deployer in the constructor. I verified the vendored OpenZeppelin files against the SHA-256 hashes in the provenance file and read the implementation directly rather than trusting the label.\n\n**What I traced against the Math Precision, Boundary and Numerical Gap guides:**\n- **Supply constant.** The literal evaluates at compile time to exactly 10^27, far below the uint256 limit. Divided by 10^18 decimals it is exactly one billion with zero remainder. The aderyn large-literal lead is a readability note only.\n- **Unchecked arithmetic in `_update`.** Subtraction is guarded by the insufficient-balance check. The unchecked addition to the recipient cannot wrap because the sum of balances equals total supply and no mint or burn path is reachable after construction. Self-transfer of the full balance leaves it unchanged.\n- **Allowance math.** The infinite sentinel is exactly the maximum uint256. An allowance of max minus one decrements normally. When allowance exceeds balance, the revert comes from the balance check and the allowance is untouched. A zero `from` address reverts on either value.\n- **Launch splits.** 10^27 is divisible by 10,000, so every basis-point share of the supply is exact, with no truncation in the swarm, pool or remainder flows.\n- **Boundaries.** No external calls, no payable function, no receive or fallback, no bytes decoding, no downcasts. The only sentinel branches are the zero-address checks, both sides traced.\n\n**Checks run.** The project's own suite passed with the README's fuzz seed: 31 tests including 1,000-run fuzz tests and the 128 by 64 stateful invariant. I added a scratch test of the edge values listed above, which passed, and deleted it afterwards. `forge fmt --check` on the project sources passed.\n\n**Not reached.** The protected launch harness that seeds and swaps through the Uniswap v4 PoolManager cannot run here because it needs v4-core and manifest-derived environment variables outside this repository. The token-side arithmetic it exercises, whole-amount transfers with no fee or burn, is covered by the rows above.","treeHash":null,"usage":{"cachedInputTokens":746944,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":10378,"runtime":"claude","turns":22,"wallClockMs":166735}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"99e4819277ea59fc","findings":[{"citation":"resolved","description":"Execution Trace guide, 'Approval residuals'. `approve` overwrites the allowance unconditionally rather than adjusting it relative to the current value, so a holder who lowers an existing nonzero allowance can have the spender front-run the lowering call, spend the old allowance, and then spend the new one as well. This is the well-known ERC-20 property, not a defect introduced by InkToken: the token inherits unmodified OpenZeppelin v5.4.0 (which intentionally dropped increaseAllowance/decreaseAllowance), the README documents the risk and the revoke-first mitigation, and ERC-20 integrations (the launch factory, the PoolManager, the MerkleDistributor) do not depend on allowance adjustment. Reported at info level so the judge can see the check was run and what was found; it is a trust assumption for holders, not something the author must change.","line":120,"path":"vendor/openzeppelin/contracts/token/ERC20/ERC20.sol","reproduction":"State: holder H owns tokens; H has called approve(S, 100). Sequence: (1) H submits approve(S, 50) intending to lower the allowance. (2) S observes it in the mempool and first calls transferFrom(H, A, 100): allowance 100 >= 100 passes, 100 tokens move to A, allowance becomes 0. (3) H's approve(S, 50) executes and sets allowance to 50. (4) S calls transferFrom(H, A, 50): passes, 50 more tokens move. Actual: A received 150 and S spent 150 although H never intended more than 100 to be spendable. Expected by H: at most 100 spendable. Verified with a scratch Foundry test (test/scratch, not kept) asserting balanceOf(A) == 150 after this sequence. Mitigation available to holders without any code change: approve(S, 0) first, wait for confirmation, then approve(S, 50).","severity":"info","snippet":"    function approve(address spender, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, value);\n        return true;\n    }","title":"Standard ERC-20 approve ordering race: a spender can consume both the old and the new allowance (inherent to the ERC-20 approve/transferFrom design; already documented in README; no code change requir"}],"hash":"c4c28508f17c36ccbb814e547465e94926c7ed93a48691bfdc9c015593ff59e2","nodeId":"5b99abb0-00ae-4703-9f5c-d38259a6bcfd","outcome":"completed","summary":"The review is complete. The findings file is in place and the tree holds no other changes.\n\n**Outcome: no defects found in the assigned area.** `.imd-findings.json` holds one info-level note and eight coverage rows, all `holds`.\n\n**What I checked, by guide**\n\n- **Execution Trace.** Traced all three entry points through OpenZeppelin's `_update`, `_approve` and `_spendAllowance`. Zero-sender, zero-recipient, infinite and near-infinite allowance, self-transfer, allowance rollback on a later revert, and value-bearing calls all behave as the standard and the README state. Ten scratch Foundry tests confirmed each path. The only check that manifests is the inherent ERC-20 approve ordering race, which the README already documents. I recorded it as info with the concrete sequence so the judge sees it was examined, and stated that no change is needed.\n- **Periphery.** The five vendored OpenZeppelin files and the licence hash identically to the files at upstream commit `c64a1edb…`, which the GitHub API confirms is the v5.4.0 tag. The base contracts are unmodified and `_msgSender` is plain `msg.sender`.\n- **First Principles.** The constructor mints exactly 10^27 units once to `msg.sender`. A CREATE2 factory receives the whole supply and the transaction origin receives nothing. There is no owner, mint, burn, pause, callback, receive or fallback, and the runtime bytecode scan for forbidden opcodes passes.\n\n**Checks run**\n\n- Project suite: 31 tests passed, including the 1,000-run fuzz tests and the 128x64 invariant run.\n- Scratch probes: 10 passed, then removed.\n- Build and format check passed.\n- Static-analysis leads: the aderyn large-literal line is a compile-time constant equal to the manifest supply, not a defect. Slither reported nothing.\n\n**Not reachable here.** The protected launch suite needs the launch harness, pool contracts and manifest environment, so it was not run locally. The token has no exemption logic, so its whole-share, seed and swap checks are satisfied by construction.","treeHash":null,"usage":{"cachedInputTokens":859488,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":16575,"runtime":"claude","turns":34,"wallClockMs":269146}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"896d1238054266ca","findings":[],"hash":"e0d924599c4bc849a2af839b5d5166cda3bb1b54084641ea7aed2211f73cca94","nodeId":"a62f15cd-8e73-4859-9ba1-9745e915ca70","outcome":"completed","summary":"The review is complete. The findings file is in place, the scratch files are removed, and no tracked file changed.\n\n**Result: no defects found in the economics area.** The file `.imd-findings.json` holds an empty findings list and nine coverage rows, one for each of the three entry points plus the invariants and flows I checked.\n\n**What I verified**\n\n- **Supply invariant.** The constructor is the only mint path. `_burn` is internal and never called, and transfers to the zero address revert before reaching the balance update. Total supply is exactly 1e27 and cannot grow or shrink.\n- **Conservation.** Every transfer debits and credits the same amount. The project's stateful invariant run and my own 8-holder fuzz confirmed the sum of balances equals total supply.\n- **Launch flows against the real PoolManager.** In a scratch project outside the repo I cloned Uniswap v4-core and ran the full sequence: 10% to a distributor, an 80% single-sided seed through sync, transfer and settle, the 10% remainder forwarded, then a trader buying and selling back. Every step moved exactly its stated amount and the manager ended whole.\n- **Factory deployment.** A CREATE2 deploy from a factory contract with no constructor arguments left the whole supply at the factory and nothing at the origin or token address.\n- **Dependency integrity.** The five vendored OpenZeppelin files are byte-identical to the upstream v5.4.0 tag, re-hashed against GitHub raw at the pinned commit.\n- **Economic surface.** No oracle, external call, owner, pause, blacklist, mint or burn selector exists. Zero-address sentinels revert. Runtime has no DELEGATECALL, CALLCODE or SELFDESTRUCT.\n\n**Leads I dismissed**\n\n- The aderyn \"large numeric literal\" line evaluates to exactly the manifest supply and is style only.\n- The ERC-20 approve front-running property is standard behaviour and already documented in the README, not a defect of this implementation.\n\n**Not covered.** No `launch.json` exists yet in the tree, so the manifest itself could not be checked. That is expected for an early review and is not a defect.","treeHash":null,"usage":{"cachedInputTokens":668653,"inputTokens":258,"model":"claude-fable-5-1","outputTokens":18860,"runtime":"claude","turns":32,"wallClockMs":266142}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"60ffae3cc413a0c6","findings":[],"hash":"e65e4f99da3453a5d00d607eb7ccfefdb65235930619fe116f2b1ebef1046ec7","nodeId":"f891729b-774d-42cb-879b-0cc5c9661e07","outcome":"completed","summary":"The findings file is present, parses, and git ignores it via the harness's own exclude list. No tracked file changed and the scratch test is gone.\n\n**Outcome: no defects found in the Access Control, Trust Gap and Asymmetry areas.** The review is recorded in `.imd-findings.json` with an empty findings list and ten coverage rows, one per entry point plus the invariants I checked.\n\nWhat I verified, with concrete values:\n\n- **Permission model.** The token has no owner, role, modifier, initializer, proxy, receive or fallback. The compiled ABI exposes only the constructor, the three state-changing ERC-20 functions and views. The existing opcode test confirms no DELEGATECALL, CALLCODE or SELFDESTRUCT in the runtime.\n- **Supply fixed after construction.** The only mint is the constructor's call minting 10^27 minor units to the immediate deployer. Burn is unreachable because transfers to the zero address revert and no function calls the internal burn. A probe confirmed both transfer and transferFrom to the zero address revert from the factory with an unlimited allowance set.\n- **Allowance authorization.** A stranger pulling 1 wei from the factory with no allowance reverts and the factory balance is unchanged. A finite allowance of 60 consumed by 25 leaves exactly 35, and 36 then reverts. The maximum allowance never decrements.\n- **Asymmetry.** Approve and spend write the same slot in mirror directions. Both transfer paths share one internal transfer. The mint and burn branches of the update function mirror checked addition against unchecked subtraction with sound bounds.\n- **Trust gap.** With no privileged actor, no pricing and no caller-class-dependent rule, none of the four seams exists. Launch flows move exact amounts, so no holder class is shorted.\n- **Dependency integrity.** I recomputed SHA-256 for all six vendored OpenZeppelin files and matched them both against the tree's PROVENANCE.md and against the upstream raw files fetched at the pinned commit. The ERC-20 is genuinely unmodified v5.4.0.\n\nTwo standard ERC-20 properties are noted in coverage rather than reported as findings. The approve-ordering race is intrinsic to the standard and documented in the README. A zero-value transferFrom with no allowance succeeds but changes no state. The aderyn large-literal lead is style only, since the literal evaluates to exactly the manifest supply.\n\nNot covered: the protected launch suite that needs the v4 PoolManager harness, which is not in this tree and runs on the verifier side. All 31 existing tests pass locally.","treeHash":null,"usage":{"cachedInputTokens":1016952,"inputTokens":546,"model":"claude-fable-5-1","outputTokens":14087,"runtime":"claude","turns":24,"wallClockMs":223928}}],"verification":[{"checks":[{"durationMs":481,"exitCode":0,"name":"build","output":"Compiling 9 files with Solc 0.8.26\nSolc 0.8.26 finished in 430.69ms\nCompiler run successful!\n","passed":true},{"durationMs":2114,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 30 tests for test/InkToken.t.sol:InkTokenTest\n[PASS] testFuzz_exceedingAllowanceRevertsAtomically(uint256) (runs: 1000, μ: 99557, ~: 100119)\n[PASS] testFuzz_exceedingBalanceRevertsAtomically(uint256) (runs: 1000, μ: 52249, ~: 52217)\n[PASS] testFuzz_selfTransferPreservesBalance(uint256) (runs: 1000, μ: 42915, ~: 42911)\n[PASS] testFuzz_transferConservesSupply(address,uint256) (runs: 1000, μ: 78006, ~: 78376)\n[PASS] testFuzz_transferFromConservesSupplyAndAllowance(uint256,uint256) (runs: 1000, μ: 136953, ~: 138894)\n[PASS] test_approveEmitsEventAndReplacesAllowance() (gas: 112980)\n[PASS] test_approveZeroSpenderReverts() (gas: 34619)\n[PASS] test_constructorEmitsExactlyOneMintEvent() (gas: 6950)\n[PASS] test_emptyAccountCannotTransferPositiveAmount() (gas: 44796)\n[PASS] test_emptyHolderCanApprove() (gas: 65339)\n[PASS] test_factoryReceivesEntireSupply() (gas: 264975)\n[PASS] test_infiniteAllowanceIsNotDecreased() (gas: 190991)\n[PASS] test_launchDistributionAndContractTransfersAreExact() (gas: 1047540)\n[PASS] test_metadataAndInitialSupply() (gas: 73817)\n[PASS] test_noMintBurnOrAdministrativeEntryPoints() (gas: 1015697)\n[PASS] test_plainEtherTransferIsRejected() (gas: 38946)\n[PASS] test_revokingAllowancePreventsSpending() (gas: 127210)\n[PASS] test_runtimeHasNoForbiddenOpcodes() (gas: 462158)\n[PASS] test_transferDeliversExactAmountAndEmitsEvent() (gas: 79883)\n[PASS] test_transferEntireSupply() (gas: 69999)\n[PASS] test_transferFromByHolderStillRequiresAllowance() (gas: 37302)\n[PASS] test_transferFromConsumesAllowanceAndEmitsTransfer() (gas: 212632)\n[PASS] test_transferFromInsufficientBalanceRollsBackAllowance() (gas: 105718)\n[PASS] test_transferFromToSameHolderConsumesAllowanceOnly() (gas: 101969)\n[PASS] test_transferFromZeroRecipientRollsBackAllowance() (gas: 102868)\n[PASS] test_transferFromZeroSenderRevertsEvenForZeroAmount() (gas: 51609)\n[PASS] test_transferToZeroAddressReverts() (gas: 73594)\n[PASS] test_unapprovedSpenderCannotMoveTokens() (gas: 186814)\n[PASS] test_zeroTransferFromEmptyAccountEmitsEvent() (gas: 57335)\n[PASS] test_zeroTransferFromNeedsNoAllowanceOrBalance() (gas: 58495)\nSuite result: ok. 30 passed; 0 failed; 0 skipped; finished in 27.13ms (141.97ms CPU time)\n\nRan 1 test for test/InkTokenInvariant.t.sol:InkTokenInvariantTest\n[PASS] invariant_supplyBalancesAndAllowancesMatchModel() (runs: 128, calls: 8192, reverts: 0)\n\n╭-----------------+--------------+-------+---------+----------╮\n| Contract        | Selector     | Calls | Reverts | Discards |\n+=============================================================+\n| InkTokenHandler | approve      | 2772  | 0       | 0        |\n|-----------------+--------------+-------+---------+----------|\n| InkTokenHandler | transfer     | 2689  | 0       | 0        |\n|-----------------+--------------+-------+---------+----------|\n| InkTokenHandler | transferFrom | 2731  | 0       | 0        |\n╰-----------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.05s (2.05s CPU time)\n\nRan 2 test suites in 2.05s (2.08s CPU time): 31 tests passed, 0 failed, 0 skipped (31 total tests)\n","passed":true},{"durationMs":29,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"InkToken.approve(address,uint256)\",\"InkToken.transfer(address,uint256)\",\"InkToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":3,\"README.md\":113,\"foundry.toml\":22,\"src/InkToken.sol\":17,\"test/InkToken.t.sol\":373,\"test/InkTokenInvariant.t.sol\":87,\"test/helpers/TestBase.sol\":44},\"excluded\":[\"vendor/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":416,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":237,"exitCode":0,"name":"aderyn","output":"[low] large-numeric-literal at src/InkToken.sol:10: Large Numeric Literal","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"0a474b7af190601f11cd30b9f27a9eb41abae6587855cd9a7e62f1182ab8dbd6","verifiedTreeHash":"75d0cdff3733040b62afe88620bde4b88ccbde2a","verifierVersion":"0.1.0+c3fba9eb"},{"checks":[{"durationMs":382,"exitCode":0,"name":"build","output":"Compiling 9 files with Solc 0.8.26\nSolc 0.8.26 finished in 338.63ms\nCompiler run successful!\n","passed":true},{"durationMs":1869,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 30 tests for test/InkToken.t.sol:InkTokenTest\n[PASS] testFuzz_exceedingAllowanceRevertsAtomically(uint256) (runs: 1000, μ: 99557, ~: 100119)\n[PASS] testFuzz_exceedingBalanceRevertsAtomically(uint256) (runs: 1000, μ: 52249, ~: 52217)\n[PASS] testFuzz_selfTransferPreservesBalance(uint256) (runs: 1000, μ: 42915, ~: 42911)\n[PASS] testFuzz_transferConservesSupply(address,uint256) (runs: 1000, μ: 78006, ~: 78376)\n[PASS] testFuzz_transferFromConservesSupplyAndAllowance(uint256,uint256) (runs: 1000, μ: 136953, ~: 138894)\n[PASS] test_approveEmitsEventAndReplacesAllowance() (gas: 112980)\n[PASS] test_approveZeroSpenderReverts() (gas: 34619)\n[PASS] test_constructorEmitsExactlyOneMintEvent() (gas: 6950)\n[PASS] test_emptyAccountCannotTransferPositiveAmount() (gas: 44796)\n[PASS] test_emptyHolderCanApprove() (gas: 65339)\n[PASS] test_factoryReceivesEntireSupply() (gas: 264975)\n[PASS] test_infiniteAllowanceIsNotDecreased() (gas: 190991)\n[PASS] test_launchDistributionAndContractTransfersAreExact() (gas: 1047540)\n[PASS] test_metadataAndInitialSupply() (gas: 73817)\n[PASS] test_noMintBurnOrAdministrativeEntryPoints() (gas: 1015697)\n[PASS] test_plainEtherTransferIsRejected() (gas: 38946)\n[PASS] test_revokingAllowancePreventsSpending() (gas: 127210)\n[PASS] test_runtimeHasNoForbiddenOpcodes() (gas: 462158)\n[PASS] test_transferDeliversExactAmountAndEmitsEvent() (gas: 79883)\n[PASS] test_transferEntireSupply() (gas: 69999)\n[PASS] test_transferFromByHolderStillRequiresAllowance() (gas: 37302)\n[PASS] test_transferFromConsumesAllowanceAndEmitsTransfer() (gas: 212632)\n[PASS] test_transferFromInsufficientBalanceRollsBackAllowance() (gas: 105718)\n[PASS] test_transferFromToSameHolderConsumesAllowanceOnly() (gas: 101969)\n[PASS] test_transferFromZeroRecipientRollsBackAllowance() (gas: 102868)\n[PASS] test_transferFromZeroSenderRevertsEvenForZeroAmount() (gas: 51609)\n[PASS] test_transferToZeroAddressReverts() (gas: 73594)\n[PASS] test_unapprovedSpenderCannotMoveTokens() (gas: 186814)\n[PASS] test_zeroTransferFromEmptyAccountEmitsEvent() (gas: 57335)\n[PASS] test_zeroTransferFromNeedsNoAllowanceOrBalance() (gas: 58495)\nSuite result: ok. 30 passed; 0 failed; 0 skipped; finished in 30.57ms (139.19ms CPU time)\n\nRan 1 test for test/InkTokenInvariant.t.sol:InkTokenInvariantTest\n[PASS] invariant_supplyBalancesAndAllowancesMatchModel() (runs: 128, calls: 8192, reverts: 0)\n\n╭-----------------+--------------+-------+---------+----------╮\n| Contract        | Selector     | Calls | Reverts | Discards |\n+=============================================================+\n| InkTokenHandler | approve      | 2772  | 0       | 0        |\n|-----------------+--------------+-------+---------+----------|\n| InkTokenHandler | transfer     | 2689  | 0       | 0        |\n|-----------------+--------------+-------+---------+----------|\n| InkTokenHandler | transferFrom | 2731  | 0       | 0        |\n╰-----------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.82s (1.82s CPU time)\n\nRan 2 test suites in 1.82s (1.85s CPU time): 31 tests passed, 0 failed, 0 skipped (31 total tests)\n","passed":true},{"durationMs":27,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"InkToken.approve(address,uint256)\",\"InkToken.transfer(address,uint256)\",\"InkToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":3,\"README.md\":113,\"foundry.toml\":22,\"launch.json\":24,\"src/InkToken.sol\":17,\"test/InkToken.t.sol\":373,\"test/InkTokenInvariant.t.sol\":87,\"test/helpers/TestBase.sol\":44},\"excluded\":[\"vendor/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"4b3b4aab251614a76fdfc305c6d5eca14de8a23d7614210508d7306f7ccf878f","verifiedTreeHash":"d66db7d451aebe0b5a87a3f2dede8ec6e1a9c63c","verifierVersion":"0.1.0+c3fba9eb"},{"checks":[{"durationMs":824,"exitCode":0,"name":"build","output":"Compiling 11 files with Solc 0.8.26\nSolc 0.8.26 finished in 766.68ms\nCompiler run successful!\n","passed":true},{"durationMs":5480,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 30 tests for test/InkToken.t.sol:InkTokenTest\n[PASS] testFuzz_exceedingAllowanceRevertsAtomically(uint256) (runs: 1000, μ: 99621, ~: 100119)\n[PASS] testFuzz_exceedingBalanceRevertsAtomically(uint256) (runs: 1000, μ: 52248, ~: 52217)\n[PASS] testFuzz_selfTransferPreservesBalance(uint256) (runs: 1000, μ: 42917, ~: 42911)\n[PASS] testFuzz_transferConservesSupply(address,uint256) (runs: 1000, μ: 78052, ~: 78376)\n[PASS] testFuzz_transferFromConservesSupplyAndAllowance(uint256,uint256) (runs: 1000, μ: 136764, ~: 138906)\n[PASS] test_approveEmitsEventAndReplacesAllowance() (gas: 112980)\n[PASS] test_approveZeroSpenderReverts() (gas: 34619)\n[PASS] test_constructorEmitsExactlyOneMintEvent() (gas: 6950)\n[PASS] test_emptyAccountCannotTransferPositiveAmount() (gas: 44796)\n[PASS] test_emptyHolderCanApprove() (gas: 65339)\n[PASS] test_factoryReceivesEntireSupply() (gas: 264975)\n[PASS] test_infiniteAllowanceIsNotDecreased() (gas: 190991)\n[PASS] test_launchDistributionAndContractTransfersAreExact() (gas: 1047540)\n[PASS] test_metadataAndInitialSupply() (gas: 73817)\n[PASS] test_noMintBurnOrAdministrativeEntryPoints() (gas: 1015697)\n[PASS] test_plainEtherTransferIsRejected() (gas: 38946)\n[PASS] test_revokingAllowancePreventsSpending() (gas: 127210)\n[PASS] test_runtimeHasNoForbiddenOpcodes() (gas: 462158)\n[PASS] test_transferDeliversExactAmountAndEmitsEvent() (gas: 79883)\n[PASS] test_transferEntireSupply() (gas: 69999)\n[PASS] test_transferFromByHolderStillRequiresAllowance() (gas: 37302)\n[PASS] test_transferFromConsumesAllowanceAndEmitsTransfer() (gas: 212632)\n[PASS] test_transferFromInsufficientBalanceRollsBackAllowance() (gas: 105718)\n[PASS] test_transferFromToSameHolderConsumesAllowanceOnly() (gas: 101969)\n[PASS] test_transferFromZeroRecipientRollsBackAllowance() (gas: 102868)\n[PASS] test_transferFromZeroSenderRevertsEvenForZeroAmount() (gas: 51609)\n[PASS] test_transferToZeroAddressReverts() (gas: 73594)\n[PASS] test_unapprovedSpenderCannotMoveTokens() (gas: 186814)\n[PASS] test_zeroTransferFromEmptyAccountEmitsEvent() (gas: 57335)\n[PASS] test_zeroTransferFromNeedsNoAllowanceOrBalance() (gas: 58495)\nSuite result: ok. 30 passed; 0 failed; 0 skipped; finished in 50.34ms (254.34ms CPU time)\n\nRan 29 tests for test/InkTokenEdgeCases.t.sol:InkTokenEdgeCasesTest\n[PASS] testFuzz_approveStoresAnyValueForAnySpender(address,uint256) (runs: 1000, μ: 62737, ~: 62966)\n[PASS] testFuzz_approveZeroSpenderRevertsForAnyAmount(uint256) (runs: 1000, μ: 34863, ~: 34808)\n[PASS] testFuzz_holderCannotOverspend(uint256,uint256) (runs: 1000, μ: 97056, ~: 97512)\n[PASS] testFuzz_reapprovalOverwritesRegardlessOfPriorSpending(uint256,uint256,uint256) (runs: 1000, μ: 144316, ~: 145979)\n[PASS] testFuzz_transferBetweenHoldersRoundTrips(uint256,uint256) (runs: 1000, μ: 120415, ~: 121174)\n[PASS] testFuzz_transferToZeroRevertsForAnyAmount(uint256) (runs: 1000, μ: 41960, ~: 41905)\n[PASS] testFuzz_unknownSelectorsRevertAndChangeNothing(bytes4,bytes,bool) (runs: 1000, μ: 107700, ~: 108551)\n[PASS] testFuzz_unlimitedAllowanceNeverDecreases(uint256,uint256) (runs: 1000, μ: 190650, ~: 191586)\n[PASS] test_allowanceIsPerOwnerAndPerSpender() (gas: 171861)\n[PASS] test_allowanceJustBelowMaxIsFiniteAndDecreases() (gas: 116335)\n[PASS] test_allowanceJustBelowMaxStillCapsSpending() (gas: 85505)\n[PASS] test_approveFromZeroAddressRevertsWithInvalidApprover() (gas: 35055)\n[PASS] test_create2DeploymentMintsToFactoryAtPredictedAddress() (gas: 397665)\n[PASS] test_create2RedeploymentWithSameSaltReverts() (gas: 395102)\n[PASS] test_failedCallsEmitNothing() (gas: 82523)\n[PASS] test_fallbackCallsWithShortCalldataRevert() (gas: 72231)\n[PASS] test_launchSplitByBasisPointsIsExact() (gas: 565317)\n[PASS] test_selfApprovalAllowsSelfTransferFrom() (gas: 116013)\n[PASS] test_separateDeploymentsHaveIndependentSupplies() (gas: 470292)\n[PASS] test_supplyIsExactlyTenToTheTwentySeventh() (gas: 33446)\n[PASS] test_tokensSentToTokenContractAreHeldButSupplyUnchanged() (gas: 104705)\n[PASS] test_transferFromEmitsOnlyTransferNoApproval() (gas: 115947)\n[PASS] test_transferFromSecondSpendOfExhaustedAllowanceReverts() (gas: 138145)\n[PASS] test_transferFromZeroAddressRevertsWithInvalidSender() (gas: 34693)\n[PASS] test_transferFromZeroOwnerPositiveAmountRevertsWithInsufficientAllowance() (gas: 44817)\n[PASS] test_transferFromZeroOwnerRevertsWithInvalidApprover() (gas: 33340)\n[PASS] test_transferMaxUintRevertsWithoutOverflow() (gas: 37208)\n[PASS] test_transferOneWeiMoreThanBalanceReverts() (gas: 144435)\n[PASS] test_unlimitedAllowanceStillBoundedByBalance() (gas: 147248)\nSuite result: ok. 29 passed; 0 failed; 0 skipped; finished in 50.67ms (398.87ms CPU time)\n\nRan 1 test for test/InkTokenInvariant.t.sol:InkTokenInvariantTest\n[PASS] invariant_supplyBalancesAndAllowancesMatchModel() (runs: 128, calls: 8192, reverts: 0)\n\n╭-----------------+--------------+-------+---------+----------╮\n| Contract        | Selector     | Calls | Reverts | Discards |\n+=============================================================+\n| InkTokenHandler | approve      | 2772  | 0       | 0        |\n|-----------------+--------------+-------+---------+----------|\n| InkTokenHandler | transfer     | 2689  | 0       | 0        |\n|-----------------+--------------+-------+---------+----------|\n| InkTokenHandler | transferFrom | 2731  | 0       | 0        |\n╰-----------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.86s (1.85s CPU time)\n\nRan 1 test for test/InkTokenFailurePathInvariant.t.sol:InkTokenFailurePathInvariantTest\n[PASS]\nInkTokenFailurePathInvariantTest invariants:\n[PASS] invariant_invalidCallsNeverSucceed\n[PASS] invariant_modelMatchesAndSupplyIsFixed\n[PASS] invariant_tokenContractNeverSpendsOrApproves\n InkTokenFailurePathInvariantTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭----------------------------+---------------------------+-------+---------+----------╮\n| Contract                   | Selector                  | Calls | Reverts | Discards |\n+=====================================================================================+\n| InkTokenFailurePathHandler | approve                   | 1636  | 0       | 0        |\n|----------------------------+---------------------------+-------+---------+----------|\n| InkTokenFailurePathHandler | approveZeroSpender        | 1665  | 0       | 0        |\n|----------------------------+---------------------------+-------+---------+----------|\n| InkTokenFailurePathHandler | transfer                  | 1631  | 0       | 0        |\n|----------------------------+---------------------------+-------+---------+----------|\n| InkTokenFailurePathHandler | transferFrom              | 1626  | 0       | 0        |\n|----------------------------+---------------------------+-------+---------+----------|\n| InkTokenFailurePathHandler | transferFromOverAllowance | 1576  | 0       | 0        |\n|----------------------------+---------------------------+-------+---------+----------|\n| InkTokenFailurePathHandler | transferFromOverBalance   | 1665  | 0       | 0        |\n|----------------------------+---------------------------+-------+---------+----------|\n| InkTokenFailurePathHandler | transferFromToZero        | 1616  | 0       | 0        |\n|----------------------------+---------------------------+-------+---------+----------|\n| InkTokenFailurePathHandler | transferOverBalance       | 1671  | 0       | 0        |\n|----------------------------+---------------------------+-------+---------+----------|\n| InkTokenFailurePathHandler | transferToZero            | 1601  | 0       | 0        |\n|----------------------------+---------------------------+-------+---------+----------|\n| InkTokenFailurePathHandler | unknownCall               | 1697  | 0       | 0        |\n╰----------------------------+---------------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 5.41s (5.41s CPU time)\n\nRan 4 test suites in 5.41s (7.37s CPU time): 61 tests passed, 0 failed, 0 skipped (61 total tests)\n","passed":true},{"durationMs":39,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"InkToken.approve(address,uint256)\",\"InkToken.transfer(address,uint256)\",\"InkToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":3,\"README.md\":113,\"foundry.toml\":22,\"src/InkToken.sol\":17,\"test/InkToken.t.sol\":373,\"test/InkTokenEdgeCases.t.sol\":360,\"test/InkTokenFailurePathInvariant.t.sol\":258,\"test/InkTokenInvariant.t.sol\":87,\"test/helpers/TestBase.sol\":44},\"excluded\":[\"vendor/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"964913ba429aef9d7937ac41db44729023b8352cd903fb9a6002c8e68edef5da","verifiedTreeHash":"a025485c139513a3975b3c875e06b0526e9461c5","verifierVersion":"0.1.0+c3fba9eb"}]}