{"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":"0dd1fea6-4e56-4d61-a8de-f15d011f0f6e","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"131d5457aac4fd0fdb033c43ebb59d6df080b510fdac0d1f2c6e7788a35a078c","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":"4f276eabd1a10e80e1d22d2e5abf300e25e3965c2ca004bf240b2e05bc523acf","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":"65b388c00ad7d0fd22addfb4637a12c79ffbc3862bc337bb0cc3b47356da2304","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":"74e6c6262ef16d4b3cb50fbec9181053155b4a222ba40e886c80e9fed0a504fe","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":"3b1c8ba2a0c0a3ef6f8f4f158cc44fc9486585bb92600640ca1dd629e4078232","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":"00508161b918a2bd37af7b4e5639d3318b8fd7b263e5b41034da0c9ca828cf10","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":"d390f02f661225612074a70e96130216effe3333177913c16484ed6569f13f3a","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"2c5ea2c2ce5382c5b808d2ba71a7eeac4e95f9c29d6f85c83bac6a9b4ee9affa","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","state":"accepted"}],"objective":"A custom token: Coinstark (COINSTARK).\nToken name: Coinstark\nToken symbol: COINSTARK\nToken supply: 1,000,000,000 with 18 decimals, all minted once to the deployer in the constructor.","parentJobId":null,"planHash":"4c5556c7b0a5828d6e4f74c686362be576b14c8a1a9de9b3e1fdc7f08507df35","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"0dd1fea6-4e56-4d61-a8de-f15d011f0f6e","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1471-coinstark"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51041","feedbackHash":"1e30978efc24649e90b3431a371c65e1415c2f9ff621c1e01e213a139f0bb44f","nodeKey":"audit_economics","submissionHash":"131d5457aac4fd0fdb033c43ebb59d6df080b510fdac0d1f2c6e7788a35a078c","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52151","feedbackHash":"4cbbf941d140289ee37901eca70f35dc39c1a9cd77e17cd29b2ee7d11349070e","nodeKey":"audit_flow","submissionHash":"4f276eabd1a10e80e1d22d2e5abf300e25e3965c2ca004bf240b2e05bc523acf","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51557","feedbackHash":"89e294116545aed4ed4b83c11477f42fdb03b935d11ea855b13920e1cd8eef9d","nodeKey":"audit_judge","submissionHash":"65b388c00ad7d0fd22addfb4637a12c79ffbc3862bc337bb0cc3b47356da2304","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51428","feedbackHash":"fb9cb913f13ce9b1cf6910cc203b69e2fcd7c7074c481cb15493a30570e1703c","nodeKey":"audit_math","submissionHash":"74e6c6262ef16d4b3cb50fbec9181053155b4a222ba40e886c80e9fed0a504fe","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52121","feedbackHash":"bdcb1d3e824e920909f7b4bff5862b83091bb7853aefcae6da102e3dcb58747e","nodeKey":"audit_permissions","submissionHash":"3b1c8ba2a0c0a3ef6f8f4f158cc44fc9486585bb92600640ca1dd629e4078232","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51311","feedbackHash":"8d296a5e6246f10fa39c580e74b12d42b98422f2aad9e63351037958e7c264e3","nodeKey":"build_contract_project","submissionHash":"00508161b918a2bd37af7b4e5639d3318b8fd7b263e5b41034da0c9ca828cf10","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52197","feedbackHash":"61f45a1821b167baf26fe568646a458ad58ea211e1e00cce65293082d92d9d3b","nodeKey":"manifest","submissionHash":"d390f02f661225612074a70e96130216effe3333177913c16484ed6569f13f3a","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52371","feedbackHash":"34374fee1b3956a8559008d75de499524a85b940e180669441b499336a6feb7e","nodeKey":"write_foundry_tests","submissionHash":"2c5ea2c2ce5382c5b808d2ba71a7eeac4e95f9c29d6f85c83bac6a9b4ee9affa","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"c69227dd9a061565c7bde014e8e89b7d23ea4e551fe7b55791d8c90176d38676","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":"d4f1d43de28460309c02e35531f37650262088a2fa3f047f9865db80bae080a2","device":"273e2f46918e7b5e","findings":[],"hash":"00508161b918a2bd37af7b4e5639d3318b8fd7b263e5b41034da0c9ca828cf10","nodeId":"5f288536-da14-49b9-9fad-906074ab0015","outcome":"completed","summary":"Implemented Coinstark (COINSTARK): 1,000,000,000 tokens with 18 decimals, minted once to the deployer.\n\nIncluded vendored dependencies, deployment documentation, and success/failure, fuzz, and invariant tests.\n\nVerified with Solidity 0.8.26:\n\n- `forge build` passes.\n- `forge test`: 33 tests pass.\n- `forge fmt --check` passes.\n- Clean offline build and tests pass.","treeHash":"be75e3d2c1bf8e136afc412400e59eabc0c75bb7","usage":{"cachedInputTokens":449920,"inputTokens":60500,"model":"gpt-6-astra","outputTokens":15673,"runtime":"codex","turns":5,"wallClockMs":382914}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"3bed38612db34f32","findings":[{"citation":"resolved","description":"Coinstark inherits OpenZeppelin v5.4.0 ERC20 unchanged. Its approve(spender, value) writes the new allowance over the old one (lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol:280 `_allowances[owner][spender] = value;`). OZ v5 removed increaseAllowance/decreaseAllowance, so a holder who wants to lower an existing nonzero allowance has no atomic way to do it. A spender who watches the mempool can spend the old allowance before the replacing approve lands, then spend the new one. This is the standard ERC-20 approve race, not a bug introduced by this contract, and README.md 'After launch' already tells holders to revoke to zero first and prefer bounded approvals. It is recorded here so the judge has the full economic surface of the token; it is a trust assumption on the spender the holder chose, not a defect that needs a code change under the requested design (a plain fixed-supply ERC-20). If the author wants to remove it, adding increaseAllowance/decreaseAllowance helpers or ERC-2612 permit would be a design change outside the brief.","line":9,"path":"src/Coinstark.sol","reproduction":"State: alice holds 300e18 COINSTARK and has approved spender for 100e18. Alice sends approve(spender, 50e18) intending to lower it. Sequence: (1) spender front-runs with transferFrom(alice, spender, 100e18) -> succeeds, allowance 0. (2) alice's approve(spender, 50e18) mines -> allowance 50e18. (3) spender calls transferFrom(alice, spender, 50e18) -> succeeds. Actual: spender received 150e18 and alice holds 150e18. Expected by the holder: at most 100e18 (the larger of old and new) could ever be spent. Verified in a Foundry scratch test on this tree: both transferFrom calls return true and balanceOf(spender) == 150e18.","severity":"info","snippet":"contract Coinstark is ERC20 {","title":"approve() replaces the allowance in place, so a spender can front-run a reduction and spend old plus new (inherent ERC-20 behavior, documented in README)"}],"hash":"131d5457aac4fd0fdb033c43ebb59d6df080b510fdac0d1f2c6e7788a35a078c","nodeId":"014bfed9-e0cf-4e9d-9149-3a6c7c694908","outcome":"completed","summary":"Review complete. The findings file is written and validated, the scratch test is removed, and the tree is otherwise unchanged.\n\n**Outcome:** no defects found in the assigned area. The token is an unmodified OpenZeppelin v5.4.0 ERC-20 with a single constructor mint of exactly 1e27 units to msg.sender, no overrides, no owner, and no external calls.\n\n**What I checked against the Economic Security, Invariant and Flow Gap guides**\n\n- **Launch flows arrive whole.** No tax, burn, reflection, exemption, blacklist, pause or hook exists, so factory to distributor, distributor to claimant, pool seed, and swaps in both directions all move exactly the stated amount. Verified with a CREATE2 factory harness moving the 10 / 88 / 2 split and round-tripping through a pool-manager stand-in with an unlimited allowance.\n- **Conservation.** Sum of balances always equals totalSupply equals 1e27. The ABI has only approve, transfer and transferFrom as state-changing functions, so nothing reaches mint or burn after construction. The existing invariant suite and all 33 project tests pass.\n- **Sentinels and boundaries.** Zero-address sender, receiver and spender all revert with ERC-6093 errors and no state change. Allowance rolls back atomically when the transfer reverts. Infinite allowance stays unchanged.\n- **Launch floor.** No privileged entry points, decimals is 18, no DELEGATECALL, CALLCODE or SELFDESTRUCT in runtime, supply cannot grow.\n\n**Reported:** one info-level note on the standard ERC-20 approve replacement race, with a concrete front-run sequence. It is inherent to the standard, already documented in the README, and does not require a code change under the requested design.\n\n**Limits:** I could not execute the protected launch suite itself because v4-core and the LaunchLiquidity helpers are not in this tree. I reasoned about it from the token's code, which has no transfer-time logic for it to trip on. Coverage rows answer all three entry points plus five invariant and flow checks.","treeHash":null,"usage":{"cachedInputTokens":431072,"inputTokens":194,"model":"claude-fable-5-1","outputTokens":11264,"runtime":"claude","turns":22,"wallClockMs":171992}},{"artifacts":[],"attempt":1,"bundleHash":"84209b0da5d053262e11ed050156722a9b38b54cb4217bd0970a90f52f696849","device":"c69899cad79c228f","findings":[],"hash":"2c5ea2c2ce5382c5b808d2ba71a7eeac4e95f9c29d6f85c83bac6a9b4ee9affa","nodeId":"571a733a-ac76-4b89-8228-ce8869ce33d5","outcome":"completed","summary":"Added failure-path, allowance isolation, boundary-value, and fuzz tests. Expanded invariants to 32,768 random calls, checking conservation, failure rollback, and full-balance transfers.\n\nOffline `forge build` and `forge test` pass: **45 tests, 0 failures**.\n\nOnly `test/` changed. No implementation defects found.","treeHash":"c4944e480cada7bb903f7ceed4ad1ca120fe951c","usage":{"cachedInputTokens":658432,"inputTokens":81748,"model":"gpt-6-astra","outputTokens":11746,"runtime":"codex","turns":4,"wallClockMs":318471}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"bdd9b74dce66953d","findings":[{"citation":"resolved","description":"Trust-gap / provenance lens. README.md line 61 states that DEPENDENCIES.json records the SHA-256 of each vendored file and that 'Vendored code is unmodified and excluded from project formatting'. Recomputing the hashes shows that all six OpenZeppelin files match the pinned upstream archive byte for byte, but seven forge-std files do not: src/StdAssertions.sol, src/StdJson.sol, src/StdToml.sol, src/Vm.sol, src/console.sol, src/interfaces/IERC7540.sol and src/interfaces/IMulticall3.sol. Downloading the pinned archive (its SHA-256 a387f7c2... matches the recorded archive_sha256) and diffing shows the differences are line reflows only (multi-line signatures joined to 120-column lines); with all whitespace removed the files are identical, so the test library's behaviour is unchanged and the production token bytecode is unaffected. The defect is that the provenance record shipped with the project cannot be used to verify the tree: anyone following the README's integrity procedure gets seven failures and has to re-derive provenance themselves. Fix: either restore the seven files to the exact upstream bytes (so the recorded hashes hold), or recompute and record the hashes of the files actually committed and drop the 'unmodified' wording from README.md. No change to src/ is needed.","line":41,"path":"DEPENDENCIES.json","reproduction":"From the repository root: `sha256sum lib/forge-std/src/Vm.sol` prints a1b1c82924aecf0f38b53192fd1e801cccc1e1fd2ecd6b2301e4f4c4ab102a15, while DEPENDENCIES.json line 41 records 9068805b59ac1d0ea03a8fa1f15ae49c094e0c6c852a2500e0dd112f264b2cb1. Running the check over every entry (python3: for each dep in DEPENDENCIES.json, for each file,hash pair compare hashlib.sha256(open(file,'rb').read()).hexdigest() to hash) reports MISMATCH for the seven forge-std files listed above and 0 mismatches for the OpenZeppelin files. Expected: every recorded hash matches the committed file. Actual: 7 of 36 recorded hashes do not match.","severity":"info","snippet":"      \"lib/forge-std/src/Vm.sol\": \"9068805b59ac1d0ea03a8fa1f15ae49c094e0c6c852a2500e0dd112f264b2cb1\",","title":"DEPENDENCIES.json SHA-256 values do not match seven vendored forge-std files (reformatted copies); README claims vendored code is unmodified"},{"citation":"resolved","description":"Asymmetry lens: transfer() lets msg.sender choose only `to`, while transferFrom() lets msg.sender also choose `from`, gated by the allowance check in _spendAllowance. For value == 0 the check `currentAllowance < value` is 0 < 0 == false, so no allowance is consumed or required, and _update emits Transfer(from, to, 0) with an attacker-chosen `from`. Balances and allowances are untouched, the token remains ERC-20 compliant (the standard requires zero-value transfers to succeed), and the project's own test test_zeroTransferFromNeedsNoAllowance already documents the behaviour, so this is not a code defect in Coinstark. It is recorded so the launch's indexers, airdrop snapshots or 'has interacted with' heuristics do not treat a Transfer event's `from` field as proof that the holder acted. No fix to the token is recommended; changing it would deviate from the vendored, unmodified OpenZeppelin ERC-20 the README promises.","line":297,"path":"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol","reproduction":"Deploy Coinstark from address 0xDE; 0xDE calls transfer(0x401D, 1e24). Then from msg.sender = 0xBAD, with allowance(0x401D, 0xBAD) == 0, call transferFrom(0x401D, 0xBAD, 0). Expected under a strict 'only an approved spender may act for a holder' reading: revert with ERC20InsufficientAllowance. Actual: returns true and emits Transfer(from=0x401D, to=0xBAD, value=0); balanceOf(0x401D) is still 1e24 and allowance(0x401D, 0xBAD) is still 0. Verified with a scratch Foundry test using vm.expectEmit on the token address.","severity":"info","snippet":"            if (currentAllowance < value) {","title":"Zero-value transferFrom needs no allowance, so any caller can emit Transfer(victim, anyone, 0) on behalf of any holder (standard OpenZeppelin behaviour, no balance effect)"}],"hash":"3b1c8ba2a0c0a3ef6f8f4f158cc44fc9486585bb92600640ca1dd629e4078232","nodeId":"a01c3d8f-2a4b-489e-b323-ae0537b16081","outcome":"completed","summary":"The review is complete and `.imd-findings.json` is written. No source files were changed.\n\n**Result: no defects in the token.** Coinstark is the unmodified OpenZeppelin v5.4.0 ERC-20 plus a constructor that mints the exact manifest supply to msg.sender. There is no owner, role, pause, blacklist, mint, burn, permit, fallback or receive path, and the compiled ABI confirms only the three state-changing entry points. The deployer holds no power once it transfers. All three guides in my area were applied in full.\n\n- **Access Control:** permission map is empty beyond the holder-controls-own-balance and allowance rules. The deployer cannot pull from a holder without allowance. Unknown selectors and ETH sends revert.\n- **Asymmetry:** transfer and transferFrom share one `_update` path with no exemption branch. Approve and spendAllowance are the only writers of the allowance slot and both are guarded as intended.\n- **Trust Gap:** no privileged actor, settable parameter, fee recipient or price formula exists, so none of the four seams has an actor or an economic delta.\n\n**Two informational notes were recorded, neither blocking.**\n\n1. Seven forge-std files under `lib/` do not hash to the values in DEPENDENCIES.json. I downloaded the pinned archive and confirmed the differences are line reflows only, with identical content once whitespace is stripped. The OpenZeppelin files all match exactly. The README's claim that vendored code is unmodified is therefore inaccurate for the test library. Fix by restoring the upstream bytes or recording the real hashes.\n2. A zero-value transferFrom from any caller emits a Transfer event with an arbitrary `from` and no allowance. This is standard ERC-20 behaviour already covered by the project's own tests. It is recorded so off-chain indexers do not treat the event as proof the holder acted.\n\n**Checks run:** forge build, the full project suite (33 tests and the invariant pass), forge fmt --check, a scratch probe suite covering deployer privilege, unknown selectors, ETH sends and the zero-value event, and the SHA-256 recomputation over DEPENDENCIES.json. The scratch tests were removed afterwards. The static-analysis lead about the large numeric literal resolves to exactly the manifest supply and is not a finding.\n\n**Coverage:** all three listed entry points are marked `holds`, plus five invariant rows for the constructor, privileged surface, vendored library integrity, launch flows and trust-gap seams.","treeHash":null,"usage":{"cachedInputTokens":685940,"inputTokens":386,"model":"claude-fable-5-1","outputTokens":11503,"runtime":"claude","turns":13,"wallClockMs":207010}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"cdeffb0cd839cbf7","findings":[{"citation":"resolved","description":"README.md line 61 states that DEPENDENCIES.json records the SHA-256 hash of each vendored file and that vendored code is unmodified. The recorded hashes for lib/forge-std/src/StdAssertions.sol (line 28), StdJson.sol (34), StdToml.sol (38), Vm.sol (41), console.sol (42), interfaces/IERC7540.sol (50) and interfaces/IMulticall3.sol (52) do not match the files in the tree. The recorded hashes match the upstream forge-std v1.9.7 archive at commit 77041d2 (archive sha256 a387f7c2... matches the recorded archive_sha256), but the committed copies were re-wrapped (whitespace-only reformatting; the content with whitespace removed is identical). The OpenZeppelin files all match both the record and upstream byte for byte, so the production token's dependency provenance is intact. Impact is limited to the integrity record: anyone verifying DEPENDENCIES.json against the tree gets seven failures, and the README's 'unmodified' claim is false for forge-std. forge-std is test-only and does not affect the deployed bytecode. Fix: either restore the seven files from the pinned archive or regenerate the seven hashes in DEPENDENCIES.json and correct the README sentence.","line":41,"path":"DEPENDENCIES.json","reproduction":"State: the committed tree at 0c3bac1. Input: `sha256sum lib/forge-std/src/Vm.sol` prints a1b1c82924aecf0f38b53192fd1e801cccc1e1fd2ecd6b2301e4f4c4ab102a15; DEPENDENCIES.json line 41 records 9068805b59ac1d0ea03a8fa1f15ae49c094e0c6c852a2500e0dd112f264b2cb1. Expected: equal. Actual: differ. Same for console.sol (actual a2e632dcbc787bb096e2c06bad26c6e5e09bafca18466b236b1f2687c2ad79e9 vs recorded 896c5a5a...). A loop over every entry in DEPENDENCIES.json comparing sha256 of the file to the recorded value reports 7 mismatches, all under lib/forge-std/src/, and 0 under lib/openzeppelin-contracts/. Downloading the recorded archive_url for forge-std and running `cmp` on those seven files confirms they differ from upstream only by line wrapping (`diff -w` after stripping whitespace is empty).","severity":"low","snippet":"      \"lib/forge-std/src/Vm.sol\": \"9068805b59ac1d0ea03a8fa1f15ae49c094e0c6c852a2500e0dd112f264b2cb1\",","title":"DEPENDENCIES.json records SHA-256 hashes that do not match seven vendored forge-std files"}],"hash":"4f276eabd1a10e80e1d22d2e5abf300e25e3965c2ca004bf240b2e05bc523acf","nodeId":"5837d649-3c83-412c-838a-4fd1c23437df","outcome":"completed","summary":"Review complete. The findings file is written at `.imd-findings.json` with one low finding and nine coverage rows, and no source files were changed.\n\n**Outcome:** the token is a plain OpenZeppelin v5.4.0 ERC-20 with a constructor that mints the full supply once to msg.sender. I found no defect in the contract itself.\n\n**What I verified in the assigned area**\n\n- **Execution trace:** `approve`, `transfer` and `transferFrom` go straight into the vendored OpenZeppelin `_approve`, `_transfer`, `_update` and `_spendAllowance`. There are no external calls, hooks, fees, exemptions, sentinel paths or coupled state, so the factory, pool manager and distributor flows move exactly the stated amount. Unlimited allowance stays unchanged and finite allowance decrements atomically with the transfer.\n- **Periphery:** the five vendored OpenZeppelin files are byte-identical to the upstream v5.4.0 archive, whose SHA-256 matches the one recorded in the dependency manifest. The runtime has no DELEGATECALL, CALLCODE or SELFDESTRUCT, no receive or fallback, and no admin surface.\n- **First principles:** supply is exactly one billion times ten to the eighteenth, decimals are 18, name and symbol match the brief, and under CREATE2 the factory, not the transaction initiator, receives the supply. All 33 local tests pass, including the stateful invariant.\n\n**The one finding (low):** the dependency manifest records SHA-256 hashes for seven forge-std files that do not match the committed copies. The committed files differ from the pinned upstream archive only by line wrapping, and the README claims vendored code is unmodified. This is test-only tooling and does not touch deployed bytecode, so the fix is either restoring those seven files from the pinned archive or regenerating their hashes.\n\n**Not reached:** there is no launch.json in the tree yet, so the manifest row is marked unreached. The protected Uniswap v4 integration suite needs the launch environment and could not run here.","treeHash":null,"usage":{"cachedInputTokens":698320,"inputTokens":386,"model":"claude-fable-5-1","outputTokens":11006,"runtime":"claude","turns":19,"wallClockMs":200274}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"559cfaaab2c0d013","findings":[{"citation":"resolved","description":"Merged from audit_flow (low) and audit_permissions (info): same root cause. README.md line 61 says DEPENDENCIES.json records the SHA-256 of each vendored file and that vendored code is unmodified. Recomputing every hash in DEPENDENCIES.json against the committed tree gives 7 mismatches out of 33 recorded files, all under lib/forge-std/src/: StdAssertions.sol, StdJson.sol, StdToml.sol, Vm.sol, console.sol, interfaces/IERC7540.sol, interfaces/IMulticall3.sol. I downloaded both pinned archives: their SHA-256 values (OpenZeppelin cad1e509..., forge-std a387f7c2...) match the recorded archive_sha256 fields. Every OpenZeppelin file in lib/ is byte-identical to the pinned archive, so the production token's dependency is intact. The seven forge-std files differ from upstream only by line re-wrapping (multi-line signatures joined onto 120-column lines); with all whitespace stripped each file hashes identically to upstream. Impact is confined to the provenance record: anyone running the README's integrity procedure gets seven failures and must re-derive provenance by hand, and the README statement is false for forge-std. forge-std is test-only and does not enter the deployed bytecode. Fix: restore the seven files from the pinned archive so the recorded hashes hold, or regenerate those seven hashes and correct the README sentence. No change to src/ is needed.","line":41,"path":"DEPENDENCIES.json","reproduction":"State: the committed tree (HEAD 81bbe98). Input: `sha256sum lib/forge-std/src/Vm.sol`. Expected: 9068805b59ac1d0ea03a8fa1f15ae49c094e0c6c852a2500e0dd112f264b2cb1 (DEPENDENCIES.json line 41). Actual: a1b1c82924aecf0f38b53192fd1e801cccc1e1fd2ecd6b2301e4f4c4ab102a15. Looping over every `path: hash` pair in DEPENDENCIES.json with python hashlib.sha256 reports MISMATCH for exactly the seven files above (actual hashes: StdAssertions 3fbf4a02..., StdJson 61bbf9b3..., StdToml 187d2f0c..., Vm a1b1c829..., console a2e632dc..., IERC7540 3ae3eec9..., IMulticall3 1b63ca78...) and 0 mismatches for the OpenZeppelin files. Downloading the recorded forge-std archive_url (sha256 a387f7c2a10387f889b0d18b999cfa667a5273ac11cc11e18923022eb8b24bc3, equal to the recorded archive_sha256), extracting it and running `cmp` shows those seven files differ; `tr -d ' \\t\\n\\r' < file | sha256sum` on each pair is equal, so the difference is whitespace only.","severity":"low","snippet":"      \"lib/forge-std/src/Vm.sol\": \"9068805b59ac1d0ea03a8fa1f15ae49c094e0c6c852a2500e0dd112f264b2cb1\",","title":"DEPENDENCIES.json records SHA-256 hashes that do not match seven vendored forge-std files, contradicting the README's 'vendored code is unmodified' claim"},{"citation":"resolved","description":"From audit_permissions. In _spendAllowance the only allowance check is `currentAllowance < value`; for value == 0 that is 0 < 0 == false, so no allowance is required or consumed and _update emits Transfer(from, to, 0) with a caller-chosen `from`. Balances and allowances are untouched. This is standard, unmodified OpenZeppelin v5.4.0 behaviour (the ERC-20 standard requires zero-value transfers to succeed) and the project's own test test_zeroTransferFromNeedsNoAllowance in test/Coinstark.t.sol line 265 documents it. Not a defect in Coinstark and no code change is recommended; recorded so indexers, airdrop snapshots or 'has interacted' heuristics for this launch do not treat a Transfer event's `from` field as proof that the holder acted.","line":297,"path":"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol","reproduction":"Deploy Coinstark from D; D calls transfer(0x401D, 300e18). From msg.sender 0xBAD with allowance(0x401D, 0xBAD) == 0, call transferFrom(0x401D, 0xBAD, 0). Expected under a strict 'only an approved spender may act for a holder' reading: revert ERC20InsufficientAllowance. Actual: returns true and emits Transfer(from=0x401D, to=0xBAD, value=0); balanceOf(0x401D) remains 300e18 and allowance(0x401D, 0xBAD) remains 0. Verified in a scratch Foundry test on this tree with vm.expectEmit on the token address (passes, confirming the emission).","severity":"info","snippet":"            if (currentAllowance < value) {","title":"Zero-value transferFrom needs no allowance, so anyone can emit Transfer(holder, anyone, 0) on a holder's behalf (inherent OpenZeppelin ERC-20 behaviour, no balance effect)"},{"citation":"resolved","description":"From audit_economics. Coinstark inherits OpenZeppelin v5.4.0 ERC20 unchanged; _approve writes the new allowance over the old one and v5 ships no increaseAllowance/decreaseAllowance, so a holder has no atomic way to lower a nonzero allowance. A spender watching the mempool can spend the old allowance before the replacing approve lands, then spend the new one. This is the standard ERC-20 approve race, present in every plain ERC-20, and README.md 'After launch' already instructs holders to revoke to zero first and prefer bounded approvals. It is a trust assumption on the spender the holder chose, not a defect under the requested design (a plain fixed-supply ERC-20). Adding increase/decrease helpers or ERC-2612 permit would be a design change outside the brief; no change is required.","line":280,"path":"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol","reproduction":"State: alice holds 300e18 COINSTARK; alice calls approve(spender, 100e18). Sequence: (1) spender calls transferFrom(alice, spender, 100e18) -> returns true, allowance 0. (2) alice's approve(spender, 50e18), intended as a reduction, mines -> allowance 50e18. (3) spender calls transferFrom(alice, spender, 50e18) -> returns true. Expected by the holder: at most 100e18 (the larger of old and new) ever spendable. Actual: balanceOf(spender) == 150e18 and balanceOf(alice) == 150e18. Verified in a scratch Foundry test on this tree.","severity":"info","snippet":"        _allowances[owner][spender] = value;","title":"approve() overwrites the allowance in place, so a spender can front-run a reduction and spend old plus new (inherent ERC-20 approve race, documented in README)"}],"hash":"65b388c00ad7d0fd22addfb4637a12c79ffbc3862bc337bb0cc3b47356da2304","nodeId":"6249ab26-6833-47e2-ac87-9675e1993d9d","outcome":"completed","summary":"The review is complete and `.imd-findings.json` is written. No files other than the findings file were changed.\n\n**What I verified**\n\n- The token is unmodified OpenZeppelin v5.4.0 ERC-20 with a parameterless constructor minting exactly 1e27 to msg.sender. The project suite passes (45 tests), the compiled ABI exposes only the standard functions plus the constant getter, and the runtime bytecode contains no DELEGATECALL, CALLCODE or SELFDESTRUCT. Creation code is well under the size limits.\n- launch.json matches the code: empty constructor arguments, totalSupply equal to the mint, decimals 18, lowercase addresses, schema keys only.\n- I downloaded both pinned upstream archives. Every OpenZeppelin file is byte-identical to upstream. Seven forge-std files differ from upstream by whitespace only.\n\n**Findings kept (3)**\n\n1. **Low, merged from audit_flow and audit_permissions:** DEPENDENCIES.json hashes fail for seven re-wrapped forge-std files, so the README's \"vendored code is unmodified\" claim is false. Reproduced by recomputing every recorded hash against the tree. Test-only impact, no change to the token.\n2. **Info:** zero-value transferFrom needs no allowance and emits a Transfer with a caller-chosen sender. Reproduced in a scratch test. Inherent ERC-20 behaviour, no fix recommended.\n3. **Info:** the standard approve overwrite race. Reproduced in a scratch test. Already documented in the README as a holder trust assumption.\n\n**Coverage:** all three entry points answered `holds`, plus rows for the constructor and supply invariant, the manifest, and dependency provenance. No critical or high findings, so no proof files were attached.","treeHash":null,"usage":{"cachedInputTokens":532592,"inputTokens":354,"model":"claude-fable-5-1","outputTokens":10751,"runtime":"claude","turns":12,"wallClockMs":171989}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"bc1e515ca5c78ac4","findings":[],"hash":"74e6c6262ef16d4b3cb50fbec9181053155b4a222ba40e886c80e9fed0a504fe","nodeId":"33c11b8b-9161-4897-b644-aae3dbf3add3","outcome":"completed","summary":"I found no math, precision, boundary or numerical-gap defects in Coinstark, so `.imd-findings.json` has an empty findings list and a coverage row for each entry point. The existing test suite passes (33 tests, including the invariant run), and I changed no files apart from writing that JSON.\n\n**What the token is:** `src/Coinstark.sol` is OpenZeppelin's standard ERC-20 (v5.4.0) with nothing overridden. The supply is a constant: `INITIAL_SUPPLY = 1_000_000_000 * 10 ** 18`, which is 1e27 and is worked out when the contract compiles, so it can't overflow. The constructor is the only place tokens are minted, and it mints the whole supply to the deployer. There is no fee, burn, rounding or scaled maths anywhere.\n\n**Coverage:**\n\n| Entry point | Verdict | Why |\n|---|---|---|\n| `approve(address,uint256)` | holds | Sets the allowance exactly as given and rejects the zero address as owner or spender. It does no arithmetic. |\n| `transfer(address,uint256)` | holds | Checks the sender's balance before subtracting. The recipient's balance can't overflow because nothing can exceed the 1e27 supply. Transfers of 0 and of the whole balance both behave correctly. |\n| `transferFrom(address,address,uint256)` | holds | A maximum allowance is never reduced. Otherwise the allowance is checked before it is reduced, and spending exactly the allowance leaves it at 0. |\n| Invariant: supply is fixed | holds | Minting happens only in the constructor, and no function can mint or burn afterwards. The 10% swarm share comes to exactly 1e26, with no remainder. |\n\n**Static analysis:** the aderyn \"large numeric literal\" lead at `src/Coinstark.sol:11` is about style only. The value is correct and easy to read, so I left it out of the findings.\n\nNone of the Math Precision guide's checks apply here: there is no division, fee, exchange rate, unsafe narrowing cast or `unchecked` block in the project's own code. The boundary and numerical-gap checks (zero amounts, maximum allowances, whole-balance transfers, the supply ceiling) all hold.","treeHash":null,"usage":{"cachedInputTokens":168427,"inputTokens":10,"model":"claude-opus-5-5","outputTokens":2223,"runtime":"claude","turns":5,"wallClockMs":33082}},{"artifacts":[],"attempt":1,"bundleHash":"907203505d5797df8c9e86cbb587ebbfa207c941b92ddf266ccced6498ba10d9","device":"b3450b02f80aa5c2","findings":[],"hash":"d390f02f661225612074a70e96130216effe3333177913c16484ed6569f13f3a","nodeId":"b1b72388-b816-4981-81ce-37e8bccd7f25","outcome":"completed","summary":"Created [launch.json](/home/imd/.identitymd/work/0dd1fea6-4e56-4d61-a8de-f15d011f0f6e/b1b72388-b816-4981-81ce-37e8bccd7f25/launch.json) matching Coinstark’s constructor, exact supply, and required pool and economics values.\n\nValidation passed:\n- Manifest fields and compiled constructor ABI checked.\n- `forge build` succeeded.\n- `forge test`: 33 passed, 0 failed.\n\nOnly `launch.json` is changed for submission.","treeHash":"75b99496e2730f3ab99ec030de31873653bd2b84","usage":{"cachedInputTokens":185728,"inputTokens":25917,"model":"gpt-6-astra","outputTokens":2045,"runtime":"codex","turns":3,"wallClockMs":64233}}],"verification":[{"checks":[{"durationMs":1378,"exitCode":0,"name":"build","output":"Compiling 28 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.26s\nCompiler run successful!\n","passed":true},{"durationMs":2297,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 32 tests for test/Coinstark.t.sol:CoinstarkTest\n[PASS] testFuzz_insufficientAllowanceAlwaysReverts(uint256,uint256) (runs: 512, μ: 123437, ~: 123932)\nLogs:\n  Bound result 2580\n  Bound result 255\n\n[PASS] testFuzz_insufficientBalanceAlwaysReverts(uint256) (runs: 512, μ: 58947, ~: 59272)\nLogs:\n  Bound result 115792089237316195423570985008687907853269984665639564039457584007913129639940\n\n[PASS] testFuzz_transferConservesSupply(uint256,address) (runs: 512, μ: 92971, ~: 93203)\nLogs:\n  Bound result 979802104210151763061327228\n\n[PASS] testFuzz_transferFromConservesBalancesAndAllowance(uint256,uint256) (runs: 512, μ: 162920, ~: 165243)\nLogs:\n  Bound result 2580\n  Bound result 255\n\n[PASS] test_approvalNeedsNoCurrentBalance() (gas: 197454)\n[PASS] test_approvalReplacesAllowanceAndCanBeRevoked() (gas: 170064)\n[PASS] test_approveEmitsEventAndDoesNotMoveTokens() (gas: 88778)\n[PASS] test_approveZeroSpenderReverts() (gas: 37618)\n[PASS] test_constructorEmitsExactlyOneMintEvent() (gas: 9631)\n[PASS] test_emptyHolderCannotTransfer() (gas: 37842)\n[PASS] test_entireSupplyCanBeTransferred() (gas: 161667)\n[PASS] test_factoryReceivesSupplyInsteadOfInitiator() (gas: 228026)\n[PASS] test_holderUsingTransferFromMustAlsoHaveAllowance() (gas: 35772)\n[PASS] test_infiniteAllowanceRemainsUnchangedAndCanBeRevoked() (gas: 251163)\n[PASS] test_launchDistributionAndPoolTransfersDeliverExactAmounts() (gas: 567177)\n[PASS] test_metadataAndEntireSupplyBelongToDeployer() (gas: 107583)\n[PASS] test_neitherDeployerNorStrangerCanMintBurnOrControlHolders() (gas: 1223903)\n[PASS] test_plainEtherAndUnknownCallsRevert() (gas: 61507)\n[PASS] test_runtimeContainsNoForbiddenOpcodes() (gas: 787414)\n[PASS] test_selfTransferPreservesBalance() (gas: 53916)\n[PASS] test_selfTransferStillRequiresSufficientBalance() (gas: 40231)\n[PASS] test_transferAboveBalanceRevertsWithoutChangingBalances() (gas: 65267)\n[PASS] test_transferDeliversExactAmountAndEmitsEvent() (gas: 93461)\n[PASS] test_transferFromAboveAllowanceRevertsAtomically() (gas: 116075)\n[PASS] test_transferFromAboveBalanceRollsBackAllowance() (gas: 189572)\n[PASS] test_transferFromConsumesFiniteAllowanceAndEmitsTransfer() (gas: 242366)\n[PASS] test_transferFromSelfStillConsumesAllowance() (gas: 103615)\n[PASS] test_transferFromToZeroRollsBackAllowance() (gas: 114521)\n[PASS] test_transferFromWithoutApprovalReverts() (gas: 57825)\n[PASS] test_transferToZeroRevertsIncludingZeroAmount() (gas: 71926)\n[PASS] test_zeroTransferFromEmptyAccountSucceedsAndEmitsEvent() (gas: 73421)\n[PASS] test_zeroTransferFromNeedsNoAllowance() (gas: 91791)\nSuite result: ok. 32 passed; 0 failed; 0 skipped; finished in 16.94ms (75.81ms CPU time)\n\nRan 1 test for test/Coinstark.invariant.t.sol:CoinstarkInvariantTest\n[PASS] invariant_balancesAndAllowancesMatchIndependentLedger() (runs: 128, calls: 8192, reverts: 0)\n\n╭------------------+--------------+-------+---------+----------╮\n| Contract         | Selector     | Calls | Reverts | Discards |\n+==============================================================+\n| CoinstarkHandler | approve      | 2701  | 0       | 0        |\n|------------------+--------------+-------+---------+----------|\n| CoinstarkHandler | transfer     | 2714  | 0       | 0        |\n|------------------+--------------+-------+---------+----------|\n| CoinstarkHandler | transferFrom | 2777  | 0       | 0        |\n╰------------------+--------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 57\n  Bound result 99332873570005155236766093\n  Bound result 8\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 1\n  Bound result 7\n  Bound result 2320\n  Bound result 0\n  Bound result 2962\n  Bound result 445854818800153371791\n  Bound result 1879\n  Bound result 0\n  Bound result 2152\n  Bound result 5506\n  Bound result 0\n  Bound result 1000000000000000000\n  Bound result 255\n  Bound result 255\n  Bound result 444854818800153376649\n  Bound result 5877\n  Bound result 127\n  Bound result 7\n  Bound result 5506\n  Bound result 1480\n  Bound result 57\n  Bound result 17366736178430641612\n  Bound result 224\n  Bound result 131\n  Bound result 6\n  Bound result 6\n  Bound result 4442\n  Bound result 3000000000000000000\n  Bound result 2649\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.21s (2.21s CPU time)\n\nRan 2 test suites in 2.21s (2.22s CPU time): 33 tests passed, 0 failed, 0 skipped (33 total tests)\n","passed":true},{"durationMs":41,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Coinstark.approve(address,uint256)\",\"Coinstark.transfer(address,uint256)\",\"Coinstark.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"DEPENDENCIES.json\":56,\"LICENSE\":23,\"README.md\":63,\"foundry.toml\":22,\"remappings.txt\":2,\"src/Coinstark.sol\":16,\"test/Coinstark.invariant.t.sol\":98,\"test/Coinstark.t.sol\":413,\"test/helpers/CoinstarkFactoryHarness.sol\":11},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":448,"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/Coinstark.sol:11: Large Numeric Literal","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"00508161b918a2bd37af7b4e5639d3318b8fd7b263e5b41034da0c9ca828cf10","verifiedTreeHash":"be75e3d2c1bf8e136afc412400e59eabc0c75bb7","verifierVersion":"0.1.0+7ff5db2c"},{"checks":[{"durationMs":1397,"exitCode":0,"name":"build","output":"Compiling 29 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.30s\nCompiler run successful!\n","passed":true},{"durationMs":8212,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 11 tests for test/Coinstark.allowance.t.sol:CoinstarkAllowanceTest\n[PASS] testFuzz_approvalReplacementOnlyChangesOnePair(uint256,uint256,uint256) (runs: 1000, μ: 287066, ~: 287777)\n[PASS] testFuzz_balanceFailurePreservesAnySufficientAllowance(uint256,uint256,uint256) (runs: 1000, μ: 211099, ~: 211574)\nLogs:\n  Bound result 12295716289\n  Bound result 2630087231413580922893714584792833834300335205343982424587901993\n  Bound result 115792089237313565336339571427765014138685191831806263740252828314467880065525\n\n[PASS] testFuzz_replacementApprovalBoundsSubsequentSpending(uint256,uint256,uint256) (runs: 1000, μ: 336816, ~: 336359)\nLogs:\n  Bound result 684924035196599563996995099\n  Bound result 445886582848330821268027540\n  Bound result 554113417151669178731972458\n\n[PASS] testFuzz_splitDelegatedTransfersMatchOneTransfer(uint256,uint256,uint256) (runs: 1000, μ: 382284, ~: 384544)\nLogs:\n  Bound result 11480\n  Bound result 6843\n  Bound result 115792089237316195423570985008687907853269984665640564039457584007913129628556\n\n[PASS] test_approvalCannotBeBorrowedFromAnotherOwnerOrSpender() (gas: 313675)\n[PASS] test_approvalDoesNotFollowTokensToANewOwner() (gas: 328285)\n[PASS] test_entireSupplyCanMakeADelegatedRoundTrip() (gas: 290059)\n[PASS] test_maximumMinusOneAllowanceIsFinite() (gas: 355223)\n[PASS] test_maximumTransferFailsEvenWithInfiniteApproval() (gas: 156567)\n[PASS] test_zeroAddressIsRejectedAtZeroOneAndMaximum() (gas: 345290)\n[PASS] test_zeroTransferFromZeroOwnerCannotMint() (gas: 77668)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 60.78ms (227.94ms CPU time)\n\nRan 32 tests for test/Coinstark.t.sol:CoinstarkTest\n[PASS] testFuzz_insufficientAllowanceAlwaysReverts(uint256,uint256) (runs: 512, μ: 123323, ~: 123932)\nLogs:\n  Bound result 710423766205327131587574183\n  Bound result 175517093853294419342034961\n\n[PASS] testFuzz_insufficientBalanceAlwaysReverts(uint256) (runs: 512, μ: 58958, ~: 59272)\nLogs:\n  Bound result 529555536966474753816237330646751908455948048037874450008579\n\n[PASS] testFuzz_transferConservesSupply(uint256,address) (runs: 512, μ: 92838, ~: 93191)\nLogs:\n  Bound result 410242808865853298805126298\n\n[PASS] testFuzz_transferFromConservesBalancesAndAllowance(uint256,uint256) (runs: 512, μ: 163101, ~: 165239)\nLogs:\n  Bound result 24092005734027328879671702\n  Bound result 10838466515411029486197157\n\n[PASS] test_approvalNeedsNoCurrentBalance() (gas: 197454)\n[PASS] test_approvalReplacesAllowanceAndCanBeRevoked() (gas: 170064)\n[PASS] test_approveEmitsEventAndDoesNotMoveTokens() (gas: 88778)\n[PASS] test_approveZeroSpenderReverts() (gas: 37618)\n[PASS] test_constructorEmitsExactlyOneMintEvent() (gas: 9631)\n[PASS] test_emptyHolderCannotTransfer() (gas: 37842)\n[PASS] test_entireSupplyCanBeTransferred() (gas: 161667)\n[PASS] test_factoryReceivesSupplyInsteadOfInitiator() (gas: 228026)\n[PASS] test_holderUsingTransferFromMustAlsoHaveAllowance() (gas: 35772)\n[PASS] test_infiniteAllowanceRemainsUnchangedAndCanBeRevoked() (gas: 251163)\n[PASS] test_launchDistributionAndPoolTransfersDeliverExactAmounts() (gas: 567177)\n[PASS] test_metadataAndEntireSupplyBelongToDeployer() (gas: 107583)\n[PASS] test_neitherDeployerNorStrangerCanMintBurnOrControlHolders() (gas: 1223903)\n[PASS] test_plainEtherAndUnknownCallsRevert() (gas: 61507)\n[PASS] test_runtimeContainsNoForbiddenOpcodes() (gas: 787414)\n[PASS] test_selfTransferPreservesBalance() (gas: 53916)\n[PASS] test_selfTransferStillRequiresSufficientBalance() (gas: 40231)\n[PASS] test_transferAboveBalanceRevertsWithoutChangingBalances() (gas: 65267)\n[PASS] test_transferDeliversExactAmountAndEmitsEvent() (gas: 93461)\n[PASS] test_transferFromAboveAllowanceRevertsAtomically() (gas: 116075)\n[PASS] test_transferFromAboveBalanceRollsBackAllowance() (gas: 189572)\n[PASS] test_transferFromConsumesFiniteAllowanceAndEmitsTransfer() (gas: 242366)\n[PASS] test_transferFromSelfStillConsumesAllowance() (gas: 103615)\n[PASS] test_transferFromToZeroRollsBackAllowance() (gas: 114521)\n[PASS] test_transferFromWithoutApprovalReverts() (gas: 57825)\n[PASS] test_transferToZeroRevertsIncludingZeroAmount() (gas: 71926)\n[PASS] test_zeroTransferFromEmptyAccountSucceedsAndEmitsEvent() (gas: 73421)\n[PASS] test_zeroTransferFromNeedsNoAllowance() (gas: 91791)\nSuite result: ok. 32 passed; 0 failed; 0 skipped; finished in 60.78ms (179.21ms CPU time)\n\nRan 2 tests for test/Coinstark.invariant.t.sol:CoinstarkInvariantTest\n[PASS] invariant_balancesAndAllowancesMatchIndependentLedger() (runs: 256, calls: 32768, reverts: 0)\n\n╭------------------+----------------------------+-------+---------+----------╮\n| Contract         | Selector                   | Calls | Reverts | Discards |\n+============================================================================+\n| CoinstarkHandler | approve                    | 3576  | 0       | 0        |\n|------------------+----------------------------+-------+---------+----------|\n| CoinstarkHandler | approveAtBoundary          | 3582  | 0       | 0        |\n|------------------+----------------------------+-------+---------+----------|\n| CoinstarkHandler | rejectZeroAddress          | 3642  | 0       | 0        |\n|------------------+----------------------------+-------+---------+----------|\n| CoinstarkHandler | transfer                   | 3651  | 0       | 0        |\n|------------------+----------------------------+-------+---------+----------|\n| CoinstarkHandler | transferAboveBalance       | 3697  | 0       | 0        |\n|------------------+----------------------------+-------+---------+----------|\n| CoinstarkHandler | transferFrom               | 3691  | 0       | 0        |\n|------------------+----------------------------+-------+---------+----------|\n| CoinstarkHandler | transferFromAboveAllowance | 3649  | 0       | 0        |\n|------------------+----------------------------+-------+---------+----------|\n| CoinstarkHandler | transferFromAboveBalance   | 3630  | 0       | 0        |\n|------------------+----------------------------+-------+---------+----------|\n| CoinstarkHandler | transferFullBalance        | 3650  | 0       | 0        |\n╰------------------+----------------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 115792089237316195423570985008687907853269984665640314039457584007913129639945\n  Bound result 0\n  Bound result 115792089237316195423570985008687907853269984665640314039457584007913129640142\n  Bound result 10\n  Bound result 115792089237316195423570985008687907853269984665640314039457584007913129664063\n  Bound result 115792089237316195423570985008687907853269984665640314039457584007913129648631\n  Bound result 115792089237316195423570985008687907853269984665640314039457584007913129648019\n  Bound result 6\n  Bound result 250000000000000000000000000\n  Bound result 9654\n  Bound result 250000000000000000000000000\n  Bound result 244\n  Bound result 313866757177958151748645833565478858504373211\n  Bound result 118038895113224748885375307\n  Bound result 115792089237316195423570985008687907853269984665640314039457584007913129639946\n  Bound result 127\n  Bound result 115792089237316195423570985008687907853269984665640314039457584007913129640034\n  Bound result 250000000000000000000000000\n  Bound result 10\n  Bound result 18\n  Bound result 0\n  Bound result 250000000000000000000000000\n  Bound result 115792089237316195423570985008687907853269984665640314039457584007913129639949\n  Bound result 115792089237316195423570985008687907853269984665640064039457584007913129639943\n  Bound result 3\n  Bound result 4920\n  Bound result 249999999999999999999995077\n  Bound result 249999999999999999999995077\n  Bound result 115792089237316195423570985008687907853269984665640314039457584007913129640513\n  Bound result 250000000000000000000000000\n  Bound result 249999999999999999999999995\n  Bound result 0\n  Bound result 250000000000000000000000002\n  Bound result 0\n  Bound result 0\n  Bound result 749999999999999999999999997\n  Bound result 24576\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 115792089237316195423570985008687907853269984665640314039457584007914129639934\n  Bound result 0\n  Bound result 0\n  Bound result 15000000000000000000\n  Bound result 3000000000000000000\n  Bound result 8\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 8027\n  Bound result 115792089237316195423570985008687907853269984665639814039457584007913129640612\n  Bound result 24576\n  Bound result 910296398876831229860156108631132693408661015220030549216\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 8\n  Bound result 242\n  Bound result 2\n  Bound result 11\n  Bound result 6\n  Bound result 0\n  Bound result 11\n  Bound result 115792089237316195423570985008687907853269984665639814039457584007913129648269\n  Bound result 9\n  Bound result 0\n  Bound result 242\n  Bound result 3315\n  Bound result 0\n  Bound result 0\n  Bound result 4\n  Bound result 5218\n  Bound result 250000000000000000000000000\n  Bound result 7882\n  Bound result 0\n  Bound result 44689902245808557265034050106804910048636905142398565404250\n  Bound result 0\n  Bound result 2453\n  Bound result 5523\n  Bound result 518\n  Bound result 4060025723878941435\n  Bound result 0\n  Bound result 249648021971246299180\n  Bound result 6\n  Bound result 2468\n  Bound result 0\n  Bound result 115792089237316195423570985008687907853269984665640564039207935985942400783501\n  Bound result 2086\n  Bound result 2468\n  Bound result 166287873108921219080\n  Bound result 0\n  Bound result 0\n  Bound result 44174823350879648789309866020209320865511253666980685091142166909756275289506\n  Bound result 249648021971246296722\n  Bound result 460\n  Bound result 0\n  Bound result 249648021971246296718\n  Bound result 0\n  Bound result 250000000000000000000002464\n  Bound result 604\n  Bound result 25210019188825423867620386982692915088\n  Bound result 0\n  Bound result 6887\n  Bound result 7\n  Bound result 0\n  Bound result 42000000000000000000\n  Bound result 0\n  Bound result 250000249648021971246299182\n  Bound result 0\n  Bound result 749999750351978028753700818\n  Bound result 0\n\n[PASS] test_handlerReachesSuccessfulAndRejectedTransitions() (gas: 6306642)\nLogs:\n  Bound result 1\n  Bound result 115792089237316195423570985008687907853269984665640564039457584007913129639935\n  Bound result 1000000000000000000000000000\n  Bound result 1000000000000000000000000000\n  Bound result 0\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 249999999999999999999999999\n  Bound result 250000000000000000000000000\n  Bound result 250000000000000000000000001\n  Bound result 250000000000000000000000000\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 8.13s (8.13s CPU time)\n\nRan 3 test suites in 8.13s (8.25s CPU time): 45 tests passed, 0 failed, 0 skipped (45 total tests)\n","passed":true},{"durationMs":39,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Coinstark.approve(address,uint256)\",\"Coinstark.transfer(address,uint256)\",\"Coinstark.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"DEPENDENCIES.json\":56,\"LICENSE\":23,\"README.md\":63,\"foundry.toml\":22,\"remappings.txt\":2,\"src/Coinstark.sol\":16,\"test/Coinstark.allowance.t.sol\":268,\"test/Coinstark.invariant.t.sol\":239,\"test/Coinstark.t.sol\":413,\"test/helpers/CoinstarkFactoryHarness.sol\":11},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"2c5ea2c2ce5382c5b808d2ba71a7eeac4e95f9c29d6f85c83bac6a9b4ee9affa","verifiedTreeHash":"c4944e480cada7bb903f7ceed4ad1ca120fe951c","verifierVersion":"0.1.0+788bb33f"},{"checks":[{"durationMs":1433,"exitCode":0,"name":"build","output":"Compiling 28 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.32s\nCompiler run successful!\n","passed":true},{"durationMs":2568,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 32 tests for test/Coinstark.t.sol:CoinstarkTest\n[PASS] testFuzz_insufficientAllowanceAlwaysReverts(uint256,uint256) (runs: 512, μ: 123243, ~: 123786)\nLogs:\n  Bound result 11\n  Bound result 3163\n\n[PASS] testFuzz_insufficientBalanceAlwaysReverts(uint256) (runs: 512, μ: 58938, ~: 59272)\nLogs:\n  Bound result 436886228165019757500358439043873284090\n\n[PASS] testFuzz_transferConservesSupply(uint256,address) (runs: 512, μ: 93074, ~: 93783)\nLogs:\n  Bound result 68789371072030091414\n\n[PASS] testFuzz_transferFromConservesBalancesAndAllowance(uint256,uint256) (runs: 512, μ: 162711, ~: 165239)\nLogs:\n  Bound result 992430552054952015310009664\n  Bound result 965546238233334250034515298\n\n[PASS] test_approvalNeedsNoCurrentBalance() (gas: 197454)\n[PASS] test_approvalReplacesAllowanceAndCanBeRevoked() (gas: 170064)\n[PASS] test_approveEmitsEventAndDoesNotMoveTokens() (gas: 88778)\n[PASS] test_approveZeroSpenderReverts() (gas: 37618)\n[PASS] test_constructorEmitsExactlyOneMintEvent() (gas: 9631)\n[PASS] test_emptyHolderCannotTransfer() (gas: 37842)\n[PASS] test_entireSupplyCanBeTransferred() (gas: 161667)\n[PASS] test_factoryReceivesSupplyInsteadOfInitiator() (gas: 228026)\n[PASS] test_holderUsingTransferFromMustAlsoHaveAllowance() (gas: 35772)\n[PASS] test_infiniteAllowanceRemainsUnchangedAndCanBeRevoked() (gas: 251163)\n[PASS] test_launchDistributionAndPoolTransfersDeliverExactAmounts() (gas: 567177)\n[PASS] test_metadataAndEntireSupplyBelongToDeployer() (gas: 107583)\n[PASS] test_neitherDeployerNorStrangerCanMintBurnOrControlHolders() (gas: 1223903)\n[PASS] test_plainEtherAndUnknownCallsRevert() (gas: 61507)\n[PASS] test_runtimeContainsNoForbiddenOpcodes() (gas: 787414)\n[PASS] test_selfTransferPreservesBalance() (gas: 53916)\n[PASS] test_selfTransferStillRequiresSufficientBalance() (gas: 40231)\n[PASS] test_transferAboveBalanceRevertsWithoutChangingBalances() (gas: 65267)\n[PASS] test_transferDeliversExactAmountAndEmitsEvent() (gas: 93461)\n[PASS] test_transferFromAboveAllowanceRevertsAtomically() (gas: 116075)\n[PASS] test_transferFromAboveBalanceRollsBackAllowance() (gas: 189572)\n[PASS] test_transferFromConsumesFiniteAllowanceAndEmitsTransfer() (gas: 242366)\n[PASS] test_transferFromSelfStillConsumesAllowance() (gas: 103615)\n[PASS] test_transferFromToZeroRollsBackAllowance() (gas: 114521)\n[PASS] test_transferFromWithoutApprovalReverts() (gas: 57825)\n[PASS] test_transferToZeroRevertsIncludingZeroAmount() (gas: 71926)\n[PASS] test_zeroTransferFromEmptyAccountSucceedsAndEmitsEvent() (gas: 73421)\n[PASS] test_zeroTransferFromNeedsNoAllowance() (gas: 91791)\nSuite result: ok. 32 passed; 0 failed; 0 skipped; finished in 14.90ms (66.95ms CPU time)\n\nRan 1 test for test/Coinstark.invariant.t.sol:CoinstarkInvariantTest\n[PASS] invariant_balancesAndAllowancesMatchIndependentLedger() (runs: 128, calls: 8192, reverts: 0)\n\n╭------------------+--------------+-------+---------+----------╮\n| Contract         | Selector     | Calls | Reverts | Discards |\n+==============================================================+\n| CoinstarkHandler | approve      | 2798  | 0       | 0        |\n|------------------+--------------+-------+---------+----------|\n| CoinstarkHandler | transfer     | 2650  | 0       | 0        |\n|------------------+--------------+-------+---------+----------|\n| CoinstarkHandler | transferFrom | 2744  | 0       | 0        |\n╰------------------+--------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 1612\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 1695\n  Bound result 928\n  Bound result 589\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 192\n  Bound result 1294\n  Bound result 694\n  Bound result 0\n  Bound result 1000\n  Bound result 10\n  Bound result 0\n  Bound result 100\n  Bound result 149\n  Bound result 54\n  Bound result 966\n  Bound result 242\n  Bound result 260\n  Bound result 0\n  Bound result 2686\n  Bound result 5050\n  Bound result 3942\n  Bound result 1\n  Bound result 4000000000000000000\n  Bound result 209811841348919516072096511\n  Bound result 4\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.46s (2.46s CPU time)\n\nRan 2 test suites in 2.46s (2.48s CPU time): 33 tests passed, 0 failed, 0 skipped (33 total tests)\n","passed":true},{"durationMs":48,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Coinstark.approve(address,uint256)\",\"Coinstark.transfer(address,uint256)\",\"Coinstark.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"DEPENDENCIES.json\":56,\"LICENSE\":23,\"README.md\":63,\"foundry.toml\":22,\"launch.json\":24,\"remappings.txt\":2,\"src/Coinstark.sol\":16,\"test/Coinstark.invariant.t.sol\":98,\"test/Coinstark.t.sol\":413,\"test/helpers/CoinstarkFactoryHarness.sol\":11},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"d390f02f661225612074a70e96130216effe3333177913c16484ed6569f13f3a","verifiedTreeHash":"75b99496e2730f3ab99ec030de31873653bd2b84","verifierVersion":"0.1.0+7ff5db2c"}]}