{"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":"79a829c2-0f09-426a-a50b-85e521e2040d","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"462148a7fc15b00341e326137168be1bda0d278b5feaea1101af31d73a182b8c","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":"ea7bac65272ece33d04f77d1c0d1e7a36ae83ab4f8c1c9392bf508e82db2e744","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":"579cae705d01474fd3256c6db2eda707f1416560affe95e5240c331dd4ceed04","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":"483ba446c9870dd14ccf894db3fe5467b4ed5144d5a7cdf09f87197c2c91b9cc","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":"b9367e1c284d6c9c00828a3affaefff57e4a7560ffaa574afc009a7ae78f35ba","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":"7d6d848f83f300a6931edb9e7677188656aa9ae361e92c717867018b372b02a3","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":"abea52b61a64ce0603512b12bb15779e20eb6042581f399a2eded26139b99ff7","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"3ecf8baeecc1e26da97de45f92cfaf76975c40005d1fd26380f4310505d08cd0","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"4c76766b00591dfe982fe85d3de589fdb2f810e5137c301155d1c5e36a1d3b23","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"4c76766b00591dfe982fe85d3de589fdb2f810e5137c301155d1c5e36a1d3b23","skillId":"write-foundry-tests","state":"accepted"}],"objective":"A custom token: GLOBAL INK (PAVE).\nToken name: GLOBAL INK\nToken symbol: PAVE\nToken supply: 1,000,000,000 with 18 decimals, all minted once to the deployer in the constructor.","parentJobId":null,"planHash":"ffdddbede356fe0520d28bc044c9b0dcfe78b04fa2150b79bd0ec024b429e88b","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"79a829c2-0f09-426a-a50b-85e521e2040d","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1640-global-ink"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"52609","feedbackHash":"41d4b704df2d472c2874db8e692bffcc3b04840ef0aa5dbcc669bc5362f84e5b","nodeKey":"audit_economics","submissionHash":"462148a7fc15b00341e326137168be1bda0d278b5feaea1101af31d73a182b8c","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52619","feedbackHash":"7f47f69fb97e407d8ea976feb8b4bfdf26bd2f28c6555876edef40632852f89e","nodeKey":"audit_flow","submissionHash":"ea7bac65272ece33d04f77d1c0d1e7a36ae83ab4f8c1c9392bf508e82db2e744","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51451","feedbackHash":"bb95014fa6259272eb262c56570428095558f0c701ba4eec4232a93f0a7f2cdf","nodeKey":"audit_judge","submissionHash":"579cae705d01474fd3256c6db2eda707f1416560affe95e5240c331dd4ceed04","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"50976","feedbackHash":"2c7ab46aabb3b453e234a9d9f26b065006692454ed841706d5b0bd607652e85f","nodeKey":"audit_math","submissionHash":"483ba446c9870dd14ccf894db3fe5467b4ed5144d5a7cdf09f87197c2c91b9cc","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51534","feedbackHash":"29762038a711947b8ccabd3c4151b083fc335277f71cd4af1d8b76060cb7a2fb","nodeKey":"audit_permissions","submissionHash":"b9367e1c284d6c9c00828a3affaefff57e4a7560ffaa574afc009a7ae78f35ba","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52182","feedbackHash":"f89a1b15f4cc103fd84ddf7226f63f935f050b8c3e3cfdb1196bee1b652be980","nodeKey":"build_contract_project","submissionHash":"7d6d848f83f300a6931edb9e7677188656aa9ae361e92c717867018b372b02a3","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52188","feedbackHash":"968171ceac51475f922f98c0b89b49f3d82ca26a12e01e20b4f63d622d0dde4b","nodeKey":"manifest","submissionHash":"abea52b61a64ce0603512b12bb15779e20eb6042581f399a2eded26139b99ff7","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51214","feedbackHash":"17107e9f47e240051c4d18ad9ff2e7a008f05bc223102a22341be05005a5d21c","nodeKey":"write_foundry_tests","submissionHash":"3ecf8baeecc1e26da97de45f92cfaf76975c40005d1fd26380f4310505d08cd0","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"9d9275688eb06266e95320f306904b523d8c539262b439af9e5d5fc701af64fc","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":"ebebe7c01a65506c35df56d6b147e1fa4a0da112ba6ca90406a205ef220ad63f","device":"dd2ee4882a1be950","findings":[{"description":"transferFrom checks the allowance and the balance but never checks that `from` is a real account. With amount 0 both checks pass for from == address(0) (allowance 0 >= 0, balance 0 >= 0), so any caller can make the token emit Transfer(address(0), to, 0) and Approval(address(0), caller, 0) at will. No balance or supply changes, so this is cosmetic: indexers and explorers that treat Transfer from the zero address as a mint will show zero-value mints to arbitrary recipients. It does not affect the launch floor and is not exploitable for value. Reported rather than asserted as correct; test_zeroAmountTransferFromZeroAddressCreatesNothing in test/PaveToken.edge.t.sol pins only the safety part (nothing is created, 1 wei from the zero address reverts).","line":87,"path":"src/PaveToken.sol","reproduction":"Deploy PaveToken. From any address call transferFrom(address(0), bob, 0). Expected (strict ERC-20 reading of a mint-shaped event): either revert, or no Transfer event with from == address(0) outside the constructor. Actual: the call returns true and emits Transfer(0x0000000000000000000000000000000000000000, bob, 0) plus Approval(0x0000000000000000000000000000000000000000, caller, 0). totalSupply and all balances stay unchanged.","severity":"info","title":"transferFrom(address(0), to, 0) succeeds and emits a mint-shaped Transfer(0x0, to, 0) event"}],"hash":"3ecf8baeecc1e26da97de45f92cfaf76975c40005d1fd26380f4310505d08cd0","nodeId":"e71ec448-68cd-4478-a5ab-052a64ebf1f4","outcome":"completed","summary":"The findings file is in place at the repository root; the harness deliberately excludes it from git, same as the `.imd/` reads, so that is expected.\n\nWork is complete. Summary:\n\n**Added two test files** under `test/` beside the existing suite, which I left untouched.\n\n- `test/PaveToken.invariants.t.sol` holds a handler with six actors (deployer plus five holders) and ghost variables for burned supply, transfer volume and a shadow allowance ledger. Seventeen handler functions drive bounded success paths, full-amount liveness paths, and explicit failure paths that assert the exact custom error and that nothing moved. Seven invariants run after every call: balances sum to the supply, supply equals initial minus burned and never grows, the zero address holds nothing, no balance exceeds supply, allowances match the shadow ledger, metadata is constant, and the token holds no ether and its runtime is unchanged. Run counts are set with inline config and the run uses fail-on-revert.\n- `test/PaveToken.edge.t.sol` adds 44 unit and fuzz tests for the inputs the original suite skipped: whole supply and one wei, burning everything, the uint256 ceiling on burn, transfer and increaseAllowance, max-minus-one versus unlimited allowances, repeated identical calls, self-allowance and self-recipient transferFrom, a stranger naming the zero address as owner, ether and unknown selectors, and a second independent instance.\n\n**Verification.** The full suite is 78 tests and passes with the verifier's fuzz seed and without it. Scratch checks confirmed every handler path fires and that the invariant harness fails on two mutant tokens, one that skips lowering supply on burn and one that never decrements a finite allowance.\n\n**One finding reported, severity info,** written to the findings file rather than asserted as correct. Anyone can call transferFrom with the zero address as owner and amount zero. It succeeds and emits a Transfer event from the zero address with value zero, which explorers read as a mint. No balance or supply changes and the launch floor is unaffected. The edge test pins only the safety half: nothing is created and one wei from the zero address reverts.\n\nNo other defects found. The contract has no privileged surface, no payable path, no delegatecall or selfdestruct, and its supply can only shrink.","treeHash":"d901e160b0c8d03b2abb36d017b11e9248dcd490","usage":{"cachedInputTokens":1753654,"inputTokens":450,"model":"claude-fable-5-1","outputTokens":35392,"runtime":"claude","turns":30,"wallClockMs":583468}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"8e25456c4ae69acf","findings":[],"hash":"462148a7fc15b00341e326137168be1bda0d278b5feaea1101af31d73a182b8c","nodeId":"672b3c50-e875-4609-9d9a-56e2a58f6489","outcome":"completed","summary":"Review complete. The findings file is written with an empty findings list and a full coverage record.\n\n**Outcome.** I found no defects in `src/PaveToken.sol` within the Economic Security, Invariant and Flow Gap areas. The token is a self-contained fixed-supply ERC-20 with a holder-only burn, no owner, no fees, no exemptions and no external calls.\n\n**What I checked**\n\n- Economic Security: no dependencies, oracles or callbacks to break. Every transfer path moves exactly the stated amount, so the swarm share, pool seed and trader round trips arrive whole. Burn can only shrink the caller's own balance, so no holder can be harmed by another's burn and nothing can grow the supply.\n- Invariants: a stateful fuzz campaign over transfer, approve plus transferFrom and burn across six actors never broke the conservation law that balances sum to totalSupply, which never exceeds the initial supply. Allowance paths were checked at the boundaries, including infinite allowance, overflow on increase and underflow on decrease.\n- Flow Gaps: I replayed the launch flow through a CREATE2 factory contract using the strict return-data check Uniswap v4 applies to token transfers. The 10/88/2 split and the trader buy and sell moved exact amounts with the supply unchanged.\n- Static analysis lead: the aderyn large-literal note points at the supply constant, which evaluates to exactly 1e27 as the manifest requires. Not a defect.\n\n**Coverage.** All six listed entry points are marked `holds`, plus rows for the conservation invariant, the mint invariant, the launch flow and the absence of receive or fallback. No entry point was left unreached.\n\nThe scratch tests were removed after running, so the tree is unchanged apart from the findings file.","treeHash":null,"usage":{"cachedInputTokens":467199,"inputTokens":226,"model":"claude-fable-5-1","outputTokens":10376,"runtime":"claude","turns":20,"wallClockMs":224358}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"9b06782c7559b54c","findings":[{"citation":"resolved","description":"Boundary guide, zero-input corner case. _transfer checks only `to`, never `from`. transferFrom(address(0), to, 0) passes _spendAllowance (allowance[0][caller] is 0 and 0 < 0 is false), passes the balance check (balanceOf[0] is 0 and 0 < 0 is false), and emits Transfer(address(0), to, 0). No balance or totalSupply changes, so there is no loss of funds and the sum-of-balances == totalSupply invariant holds. Indexers and explorers that treat a Transfer from the zero address as a mint will record a zero-value mint that the contract never performed; both OpenZeppelin v4 (\"transfer from the zero address\") and v5 (ERC20InvalidSender) reject this input. A non-zero amount from the zero address cannot pass (no allowance, no balance), so impact is limited to a spurious event. Minimal fix: add `if (from == address(0)) revert ZeroAddress();` at the top of _transfer, which changes no intended behaviour since no legitimate caller can act for the zero address.","line":131,"path":"src/PaveToken.sol","reproduction":"State: freshly deployed PaveToken, any caller `alice` with no balance and no allowance. Call: vm.prank(alice); token.transferFrom(address(0), bob, 0). Expected (per OZ/ERC-20 reference behaviour): revert (invalid sender). Actual: returns true and emits Transfer(from=0x0, to=bob, value=0) and Approval(0x0, alice, 0); totalSupply stays 1e27 and balanceOf(bob) stays 0. With amount = 1 the call reverts InsufficientAllowance(0x0, alice, 0, 1), confirming no value can move. Verified with a scratch Foundry test using vm.expectEmit on Transfer(address(0), bob, 0).","severity":"info","snippet":"        if (to == address(0)) revert ZeroAddress();","title":"_transfer does not reject from == address(0): anyone can emit a mint-shaped Transfer(address(0), to, 0) event"}],"hash":"483ba446c9870dd14ccf894db3fe5467b4ed5144d5a7cdf09f87197c2c91b9cc","nodeId":"ce784a03-3b6b-4010-8897-8f213933a51d","outcome":"completed","summary":"The findings file is valid, the snippet matches line 131, and the scratch directory is removed. The review is complete.\n\n**Result: no math defects found in PAVE.** The token has no division, scaling, casts or fixed-point arithmetic, so the Math Precision and Numerical Gap failure modes have nothing to attach to. Every unchecked block is preceded by the guard that makes it safe. The one item recorded is informational.\n\nWhat I checked, in `src/PaveToken.sol`:\n- **Supply constant** is exactly 1e27, below the int128 and uint128 limits Uniswap v4 uses, and the 10/88/2 percent launch splits divide it with no dust.\n- **transfer and transferFrom** keep the sum-of-balances invariant, including a full-balance self-transfer through both paths, since the receiver write re-reads storage.\n- **burn** cannot underflow totalSupply because every balance is bounded by it. Burning zero, the whole supply, supply plus one and max all behave as intended.\n- **Allowance math** decrements exactly, treats max as unlimited, converts max to finite on decrease, and reverts with a checked panic on max plus one in increaseAllowance. A revert in the transfer leg leaves the allowance untouched.\n- **Stateful invariant fuzzing** across four actors over transfer, transferFrom with finite and infinite allowances, and burn never broke the supply invariant.\n\nThe one recorded finding, severity info: a zero-value `transferFrom` naming the zero address as sender succeeds and emits a mint-shaped Transfer event. No value can move that way, so it only misleads indexers. The suggested fix is a sender-not-zero check in the internal transfer.\n\nCoverage in `.imd-findings.json` answers all six entry points plus three invariant rows. Nothing was left unreached.","treeHash":null,"usage":{"cachedInputTokens":716990,"inputTokens":354,"model":"claude-fable-5-1","outputTokens":13994,"runtime":"claude","turns":12,"wallClockMs":212124}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"79373c79d1351eba","findings":[{"citation":"resolved","description":"Merged from audit_permissions (low), audit_math (info), audit_flow (low) and write_foundry_tests (info): all four report the same root cause. `_transfer` (src/PaveToken.sol:130-140) validates only `to`, and `_approve` (src/PaveToken.sol:142-146) validates only `spender`; neither rejects the zero address as the source/owner. `_spendAllowance` (src/PaveToken.sol:148-155) lets amount 0 through with allowance 0 (`0 < 0` is false) and still calls `_approve`, so any unprivileged caller can run `transferFrom(address(0), to, 0)` and the contract emits `Approval(address(0), caller, 0)` followed by `Transfer(address(0), to, 0)`. The NatSpec (lines 5-8, 43-44) and the README promise the supply is minted exactly once and that the constructor's `Transfer(address(0), ...)` at line 66 is the only mint event; a Transfer whose `from` is the zero address is what explorers, indexers and supply trackers key on as a mint. No balance, allowance or totalSupply changes (any amount > 0 reverts with InsufficientAllowance because allowance[address(0)][*] and balanceOf[address(0)] are always 0), so no funds are at risk and the launch floor is unaffected. Severity recalibrated to low: spoofed zero-value mint events and zero-value Approval events from arbitrary owners, at will, from anyone. The reference implementation (OpenZeppelin ERC20 v4 'transfer from the zero address', v5 ERC20InvalidSender / ERC20InvalidApprover) rejects this input. Same mechanism, noted as context and not a separate finding: `transferFrom(victim, anyone, 0)` by a caller with no allowance emits `Approval(victim, caller, 0)`; ERC-20 permits zero-value transfers so that part is compliant. Minimal fix that preserves intended behaviour: add `if (from == address(0)) revert ZeroAddress();` at the top of `_transfer` (and optionally `if (owner == address(0)) revert ZeroAddress();` in `_approve`). No legitimate caller can act for the zero address, so nothing else changes; the existing test test_zeroAmountTransferFromZeroAddressCreatesNothing in test/PaveToken.edge.t.sol should be updated to expect the revert.","line":131,"path":"src/PaveToken.sol","reproduction":"State: freshly deployed PaveToken (deployer holds 1e27). Caller alice = 0xA11CE with no balance and no allowance; bob = 0xB0B. Call: vm.prank(alice); token.transferFrom(address(0), bob, 0). Expected: revert (the zero address is not a valid sender; only the constructor emits Transfer from address(0)). Actual: returns true, emits Approval(address(0), 0xA11CE, 0) then Transfer(address(0), 0xB0B, 0); totalSupply stays 1e27 and balanceOf(bob) stays 0. Reproduced in a scratch Foundry test with vm.expectEmit(true,true,true,true) for both events (passed on the current code). Control: vm.prank(alice); token.transferFrom(address(0), bob, 1) reverts with InsufficientAllowance(address(0), 0xA11CE, 0, 1), confirming no value path exists.","severity":"low","snippet":"        if (to == address(0)) revert ZeroAddress();","title":"transferFrom accepts from == address(0) at amount 0 and emits a mint-shaped Transfer(address(0), to, 0) plus Approval(address(0), caller, 0)"}],"hash":"579cae705d01474fd3256c6db2eda707f1416560affe95e5240c331dd4ceed04","nodeId":"f2a497cb-8c9b-47d6-bed6-42cf5fac47bb","outcome":"completed","summary":"The review is complete and written to `.imd-findings.json`. No source files were changed, and the scratch tests were removed.\n\n**Outcome:** PaveToken is a sound fixed-supply ERC-20. One low-severity defect survives, and it is the same root cause all four specialists reported.\n\n**Kept finding (merged from audit_permissions, audit_math, audit_flow and the test writer):**\n- `_transfer` in `src/PaveToken.sol:131` checks only the recipient, never the sender. Any caller can run `transferFrom(address(0), to, 0)` and the token emits a mint-shaped `Transfer(address(0), to, 0)` plus `Approval(address(0), caller, 0)`. I reproduced it with a Foundry test using expectEmit on both events, and confirmed that amount 1 reverts with InsufficientAllowance, so no value can move. Severity stays low: spoofed events only, no funds or supply at risk. Fix is a one-line sender zero-address check.\n\n**Dropped:** the aderyn large-numeric-literal lead at line 45. The constant is the readable supply expression and equals the manifest value.\n\n**Coverage:** all six entry points answered. Five hold, transferFrom carries the finding. I also recorded the constructor supply invariant, bytecode and size limits, and the manifest match (no constructor arguments, supply 1e27, decimals 18, name and symbol agree with launch.json). The existing 78 project tests pass.","treeHash":null,"usage":{"cachedInputTokens":373150,"inputTokens":194,"model":"claude-fable-5-1","outputTokens":9700,"runtime":"claude","turns":15,"wallClockMs":149766}},{"artifacts":[],"attempt":1,"bundleHash":"26210165910e53cc12abd9df9f3dbaee84e3eca705d29b33944486bf9e9f5ba1","device":"d11ea2b5e05fa7a8","findings":[],"hash":"7d6d848f83f300a6931edb9e7677188656aa9ae361e92c717867018b372b02a3","nodeId":"1201a599-3488-4713-849f-b0004f5c6ff5","outcome":"completed","summary":"The GLOBAL INK (PAVE) token is implemented, tested, documented and committed. A fresh offline clone of the commit builds, passes all 33 tests with the verifier's fuzz seed, and passes the format check.\n\n**What was delivered**\n\n- `src/PaveToken.sol`: a self-contained, fixed-supply ERC-20. The contract name is `PaveToken` (9 characters, manifest-safe). It returns name `GLOBAL INK`, symbol `PAVE`, 18 decimals, and mints the full supply once to the deployer in a zero-argument constructor that calls no other contract.\n- No owner, mint, pause, blacklist, freeze, seize, burnFrom, upgrade path or transfer fee exists, so the factory, distributor and PoolManager flows move exactly what they say. Holders can burn their own tokens, so supply can only shrink.\n- `test/PaveToken.t.sol`: 33 tests covering metadata, the exact supply, the mint to an EOA and to a contract deployer, every transfer and allowance success and failure path, burn, fuzzed supply conservation, and a bytecode scan for DELEGATECALL, CALLCODE and SELFDESTRUCT. Tests read no environment variables.\n- `README.md` documents behaviour, assumptions, the manifest's deployment parameters, the launch terms, and operational responsibilities, including that there is nothing to configure after launch.\n- `foundry.toml` pins solc 0.8.26 with `bytecode_hash = \"none\"`, the optimizer on, and ffi and filesystem permissions off. forge-std v1.11.0 is vendored as plain files under `lib/forge-std` with no nested git metadata, mapped by `remappings.txt`.\n\n**Verification**\n\n| Check | Result |\n| --- | --- |\n| `forge build` | passes |\n| `forge test` with the verifier seed, empty environment, offline fresh clone | 33 passed, 0 failed |\n| `forge fmt --check` | clean |\n| Scratch replay of the protected floor's admin-call, freeze and swarm-share probes | 3 passed |\n\nThe scratch replay could not exercise the PoolManager seed and swap, since the protected harness's v4 dependencies are not in this repository. A fee-free token with no exemptions has nothing that could make those fail.\n\nNo value was left open for the requester, so no blocked file was written.","treeHash":"38b06364e131d6fb36fd86d8bc534bfdc1810b89","usage":{"cachedInputTokens":896724,"inputTokens":546,"model":"claude-fable-5-1","outputTokens":21632,"runtime":"claude","turns":30,"wallClockMs":273998}},{"artifacts":[],"attempt":1,"bundleHash":"b016a7b30a5fd0c228638600b134a10fa3725bfd25d7b1e1f5c7bc129f0285f9","device":"d4b53d656a3fbe07","findings":[],"hash":"abea52b61a64ce0603512b12bb15779e20eb6042581f399a2eded26139b99ff7","nodeId":"88a802da-e2bf-4efd-be86-8733311f7477","outcome":"completed","summary":"Done. The manifest is written and verified against the accepted tree.\n\n**What I wrote:** `launch.json` at the repository root, kind \"custom_token\", describing the single accepted contract PaveToken. The token entry gives name GLOBAL INK, symbol PAVE, 18 decimals, an empty constructorArgs list, and a totalSupply of 1e27 minor units. The contracts list is empty because the accepted tree has no application contracts. The pool and economics objects are copied exactly from the launch terms, with IMD as the paired currency, fee 12500, tick spacing 60, and the one-to-one provenance price. The notes describe the token's fixed supply, lack of privileged powers, and holder-only burn.\n\n**How I checked it:**\n- The compiled PaveToken ABI has no constructor inputs, so the empty constructorArgs matches declaration order exactly.\n- The constructor mints `1_000_000_000 * 10 ** 18` to msg.sender once, which equals the manifest's totalSupply string.\n- The manifest has only the six schema keys, string uint256 values, numeric fee, tickSpacing and decimals, lowercase addresses, and notes under 4000 characters.\n- `forge build` compiled cleanly and `forge test` passed all 33 tests.\n- Git status shows launch.json as the only new file. Nothing else was changed.","treeHash":"a213bbb02b7c375c8d9155db569b701eccdcdebf","usage":{"cachedInputTokens":187181,"inputTokens":130,"model":"claude-fable-5-1","outputTokens":2605,"runtime":"claude","turns":8,"wallClockMs":40261}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"739094f0e08668ee","findings":[{"citation":"resolved","description":"_transfer validates only `to`, and _approve validates only `spender`; neither rejects the zero address as the token source/owner. Any caller can therefore run transferFrom(address(0), to, 0): _spendAllowance reads allowance[0][caller] == 0, passes `0 < 0`, and calls _approve(address(0), caller, 0), which emits Approval(owner = address(0)); _transfer then passes `0 < 0` and emits Transfer(from = address(0), to, 0). The contract documents that the supply is minted exactly once and that Transfer-from-zero is the mint event (constructor, line 66), yet an unprivileged caller can make it emit further Transfer logs whose `from` is the zero address, at will and for any `to`. No balance, allowance or totalSupply changes, so no funds are at risk: impact is limited to indexers/explorers that treat Transfer(from = 0) as a mint and to the broken 'one mint event' guarantee. The reference ERC-20 (OpenZeppelin v5) reverts on this input (ERC20InvalidApprover / ERC20InvalidSender). Minimal fix that preserves intended behaviour: in _transfer add `if (from == address(0)) revert ZeroAddress();` (and likewise reject owner == address(0) in _approve).","line":130,"path":"src/PaveToken.sol","reproduction":"Deploy PaveToken. From any account 0xBEEF with no balance and no allowance call transferFrom(address(0), 0xA11CE, 0). Expected: revert (zero address is not a valid sender; only the constructor emits Transfer from address(0)). Actual: returns true and emits Approval(address(0), 0xBEEF, 0) followed by Transfer(address(0), 0xA11CE, 0); totalSupply stays 1e27. Confirmed locally with a Foundry test using vm.expectEmit for both events (passed on the current code). Any amount > 0 reverts InsufficientAllowance(address(0), 0xBEEF, 0, amount), so the state is limited to amount == 0.","severity":"low","snippet":"    function _transfer(address from, address to, uint256 amount) private {\n        if (to == address(0)) revert ZeroAddress();","title":"transferFrom accepts from == address(0) with amount 0 and emits a mint-shaped Transfer(address(0), to, 0) plus Approval(address(0), spender, 0)"}],"hash":"b9367e1c284d6c9c00828a3affaefff57e4a7560ffaa574afc009a7ae78f35ba","nodeId":"69ad1a04-e719-4147-ae9b-f196b17b77d8","outcome":"completed","summary":"The review is written to `.imd-findings.json`: one low-severity finding, and coverage rows for all six entry points. No repository files were changed.\n\n**Finding (low):** `transferFrom(address(0), to, 0)` succeeds for any caller and emits `Approval(address(0), caller, 0)` followed by `Transfer(address(0), to, 0)`.\n- **Cause:** `_transfer` (`src/PaveToken.sol:130`) only rejects a zero `to`, and `_approve` only rejects a zero `spender`.\n- **Impact:** no balance, allowance or supply changes. The harm is limited to a mint-shaped log that anyone can emit, despite the contract's \"minted exactly once\" claim.\n- **Reach:** any amount above 0 reverts with `InsufficientAllowance`, so only the zero-amount call gets through.\n- **Reproduction:** I confirmed both events with a scratch Foundry test (since deleted). No proof test is attached to the finding, since it is not critical or high.\n- **Fix:** reject `from == address(0)` in `_transfer`, and a zero owner in `_approve`.\n\n**Coverage:**\n- `transferFrom` is marked `finding`.\n- `approve`, `burn`, `increaseAllowance`, `decreaseAllowance` and `transfer` are marked `holds`. Each touches only the caller's own balance or allowance, and the unchecked arithmetic is guarded by a prior check.\n- Two invariants are also recorded as `holds`: no privileged role exists after deployment, and `totalSupply` never increases and matches the sum of balances.\n\nThe existing test suite passes (33 tests). The supplied protected tests were not run. There is no `launch.json` in the tree, so no manifest was reviewed.","treeHash":null,"usage":{"cachedInputTokens":138399,"inputTokens":8,"model":"claude-opus-5-5","outputTokens":3799,"runtime":"claude","turns":4,"wallClockMs":41999}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"523b06a3dd921f5d","findings":[{"citation":"resolved","description":"Execution Trace / sentinel bypass. `_transfer` (src/PaveToken.sol:130-140) validates only `to`; `from` is never checked, and `_spendAllowance` (src/PaveToken.sol:148-155) lets a zero `amount` through with a zero allowance (`current < amount` is false for 0 < 0). So `transferFrom(address(0), X, 0)` from any caller succeeds, returns true, and emits `Approval(address(0), caller, 0)` followed by `Transfer(address(0), X, 0)`. A `Transfer` whose `from` is the zero address is the ERC-20 mint signal that explorers, indexers and supply trackers key on; the constructor is the only legitimate emitter (line 66), and the NatSpec at lines 5-8 promises the supply is minted exactly once. No balance or supply changes (the nonzero case reverts because balanceOf[address(0)] is always 0 and allowance[address(0)][*] is 0), so the impact is limited to spoofed events: off-chain tooling can be made to show arbitrary zero-value 'mints' to arbitrary addresses, and zero-value `Approval` events from any owner (including address(0)) to the caller. OpenZeppelin's `_transfer` rejects a zero `from` (`ERC20InvalidSender`) for exactly this reason. Fix that preserves intended behaviour: add `if (from == address(0)) revert ZeroAddress();` at the top of `_transfer`. Related note, same mechanism: because `_spendAllowance` calls `_approve` even when it consumes nothing, `transferFrom(victim, anyone, 0)` by a caller with no allowance emits `Approval(victim, caller, 0)` and `Transfer(victim, anyone, 0)`; the ERC-20 standard permits zero-value transfers, so that part is compliant and reported here only as context.","line":131,"path":"src/PaveToken.sol","reproduction":"State: fresh PaveToken (deployer holds 1e27). Call: vm.prank(attacker); token.transferFrom(address(0), attacker, 0). Expected (per NatSpec lines 5-8 and OpenZeppelin semantics): revert, since address(0) is not a valid sender. Actual: returns true and emits Approval(address(0), attacker, 0) then Transfer(address(0), attacker, 0); totalSupply stays 1e27. Verified with a Foundry test using vm.expectEmit for both events (test passed on the current code). Nonzero amount: transferFrom(address(0), attacker, 1) reverts with InsufficientAllowance(address(0), attacker, 0, 1), confirming no value path exists.","severity":"low","snippet":"        if (to == address(0)) revert ZeroAddress();","title":"transferFrom accepts from == address(0): anyone can emit a mint-shaped Transfer(address(0), to, 0) and Approval(address(0), caller, 0)"}],"hash":"ea7bac65272ece33d04f77d1c0d1e7a36ae83ab4f8c1c9392bf508e82db2e744","nodeId":"0b09ebe8-b5e8-46b2-87e4-481531bbceba","outcome":"completed","summary":"Review complete. The findings file is written and validated, and the scratch tests are removed so the tree has only `.imd-findings.json` added.\n\n**Result: one low finding, no critical, high or medium defects.** The token behaves as the brief and the protected floor require.\n\n**What I covered** (Execution Trace, Periphery, First Principles against `src/PaveToken.sol`):\n\n- **Every entry point traced** through checks, state writes and failure paths: `approve`, `burn`, `decreaseAllowance`, `increaseAllowance`, `transfer`, `transferFrom`, plus the constructor. All hold except one event-level quirk in `transferFrom`.\n- **Invariants confirmed** by reading every writer and by fuzzing: sum of balances equals total supply, supply never exceeds 1e27, every unchecked block is justified by that bound, self-transfer at full balance does not double count.\n- **Launch flows** move exactly what they say. There is no fee, exemption list, external call, owner, mint path, receive or fallback. The existing opcode-scan test passes and the interface matches the protected harness.\n- **Periphery** has nothing to review: the contract vendors no library and its three internals are private. The aderyn lead on line 45 is the literal 1e27 and is not a defect.\n\n**The finding (low):** `transferFrom(address(0), X, 0)` succeeds from any caller because `_transfer` validates only the recipient and a zero amount passes the allowance check with no allowance. It emits a mint-shaped `Transfer(address(0), X, 0)` and `Approval(address(0), caller, 0)`. No balance or supply changes, so the impact is spoofed events for indexers and explorers. The fix is a one-line zero-sender check at the top of `_transfer`, which is what OpenZeppelin does.\n\n**Coverage record** has eleven rows: six for the listed entry points, one for the constructor, three invariants and the static-analysis lead. None are marked unreached.","treeHash":null,"usage":{"cachedInputTokens":460870,"inputTokens":226,"model":"claude-fable-5-1","outputTokens":11919,"runtime":"claude","turns":20,"wallClockMs":169967}}],"verification":[{"checks":[{"durationMs":1823,"exitCode":0,"name":"build","output":"Compiling 23 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.74s\nCompiler run successful!\n","passed":true},{"durationMs":10111,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 33 tests for test/PaveToken.t.sol:PaveTokenTest\n[PASS] testFuzz_burnNeverIncreasesSupply(uint256) (runs: 256, μ: 60084, ~: 59950)\nLogs:\n  Bound result 191683966628376484181387944\n\n[PASS] testFuzz_transferBeyondBalanceReverts(uint256,uint256) (runs: 256, μ: 99431, ~: 100092)\nLogs:\n  Bound result 947\n  Bound result 25508914231168572650557645832590481151479263478037\n\n[PASS] testFuzz_transferConservesSupply(address,uint256) (runs: 256, μ: 88837, ~: 88788)\nLogs:\n  Bound result 1\n\n[PASS] testFuzz_transferFromRespectsAllowance(uint256,uint256) (runs: 256, μ: 115296, ~: 96312)\nLogs:\n  Bound result 947\n  Bound result 645807081566920310690827480\n\n[PASS] test_approveOverwritesPreviousAllowance() (gas: 92281)\n[PASS] test_approveRevertsForZeroSpender() (gas: 32483)\n[PASS] test_approveSetsAllowanceAndEmits() (gas: 64753)\n[PASS] test_burnMoreThanHeldReverts() (gas: 89564)\n[PASS] test_burnOnlyAffectsCaller() (gas: 111353)\n[PASS] test_burnReducesBalanceAndSupply() (gas: 111552)\n[PASS] test_constructorEmitsMintTransfer() (gas: 8106)\n[PASS] test_constructorMintsWholeSupplyToDeployer() (gas: 9961)\n[PASS] test_constructorTakesNoArgumentsAndHasNoMint() (gas: 186844)\n[PASS] test_decreaseAllowanceBelowZeroReverts() (gas: 85269)\n[PASS] test_increaseAllowanceOverflowReverts() (gas: 84834)\n[PASS] test_increaseAndDecreaseAllowance() (gas: 144799)\n[PASS] test_metadata() (gas: 23879)\n[PASS] test_mintsToAContractDeployer() (gas: 343880)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 740166)\n[PASS] test_supplyIsOneBillionWith18Decimals() (gas: 20551)\n[PASS] test_transferFromByNonSpenderCannotMoveHolderFunds() (gas: 95372)\n[PASS] test_transferFromEmptyAccountReverts() (gas: 37659)\n[PASS] test_transferFromRevertsBeyondAllowance() (gas: 87947)\n[PASS] test_transferFromRevertsBeyondBalanceEvenWithAllowance() (gas: 95168)\n[PASS] test_transferFromRevertsToZeroAddress() (gas: 89844)\n[PASS] test_transferFromRevertsWithoutAllowance() (gas: 40682)\n[PASS] test_transferFromSpendsAllowance() (gas: 151422)\n[PASS] test_transferFromWithInfiniteAllowanceDoesNotDecrement() (gas: 129910)\n[PASS] test_transferMovesExactAmountAndEmits() (gas: 86858)\n[PASS] test_transferRevertsOnInsufficientBalance() (gas: 92292)\n[PASS] test_transferRevertsToZeroAddress() (gas: 32526)\n[PASS] test_transferToSelfKeepsBalance() (gas: 95064)\n[PASS] test_transferZeroAmountSucceeds() (gas: 44338)\nSuite result: ok. 33 passed; 0 failed; 0 skipped; finished in 63.02ms (116.32ms CPU time)\n\nRan 44 tests for test/PaveToken.edge.t.sol:PaveTokenEdgeTest\n[PASS] testFuzz_approveIsIdempotent(uint256) (runs: 1000, μ: 89521, ~: 89725)\n[PASS] testFuzz_chainedTransfersConserveSupply(uint256,uint256,uint256) (runs: 1000, μ: 250461, ~: 255637)\nLogs:\n  Bound result 521326583675214501249955744\n  Bound result 173938378213349094\n  Bound result 160085126309803022\n\n[PASS] testFuzz_decreaseAllowanceExactBoundary(uint256,uint256) (runs: 1000, μ: 88954, ~: 86097)\n[PASS] testFuzz_finiteAllowanceSpendEmitsApprovalWithRemainder(uint256,uint256) (runs: 1000, μ: 130854, ~: 131082)\nLogs:\n  Bound result 14022\n  Bound result 10201\n\n[PASS] testFuzz_increaseAllowanceOverflowBoundary(uint256,uint256) (runs: 1000, μ: 95867, ~: 96434)\nLogs:\n  Bound result 1554616332845435934866526502031750806872656090405052261111090690\n\n[PASS] testFuzz_selfTransferBeyondBalanceReverts(uint256,uint256) (runs: 1000, μ: 97536, ~: 98207)\nLogs:\n  Bound result 537954095953572320084113985\n  Bound result 206909841771816092935714529302756\n\n[PASS] testFuzz_selfTransferIsIdentity(uint256,uint256) (runs: 1000, μ: 109351, ~: 109763)\nLogs:\n  Bound result 170243127465\n  Bound result 22974265402\n\n[PASS] testFuzz_supplyNeverGrowsAcrossBurnsAndTransfers(uint256,uint256,uint256) (runs: 1000, μ: 172435, ~: 173463)\nLogs:\n  Bound result 3810644090227461135\n  Bound result 1089483020331011450\n  Bound result 421376379831495783881579453\n\n[PASS] testFuzz_transferRoundTripRestoresBalances(uint256) (runs: 1000, μ: 118478, ~: 118411)\nLogs:\n  Bound result 70000000000000000000\n\n[PASS] testFuzz_unknownSelectorsNeverChangeState(bytes4,uint256) (runs: 1000, μ: 58574, ~: 58516)\n[PASS] test_allowanceIsPerSpenderAndPerOwner() (gas: 128834)\n[PASS] test_allowanceOfMaxMinusOneIsFiniteAndDecrements() (gas: 125260)\n[PASS] test_approveDoesNotMoveTokens() (gas: 71696)\n[PASS] test_burnDoesNotTouchAllowancesButStarvesThem() (gas: 193783)\n[PASS] test_burnFromEmptyAccountRevertsOnOneWei() (gas: 34991)\n[PASS] test_burnMaxUintReverts() (gas: 35359)\n[PASS] test_burnWholeSupplyLeavesNothingToMove() (gas: 91532)\n[PASS] test_burnZeroIsANoOpThatStillEmits() (gas: 43391)\n[PASS] test_decreaseAllowanceFromZeroByZeroSucceeds() (gas: 42535)\n[PASS] test_decreaseAllowanceRevertsForZeroSpender() (gas: 61910)\n[PASS] test_deployerIsWhoeverCreatesIt() (gas: 14411)\n[PASS] test_emptiedDeployerCannotSendOneWei() (gas: 87601)\n[PASS] test_holderCannotBeBurnedByAnyoneElse() (gas: 175528)\n[PASS] test_increaseAllowanceRevertsForZeroSpender() (gas: 34870)\n[PASS] test_increaseAllowanceToExactlyMaxSucceeds() (gas: 93041)\n[PASS] test_ownerCanTransferFromItselfOnlyWithSelfAllowance() (gas: 224638)\n[PASS] test_rejectsEmptyCalldataAndUnknownSelector() (gas: 48124)\n[PASS] test_rejectsEtherOnAnyFunction() (gas: 44687)\n[PASS] test_rejectsPlainEther() (gas: 38801)\n[PASS] test_runtimeCodeIsSmallAndStable() (gas: 6921)\n[PASS] test_sameApproveTwiceDoesNotAccumulate() (gas: 89504)\n[PASS] test_sameTransferTwiceSpendsTwice() (gas: 112117)\n[PASS] test_spendingFullAllowanceTwiceFailsTheSecondTime() (gas: 164372)\n[PASS] test_transferFromToOwnerKeepsBalanceButSpendsAllowance() (gas: 109671)\n[PASS] test_transferFromToSpenderCreditsSpender() (gas: 129626)\n[PASS] test_transferMaxUintReverts() (gas: 38141)\n[PASS] test_transferOneWeiThenTheRest() (gas: 107524)\n[PASS] test_transferWholeSupplyInOneCall() (gas: 79514)\n[PASS] test_twoInstancesAreIndependent() (gas: 71207)\n[PASS] test_unlimitedAllowanceCanMoveWholeSupply() (gas: 136903)\n[PASS] test_unlimitedAllowanceEmitsNoApprovalOnSpend() (gas: 119381)\n[PASS] test_unlimitedAllowanceStillBoundedByBalance() (gas: 95196)\n[PASS] test_zeroAmountTransferFromWithoutAllowanceSucceedsAndMovesNothing() (gas: 73316)\n[PASS] test_zeroAmountTransferFromZeroAddressCreatesNothing() (gas: 104126)\nSuite result: ok. 44 passed; 0 failed; 0 skipped; finished in 72.87ms (602.99ms CPU time)\n\nRan 1 test for test/PaveToken.invariants.t.sol:PaveTokenInvariantTest\n[PASS]\nPaveTokenInvariantTest invariants:\n[PASS] invariant_allowancesMatchShadowLedger\n[PASS] invariant_metadataIsConstant\n[PASS] invariant_noBalanceExceedsSupply\n[PASS] invariant_supplyEqualsSumOfBalances\n[PASS] invariant_supplyIsInitialMinusBurned\n[PASS] invariant_tokenHoldsNoEtherAndCodeIsStable\n[PASS] invariant_zeroAddressHoldsNothing\n PaveTokenInvariantTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭------------------+-----------------------------+-------+---------+----------╮\n| Contract         | Selector                    | Calls | Reverts | Discards |\n+=============================================================================+\n| PaveTokenHandler | approve                     | 928   | 0       | 0        |\n|------------------+-----------------------------+-------+---------+----------|\n| PaveTokenHandler | approveUnlimited            | 953   | 0       | 0        |\n|------------------+-----------------------------+-------+---------+----------|\n| PaveTokenHandler | approveZeroSpender          | 1002  | 0       | 0        |\n|------------------+-----------------------------+-------+---------+----------|\n| PaveTokenHandler | burn                        | 969   | 0       | 0        |\n|------------------+-----------------------------+-------+---------+----------|\n| PaveTokenHandler | burnFull                    | 979   | 0       | 0        |\n|------------------+-----------------------------+-------+---------+----------|\n| PaveTokenHandler | burnTooMuch                 | 961   | 0       | 0        |\n|------------------+-----------------------------+-------+---------+----------|\n| PaveTokenHandler | callWithEther               | 1001  | 0       | 0        |\n|------------------+-----------------------------+-------+---------+----------|\n| PaveTokenHandler | decreaseAllowance           | 1030  | 0       | 0        |\n|------------------+-----------------------------+-------+---------+----------|\n| PaveTokenHandler | increaseAllowance           | 1015  | 0       | 0        |\n|------------------+-----------------------------+-------+---------+----------|\n| PaveTokenHandler | transfer                    | 978   | 0       | 0        |\n|------------------+-----------------------------+-------+---------+----------|\n| PaveTokenHandler | transferFrom                | 964   | 0       | 0        |\n|------------------+-----------------------------+-------+---------+----------|\n| PaveTokenHandler | transferFromBeyondAllowance | 939   | 0       | 0        |\n|------------------+-----------------------------+-------+---------+----------|\n| PaveTokenHandler | transferFromBeyondBalance   | 935   | 0       | 0        |\n|------------------+-----------------------------+-------+---------+----------|\n| PaveTokenHandler | transferFromFull            | 923   | 0       | 0        |\n|------------------+-----------------------------+-------+---------+----------|\n| PaveTokenHandler | transferFull                | 952   | 0       | 0        |\n|------------------+-----------------------------+-------+---------+----------|\n| PaveTokenHandler | transferInsufficient        | 907   | 0       | 0        |\n|------------------+-----------------------------+-------+---------+----------|\n| PaveTokenHandler | transferToZero              | 948   | 0       | 0        |\n╰------------------+-----------------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 3\n  Bound result 1\n  Bound result 0\n  Bound result 0\n  Bound result 2\n  Bound result 2\n  Bound result 5\n  Bound result 100\n  Bound result 1\n  Bound result 2\n  Bound result 0\n  Bound result 2\n  Bound result 5\n  Bound result 2\n  Bound result 1\n  Bound result 5\n  Bound result 0\n  Bound result 3\n  Bound result 0\n  Bound result 4\n  Bound result 29740801712372974078906876412291616187117019296933918526065466329471297489938\n  Bound result 2\n  Bound result 0\n  Bound result 0\n  Bound result 12\n  Bound result 1\n  Bound result 0\n  Bound result 1\n  Bound result 2\n  Bound result 2\n  Bound result 5\n  Bound result 3\n  Bound result 0\n  Bound result 3\n  Bound result 2\n  Bound result 0\n  Bound result 2\n  Bound result 5\n  Bound result 4\n  Bound result 4\n  Bound result 2\n  Bound result 2\n  Bound result 4\n  Bound result 0\n  Bound result 5\n  Bound result 2\n  Bound result 4\n  Bound result 1\n  Bound result 0\n  Bound result 3\n  Bound result 0\n  Bound result 5\n  Bound result 3933\n  Bound result 4\n  Bound result 18\n  Bound result 4\n  Bound result 4\n  Bound result 0\n  Bound result 1\n  Bound result 3\n  Bound result 1\n  Bound result 4\n  Bound result 0\n  Bound result 825\n  Bound result 5\n  Bound result 0\n  Bound result 1\n  Bound result 4\n  Bound result 3\n  Bound result 0\n  Bound result 5\n  Bound result 115792089237316195423570985008687907853269984665639564039457584007913129640191\n  Bound result 2\n  Bound result 1\n  Bound result 0\n  Bound result 2\n  Bound result 4\n  Bound result 5\n  Bound result 0\n  Bound result 4\n  Bound result 5\n  Bound result 1\n  Bound result 5\n  Bound result 1000000000000000000\n  Bound result 5\n  Bound result 1000000000000000000\n  Bound result 1\n  Bound result 2\n  Bound result 4\n  Bound result 1000000000000000000\n  Bound result 2\n  Bound result 0\n  Bound result 0\n  Bound result 1\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 3\n  Bound result 3\n  Bound result 1\n  Bound result 3\n  Bound result 0\n  Bound result 1\n  Bound result 4\n  Bound result 4\n  Bound result 0\n  Bound result 1\n  Bound result 3\n  Bound result 1\n  Bound result 2\n  Bound result 1\n  Bound result 2\n  Bound result 2\n  Bound result 0\n  Bound result 4\n  Bound result 1\n  Bound result 3\n  Bound result 0\n  Bound result 0\n  Bound result 3\n  Bound result 2\n  Bound result 763\n  Bound result 0\n  Bound result 4\n  Bound result 5\n  Bound result 0\n  Bound result 4\n  Bound result 3\n  Bound result 0\n  Bound result 5\n  Bound result 5\n  Bound result 16376\n  Bound result 2\n  Bound result 4\n  Bound result 0\n  Bound result 2\n  Bound result 4\n  Bound result 12689\n  Bound result 0\n  Bound result 976\n  Bound result 3\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 10.00s (10.00s CPU time)\n\nRan 3 test suites in 10.00s (10.14s CPU time): 78 tests passed, 0 failed, 0 skipped (78 total tests)\n","passed":true},{"durationMs":42,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"PaveToken.approve(address,uint256)\",\"PaveToken.burn(uint256)\",\"PaveToken.decreaseAllowance(address,uint256)\",\"PaveToken.increaseAllowance(address,uint256)\",\"PaveToken.transfer(address,uint256)\",\"PaveToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":5,\"README.md\":93,\"foundry.toml\":19,\"remappings.txt\":1,\"src/PaveToken.sol\":156,\"test/PaveToken.edge.t.sol\":511,\"test/PaveToken.invariants.t.sol\":442,\"test/PaveToken.t.sol\":371},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"3ecf8baeecc1e26da97de45f92cfaf76975c40005d1fd26380f4310505d08cd0","verifiedTreeHash":"d901e160b0c8d03b2abb36d017b11e9248dcd490","verifierVersion":"0.1.0+7129bf9d"},{"checks":[{"durationMs":853,"exitCode":0,"name":"build","output":"Compiling 21 files with Solc 0.8.26\nSolc 0.8.26 finished in 781.84ms\nCompiler run successful!\n","passed":true},{"durationMs":81,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 33 tests for test/PaveToken.t.sol:PaveTokenTest\n[PASS] testFuzz_burnNeverIncreasesSupply(uint256) (runs: 256, μ: 60099, ~: 59950)\nLogs:\n  Bound result 118860592841078480164682960\n\n[PASS] testFuzz_transferBeyondBalanceReverts(uint256,uint256) (runs: 256, μ: 99409, ~: 100080)\nLogs:\n  Bound result 23420\n  Bound result 500000000000000000000\n\n[PASS] testFuzz_transferConservesSupply(address,uint256) (runs: 256, μ: 88906, ~: 88782)\nLogs:\n  Bound result 443621155250372521729166371\n\n[PASS] testFuzz_transferFromRespectsAllowance(uint256,uint256) (runs: 256, μ: 114526, ~: 96312)\nLogs:\n  Bound result 197198309146405333003770\n  Bound result 835542303017176900831049989\n\n[PASS] test_approveOverwritesPreviousAllowance() (gas: 92281)\n[PASS] test_approveRevertsForZeroSpender() (gas: 32483)\n[PASS] test_approveSetsAllowanceAndEmits() (gas: 64753)\n[PASS] test_burnMoreThanHeldReverts() (gas: 89564)\n[PASS] test_burnOnlyAffectsCaller() (gas: 111353)\n[PASS] test_burnReducesBalanceAndSupply() (gas: 111552)\n[PASS] test_constructorEmitsMintTransfer() (gas: 8106)\n[PASS] test_constructorMintsWholeSupplyToDeployer() (gas: 9961)\n[PASS] test_constructorTakesNoArgumentsAndHasNoMint() (gas: 186844)\n[PASS] test_decreaseAllowanceBelowZeroReverts() (gas: 85269)\n[PASS] test_increaseAllowanceOverflowReverts() (gas: 84834)\n[PASS] test_increaseAndDecreaseAllowance() (gas: 144799)\n[PASS] test_metadata() (gas: 23879)\n[PASS] test_mintsToAContractDeployer() (gas: 343880)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 740166)\n[PASS] test_supplyIsOneBillionWith18Decimals() (gas: 20551)\n[PASS] test_transferFromByNonSpenderCannotMoveHolderFunds() (gas: 95372)\n[PASS] test_transferFromEmptyAccountReverts() (gas: 37659)\n[PASS] test_transferFromRevertsBeyondAllowance() (gas: 87947)\n[PASS] test_transferFromRevertsBeyondBalanceEvenWithAllowance() (gas: 95168)\n[PASS] test_transferFromRevertsToZeroAddress() (gas: 89844)\n[PASS] test_transferFromRevertsWithoutAllowance() (gas: 40682)\n[PASS] test_transferFromSpendsAllowance() (gas: 151422)\n[PASS] test_transferFromWithInfiniteAllowanceDoesNotDecrement() (gas: 129910)\n[PASS] test_transferMovesExactAmountAndEmits() (gas: 86858)\n[PASS] test_transferRevertsOnInsufficientBalance() (gas: 92292)\n[PASS] test_transferRevertsToZeroAddress() (gas: 32526)\n[PASS] test_transferToSelfKeepsBalance() (gas: 95064)\n[PASS] test_transferZeroAmountSucceeds() (gas: 44338)\nSuite result: ok. 33 passed; 0 failed; 0 skipped; finished in 9.37ms (28.76ms CPU time)\n\nRan 1 test suite in 10.18ms (9.37ms CPU time): 33 tests passed, 0 failed, 0 skipped (33 total tests)\n","passed":true},{"durationMs":33,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"PaveToken.approve(address,uint256)\",\"PaveToken.burn(uint256)\",\"PaveToken.decreaseAllowance(address,uint256)\",\"PaveToken.increaseAllowance(address,uint256)\",\"PaveToken.transfer(address,uint256)\",\"PaveToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":5,\"README.md\":93,\"foundry.toml\":19,\"remappings.txt\":1,\"src/PaveToken.sol\":156,\"test/PaveToken.t.sol\":371},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":322,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":256,"exitCode":0,"name":"aderyn","output":"[low] large-numeric-literal at src/PaveToken.sol:45: Large Numeric Literal","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"7d6d848f83f300a6931edb9e7677188656aa9ae361e92c717867018b372b02a3","verifiedTreeHash":"38b06364e131d6fb36fd86d8bc534bfdc1810b89","verifierVersion":"0.1.0+7129bf9d"},{"checks":[{"durationMs":775,"exitCode":0,"name":"build","output":"Compiling 21 files with Solc 0.8.26\nSolc 0.8.26 finished in 703.11ms\nCompiler run successful!\n","passed":true},{"durationMs":78,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 33 tests for test/PaveToken.t.sol:PaveTokenTest\n[PASS] testFuzz_burnNeverIncreasesSupply(uint256) (runs: 256, μ: 60099, ~: 59950)\nLogs:\n  Bound result 118860592841078480164682960\n\n[PASS] testFuzz_transferBeyondBalanceReverts(uint256,uint256) (runs: 256, μ: 99409, ~: 100080)\nLogs:\n  Bound result 197198309146405333003770\n  Bound result 24772086743067790786082429587132131643572126880917971865377221801335386083\n\n[PASS] testFuzz_transferConservesSupply(address,uint256) (runs: 256, μ: 88906, ~: 88782)\nLogs:\n  Bound result 1\n\n[PASS] testFuzz_transferFromRespectsAllowance(uint256,uint256) (runs: 256, μ: 114526, ~: 96312)\nLogs:\n  Bound result 23420\n  Bound result 500000000000000000000\n\n[PASS] test_approveOverwritesPreviousAllowance() (gas: 92281)\n[PASS] test_approveRevertsForZeroSpender() (gas: 32483)\n[PASS] test_approveSetsAllowanceAndEmits() (gas: 64753)\n[PASS] test_burnMoreThanHeldReverts() (gas: 89564)\n[PASS] test_burnOnlyAffectsCaller() (gas: 111353)\n[PASS] test_burnReducesBalanceAndSupply() (gas: 111552)\n[PASS] test_constructorEmitsMintTransfer() (gas: 8106)\n[PASS] test_constructorMintsWholeSupplyToDeployer() (gas: 9961)\n[PASS] test_constructorTakesNoArgumentsAndHasNoMint() (gas: 186844)\n[PASS] test_decreaseAllowanceBelowZeroReverts() (gas: 85269)\n[PASS] test_increaseAllowanceOverflowReverts() (gas: 84834)\n[PASS] test_increaseAndDecreaseAllowance() (gas: 144799)\n[PASS] test_metadata() (gas: 23879)\n[PASS] test_mintsToAContractDeployer() (gas: 343880)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 740166)\n[PASS] test_supplyIsOneBillionWith18Decimals() (gas: 20551)\n[PASS] test_transferFromByNonSpenderCannotMoveHolderFunds() (gas: 95372)\n[PASS] test_transferFromEmptyAccountReverts() (gas: 37659)\n[PASS] test_transferFromRevertsBeyondAllowance() (gas: 87947)\n[PASS] test_transferFromRevertsBeyondBalanceEvenWithAllowance() (gas: 95168)\n[PASS] test_transferFromRevertsToZeroAddress() (gas: 89844)\n[PASS] test_transferFromRevertsWithoutAllowance() (gas: 40682)\n[PASS] test_transferFromSpendsAllowance() (gas: 151422)\n[PASS] test_transferFromWithInfiniteAllowanceDoesNotDecrement() (gas: 129910)\n[PASS] test_transferMovesExactAmountAndEmits() (gas: 86858)\n[PASS] test_transferRevertsOnInsufficientBalance() (gas: 92292)\n[PASS] test_transferRevertsToZeroAddress() (gas: 32526)\n[PASS] test_transferToSelfKeepsBalance() (gas: 95064)\n[PASS] test_transferZeroAmountSucceeds() (gas: 44338)\nSuite result: ok. 33 passed; 0 failed; 0 skipped; finished in 7.41ms (32.91ms CPU time)\n\nRan 1 test suite in 8.18ms (7.41ms CPU time): 33 tests passed, 0 failed, 0 skipped (33 total tests)\n","passed":true},{"durationMs":25,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"PaveToken.approve(address,uint256)\",\"PaveToken.burn(uint256)\",\"PaveToken.decreaseAllowance(address,uint256)\",\"PaveToken.increaseAllowance(address,uint256)\",\"PaveToken.transfer(address,uint256)\",\"PaveToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":5,\"README.md\":93,\"foundry.toml\":19,\"launch.json\":24,\"remappings.txt\":1,\"src/PaveToken.sol\":156,\"test/PaveToken.t.sol\":371},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"abea52b61a64ce0603512b12bb15779e20eb6042581f399a2eded26139b99ff7","verifiedTreeHash":"a213bbb02b7c375c8d9155db569b701eccdcdebf","verifierVersion":"0.1.0+7129bf9d"}]}