{"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":"d8d99f89-79aa-4ebc-ac33-91cd2cf01502","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"16c564c558774d3eba38524309012c9b9e1b19dca75b7d7e9b8b1d1964ad1eff","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","subagents":3,"tools":[]},"key":"audit_economics","kind":"code","role":"review","skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"02b2254d754d888c65a111a57ea60c112d4f0aff786b6d720afafa9adf02fcb6","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","subagents":3,"tools":[]},"key":"audit_flow","kind":"code","role":"review","skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"2bd997cb1ffe4c38318222445b47cceb7a0855207fb8498282e156f5164ff760","dependsOn":["build_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"b89279670f5a00f5d26286edee00c97dd158b997031350a01cafe6e0329ad227","skillId":"audit-judge","subagents":4,"tools":[]},"key":"audit_judge","kind":"code","role":"review","skillHash":"b89279670f5a00f5d26286edee00c97dd158b997031350a01cafe6e0329ad227","skillId":"audit-judge","state":"accepted"},{"acceptedSubmissionHash":"484031899cab31f0f1171117f412aa6fee522e534c04758c349c65223a4c1651","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","subagents":3,"tools":[]},"key":"audit_math","kind":"code","role":"review","skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"9cd3cd6259a1f1f2e97067de6ef0245b0e2d3f50aed609651ec2260c83f49187","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","subagents":3,"tools":[]},"key":"audit_permissions","kind":"code","role":"review","skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"6e61a33a8bb1b273c7dcd000956934da9453932fa402d98cddfd87fd608ebcd9","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"15b04fc8f60521936b9e2b37c09a804685ec689fc98cd5b04510d986d3106a15","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"15b04fc8f60521936b9e2b37c09a804685ec689fc98cd5b04510d986d3106a15","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":"b3271f68b75fc4a7dd2a84f89ecb4a6740cc05061069963ebd611865acb6f1f9","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"a14cc673e36a30f68f8fcb9d56e2278d9c8f20576053e5b1dc07e41016e2ea95","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"606842ccca0e7c5d3017a54684625438eab9b351eb51dcf0cf88c43d1ea41464","skillId":"write-foundry-tests","subagents":4,"tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"606842ccca0e7c5d3017a54684625438eab9b351eb51dcf0cf88c43d1ea41464","skillId":"write-foundry-tests","state":"accepted"}],"objective":"A custom token: Routr (ROUTR).\nToken name: Routr\nToken symbol: ROUTR\nToken supply: 1,000,000,000 with 18 decimals, all minted once to the deployer in the constructor.","parentJobId":null,"planHash":"ecba164fd7d0c47eb794a5390aee64797a4004f0f576def8f0bebbc1661bef55","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"d8d99f89-79aa-4ebc-ac33-91cd2cf01502","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-2688-routr"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"53910","feedbackHash":"1315ef9d5b0c428d5ad6f0510a54b384d85c419c4e2f88787171e3249aa157ac","nodeKey":"audit_economics","submissionHash":"16c564c558774d3eba38524309012c9b9e1b19dca75b7d7e9b8b1d1964ad1eff","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"50959","feedbackHash":"c8ef7b99bf17ad0ebad5ffce270f91bf27b75b4589e4f0e84e212cec905374a1","nodeKey":"audit_flow","submissionHash":"02b2254d754d888c65a111a57ea60c112d4f0aff786b6d720afafa9adf02fcb6","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52231","feedbackHash":"7ac6b38d85ff00a21d2c4c23ac23fd0be502c7170c5dcbe4429f36157e66d49f","nodeKey":"audit_judge","submissionHash":"2bd997cb1ffe4c38318222445b47cceb7a0855207fb8498282e156f5164ff760","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"50962","feedbackHash":"63fd8e25d31099481aa45b4744ebd262b3cccd2005b10bb831ad0f5e42d08d3d","nodeKey":"audit_math","submissionHash":"484031899cab31f0f1171117f412aa6fee522e534c04758c349c65223a4c1651","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"50974","feedbackHash":"3dac466a561904c817fae95e932b0692cc41b4916ce5005d668586385ce63cc2","nodeKey":"audit_permissions","submissionHash":"9cd3cd6259a1f1f2e97067de6ef0245b0e2d3f50aed609651ec2260c83f49187","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52656","feedbackHash":"ebffcca88a69ca5e4a1000ebc675ea3f40d850024073fe42826f6749791d7c6c","nodeKey":"build_contract_project","submissionHash":"6e61a33a8bb1b273c7dcd000956934da9453932fa402d98cddfd87fd608ebcd9","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"50990","feedbackHash":"4f5acf8e498566d967249c9ac6e953ff09f851f34e8daa9108c295e9c8649a32","nodeKey":"manifest","submissionHash":"b3271f68b75fc4a7dd2a84f89ecb4a6740cc05061069963ebd611865acb6f1f9","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52286","feedbackHash":"0b12a8e941f3945bf2f97dbcd968d70aa84fbebe3b4e40f458cd07e366c664d3","nodeKey":"write_foundry_tests","submissionHash":"a14cc673e36a30f68f8fcb9d56e2278d9c8f20576053e5b1dc07e41016e2ea95","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"1cbdf7afdcb85d4df36262d4228537af93ec505cc939e614d9c8256b1e43e2b0","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"468e82a89b9bfe18","findings":[],"hash":"02b2254d754d888c65a111a57ea60c112d4f0aff786b6d720afafa9adf02fcb6","nodeId":"a33cc2f4-0a22-4955-968b-c51519b4916a","outcome":"completed","summary":"**Result: no defects found in the control-flow area.** The findings file holds an empty list plus eight coverage rows, and no tracked file was changed.\n\n**What I checked**, following the Execution Trace, Periphery and First Principles guides:\n\n- **Routr.sol itself** is seventeen lines: an unmodified OpenZeppelin ERC-20 whose constructor mints exactly one billion tokens with 18 decimals to the deployer. The constructor is nonpayable, takes no arguments and makes no external calls, so the factory's CREATE2 deployment receives the whole supply.\n- **Execution trace** of all three entry points through the inherited code. Approve overwrites the allowance and rejects a zero spender. Transfer checks balance before an unchecked subtraction, credits exactly what it debits, and never touches total supply. TransferFrom spends allowance before moving tokens and rolls both back together on any revert. The only sentinel is the unlimited allowance, which behaves as documented.\n- **Periphery**: the five vendored OpenZeppelin files are byte-identical to upstream commit 69c8def5 (v5.1.0), fetched independently, so the hash file in the tree is not the only evidence. Context returns plain msg.sender with no forwarder logic.\n- **First principles and launch floor**: the runtime bytecode has no reachable CALL, DELEGATECALL, CALLCODE, CREATE or SELFDESTRUCT, is 1,752 bytes, and exposes only the standard ERC-20 surface plus a constant. Exact transfers mean the swarm share, pool seed and trader swaps cannot arrive short or revert.\n- **Verification**: the committed suite builds and passes offline (32 tests including fuzz and invariants). A scratch probe of my own also passed: CREATE2 deployment with a foreign tx.origin, redeploy at the same salt, deployment with value, exact allowance consumption, near-max finite allowance, and short or unknown calldata. The scratch file was removed afterwards.\n\n**Leads not promoted**: the aderyn large-numeric-literal line at src/Routr.sol:12 is cosmetic and the constant evaluates correctly to 10^27, so it is not a defect. The README names Ethereum as the intended chain; the launch chain comes from the job, not from the README, so this is documentation only.\n\n**Nothing left unreached** in the assigned area. The manifest step has not run yet, so there is no launch.json to check; when it is written it should carry an empty constructorArgs list and a totalSupply of 1000000000000000000000000000.","treeHash":null,"usage":{"cachedInputTokens":677520,"inputTokens":290,"model":"claude-fable-5-1","outputTokens":11221,"runtime":"claude","turns":24,"wallClockMs":181179}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"be306690d4a9deec","findings":[{"citation":"resolved","description":"Routr inherits OpenZeppelin v5.1.0 ERC20 unchanged. approve(spender, value) overwrites the allowance slot instead of adjusting it, so a spender that sees a holder's allowance-change transaction in the mempool can spend the current allowance first and then the replacement. This is inherent to the ERC-20 approve/transferFrom interface, is documented in README.md (\"After launch\"), and is not a defect of this code: the unlimited-allowance and exact-transfer behaviour that the Uniswap v4 PoolManager and the launch distributor rely on is correct. Recorded as a trust/usage note only; no code change is recommended. Holders should set a nonzero allowance to zero before replacing it, or approve only the amount a spender is about to use.","line":287,"path":"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol","reproduction":"Deploy Routr; holder H holds the supply. 1) H calls approve(S, 100e18). 2) H broadcasts approve(S, 50e18) intending to reduce. 3) S front-runs with transferFrom(H, S, 100e18): succeeds, allowance 0. 4) H's approve(S, 50e18) lands: allowance 50e18. 5) S calls transferFrom(H, S, 50e18): succeeds. Expected by H: S can take at most 50e18 after the reduction. Actual: S holds 150e18. Verified with a Foundry test (test_allowanceReplacementRace) that passes on this code, confirming the behaviour.","severity":"info","snippet":"        _allowances[owner][spender] = value;","title":"Standard ERC-20 allowance replacement race: a spender can consume the old and the new allowance when approve() overwrites a nonzero value"}],"hash":"16c564c558774d3eba38524309012c9b9e1b19dca75b7d7e9b8b1d1964ad1eff","nodeId":"cebbb928-a00c-4e98-902d-3bc94bee67a3","outcome":"completed","summary":"The review is complete and the findings file is written. The working tree is unchanged apart from the deliverable, which the repository already excludes from tracking.\n\n**Outcome: no defect found in the Routr token's economics.** The findings file at `.imd-findings.json` holds one info-level note and eleven coverage rows, all three verifier entry points marked `holds`.\n\n**What I checked, against the Economic Security, Invariant and Flow Gap guides:**\n\n- **Supply and mint.** The constructor mints exactly 10^27 minor units to the caller, once. Deployed via CREATE2 from a factory contract, the factory holds everything and the transaction origin holds nothing.\n- **Conservation.** No runtime path reaches mint or burn, and transfers to the zero address revert, so the sum of balances equals total supply forever. The existing stateful invariant suite passes with the pinned fuzz seed.\n- **Launch flows.** No tax, exemption list or hook exists. Factory to distributor, distributor to claimant, pool pushes and allowance-based pool pulls all produce balance deltas equal to the requested amount in a local probe.\n- **Privileged powers.** The compiled ABI has only the nine ERC-20 and metadata functions plus the supply constant. No owner, initializer, pause, blacklist, receive or fallback.\n- **Bytecode.** The protected floor's reachable-opcode walk, rerun locally, finds no DELEGATECALL, CALLCODE or SELFDESTRUCT. Runtime is under the EIP-170 limit.\n- **Dependency integrity.** All five vendored OpenZeppelin files hash identically to the pinned v5.1.0 commit on GitHub, and the project's checksum file passes.\n- **Static analysis leads.** Slither reported nothing. Aderyn's low-severity large-literal note is style only and the literal is already written with digit separators.\n\n**The one note recorded** is the standard ERC-20 allowance overwrite race, where a spender can consume both the old and the replacement allowance. It reproduces on this code, but it is inherent to the ERC-20 interface, documented in the README, and needs no change. I recorded it as info so the judge sees it was considered.\n\n**Not reached.** The full Uniswap v4 seed and swap in the protected harness cannot run here because the v4 sources and launch environment are not in the repository. A plain exact-transfer token has no mechanism that could fail there, but that run belongs to the verifier.","treeHash":null,"usage":{"cachedInputTokens":687564,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":14608,"runtime":"claude","turns":25,"wallClockMs":193324}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"4f2ce49dc630c86e","findings":[{"citation":"resolved","description":"Merged from audit_economics (2b7cd465...) and audit_permissions (94759fb0...): same root cause. Routr (src/Routr.sol) inherits OpenZeppelin v5.1.0 approve/_approve unchanged, and the vendored file matches lib/openzeppelin-contracts/SHA256SUMS. _approve overwrites the allowance slot rather than adjusting it, so a spender can spend the old allowance before a replacement lands and then spend the new one. Inherent to the ERC-20 interface, documented in README.md 'After launch' (zero the allowance first). Only a spender the holder already approved can do this, and the excess is bounded by the old allowance. Severity stays info: it breaks no launch flow, no Routr guarantee and no floor rule. Recorded as a usage note. It does not ask the author to change code, and adding non-standard allowance behaviour is not recommended.","line":287,"path":"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol","reproduction":"Reproduced with a Foundry test on this tree (forge test, PASS, confirming the behaviour). State: H holds 1,000e18 ROUTR. 1) H: approve(S, 100e18). 2) S: transferFrom(H, S, 100e18) succeeds, allowance 0. 3) H: approve(S, 50e18). 4) S: transferFrom(H, S, 50e18) succeeds. Expected by H, who meant to lower the cap: S takes at most 100e18 in total. Actual: balanceOf(S) == 150e18.","severity":"info","snippet":"        _allowances[owner][spender] = value;","title":"approve() overwrites the allowance, so a spender can front-run a re-approval and spend old plus new (standard ERC-20 property; no code change required)"}],"hash":"2bd997cb1ffe4c38318222445b47cceb7a0855207fb8498282e156f5164ff760","nodeId":"1e941fc4-55a0-4fc4-a67a-4a3012f390da","outcome":"completed","summary":"The review is finished and `.imd-findings.json` is written: one info finding, no blockers, and no repository files changed. `git status` is clean, so the findings file is git-ignored, but it exists and parses as valid JSON.\n\n- **Specialist findings:** the two reports of the allowance replacement race (`audit_economics` and `audit_permissions`) share one root cause, so I merged them into one info finding at `ERC20.sol:287`. My Foundry test reproduced it: after approve 100, spend 100, approve 50, spend 50, the spender holds 150e18. It's standard ERC-20 behaviour and the README documents it, so no code change is needed. There's no proof attached because proofs are only required for critical or high findings.\n- **Static analysis:** the aderyn large-literal warning is a false positive and is left out. `INITIAL_SUPPLY` is exactly 10^27.\n- **My own pass found nothing new:**\n    - `Routr` is unmodified OpenZeppelin v5.1.0 ERC20 plus a constructor mint, and the vendored files match their hashes.\n    - A contract deploying it through CREATE2 receives the full supply.\n    - The empty `constructorArgs` match the constructor, and `launch.json` reads as schema-valid.\n    - The runtime is 1,752 bytes, with no reachable call, create or `SELFDESTRUCT` opcodes and no admin functions, `receive` or `fallback`.\n- **Coverage:** `approve` is marked `finding` (ref 1); `transfer` and `transferFrom` are marked `holds`. I also added three invariant rows, all `holds`: fixed supply, deployability and no privileged behaviour.\n- **Tests:** all 46 existing tests pass, and my three scratch tests passed before I deleted them.\n- **Not run:** the protected launch suite needs the verifier's Uniswap v4 setup, which isn't in this repository. The real seed and swap flows are therefore unexercised, though nothing in the token could tax or block them, since transfers are exact.\n- **Stale docs (not reported as defects):** the README says the project doesn't supply a launch manifest, but `launch.json` is present. `REVIEW.md` says 31 unit/fuzz tests, while the suite now runs 46 tests in total.","treeHash":null,"usage":{"cachedInputTokens":175343,"inputTokens":10,"model":"claude-opus-5-5","outputTokens":6060,"runtime":"claude","turns":5,"wallClockMs":102400}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"3f6a9bdd601cb99f","findings":[],"hash":"484031899cab31f0f1171117f412aa6fee522e534c04758c349c65223a4c1651","nodeId":"6357852d-2f4e-4c95-ad82-c0fa7d66db0e","outcome":"completed","summary":"The review is complete. The findings file is in place and ignored by the repository's exclude list as the harness intends, and the tree holds no stray files.\n\n**Outcome: no defects found in the math area.** The findings file at `.imd-findings.json` holds an empty findings list and six coverage rows, all `holds`.\n\n**What was reviewed**\n\n- `src/Routr.sol` is a 17-line fixed-supply token on OpenZeppelin v5.1.0 ERC20. The vendored files match their recorded SHA-256 hashes.\n- The compiled ABI exposes only the nine standard ERC-20 functions plus the `INITIAL_SUPPLY` constant. There is no mint, burn, owner, pause, or callback path.\n\n**Math Precision pass.** The contract has no division, no scaling, no casts, and no fixed-point systems. The constant was computed by command and equals exactly 10^27, which fits in uint128 and is far below uint256. The aderyn large-literal lead is style only.\n\n**Boundary pass.** There are no external calls, no payable or fallback functions, no bytes decoding, and the only sentinel is the zero address, which reverts on every path. Max-uint, supply plus one, exact supply, zero, and one-wei inputs on each entry point behaved as specified.\n\n**Numerical Gap pass.** The unchecked subtraction and addition in the inherited transfer path are bounded by the preceding balance check and by total supply. A fuzz over the full amount and allowance domain, with the infinite-allowance sentinel and its neighbour at max minus one, matched the model in every run. Conservation of balances against total supply held in both the project's invariant suite and my scratch probes.\n\n**Evidence run**\n\n| Check | Result |\n| --- | --- |\n| Project build and test suite | 32 passed, 0 failed |\n| Scratch boundary and fuzz probes | 10 passed, 0 failed |\n| OpenZeppelin hash verification | all files OK |\n\nThe scratch test directory was removed afterward. Static analysis reported nothing at low impact or above beyond the literal-style note. Nothing outside the assigned area was unreached: the three entry points and the three invariants each have a coverage row with a reason.","treeHash":null,"usage":{"cachedInputTokens":672059,"inputTokens":50,"model":"claude-fable-5-1","outputTokens":11751,"runtime":"claude","turns":30,"wallClockMs":177508}},{"artifacts":[],"attempt":1,"bundleHash":"e9cd0b4853f3985dc3002768ead6380def65a31d4ae62359976ba0acdfdb7619","device":"4d6b0e34f0d3e310","findings":[],"hash":"6e61a33a8bb1b273c7dcd000956934da9453932fa402d98cddfd87fd608ebcd9","nodeId":"97019e82-7096-4e80-832c-eff1d445b1cb","outcome":"completed","summary":"Implemented Routr (ROUTR): 18 decimals, exactly 1,000,000,000 tokens minted once to the deployer. Dependencies are vendored, with deployment and operational documentation included.\n\nVerified with Solidity 0.8.26:\n\n- `forge build` passed.\n- `forge test` passed: 32 results, using the specified fuzz seed.\n- `forge fmt --check` passed.\n\nProtected integration tests require the verifier’s launch infrastructure and were not run locally.","treeHash":"86df8dc3514ce5ffc59c6bb872827775c1f8c02f","usage":{"cachedInputTokens":460416,"inputTokens":45632,"model":"gpt-6-astra","outputTokens":16213,"runtime":"codex","turns":5,"wallClockMs":479123}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"98b4506bef931d13","findings":[{"citation":"resolved","description":"Routr (src/Routr.sol:10, `contract Routr is ERC20 {`) inherits OpenZeppelin v5.1.0's approve/_approve unchanged. The approve <-> transferFrom pair is asymmetric: approve overwrites the row, transferFrom decrements it. A holder who lowers an existing non-zero allowance intends to cap the spender at the new value, but the spender who already holds the old allowance can consume it before the replacement lands and then consume the new one as well. This is inherent to the ERC-20 standard, OpenZeppelin v5 deliberately ships no increaseAllowance/decreaseAllowance, and README.md lines 105-109 already warn holders to zero the allowance first. It is recorded here for completeness of the Access Control / Asymmetry pass as a trust assumption on spenders, not as a defect that needs a fix. Only a spender the holder already trusted with the old amount can do this, and the loss is bounded by that old amount.","line":287,"path":"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol","reproduction":"State: holder H has 1,000e18 ROUTR and has called approve(S, 100e18). H then submits approve(S, 50e18) intending S to be able to take at most 50e18 more. S sees the pending approve and first calls transferFrom(H, S, 100e18) (succeeds, allowance H->S becomes 0), then after H's approve(S, 50e18) is mined calls transferFrom(H, S, 50e18) (succeeds). Expected by H: S obtains at most 100e18 in total. Actual: S obtains 150e18. Verified with a Foundry test on this tree (sequence approve 100e18 -> transferFrom 100e18 -> approve 50e18 -> transferFrom 50e18 leaves balanceOf(S) == 150e18).","severity":"info","snippet":"        _allowances[owner][spender] = value;","title":"approve() replaces the allowance in place, so a spender can front-run a re-approval and spend old plus new (standard ERC-20 property, documented in README; no code change recommended)"}],"hash":"9cd3cd6259a1f1f2e97067de6ef0245b0e2d3f50aed609651ec2260c83f49187","nodeId":"ca55a58d-988f-40a8-b13c-11fad1d4a11e","outcome":"completed","summary":"The permissions review of Routr is complete. The findings file is written and the tree is otherwise unchanged.\n\n**Result: no defect in the permission model.** Routr is OpenZeppelin v5.1.0 ERC20 with a single constructor mint and nothing else. There is no owner, role, initializer, pause, blacklist, mint, burn, upgrade, fallback or receive. Each of the three state-changing entry points acts only on the caller's own balance or allowance row.\n\nWhat I verified, against the Access Control, Trust Gap and Asymmetry guides:\n\n- **Entry points.** The compiled ABI has exactly the nine ERC-20 and metadata functions plus the supply constant. Every selector called from the deployer leaves the supply unchanged. Unknown selectors and ETH revert.\n- **Guard consistency.** Balances are written only through the inherited update path, reached from `transfer` with the caller as sender and from `transferFrom` after the allowance is spent. Allowances are written only by `approve` for the caller's own row and by the decrement inside `transferFrom`. No weaker writer exists.\n- **Deployer trust.** The constructor mints to msg.sender, which under the factory launch is the factory, not the transaction origin. After deployment the deployer has no power beyond an ordinary holder's, so the trust ends once the factory's one transaction distributes the supply. The deployer and a stranger both fail to pull a holder's balance without allowance.\n- **Bytecode.** An opcode walk of the runtime finds no CALL, STATICCALL, DELEGATECALL, CALLCODE, CREATE, CREATE2 or SELFDESTRUCT in reachable code, so no reentrancy or confused-deputy surface exists.\n- **Dependencies.** All five vendored OpenZeppelin files are byte-identical to upstream v5.1.0, fetched and diffed. The sender context is plain msg.sender, so no meta-transaction spoofing.\n- **Suite.** The full suite passes offline from a clean build with no environment variables.\n\nOne **info** item is recorded: the inherent ERC-20 approve replacement race, with a concrete sequence showing a spender obtaining 150e18 where the holder intended a cap of 100e18. It is a standard property the README already documents, and I recommend no code change. It is included so the Asymmetry pass on the approve and transferFrom pair is accounted for.\n\nCoverage in `.imd-findings.json` has eight rows: the three listed entry points all hold, plus rows for the constructor mint, absence of privileged entry points, bytecode safety, dependency integrity and the deployer trust assumption.\n\nOut of my area but noted for the manifest step: the constructor takes no arguments, so `constructorArgs` must be an empty list and `totalSupply` the exact 10^27 string. The scratch test I used was removed and build output cleaned. Only the findings file remains, which the repository's exclude list already covers.","treeHash":null,"usage":{"cachedInputTokens":990546,"inputTokens":354,"model":"claude-fable-5-1","outputTokens":17554,"runtime":"claude","turns":37,"wallClockMs":305847}},{"artifacts":[],"attempt":1,"bundleHash":"a88e4426cce344a63972ba0be371e464bb121f2e1960faa93d47f7874d14b79c","device":"fcb71e606c933181","findings":[],"hash":"a14cc673e36a30f68f8fcb9d56e2278d9c8f20576053e5b1dc07e41016e2ea95","nodeId":"5ff5cc33-32aa-43a0-8134-54f0376b5de8","outcome":"completed","summary":"I added a new test file, `test/RoutrLaunch.t.sol`, alongside the earlier contributor's tests, which I left unchanged. `forge build` succeeds, and `forge test` with the verifier's fuzz seed passes all 46 tests: the 32 that were already there and 14 new ones, with no failures or skips.\n\nI found no defects. Routr is OpenZeppelin's ERC-20 with one mint in the constructor, so I wrote no `.imd-findings.json`. One fuzz test failed on my first run, but the mistake was in my test setup, not the token. The test tried to fund an account with more tokens than the deployer still held after `setUp`. I fixed the test's input range and it passes.\n\n**New unit and fuzz tests (`RoutrLaunchTest`):**\n- **Launch deployment:** a stand-in factory deploys the token at a predicted address and receives the whole supply, and the person sending the transaction gets nothing. Deploying twice with the same salt reverts. A fuzz test then runs the whole launch in one call, with the pool share fuzzed from 0 to 90% of supply. The 10% swarm share, the pool seed and the remainder each arrive exactly, and a claim from the distributor arrives whole.\n- **Admin calls:** all 21 privileged calls the launch's protected test tries, with the same oversized arguments, fail from both a stranger and the deployer. Supply and the holder's balance are unchanged, and the holder can still transfer afterwards. A further fuzz test sends random calls that aren't part of the token's interface: each one reverts and nothing changes.\n- **Bytecode:** the deployed code contains no reachable `DELEGATECALL`, `CALLCODE` or `SELFDESTRUCT`, checked the same way the protected test checks it, and is within the 24,576-byte size limit.\n- **Edge cases:**\n  - Address(0) can't call `approve` or `transfer`.\n  - An allowance of max − 1 is reduced when spent, but the max allowance is not.\n  - Spending with exactly the allowance and exactly the balance works, and the next pull fails.\n  - Tokens sent to the token contract itself are stuck for good.\n  - Any approved amount is stored exactly.\n  - A pull larger than the owner's balance reverts with the balance error and leaves the allowance untouched.\n\n**New invariant suite (`RoutrOpenInvariantTest`):** 256 runs × 64 calls with no unexpected reverts. Balances spread across up to 64 addresses, including new ones and the token contract itself, with unlimited approvals mixed in. The random calls also include ones that must fail: spending over the allowance, sending to the zero address by either `transfer` or `transferFrom`, overdrawing, and approving the zero address. Each must revert with the exact expected error. After every sequence these hold:\n- Total supply never changes, and the balances of all addresses used add up to it.\n- Every balance and allowance matches an independent record kept by the test.\n- The zero address has no balance and no allowance either way.\n\nFuzz and invariant run counts are set in the test file itself, since `foundry.toml` is not mine to change. The new file is the only change and is not committed yet.","treeHash":"596ffbd3b7f281b7f9efc0b041e8d85188bf8cd1","usage":{"cachedInputTokens":375150,"inputTokens":20,"model":"claude-opus-5-5","outputTokens":13047,"runtime":"claude","turns":12,"wallClockMs":175465}},{"artifacts":[],"attempt":1,"bundleHash":"b91161de432557db96761f3f8e207dcaebf0231704ca6cb4bd3c60335a8c18ba","device":"1f805d33d69c340e","findings":[],"hash":"b3271f68b75fc4a7dd2a84f89ecb4a6740cc05061069963ebd611865acb6f1f9","nodeId":"a0247422-86df-4b66-8d25-4798bf01cf82","outcome":"completed","summary":"Created `launch.json` matching Routr’s constructor, exact supply, pool settings, and economics. No other submission files changed.\n\n`forge build` passed. `forge test` passed all 32 reported tests with the supplied fuzz seed. Manifest fields and constructor ABI checks also passed.","treeHash":"822b10d4ac9c6f8e7c9f96ad2d2a8fbe8605cffc","usage":{"cachedInputTokens":280960,"inputTokens":35619,"model":"gpt-6-astra","outputTokens":2433,"runtime":"codex","turns":4,"wallClockMs":77322}}],"verification":[{"checks":[{"durationMs":1241,"exitCode":0,"name":"build","output":"Compiling 27 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.15s\nCompiler run successful!\n","passed":true},{"durationMs":5310,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 31 tests for test/Routr.t.sol:RoutrTest\n[PASS] testFuzz_overdrawRevertsWithoutChangingBalances(uint256) (runs: 1024, μ: 69101, ~: 69414)\nLogs:\n  Bound result 2430312845639861313293375907548438443843243690707690\n\n[PASS] testFuzz_transferConservesSupply(address,uint256) (runs: 1024, μ: 92893, ~: 93254)\nLogs:\n  Bound result 683163384250912390001902247\n\n[PASS] testFuzz_transferFromMatchesBalanceAndAllowanceModel(uint256,uint256) (runs: 1024, μ: 148119, ~: 160885)\nLogs:\n  Bound result 872371103964581246874512653\n\n[PASS] test_approvalCanBeReplacedAndRevoked() (gas: 166395)\n[PASS] test_approvalDoesNotRequireCurrentBalance() (gas: 78638)\n[PASS] test_approvalToZeroSpenderReverts() (gas: 37594)\n[PASS] test_approveEmitsAndSetsAllowanceWithoutMovingTokens() (gas: 103740)\n[PASS] test_constructorEmitsOneMint() (gas: 9727)\n[PASS] test_deployerAndStrangerHaveNoAdministrativeEntryPoints() (gas: 1315385)\n[PASS] test_directDeploymentMintsToCaller() (gas: 20130)\n[PASS] test_factoryReceivesAllSupplyAndLaunchTransfersArriveWhole() (gas: 646923)\n[PASS] test_metadataAndInitialSupply() (gas: 107650)\n[PASS] test_nativeEtherIsRejected() (gas: 42641)\n[PASS] test_selfTransferPreservesBalanceAndEmitsEvent() (gas: 43696)\n[PASS] test_selfTransferStillChecksBalance() (gas: 35951)\n[PASS] test_transferEmitsEventAndMovesExactAmount() (gas: 91483)\n[PASS] test_transferEntireSupply() (gas: 161709)\n[PASS] test_transferFromByHolderStillRequiresAllowance() (gas: 35769)\n[PASS] test_transferFromCannotUseAnotherSpendersApproval() (gas: 103138)\n[PASS] test_transferFromConsumesAllowanceAndEmitsTransfer() (gas: 226975)\n[PASS] test_transferFromInfiniteAllowanceIsNotDecremented() (gas: 144241)\n[PASS] test_transferFromInsufficientAllowanceRevertsAtomically() (gas: 115680)\n[PASS] test_transferFromInsufficientBalanceRestoresAllowance() (gas: 126174)\n[PASS] test_transferFromSelfConsumesAllowanceWithoutChangingBalance() (gas: 105411)\n[PASS] test_transferFromToZeroRestoresAllowance() (gas: 114189)\n[PASS] test_transferToContractRequiresNoReceiverCallback() (gas: 272062)\n[PASS] test_transferToZeroRevertsEvenForZeroAmount() (gas: 71970)\n[PASS] test_transferWithoutBalanceReverts() (gas: 57449)\n[PASS] test_zeroTransferFromEmptyAccountEmitsEvent() (gas: 73400)\n[PASS] test_zeroTransferFromWithoutAllowanceSucceeds() (gas: 81426)\n[PASS] test_zeroTransferFromZeroSenderReverts() (gas: 35385)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 22.09ms (67.72ms CPU time)\n\nRan 1 test for test/Routr.invariant.t.sol:RoutrInvariantTest\n[PASS]\nRoutrInvariantTest invariants:\n[PASS] invariant_allowancesMatchModel\n[PASS] invariant_fixedSupplyAndBalancesMatchModel\n RoutrInvariantTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭--------------+----------------+-------+---------+----------╮\n| Contract     | Selector       | Calls | Reverts | Discards |\n+============================================================+\n| RoutrHandler | approve        | 4042  | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| RoutrHandler | rejectOverdraw | 4100  | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| RoutrHandler | transfer       | 4102  | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| RoutrHandler | transferFrom   | 4140  | 0       | 0        |\n╰--------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 0\n  Bound result 997700931777107664293388720\n  Bound result 5737\n  Bound result 6561\n  Bound result 997700931777107664293388717\n  Bound result 0\n  Bound result 9\n  Bound result 0\n  Bound result 0\n  Bound result 20000000000000000000\n  Bound result 1\n  Bound result 1455\n  Bound result 0\n  Bound result 6434\n  Bound result 0\n  Bound result 5\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 1016\n  Bound result 2204391264726303333110576\n  Bound result 5\n  Bound result 0\n  Bound result 0\n  Bound result 2514000704\n  Bound result 952795438680221603875\n  Bound result 1\n  Bound result 1047329436464\n  Bound result 0\n  Bound result 555\n  Bound result 0\n  Bound result 2\n  Bound result 524\n  Bound result 997700931777107664293388719\n  Bound result 125394674590193414193176\n  Bound result 6000000000000000000\n  Bound result 37671418194559531963790\n  Bound result 211\n  Bound result 16558812844\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 5.18s (5.17s CPU time)\n\nRan 2 test suites in 5.18s (5.20s CPU time): 32 tests passed, 0 failed, 0 skipped (32 total tests)\n","passed":true},{"durationMs":82,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Routr.approve(address,uint256)\",\"Routr.transfer(address,uint256)\",\"Routr.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":3,\"DEPENDENCIES.md\":31,\"README.md\":116,\"REVIEW.md\":52,\"foundry.toml\":25,\"src/Routr.sol\":17,\"test/Routr.invariant.t.sol\":110,\"test/Routr.t.sol\":394},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":567,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":278,"exitCode":0,"name":"aderyn","output":"[low] large-numeric-literal at src/Routr.sol:12: Large Numeric Literal","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"6e61a33a8bb1b273c7dcd000956934da9453932fa402d98cddfd87fd608ebcd9","verifiedTreeHash":"86df8dc3514ce5ffc59c6bb872827775c1f8c02f","verifierVersion":"0.1.0+d372f99e"},{"checks":[{"durationMs":1643,"exitCode":0,"name":"build","output":"Compiling 28 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.57s\nCompiler run successful!\n","passed":true},{"durationMs":6922,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 31 tests for test/Routr.t.sol:RoutrTest\n[PASS] testFuzz_overdrawRevertsWithoutChangingBalances(uint256) (runs: 1024, μ: 69101, ~: 69414)\nLogs:\n  Bound result 115792089237316195423570985008687907853269984665639564039457584007913169588386\n\n[PASS] testFuzz_transferConservesSupply(address,uint256) (runs: 1024, μ: 93021, ~: 93254)\nLogs:\n  Bound result 25035452576953324332015481\n\n[PASS] testFuzz_transferFromMatchesBalanceAndAllowanceModel(uint256,uint256) (runs: 1024, μ: 148562, ~: 160873)\nLogs:\n  Bound result 872371103964581246874512653\n\n[PASS] test_approvalCanBeReplacedAndRevoked() (gas: 166395)\n[PASS] test_approvalDoesNotRequireCurrentBalance() (gas: 78638)\n[PASS] test_approvalToZeroSpenderReverts() (gas: 37594)\n[PASS] test_approveEmitsAndSetsAllowanceWithoutMovingTokens() (gas: 103740)\n[PASS] test_constructorEmitsOneMint() (gas: 9727)\n[PASS] test_deployerAndStrangerHaveNoAdministrativeEntryPoints() (gas: 1315385)\n[PASS] test_directDeploymentMintsToCaller() (gas: 20130)\n[PASS] test_factoryReceivesAllSupplyAndLaunchTransfersArriveWhole() (gas: 646923)\n[PASS] test_metadataAndInitialSupply() (gas: 107650)\n[PASS] test_nativeEtherIsRejected() (gas: 42641)\n[PASS] test_selfTransferPreservesBalanceAndEmitsEvent() (gas: 43696)\n[PASS] test_selfTransferStillChecksBalance() (gas: 35951)\n[PASS] test_transferEmitsEventAndMovesExactAmount() (gas: 91483)\n[PASS] test_transferEntireSupply() (gas: 161709)\n[PASS] test_transferFromByHolderStillRequiresAllowance() (gas: 35769)\n[PASS] test_transferFromCannotUseAnotherSpendersApproval() (gas: 103138)\n[PASS] test_transferFromConsumesAllowanceAndEmitsTransfer() (gas: 226975)\n[PASS] test_transferFromInfiniteAllowanceIsNotDecremented() (gas: 144241)\n[PASS] test_transferFromInsufficientAllowanceRevertsAtomically() (gas: 115680)\n[PASS] test_transferFromInsufficientBalanceRestoresAllowance() (gas: 126174)\n[PASS] test_transferFromSelfConsumesAllowanceWithoutChangingBalance() (gas: 105411)\n[PASS] test_transferFromToZeroRestoresAllowance() (gas: 114189)\n[PASS] test_transferToContractRequiresNoReceiverCallback() (gas: 272062)\n[PASS] test_transferToZeroRevertsEvenForZeroAmount() (gas: 71970)\n[PASS] test_transferWithoutBalanceReverts() (gas: 57449)\n[PASS] test_zeroTransferFromEmptyAccountEmitsEvent() (gas: 73400)\n[PASS] test_zeroTransferFromWithoutAllowanceSucceeds() (gas: 81426)\n[PASS] test_zeroTransferFromZeroSenderReverts() (gas: 35385)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 68.07ms (202.80ms CPU time)\n\nRan 13 tests for test/RoutrLaunch.t.sol:RoutrLaunchTest\n[PASS] testFuzz_approveStoresExactValue(address,address,uint256) (runs: 1000, μ: 71962, ~: 72314)\n[PASS] testFuzz_launchFlowsArriveWhole(bytes32,uint256) (runs: 1000, μ: 873661, ~: 874626)\nLogs:\n  Bound result 8926\n\n[PASS] testFuzz_transferFromOverBalanceRevertsWithBalanceError(uint256,uint256) (runs: 1000, μ: 186790, ~: 187583)\nLogs:\n  Bound result 223002706694146394652567121\n  Bound result 63584649642595142473195087221626428850774521697\n\n[PASS] testFuzz_unknownCalldataRevertsAndChangesNothing(bytes,address) (runs: 1000, μ: 59459, ~: 59229)\n[PASS] test_allowanceOneBelowMaxIsDecremented() (gas: 125066)\n[PASS] test_approveFromZeroAddressCallerIsImpossible() (gas: 33096)\n[PASS] test_create2DeploymentLandsAtPredictedAddressAndMintsToFactory() (gas: 752908)\n[PASS] test_create2SameSaltTwiceReverts() (gas: 742238)\n[PASS] test_floorAdminSelectorsDoNothing() (gas: 1984279)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 2479691)\n[PASS] test_tokensSentToTheTokenContractAreStuck() (gas: 124929)\n[PASS] test_transferFromWithExactAllowanceAndExactBalance() (gas: 187506)\n[PASS] test_transferFromZeroAddressCallerIsImpossible() (gas: 33100)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 74.23ms (268.79ms CPU time)\n\nRan 1 test for test/Routr.invariant.t.sol:RoutrInvariantTest\n[PASS]\nRoutrInvariantTest invariants:\n[PASS] invariant_allowancesMatchModel\n[PASS] invariant_fixedSupplyAndBalancesMatchModel\n RoutrInvariantTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭--------------+----------------+-------+---------+----------╮\n| Contract     | Selector       | Calls | Reverts | Discards |\n+============================================================+\n| RoutrHandler | approve        | 4042  | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| RoutrHandler | rejectOverdraw | 4100  | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| RoutrHandler | transfer       | 4102  | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| RoutrHandler | transferFrom   | 4140  | 0       | 0        |\n╰--------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 0\n  Bound result 997700931777107664293388720\n  Bound result 5737\n  Bound result 6559\n  Bound result 997700931777107664293395276\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 100\n  Bound result 11\n  Bound result 1\n  Bound result 11\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 14\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 2204391264726303333598826\n  Bound result 6\n  Bound result 0\n  Bound result 14\n  Bound result 0\n  Bound result 1112899692998566781944826\n  Bound result 5\n  Bound result 1047329436464\n  Bound result 0\n  Bound result 111\n  Bound result 0\n  Bound result 123000000000000000000\n  Bound result 524\n  Bound result 997700931777107664293395376\n  Bound result 1042532979359375531609118\n  Bound result 9000\n  Bound result 690467262849954748258030\n  Bound result 1719639407\n  Bound result 16558812844\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 5.07s (5.07s CPU time)\n\nRan 1 test for test/RoutrLaunch.t.sol:RoutrOpenInvariantTest\n[PASS]\nRoutrOpenInvariantTest invariants:\n[PASS] invariant_allowancesMatchGhost\n[PASS] invariant_noAllowanceForZeroAddress\n[PASS] invariant_supplyIsFixedAndFullyAccounted\n RoutrOpenInvariantTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭------------------+--------------------+-------+---------+----------╮\n| Contract         | Selector           | Calls | Reverts | Discards |\n+====================================================================+\n| RoutrOpenHandler | approve            | 2012  | 0       | 0        |\n|------------------+--------------------+-------+---------+----------|\n| RoutrOpenHandler | approveZeroSpender | 2090  | 0       | 0        |\n|------------------+--------------------+-------+---------+----------|\n| RoutrOpenHandler | overdraw           | 2054  | 0       | 0        |\n|------------------+--------------------+-------+---------+----------|\n| RoutrOpenHandler | overspendAllowance | 2052  | 0       | 0        |\n|------------------+--------------------+-------+---------+----------|\n| RoutrOpenHandler | sendToZero         | 2093  | 0       | 0        |\n|------------------+--------------------+-------+---------+----------|\n| RoutrOpenHandler | transfer           | 4060  | 0       | 0        |\n|------------------+--------------------+-------+---------+----------|\n| RoutrOpenHandler | transferFrom       | 2023  | 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 0\n  Bound result 127\n  Bound result 115792089237316195423570985008687907853269984665640564039457584007913129639935\n  Bound result 24576\n  Bound result 0\n  Bound result 1313373042\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 5842\n  Bound result 0\n  Bound result 5\n  Bound result 10000000000000000000\n  Bound result 1000\n  Bound result 0\n  Bound result 999999989999999999999999872\n  Bound result 0\n  Bound result 0\n  Bound result 1\n  Bound result 1000000000\n  Bound result 8776\n  Bound result 9000\n  Bound result 0\n  Bound result 24576\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 7807\n  Bound result 0\n  Bound result 4895\n  Bound result 0\n  Bound result 2633\n  Bound result 3773\n  Bound result 0\n  Bound result 0\n  Bound result 6000000000000000000\n  Bound result 5\n  Bound result 3\n  Bound result 0\n  Bound result 20000000000000000000\n  Bound result 17992\n  Bound result 822333294739597949471917823180105001410001\n  Bound result 1\n  Bound result 7161\n  Bound result 1529\n  Bound result 0\n  Bound result 254\n  Bound result 1719639407\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 6.79s (6.79s CPU time)\n\nRan 4 test suites in 6.80s (12.00s CPU time): 46 tests passed, 0 failed, 0 skipped (46 total tests)\n","passed":true},{"durationMs":36,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Routr.approve(address,uint256)\",\"Routr.transfer(address,uint256)\",\"Routr.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":3,\"DEPENDENCIES.md\":31,\"README.md\":116,\"REVIEW.md\":52,\"foundry.toml\":25,\"src/Routr.sol\":17,\"test/Routr.invariant.t.sol\":110,\"test/Routr.t.sol\":394,\"test/RoutrLaunch.t.sol\":461},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"a14cc673e36a30f68f8fcb9d56e2278d9c8f20576053e5b1dc07e41016e2ea95","verifiedTreeHash":"596ffbd3b7f281b7f9efc0b041e8d85188bf8cd1","verifierVersion":"0.1.0+d372f99e"},{"checks":[{"durationMs":1218,"exitCode":0,"name":"build","output":"Compiling 27 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.12s\nCompiler run successful!\n","passed":true},{"durationMs":5208,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 31 tests for test/Routr.t.sol:RoutrTest\n[PASS] testFuzz_overdrawRevertsWithoutChangingBalances(uint256) (runs: 1024, μ: 69101, ~: 69414)\nLogs:\n  Bound result 115792089237316195423570985008687907853269984665639564039477584007913129639935\n\n[PASS] testFuzz_transferConservesSupply(address,uint256) (runs: 1024, μ: 92893, ~: 93254)\nLogs:\n  Bound result 1121464958000\n\n[PASS] testFuzz_transferFromMatchesBalanceAndAllowanceModel(uint256,uint256) (runs: 1024, μ: 148119, ~: 160885)\nLogs:\n  Bound result 5\n\n[PASS] test_approvalCanBeReplacedAndRevoked() (gas: 166395)\n[PASS] test_approvalDoesNotRequireCurrentBalance() (gas: 78638)\n[PASS] test_approvalToZeroSpenderReverts() (gas: 37594)\n[PASS] test_approveEmitsAndSetsAllowanceWithoutMovingTokens() (gas: 103740)\n[PASS] test_constructorEmitsOneMint() (gas: 9727)\n[PASS] test_deployerAndStrangerHaveNoAdministrativeEntryPoints() (gas: 1315385)\n[PASS] test_directDeploymentMintsToCaller() (gas: 20130)\n[PASS] test_factoryReceivesAllSupplyAndLaunchTransfersArriveWhole() (gas: 646923)\n[PASS] test_metadataAndInitialSupply() (gas: 107650)\n[PASS] test_nativeEtherIsRejected() (gas: 42641)\n[PASS] test_selfTransferPreservesBalanceAndEmitsEvent() (gas: 43696)\n[PASS] test_selfTransferStillChecksBalance() (gas: 35951)\n[PASS] test_transferEmitsEventAndMovesExactAmount() (gas: 91483)\n[PASS] test_transferEntireSupply() (gas: 161709)\n[PASS] test_transferFromByHolderStillRequiresAllowance() (gas: 35769)\n[PASS] test_transferFromCannotUseAnotherSpendersApproval() (gas: 103138)\n[PASS] test_transferFromConsumesAllowanceAndEmitsTransfer() (gas: 226975)\n[PASS] test_transferFromInfiniteAllowanceIsNotDecremented() (gas: 144241)\n[PASS] test_transferFromInsufficientAllowanceRevertsAtomically() (gas: 115680)\n[PASS] test_transferFromInsufficientBalanceRestoresAllowance() (gas: 126174)\n[PASS] test_transferFromSelfConsumesAllowanceWithoutChangingBalance() (gas: 105411)\n[PASS] test_transferFromToZeroRestoresAllowance() (gas: 114189)\n[PASS] test_transferToContractRequiresNoReceiverCallback() (gas: 272062)\n[PASS] test_transferToZeroRevertsEvenForZeroAmount() (gas: 71970)\n[PASS] test_transferWithoutBalanceReverts() (gas: 57449)\n[PASS] test_zeroTransferFromEmptyAccountEmitsEvent() (gas: 73400)\n[PASS] test_zeroTransferFromWithoutAllowanceSucceeds() (gas: 81426)\n[PASS] test_zeroTransferFromZeroSenderReverts() (gas: 35385)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 24.16ms (76.12ms CPU time)\n\nRan 1 test for test/Routr.invariant.t.sol:RoutrInvariantTest\n[PASS]\nRoutrInvariantTest invariants:\n[PASS] invariant_allowancesMatchModel\n[PASS] invariant_fixedSupplyAndBalancesMatchModel\n RoutrInvariantTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭--------------+----------------+-------+---------+----------╮\n| Contract     | Selector       | Calls | Reverts | Discards |\n+============================================================+\n| RoutrHandler | approve        | 4042  | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| RoutrHandler | rejectOverdraw | 4100  | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| RoutrHandler | transfer       | 4102  | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| RoutrHandler | transferFrom   | 4140  | 0       | 0        |\n╰--------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 0\n  Bound result 997700931777107664293388720\n  Bound result 5737\n  Bound result 6561\n  Bound result 997700931777107664293388717\n  Bound result 0\n  Bound result 9\n  Bound result 0\n  Bound result 0\n  Bound result 20000000000000000000\n  Bound result 1\n  Bound result 1455\n  Bound result 0\n  Bound result 6434\n  Bound result 0\n  Bound result 5\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 1016\n  Bound result 2204391264726303333110576\n  Bound result 5\n  Bound result 0\n  Bound result 0\n  Bound result 2514000704\n  Bound result 952795438680221603875\n  Bound result 1\n  Bound result 1047329436464\n  Bound result 0\n  Bound result 555\n  Bound result 0\n  Bound result 2\n  Bound result 524\n  Bound result 997700931777107664293388719\n  Bound result 125394674590193414193176\n  Bound result 6000000000000000000\n  Bound result 37671418194559531963790\n  Bound result 211\n  Bound result 16558812844\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 5.10s (5.09s CPU time)\n\nRan 2 test suites in 5.10s (5.12s CPU time): 32 tests passed, 0 failed, 0 skipped (32 total tests)\n","passed":true},{"durationMs":29,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Routr.approve(address,uint256)\",\"Routr.transfer(address,uint256)\",\"Routr.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":3,\"DEPENDENCIES.md\":31,\"README.md\":116,\"REVIEW.md\":52,\"foundry.toml\":25,\"launch.json\":24,\"src/Routr.sol\":17,\"test/Routr.invariant.t.sol\":110,\"test/Routr.t.sol\":394},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"b3271f68b75fc4a7dd2a84f89ecb4a6740cc05061069963ebd611865acb6f1f9","verifiedTreeHash":"822b10d4ac9c6f8e7c9f96ad2d2a8fbe8605cffc","verifierVersion":"0.1.0+d372f99e"}]}