{"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":"c07a0d7b-b0e3-4c8b-a15c-03525aea938a","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"de5bc50e023e494fce48806c71782755ffe8bb328c6db6647c8b508795b26ed4","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":"47c5473fe87e0bbdb9a8b38fe899ba236940e558f85493df70e494372063eca3","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":"767c4cbf11fc724a766c0af219eac8aa21ca333c308fa1e1e632594ffb873e31","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":"92f64a9feeaa801bb4cd85118287f30069c10e992726c6601a219ddf720ecfec","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":"317ceef0f5957950679173d142174e82c298f8943a5c7b39aa1db9fb20ecd6d9","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":"5e7ee148cf8ba185367d7b5eebbd4ab365ebec00a8c0418cfb48df094ebe2882","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":"8f4fde171ec9078f108d87a875eb51dccc22c998e48200b15c56e8e02eb172d8","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"cbc11e6524eff0738f8bac787d7e8b419007a4b370d2aafa47a476df73eef8f0","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: CrawlHive (CRAWLHIVE).\nToken name: CrawlHive\nToken symbol: CRAWLHIVE\nToken supply: 1,000,000,000 with 18 decimals, all minted once to the deployer in the constructor.","parentJobId":null,"planHash":"24e789ed8db0acb255fb769ee270bf93f3ccd677b43488b98eaf74643bb7470f","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"c07a0d7b-b0e3-4c8b-a15c-03525aea938a","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1621-crawlhive"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51442","feedbackHash":"740c405b02499a46c0bc39f95f367cf93507720355b9f4a84e4ac23dc99bf5d3","nodeKey":"audit_economics","submissionHash":"de5bc50e023e494fce48806c71782755ffe8bb328c6db6647c8b508795b26ed4","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51304","feedbackHash":"1cc0fd9efa2429d20319624cdca3f11f1a44ac34840f92cad36da62b74fe0e90","nodeKey":"audit_flow","submissionHash":"47c5473fe87e0bbdb9a8b38fe899ba236940e558f85493df70e494372063eca3","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52189","feedbackHash":"34427fea2ef104b9c07d3918d6e38b8716d2a42a5e338e8869963a973be3f582","nodeKey":"audit_judge","submissionHash":"767c4cbf11fc724a766c0af219eac8aa21ca333c308fa1e1e632594ffb873e31","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52170","feedbackHash":"3a2964b285a55be530880232f60981bcc4f114a57d180825b2b180a5825190f0","nodeKey":"audit_math","submissionHash":"92f64a9feeaa801bb4cd85118287f30069c10e992726c6601a219ddf720ecfec","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52612","feedbackHash":"87f423285e33ba138caab995fe0b36cbbeb45ab3d2fa94abad70a8f1fe1b8f8b","nodeKey":"audit_permissions","submissionHash":"317ceef0f5957950679173d142174e82c298f8943a5c7b39aa1db9fb20ecd6d9","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52253","feedbackHash":"5708833ec534ecd763daefa2cb4ad3b9fd2b47be0d433905b7f3615a551b7912","nodeKey":"build_contract_project","submissionHash":"5e7ee148cf8ba185367d7b5eebbd4ab365ebec00a8c0418cfb48df094ebe2882","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51040","feedbackHash":"881442809f3f0c9bcef8c624c548c8d0a456b97b52de8d90a410122b76bad127","nodeKey":"manifest","submissionHash":"8f4fde171ec9078f108d87a875eb51dccc22c998e48200b15c56e8e02eb172d8","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52666","feedbackHash":"2dbf5c19333a7c9d9c84c6cff0636ded1b851d21d16c24e0ed4ed506a006ab03","nodeKey":"write_foundry_tests","submissionHash":"cbc11e6524eff0738f8bac787d7e8b419007a4b370d2aafa47a476df73eef8f0","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"ef89bf3b55fab73643cf77b44a537f342a44c79d8b389de1ef1e236d07084434","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"fbdcf3c80b280e3b","findings":[{"citation":"resolved","description":"Access-control lens, inherited unchanged by src/CrawlHiveToken.sol (contract CrawlHiveToken is ERC20). _spendAllowance only reverts when currentAllowance < value, so value == 0 passes with a zero allowance; _transfer then runs _update(from, to, 0) and emits Transfer(from, to, 0) for a `from` the caller does not control. No balance moves and the allowance guard holds for every value >= 1 (verified: transferFrom(alice, mallory, 1) with zero allowance reverts ERC20InsufficientAllowance(mallory, 0, 1)). This is the ERC-20 rule that zero-value transfers are normal transfers and fire the event; OpenZeppelin 5.4.0 implements it on purpose and the vendored file is byte-identical to upstream. The only practical use is event spam / address-poisoning of explorer histories. Reported for completeness of the permission map; no code change is recommended, since blocking zero-value transfers would deviate from the standard and could break integrators.","line":297,"path":"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol","reproduction":"State: factory deploys CrawlHiveToken, transfers 100e18 to alice; allowance(alice, mallory) == 0. Call: vm.prank(mallory); token.transferFrom(alice, mallory, 0). Expected under a strict reading of 'spender must hold an allowance': revert. Actual: returns true, emits Transfer(alice, mallory, 0), balances unchanged (alice 100e18, mallory 0). Reproduced in test/scratch/AccessProbe.t.sol::test_zeroValueTransferFromNeedsNoAllowance.","severity":"info","snippet":"            if (currentAllowance < value) {","title":"Zero-value transferFrom needs no allowance: anyone can emit Transfer(victim, X, 0) (standard ERC-20 behaviour, not blocking)"},{"citation":"resolved","description":"Asymmetry lens on the approve <-> transferFrom pair, inherited unchanged by src/CrawlHiveToken.sol. approve writes the allowance with `=` while _spendAllowance decrements with `-=`; a spender who sees a pending approve(spender, newValue) can spend the old allowance first and then the new one. The token does not expose increaseAllowance/decreaseAllowance (OpenZeppelin removed them in 5.x by design) and the README's 'Operational responsibilities' section already tells holders to zero an allowance before changing it. This is inherent to the ERC-20 interface, affects every compliant token, and is not a defect of this implementation; recorded so the judge sees the pair was examined. No change recommended.","line":280,"path":"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol","reproduction":"State: alice holds 100e18; alice approve(spender, 50e18). alice then submits approve(spender, 20e18) intending to lower it. Sequence: spender front-runs with transferFrom(alice, spender, 50e18) (succeeds), alice's approve(spender, 20e18) mines, spender calls transferFrom(alice, spender, 20e18) (succeeds). Expected by alice: spender can take at most 50e18 (or 20e18). Actual: spender holds 70e18, alice 30e18. Reproduced in test/scratch/AccessProbe.t.sol::test_approveRaceSpendsOldAndNew.","severity":"info","snippet":"        _allowances[owner][spender] = value;","title":"approve sets an absolute allowance: the well-known approve/transferFrom front-running race applies (standard ERC-20, documented in README)"}],"hash":"317ceef0f5957950679173d142174e82c298f8943a5c7b39aa1db9fb20ecd6d9","nodeId":"651519d8-3ae8-4b89-9dae-dec713b5f5c5","outcome":"completed","summary":"The review is complete and the findings file is written and validated.\n\n**Outcome: no blocking defects in the assigned area.** The token is an unmodified OpenZeppelin 5.4.0 ERC-20 with a single constructor mint, and its permission model is exactly the standard one. Both findings I recorded are informational and describe inherent ERC-20 behavior, not defects in this code.\n\nWhat I checked:\n- **Access Control.** Mapped every writer of the three storage variables. Balances move only by the holder (transfer) or by a spender within allowance (transferFrom). Allowances are written only by their owner, or decremented symmetrically on spend. Supply is written only in the constructor. There is no owner, role, initializer, proxy, receive or fallback, and the compiled ABI confirms only the three listed state-changing selectors.\n- **Asymmetry.** Compared approve against transferFrom, transfer against transferFrom, and the mint and burn branches of the internal update. Only the external paths that reject the zero address are reachable. Self-transfer nets to zero.\n- **Trust Gap.** No privileged actor and no economic formula exist inside the token, so no seam between lenses is present. The factory holding the full supply at deployment is the launch design and is recorded as a trust assumption.\n- **Dependency integrity.** All five vendored OpenZeppelin files are byte-identical to upstream at the pinned commit, fetched during this review.\n- **Static-analysis lead.** The large-literal lead at line 23 evaluates to the manifest supply and is style only.\n\nFindings recorded as info, each with a reproduction run in a scratch test:\n1. A zero-value transferFrom succeeds with no allowance and emits a Transfer event from an arbitrary address. This is the ERC-20 zero-value rule and no change is recommended.\n2. The approve/transferFrom front-running race applies, as to every ERC-20. The README already documents it.\n\nCoverage has 11 rows: the three entry points, the constructor, four invariants, dependency integrity and the trust-gap seams all hold. One row is unreached: the protected pool-seed and swap test cannot run here because Uniswap v4 core is not in the tree, though by inspection the untaxed token reduces those flows to plain transfers.\n\nThe scratch test lives under test/scratch/ and is gitignored. No tracked file was changed.","treeHash":null,"usage":{"cachedInputTokens":414466,"inputTokens":194,"model":"claude-fable-5-1","outputTokens":13613,"runtime":"claude","turns":21,"wallClockMs":192727}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"4be5e039e1c77ce3","findings":[{"citation":"resolved","description":"CrawlHiveToken inherits OpenZeppelin ERC20 unchanged (vendored copy verified byte-for-byte equal in code to upstream; only header comments and import order differ). approve(spender, value) overwrites the allowance without reference to the previous value (lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol:120-124), so a spender that sees a pending allowance change can spend the old allowance first and then the new one. This is the ERC-20 standard's own semantics, not a defect introduced by this code, and README.md 'Security notes' already documents it with the usual mitigation (set to zero first, or use exact amounts). Reported at info so the judge sees it was traced and dismissed; no change to the token is recommended, since departing from standard approve semantics would break wallets and the PoolManager/permit2-style integrations that assume them.","line":15,"path":"src/CrawlHiveToken.sol","reproduction":"State: deployer transfers 1000e18 to alice. 1) alice: approve(bob, 100e18). 2) bob: transferFrom(alice, bob, 100e18) -> bob 100e18. 3) alice (intending to lower to 50e18): approve(bob, 50e18). 4) bob: transferFrom(alice, bob, 50e18) -> bob 150e18, allowance 0. Expected by alice: at most 100e18 spendable in total; actual: 150e18. Reproduced in a scratch Foundry test (test_approveRaceMoves150, passes on this tree). Severity info: inherent to ERC-20, documented, no fix requested.","severity":"info","snippet":"contract CrawlHiveToken is ERC20 {","title":"Inherited ERC-20 approve race: lowering a non-zero allowance can be front-run (standard behaviour, already documented in README)"}],"hash":"47c5473fe87e0bbdb9a8b38fe899ba236940e558f85493df70e494372063eca3","nodeId":"b0c18626-320b-4b77-b233-ab49be74653b","outcome":"completed","summary":"The review is complete and the findings file is written. The git status check fails only because the sandbox blocks reading the global gitconfig; it does not affect the deliverable.\n\n**Outcome:** no defects found in CrawlHiveToken. The findings file holds one info-level note and ten coverage rows, all `holds`.\n\n**What I traced** (Execution Trace, Periphery, First Principles guides):\n\n- **approve, transfer, transferFrom** through the inherited OpenZeppelin ERC20 to `_approve`, `_spendAllowance`, `_transfer` and `_update`. Every revert path, state write and event behaves as the standard specifies. No external calls, no fee, no hook, no reentrancy window.\n- **Constructor** takes no arguments, makes no external calls, and mints exactly 1e27 once to the caller. Under CREATE2 from a factory stub the factory receives the whole supply, which is what the protected launch test requires.\n- **Periphery:** the vendored OpenZeppelin files are byte-identical in code to the pristine mirror, differing only in header comments and import order. forge-std 1.17.0 only affects tests. The deploy script reads no keys and is not the launch path.\n- **Floor invariants:** no mint, owner, pause, blocklist, freeze, seize or burnFrom entry point exists. The runtime contains no DELEGATECALL, CALLCODE or SELFDESTRUCT and is well within size limits. Slither run locally reported zero results at low impact or above, matching the verifier's output. The aderyn large-literal lead is the readable supply constant and not a defect.\n\n**The one info note** records the standard ERC-20 approval overwrite race, reproduced in a scratch test (approve 100, spend 100, approve 50, spend 50 moves 150). It is inherent to the standard, already documented in the README, and I recommend no change, since non-standard approve semantics would break wallet and PoolManager integrations.\n\nThe scratch test directory was removed, so the tree is unchanged apart from `.imd-findings.json`.","treeHash":null,"usage":{"cachedInputTokens":601810,"inputTokens":258,"model":"claude-fable-5-1","outputTokens":11105,"runtime":"claude","turns":20,"wallClockMs":165490}},{"artifacts":[],"attempt":1,"bundleHash":"0b7ffcb6463aa8dd77656299f64a04a739b812ff825368fcbd65bdef5f3e8001","device":"7591760a616c6429","findings":[],"hash":"5e7ee148cf8ba185367d7b5eebbd4ab365ebec00a8c0418cfb48df094ebe2882","nodeId":"554e5ef7-641b-4203-a916-55be468836cd","outcome":"completed","summary":"The CrawlHive token project is complete, verified, and committed on main as commit 0e68af9.\n\n**What was built**\n\n- `src/CrawlHiveToken.sol` is a plain OpenZeppelin ERC-20 named CrawlHive, symbol CRAWLHIVE, 18 decimals. The constructor takes no arguments and mints the whole 1,000,000,000 supply once to msg.sender, which on the launch is the factory. There is no owner, mint, pause, blocklist, fee, or upgrade path.\n- `test/CrawlHiveToken.t.sol` holds 30 tests: metadata and supply, CREATE2 deployment from a factory stub, exact transfers and allowances, revert cases for balance, allowance, zero address and ether, the 10/88/2 launch flow and a claim, probes of every mint and freeze selector the floor tries, a runtime opcode scan, and three fuzz tests.\n- `script/DeployCrawlHive.s.sol` is a local helper whose function the tests call directly. The README states it is not the launch path.\n- `foundry.toml` pins solc 0.8.26, sets `bytecode_hash = \"none\"` and disables cbor metadata, ffi and filesystem access.\n- forge-std 1.17.0 and the five OpenZeppelin 5.4.0 files ERC20 needs are vendored as plain files with provenance notes. No submodules.\n- `README.md` documents assumptions, the manifest values for the token, operational responsibilities, and an empty \"After launch\" section since nothing is owner-settable.\n\n**Verification**\n\n| Check | Result |\n| --- | --- |\n| forge build (clean, empty env) | pass |\n| forge test (clean, empty env) | 30 passed |\n| forge fmt --check | pass |\n| Verifier's protected floor test, run in scratch against the built creation code | 8 passed |\n\nFor the protected test I assembled the factory's harness and a local v4-core copy in the scratch area, computed the CREATE2 token address, and seeded a single-sided pool against the IMD address. The seed and both swap directions succeeded. The scratch area was removed before the final clean rebuild.\n\nNo launch.json or blocked file was written. No open questions remain for the requester.","treeHash":"c0fe430018816ee246b158e1b99d45308d28e29e","usage":{"cachedInputTokens":1164064,"inputTokens":610,"model":"claude-fable-5-1","outputTokens":27478,"runtime":"claude","turns":29,"wallClockMs":320806}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"fe5e46fb044c6af1","findings":[{"citation":"resolved","description":"CrawlHiveToken inherits OpenZeppelin 5.4.0 ERC20 unchanged. I verified the five vendored files (ERC20.sol, IERC20.sol, IERC20Metadata.sol, Context.sol, draft-IERC6093.sol) are byte-identical to the @openzeppelin/contracts 5.4.0 npm package. approve() writes the allowance absolutely (lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol:280 `_allowances[owner][spender] = value;`) while _spendAllowance decrements, so a spender who sees a pending allowance change can spend the old allowance and then the new one. This is the ERC-20 standard's own semantics and affects every compliant token; README 'Security notes' documents it with the usual mitigation (set to zero first, or approve exact amounts). Two specialists (audit_permissions, audit_flow) reported the same root cause; merged here. Not a defect of this implementation and no change is recommended: departing from standard approve semantics would break wallets and PoolManager/Permit2-style integrators. Recorded so the pair is visibly examined; non-blocking.","line":15,"path":"src/CrawlHiveToken.sol","reproduction":"State: factory deploys CrawlHiveToken via CREATE2 and transfers 100e18 to alice. 1) alice: approve(mallory, 50e18). 2) mallory: transferFrom(alice, mallory, 50e18) succeeds. 3) alice (intending to lower the allowance): approve(mallory, 20e18). 4) mallory: transferFrom(alice, mallory, 20e18) succeeds. Expected by alice: mallory can take at most 50e18 total. Actual: balanceOf(mallory) == 70e18, balanceOf(alice) == 30e18. Reproduced in test/scratch/JudgeProbe.t.sol::test_approveRaceSpendsOldAndNew (passes on this tree, i.e. the race happens as stated).","severity":"info","snippet":"contract CrawlHiveToken is ERC20 {","title":"Inherited ERC-20 approve/transferFrom race: lowering a non-zero allowance can be front-run (standard behaviour, documented; merged from audit_permissions and audit_flow)"},{"citation":"resolved","description":"Inherited unchanged by src/CrawlHiveToken.sol. _spendAllowance only reverts when currentAllowance < value, so value == 0 passes with a zero allowance; _transfer then runs _update(from, to, 0) and emits Transfer(from, to, 0) for a `from` the caller does not control. No balance or allowance changes, and the guard holds for every value >= 1. ERC-20 requires zero-value transfers to be treated as normal transfers and to fire the event; OpenZeppelin implements this on purpose. The only practical effect is event spam / explorer address-poisoning. Reported from audit_permissions, reproduced, kept at info; no code change recommended since blocking zero-value transfers would deviate from the standard.","line":297,"path":"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol","reproduction":"State: factory deploys CrawlHiveToken, transfers 100e18 to alice; allowance(alice, mallory) == 0. Call: vm.prank(mallory); token.transferFrom(alice, mallory, 0). Expected under a strict reading of 'spender must hold an allowance': revert. Actual: returns true and emits Transfer(alice, mallory, 0); balances unchanged (alice 100e18, mallory 0). Follow-up transferFrom(alice, mallory, 1) from mallory reverts ERC20InsufficientAllowance(mallory, 0, 1). Reproduced in test/scratch/JudgeProbe.t.sol::test_zeroValueTransferFromNeedsNoAllowance.","severity":"info","snippet":"            if (currentAllowance < value) {","title":"Zero-value transferFrom needs no allowance: anyone can emit Transfer(victim, X, 0) (standard ERC-20 behaviour, non-blocking)"}],"hash":"767c4cbf11fc724a766c0af219eac8aa21ca333c308fa1e1e632594ffb873e31","nodeId":"1f41495a-d43c-44ad-bc4a-4f480962fd4f","outcome":"completed","summary":"The review is complete and `.imd-findings.json` is written at the repository root with two info-level findings and a nine-row coverage record. Git status shows only the findings file and the scratch test as untracked, both of which are expected outputs. No repository file was modified.\n\n**Outcome: no blocking defects.** CrawlHiveToken is a plain OpenZeppelin 5.4.0 ERC-20 with a fixed supply minted to the deployer and no custom logic beyond a constant `decimals()` override.\n\n**Specialist findings, judged**\n\n- **Approve race** (reported by audit_permissions and audit_flow): same root cause, merged into one finding at info. Reproduced in a scratch test: a spender takes 50e18, the owner lowers the allowance to 20e18, the spender takes 20e18 more, ending with 70e18. This is the ERC-20 standard's own semantics, documented in the README. No change recommended.\n- **Zero-value transferFrom without allowance** (audit_permissions): reproduced. It emits a zero-value Transfer event and moves nothing. Any value of 1 or more reverts with the expected allowance error. Kept at info, standard behaviour.\n- **audit_economics, audit_math, write_foundry_tests** reported nothing, which matches my own tracing.\n\n**My own checks, all holding**\n\n- All five vendored OpenZeppelin files are byte-identical to the 5.4.0 npm package.\n- Constructor takes no arguments and mints exactly the manifest supply to msg.sender, verified via a CREATE2 factory stub.\n- Creation and runtime bytecode are well under the protocol size limits, and the runtime contains no DELEGATECALL, CALLCODE or SELFDESTRUCT.\n- The ABI exposes only approve, transfer and transferFrom as state-changing entry points, so no mint, owner, pause or rescue path exists.\n- The manifest uses only schema keys, with lowercase addresses, string uint256 values, and a supply string equal to the constant.\n- The aderyn large-literal lint is style only. The constant evaluates to exactly 1e27.\n- The existing 61 repository tests pass, as does my 4-test scratch probe.\n\nOne documentation nit I did not file as a finding: the README says launch.json is intentionally not included, but the manifest step has since added it. That is a stale sentence, not a code defect.","treeHash":null,"usage":{"cachedInputTokens":445338,"inputTokens":226,"model":"claude-fable-5-1","outputTokens":11127,"runtime":"claude","turns":21,"wallClockMs":180118}},{"artifacts":[],"attempt":1,"bundleHash":"606ac1fdca8502a0cd1118b6dc9d7a44ef81f33dc827380c1f7492ba392eb10f","device":"df74f6c887684f20","findings":[],"hash":"8f4fde171ec9078f108d87a875eb51dccc22c998e48200b15c56e8e02eb172d8","nodeId":"512141ad-42cb-4ad4-aef0-1e9f3ea5373a","outcome":"completed","summary":"I wrote launch.json for the CrawlHive launch. It is the only changed file.\n\n**What the manifest says**\n\n- Kind is custom_token. The token contract is CrawlHiveToken, name CrawlHive, symbol CRAWLHIVE, 18 decimals.\n- The constructor in src/CrawlHiveToken.sol takes no arguments, so constructorArgs is empty. It mints 1,000,000,000 tokens to msg.sender once, so totalSupply is 1e27 in minor units, matching the contract's TOTAL_SUPPLY constant.\n- No application contracts exist in the accepted tree, so contracts is an empty list.\n- Pool and economics are copied exactly as the launch gives them: IMD as the paired currency, fee 12500, tick spacing 60, the one-to-one provenance price, and the requester's verbatim economics object.\n- Notes describe the token as a plain fixed-supply ERC-20 with no fees, exemptions, owner, mint, pause, blocklist or upgrade path, and state that no initialization calls are needed.\n\n**Verification**\n\n- A schema check confirmed only the allowed top-level keys, string uint256 and address values, lowercase addresses, a 32-character-safe contract name, and notes under 4000 characters.\n- forge build compiled cleanly and forge test passed all 30 tests.\n- git status shows launch.json as the sole new file. No configuration, lib, or test files were touched.","treeHash":"465e352e499a95f0f695e693d249eea6f09947b0","usage":{"cachedInputTokens":209522,"inputTokens":162,"model":"claude-fable-5-1","outputTokens":3193,"runtime":"claude","turns":10,"wallClockMs":48771}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"fa99051b60a858d6","findings":[],"hash":"92f64a9feeaa801bb4cd85118287f30069c10e992726c6601a219ddf720ecfec","nodeId":"c5abccfa-baa0-4d96-a382-40e1af62aa58","outcome":"completed","summary":"The review is complete. No defects were found in the Math Precision, Boundary or Numerical Gap area, and the report is written to `.imd-findings.json` with an empty findings list and eight coverage rows.\n\n**What the code is.** CrawlHiveToken is an unmodified OpenZeppelin 5.4.0 ERC20 with a compile-time constant supply minted once in the constructor. It adds no arithmetic of its own beyond the supply constant, no external calls, no payable path, no fees, no burns and no owner.\n\n**What I checked and how.**\n- Diffed all five vendored OpenZeppelin files against the pinned upstream commit. All are byte-identical, so the inherited transfer and allowance math is the audited library code.\n- Verified the supply constant is exactly 1e27 with no overflow, and that it agrees with the brief, the README and the declared decimals. The aderyn \"large numeric literal\" lead is a compile-time constant and not a defect.\n- Wrote and ran a scratch Foundry suite covering zero, one wei, exact-balance, balance-plus-one, max uint256, self-transfer, zero-address, infinite allowance, max-minus-one allowance, exact and over-allowance transferFrom, and allowance preservation when a balance check reverts. Two fuzz properties ran over 2,000 cases each: balance conservation summing to the supply, and allowance decrement equal to the spent value. All 14 tests passed.\n- The existing project suite also passes with 30 tests.\n\n**Coverage.** All three listed entry points are marked `holds`, with five additional invariant rows for the supply constant, decimals, supply immutability, the absence of external boundaries, and the numerical-gap seams. Nothing was left unreached. The scratch test directory was removed, so the tree is unchanged apart from the findings file.","treeHash":null,"usage":{"cachedInputTokens":501511,"inputTokens":290,"model":"claude-fable-5-1","outputTokens":9466,"runtime":"claude","turns":16,"wallClockMs":128469}},{"artifacts":[],"attempt":1,"bundleHash":"c9e2ac28f2cde0f9d6f690bca083dd745e9e3d297f9767ee711f14acfb5fa65e","device":"30bcdea6dcb9ee40","findings":[],"hash":"cbc11e6524eff0738f8bac787d7e8b419007a4b370d2aafa47a476df73eef8f0","nodeId":"c04d5d56-132e-4bc6-b5cd-7cfb843c44d2","outcome":"completed","summary":"Everything passes and only files under test/ changed. No defects were found in the token, so no findings file was written.\n\n**What I added**\n\n- `test/CrawlHiveToken.invariant.t.sol`: a handler with the deployer plus five holders that drives transfer, approve and transferFrom with bounded inputs, and nine explicit failure handlers. These cover over-balance, over-allowance, the infinite allowance against an empty balance, the zero address as receiver, spender and sender, 22 would-be admin selectors from every actor, the deployer pulling without allowance, and ether sends. Each failure handler expects the exact ERC-6093 error. The handler keeps a ghost ledger of balances and allowances. Invariants check the supply is fixed, the actors' balances sum to the supply with nothing at the zero address or the contract, balances and allowances equal the ledger, metadata is immutable, and the token holds no ether. The run ends by checking both success and failure paths were exercised. Inline config sets 256 runs at depth 64 with fail-on-revert on.\n- `test/CrawlHiveToken.edges.t.sol`: 24 unit tests and 6 fuzz tests at 1000 runs for inputs the existing suite skipped. These include the supply literal, independent double deployment, deploying from the zero address, one wei above balance and allowance, the maximum amount, the same transfer twice, tokens stranded at the contract, zero-amount transferFrom without allowance, the allowance-before-balance check order, self-pulls, max-minus-one allowances, overwrite rather than accumulate approvals, directional allowances, the missing Approval event on transferFrom, and a fuzz over unknown selectors.\n\n**Results**\n\n| Suite | Tests | Result |\n| --- | --- | --- |\n| Existing unit and fuzz | 30 | pass |\n| Edge cases | 30 | pass |\n| Invariants, 256 runs × 64 calls | 1 | pass, 0 reverts, stable across two seeds |\n\n**One harness correction worth knowing.** A transferFrom from the zero address with a zero amount reverts with ERC20InvalidApprover rather than ERC20InvalidSender, because OpenZeppelin updates the allowance before the sender check. That is a refusal either way and is pinned as such in both new files.\n\n**Assessment of the implementation.** The token is unmodified OpenZeppelin 5.4 ERC20 with a constructor mint and a pure decimals override. The vendored library matches upstream, there is no privileged surface, and no property failed, so there is nothing to report.","treeHash":"d8ef3085dfeb3e411b5e0abdeb49662270e6cf23","usage":{"cachedInputTokens":691972,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":25944,"runtime":"claude","turns":24,"wallClockMs":372642}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"2b9b0095482c54e6","findings":[],"hash":"de5bc50e023e494fce48806c71782755ffe8bb328c6db6647c8b508795b26ed4","nodeId":"e72ae8d8-d990-4248-81b3-3bfdf9d2d90c","outcome":"completed","summary":"I found no defects in the economics area, so `.imd-findings.json` has an empty findings list plus a coverage row for each entry point and for the invariants I checked. The file is valid JSON, and no other file in the tree was changed.\n\n**What the code is:** `src/CrawlHiveToken.sol` is a plain ERC-20 built on the project's vendored OpenZeppelin v5 `ERC20`. Its constructor mints 1,000,000,000 × 10^18 once to `msg.sender`, and `decimals()` returns 18. Nothing else is overridden: there is no `_update` override, owner, mint function, pause, blocklist, fee or burn.\n\n**How it measures against the three guides:**\n- **Economic Security:** the supply is fixed. `_mint` is called only in the constructor, and no privileged path can move, freeze or create tokens.\n- **Invariants:** the total supply stays at exactly 1e27, and the decimals match the 18 the manifest will state.\n- **Flow Gap:** there is no logic that runs on transfer. The factory sending the swarm's share to the distributor, seeding the pool, forwarding the remainder, distributor claims and buying from or selling into the PoolManager all move exactly the amount stated.\n\n**Coverage:**\n- `approve`, `transfer` and `transferFrom` are all marked `holds`; I traced them through OpenZeppelin's `_approve`, `_spendAllowance` and `_update`.\n- `approve` has the usual ERC-20 risk where a spender can use the old allowance before a change lands. That applies to any ERC-20, not this token in particular, so it is not a finding.\n\n**Leads:**\n- The aderyn note (a large number written in the source at line 23) is only about how the number is written. The value is correct: 1,000,000,000 × 10^18.\n- Slither reported nothing.\n\n**What I could not check:** there is no `launch.json` yet, so I did not review the manifest. The project's own test suite passed 30 of 30. I did not run the separate launch test that is checked against (`Token.protected.t.sol`), because it imports pool-seeding code that isn't in this tree.","treeHash":null,"usage":{"cachedInputTokens":156048,"inputTokens":10,"model":"claude-opus-5-5","outputTokens":2409,"runtime":"claude","turns":5,"wallClockMs":28690}}],"verification":[{"checks":[{"durationMs":919,"exitCode":0,"name":"build","output":"Compiling 28 files with Solc 0.8.26\nSolc 0.8.26 finished in 818.58ms\nCompiler run successful!\n","passed":true},{"durationMs":97,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 30 tests for test/CrawlHiveToken.t.sol:CrawlHiveTokenTest\n[PASS] testFuzz_transferAboveBalanceReverts(uint256) (runs: 256, μ: 38883, ~: 39227)\n[PASS] testFuzz_transferConservesSupply(address,uint256) (runs: 256, μ: 83026, ~: 83407)\n[PASS] testFuzz_transferFromRespectsAllowance(uint256,uint256) (runs: 256, μ: 114312, ~: 93890)\n[PASS] test_RevertWhen_approveZeroSpender() (gas: 32948)\n[PASS] test_RevertWhen_callingUnknownFunction() (gas: 26593)\n[PASS] test_RevertWhen_sendingEther() (gas: 38815)\n[PASS] test_RevertWhen_transferExceedsBalance() (gas: 92667)\n[PASS] test_RevertWhen_transferFromEmptyAccount() (gas: 37780)\n[PASS] test_RevertWhen_transferFromExceedsAllowance() (gas: 87966)\n[PASS] test_RevertWhen_transferFromExceedsBalanceEvenWithAllowance() (gas: 93598)\n[PASS] test_RevertWhen_transferFromWithoutAllowance() (gas: 40420)\n[PASS] test_RevertWhen_transferToZeroAddress() (gas: 32982)\n[PASS] test_approveSetsAllowanceAndEmits() (gas: 64918)\n[PASS] test_constructorEmitsSingleMintTransfer() (gas: 8149)\n[PASS] test_constructorMintsWholeSupplyToDeployer() (gas: 17734)\n[PASS] test_create2DeploymentFromFactoryMintsToFactory() (gas: 890365)\n[PASS] test_deployScriptFunctionMintsToCaller() (gas: 1530943)\n[PASS] test_infiniteAllowanceIsNotDecremented() (gas: 120511)\n[PASS] test_launchFlowsMoveExactAmounts() (gas: 270228)\n[PASS] test_metadata() (gas: 53100)\n[PASS] test_noAdminCallIncreasesSupply() (gas: 668160)\n[PASS] test_noPrivilegedCallMovesOrFreezesAHolder() (gas: 446838)\n[PASS] test_runtimeCodeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 986005)\n[PASS] test_secondaryTransfersAreUntaxed() (gas: 175036)\n[PASS] test_totalSupplyIsExactlyOneBillionWithEighteenDecimals() (gas: 20858)\n[PASS] test_transferFromSpendsAllowanceExactly() (gas: 154958)\n[PASS] test_transferMovesExactAmountAndEmits() (gas: 87193)\n[PASS] test_transferToSelfKeepsBalance() (gas: 40700)\n[PASS] test_transferWholeBalance() (gas: 72334)\n[PASS] test_transferZeroAmountSucceeds() (gas: 44598)\nSuite result: ok. 30 passed; 0 failed; 0 skipped; finished in 6.44ms (23.06ms CPU time)\n\nRan 1 test suite in 7.29ms (6.44ms CPU time): 30 tests passed, 0 failed, 0 skipped (30 total tests)\n","passed":true},{"durationMs":47,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"CrawlHiveToken.approve(address,uint256)\",\"CrawlHiveToken.transfer(address,uint256)\",\"CrawlHiveToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":6,\"README.md\":143,\"foundry.toml\":24,\"script/DeployCrawlHive.s.sol\":25,\"src/CrawlHiveToken.sol\":34,\"test/CrawlHiveToken.t.sol\":410},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":463,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":218,"exitCode":0,"name":"aderyn","output":"[low] large-numeric-literal at src/CrawlHiveToken.sol:23: Large Numeric Literal","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"5e7ee148cf8ba185367d7b5eebbd4ab365ebec00a8c0418cfb48df094ebe2882","verifiedTreeHash":"c0fe430018816ee246b158e1b99d45308d28e29e","verifierVersion":"0.1.0+172610c0"},{"checks":[{"durationMs":876,"exitCode":0,"name":"build","output":"Compiling 28 files with Solc 0.8.26\nSolc 0.8.26 finished in 774.16ms\nCompiler run successful!\n","passed":true},{"durationMs":84,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 30 tests for test/CrawlHiveToken.t.sol:CrawlHiveTokenTest\n[PASS] testFuzz_transferAboveBalanceReverts(uint256) (runs: 256, μ: 38856, ~: 38584)\n[PASS] testFuzz_transferConservesSupply(address,uint256) (runs: 256, μ: 83114, ~: 83419)\n[PASS] testFuzz_transferFromRespectsAllowance(uint256,uint256) (runs: 256, μ: 117575, ~: 93902)\n[PASS] test_RevertWhen_approveZeroSpender() (gas: 32948)\n[PASS] test_RevertWhen_callingUnknownFunction() (gas: 26593)\n[PASS] test_RevertWhen_sendingEther() (gas: 38815)\n[PASS] test_RevertWhen_transferExceedsBalance() (gas: 92667)\n[PASS] test_RevertWhen_transferFromEmptyAccount() (gas: 37780)\n[PASS] test_RevertWhen_transferFromExceedsAllowance() (gas: 87966)\n[PASS] test_RevertWhen_transferFromExceedsBalanceEvenWithAllowance() (gas: 93598)\n[PASS] test_RevertWhen_transferFromWithoutAllowance() (gas: 40420)\n[PASS] test_RevertWhen_transferToZeroAddress() (gas: 32982)\n[PASS] test_approveSetsAllowanceAndEmits() (gas: 64918)\n[PASS] test_constructorEmitsSingleMintTransfer() (gas: 8149)\n[PASS] test_constructorMintsWholeSupplyToDeployer() (gas: 17734)\n[PASS] test_create2DeploymentFromFactoryMintsToFactory() (gas: 890365)\n[PASS] test_deployScriptFunctionMintsToCaller() (gas: 1530943)\n[PASS] test_infiniteAllowanceIsNotDecremented() (gas: 120511)\n[PASS] test_launchFlowsMoveExactAmounts() (gas: 270228)\n[PASS] test_metadata() (gas: 53100)\n[PASS] test_noAdminCallIncreasesSupply() (gas: 668160)\n[PASS] test_noPrivilegedCallMovesOrFreezesAHolder() (gas: 446838)\n[PASS] test_runtimeCodeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 986005)\n[PASS] test_secondaryTransfersAreUntaxed() (gas: 175036)\n[PASS] test_totalSupplyIsExactlyOneBillionWithEighteenDecimals() (gas: 20858)\n[PASS] test_transferFromSpendsAllowanceExactly() (gas: 154958)\n[PASS] test_transferMovesExactAmountAndEmits() (gas: 87193)\n[PASS] test_transferToSelfKeepsBalance() (gas: 40700)\n[PASS] test_transferWholeBalance() (gas: 72334)\n[PASS] test_transferZeroAmountSucceeds() (gas: 44598)\nSuite result: ok. 30 passed; 0 failed; 0 skipped; finished in 6.39ms (27.33ms CPU time)\n\nRan 1 test suite in 6.92ms (6.39ms CPU time): 30 tests passed, 0 failed, 0 skipped (30 total tests)\n","passed":true},{"durationMs":33,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"CrawlHiveToken.approve(address,uint256)\",\"CrawlHiveToken.transfer(address,uint256)\",\"CrawlHiveToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":6,\"README.md\":143,\"foundry.toml\":24,\"launch.json\":24,\"script/DeployCrawlHive.s.sol\":25,\"src/CrawlHiveToken.sol\":34,\"test/CrawlHiveToken.t.sol\":410},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"8f4fde171ec9078f108d87a875eb51dccc22c998e48200b15c56e8e02eb172d8","verifiedTreeHash":"465e352e499a95f0f695e693d249eea6f09947b0","verifierVersion":"0.1.0+172610c0"},{"checks":[{"durationMs":1693,"exitCode":0,"name":"build","output":"Compiling 30 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.58s\nCompiler run successful!\n","passed":true},{"durationMs":10026,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 30 tests for test/CrawlHiveToken.t.sol:CrawlHiveTokenTest\n[PASS] testFuzz_transferAboveBalanceReverts(uint256) (runs: 256, μ: 38867, ~: 39227)\n[PASS] testFuzz_transferConservesSupply(address,uint256) (runs: 256, μ: 83048, ~: 83413)\n[PASS] testFuzz_transferFromRespectsAllowance(uint256,uint256) (runs: 256, μ: 117859, ~: 118080)\n[PASS] test_RevertWhen_approveZeroSpender() (gas: 32948)\n[PASS] test_RevertWhen_callingUnknownFunction() (gas: 26593)\n[PASS] test_RevertWhen_sendingEther() (gas: 38815)\n[PASS] test_RevertWhen_transferExceedsBalance() (gas: 92667)\n[PASS] test_RevertWhen_transferFromEmptyAccount() (gas: 37780)\n[PASS] test_RevertWhen_transferFromExceedsAllowance() (gas: 87966)\n[PASS] test_RevertWhen_transferFromExceedsBalanceEvenWithAllowance() (gas: 93598)\n[PASS] test_RevertWhen_transferFromWithoutAllowance() (gas: 40420)\n[PASS] test_RevertWhen_transferToZeroAddress() (gas: 32982)\n[PASS] test_approveSetsAllowanceAndEmits() (gas: 64918)\n[PASS] test_constructorEmitsSingleMintTransfer() (gas: 8149)\n[PASS] test_constructorMintsWholeSupplyToDeployer() (gas: 17734)\n[PASS] test_create2DeploymentFromFactoryMintsToFactory() (gas: 890365)\n[PASS] test_deployScriptFunctionMintsToCaller() (gas: 1530943)\n[PASS] test_infiniteAllowanceIsNotDecremented() (gas: 120511)\n[PASS] test_launchFlowsMoveExactAmounts() (gas: 270228)\n[PASS] test_metadata() (gas: 53100)\n[PASS] test_noAdminCallIncreasesSupply() (gas: 668160)\n[PASS] test_noPrivilegedCallMovesOrFreezesAHolder() (gas: 446838)\n[PASS] test_runtimeCodeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 986005)\n[PASS] test_secondaryTransfersAreUntaxed() (gas: 175036)\n[PASS] test_totalSupplyIsExactlyOneBillionWithEighteenDecimals() (gas: 20858)\n[PASS] test_transferFromSpendsAllowanceExactly() (gas: 154958)\n[PASS] test_transferMovesExactAmountAndEmits() (gas: 87193)\n[PASS] test_transferToSelfKeepsBalance() (gas: 40700)\n[PASS] test_transferWholeBalance() (gas: 72334)\n[PASS] test_transferZeroAmountSucceeds() (gas: 44598)\nSuite result: ok. 30 passed; 0 failed; 0 skipped; finished in 35.66ms (75.95ms CPU time)\n\nRan 30 tests for test/CrawlHiveToken.edges.t.sol:CrawlHiveTokenEdgesTest\n[PASS] testFuzz_anyDeployerReceivesWholeSupply(uint160) (runs: 1000, μ: 12387, ~: 12383)\n[PASS] testFuzz_anyNonZeroReceiverGetsExactly(uint160,uint256) (runs: 1000, μ: 92892, ~: 93120)\n[PASS] testFuzz_approveThenPullLeavesExactRemainder(uint256,uint256) (runs: 1000, μ: 142057, ~: 144290)\n[PASS] testFuzz_chainOfTransfersConservesSupply(uint256,uint256,uint256) (runs: 1000, μ: 213798, ~: 216259)\n[PASS] testFuzz_unknownSelectorsRevert(bytes4,bytes) (runs: 1000, μ: 32343, ~: 32121)\n[PASS] testFuzz_zeroAddressIsNeverAValidReceiver(uint256) (runs: 1000, μ: 33530, ~: 33258)\n[PASS] test_RevertWhen_deployedFromZeroAddress() (gas: 4175)\n[PASS] test_RevertWhen_transferFromOneWeiAboveAllowance() (gas: 92550)\n[PASS] test_RevertWhen_transferFromToZeroAddress() (gas: 93377)\n[PASS] test_RevertWhen_transferFromZeroSenderEvenForZero() (gas: 37905)\n[PASS] test_RevertWhen_transferMaxUint() (gas: 38148)\n[PASS] test_RevertWhen_transferOneWeiAboveBalance() (gas: 92660)\n[PASS] test_allowanceIsCheckedBeforeBalance() (gas: 40532)\n[PASS] test_allowanceIsDirectional() (gas: 102698)\n[PASS] test_approveOverwritesRatherThanAccumulates() (gas: 89879)\n[PASS] test_approveSelfAndZeroAmountAreAllowed() (gas: 69897)\n[PASS] test_approveZeroRevokes() (gas: 130523)\n[PASS] test_defaultsAreZero() (gas: 45347)\n[PASS] test_fullRoundTripReturnsExactly() (gas: 180253)\n[PASS] test_infiniteAllowanceSurvivesRepeatedPulls() (gas: 173936)\n[PASS] test_maxMinusOneAllowanceIsDecremented() (gas: 123870)\n[PASS] test_ownerCanPullFromItselfOnlyWithSelfAllowance() (gas: 159116)\n[PASS] test_sameTransferTwiceFailsTheSecondTime() (gas: 97470)\n[PASS] test_supplyMatchesManifestLiteral() (gas: 28181)\n[PASS] test_transferFromBackToOwnerStillSpendsAllowance() (gas: 108367)\n[PASS] test_transferFromEmitsTransferButNoApproval() (gas: 123454)\n[PASS] test_transferFromZeroAmountNeedsNoAllowance() (gas: 62168)\n[PASS] test_transferOneWei() (gas: 77160)\n[PASS] test_transferToTokenContractIsAllowedAndStranded() (gas: 119748)\n[PASS] test_twoDeploymentsAreIndependent() (gas: 43188)\nSuite result: ok. 30 passed; 0 failed; 0 skipped; finished in 35.80ms (206.00ms CPU time)\n\nRan 1 test for test/CrawlHiveToken.invariant.t.sol:CrawlHiveTokenInvariantTest\n[PASS]\nCrawlHiveTokenInvariantTest invariants:\n[PASS] invariant_allowancesMatchGhostLedger\n[PASS] invariant_balancesMatchGhostLedger\n[PASS] invariant_metadataIsFixed\n[PASS] invariant_sumOfBalancesEqualsSupply\n[PASS] invariant_tokenHoldsNoEther\n[PASS] invariant_totalSupplyIsFixed\n CrawlHiveTokenInvariantTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭------------------+------------------------------------------------------+-------+---------+----------╮\n| Contract         | Selector                                             | Calls | Reverts | Discards |\n+======================================================================================================+\n| CrawlHiveHandler | adminCallReverts                                     | 1299  | 0       | 0        |\n|------------------+------------------------------------------------------+-------+---------+----------|\n| CrawlHiveHandler | approve                                              | 1225  | 0       | 0        |\n|------------------+------------------------------------------------------+-------+---------+----------|\n| CrawlHiveHandler | approveZeroSpenderReverts                            | 1321  | 0       | 0        |\n|------------------+------------------------------------------------------+-------+---------+----------|\n| CrawlHiveHandler | deployerPullWithoutAllowanceReverts                  | 1216  | 0       | 0        |\n|------------------+------------------------------------------------------+-------+---------+----------|\n| CrawlHiveHandler | sendEtherReverts                                     | 1287  | 0       | 0        |\n|------------------+------------------------------------------------------+-------+---------+----------|\n| CrawlHiveHandler | transfer                                             | 1288  | 0       | 0        |\n|------------------+------------------------------------------------------+-------+---------+----------|\n| CrawlHiveHandler | transferAboveBalanceReverts                          | 1246  | 0       | 0        |\n|------------------+------------------------------------------------------+-------+---------+----------|\n| CrawlHiveHandler | transferFrom                                         | 1335  | 0       | 0        |\n|------------------+------------------------------------------------------+-------+---------+----------|\n| CrawlHiveHandler | transferFromAboveAllowanceReverts                    | 1193  | 0       | 0        |\n|------------------+------------------------------------------------------+-------+---------+----------|\n| CrawlHiveHandler | transferFromAboveBalanceWithInfiniteAllowanceReverts | 1242  | 0       | 0        |\n|------------------+------------------------------------------------------+-------+---------+----------|\n| CrawlHiveHandler | transferFromToZeroReverts                            | 1251  | 0       | 0        |\n|------------------+------------------------------------------------------+-------+---------+----------|\n| CrawlHiveHandler | transferFromZeroSenderReverts                        | 1271  | 0       | 0        |\n|------------------+------------------------------------------------------+-------+---------+----------|\n| CrawlHiveHandler | transferToZeroReverts                                | 1210  | 0       | 0        |\n╰------------------+------------------------------------------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 9.92s (9.91s CPU time)\n\nRan 3 test suites in 9.92s (9.99s CPU time): 61 tests passed, 0 failed, 0 skipped (61 total tests)\n","passed":true},{"durationMs":42,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"CrawlHiveToken.approve(address,uint256)\",\"CrawlHiveToken.transfer(address,uint256)\",\"CrawlHiveToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":6,\"README.md\":143,\"foundry.toml\":24,\"script/DeployCrawlHive.s.sol\":25,\"src/CrawlHiveToken.sol\":34,\"test/CrawlHiveToken.edges.t.sol\":364,\"test/CrawlHiveToken.invariant.t.sol\":398,\"test/CrawlHiveToken.t.sol\":410},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"cbc11e6524eff0738f8bac787d7e8b419007a4b370d2aafa47a476df73eef8f0","verifiedTreeHash":"d8ef3085dfeb3e411b5e0abdeb49662270e6cf23","verifierVersion":"0.1.0+172610c0"}]}