{"assessments":[],"deployments":[{"attestationHash":"9b627c0726f72f030b5be7d01680403ee121fed3c7f21eb867f834ed8cdc9717","chainId":1,"contracts":[{"address":"0x1d84554eb3f220eafb7b3639ced0b1c5ac99f60d","blockNumber":26371513,"name":"WindowShopperToken","role":"token","txHash":"0xf94a49b0df82b48eb1e7c5bc484413a2eecdb92abfeed78e59e435657de55f3b"},{"address":"0x784ff9a3ac5d88a30bfff6f7f2a270161fbe6000","blockNumber":26371513,"name":"PoolInitializationGuard","role":"hook","txHash":"0xf94a49b0df82b48eb1e7c5bc484413a2eecdb92abfeed78e59e435657de55f3b"},{"address":"0xd81be66490ab14757496343370e79c81022b27f9","blockNumber":26371513,"name":"MerkleDistributor","role":"distributor","txHash":"0xf94a49b0df82b48eb1e7c5bc484413a2eecdb92abfeed78e59e435657de55f3b"}],"id":"894bc456-b754-4298-8fe7-a33515902b5c","manifestHash":"66cd8ddc9bf6e688085a223293838b38018a179b871515989e9385be15abb016","status":"live"}],"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":"c5817201-3aff-4836-b2dc-859e99723149","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"cf994cdb0cd95b241eaa6bfa47c78de3b77971c616755dac91946186f9548134","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":"2dc0ab9c4713cb1965454488d12d20763ee6cb2bad4ea6372c34ad773bd5bc70","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":"92e3c5cfd0e5d8040bd3bf525386a12c226758efaabd769efec7072edf5025b6","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":"c27ccf2dd5370d1bf0f7d825f2ddb1c0efab6a7d15da7ccbc9a4b7f1a7df4b52","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":"4124e202a4453514da6c34abed40ebb1255ec6e26b8636f2ab4a55a9eed9cf34","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":"7db2455bc57ce3724f2a1adea7a374edcfd84616be808dd426f23b089f6afd6d","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":"a96633bf0a86171e7b71cc96c929b6a65134a05b471eb7a078fb3356d21fba91","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"c40da8142cb6dfc0794cdfdc05998faf99c67c70cd3ed5f333db74ab1ac0857f","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"1ddb4d02eb75e52d5f38cfd5c9bb54f332687b81929c68880cf1e8a6ab27254d","skillId":"write-foundry-tests","subagents":4,"tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"1ddb4d02eb75e52d5f38cfd5c9bb54f332687b81929c68880cf1e8a6ab27254d","skillId":"write-foundry-tests","state":"accepted"}],"objective":"A custom token: IMDwindowshopper (WWW).\nToken name: IMDwindowshopper\nToken symbol: WWW\nToken supply: 1,000,000,000 with 18 decimals, all minted once to the deployer in the constructor.","parentJobId":null,"planHash":"9f7fbf7ffa16f8233e22f53e723b05add5416e0a4f0e25cd3943da9a05cc720f","previousHash":"c2e6019b34e002e290078cdd411e89a9fc709dbbc7a7d77a96abcdc68e09b88b","projectId":"c5817201-3aff-4836-b2dc-859e99723149","publication":{"commit":"4c8501409648ea0a7be6ff6db83857916607f2d2","deliveredAt":"2026-11-08T16:59:11.450Z","repoUrl":"https://github.com/identity-md-launches/launch-3153-imdwindowshopper"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[],"site":null,"snapshotHash":"9dcf79a7be8978b258776c59ed34261fefd51de60c5788c1fafe3747ccc67b5b","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"d2d0460994f47014","findings":[],"hash":"2dc0ab9c4713cb1965454488d12d20763ee6cb2bad4ea6372c34ad773bd5bc70","nodeId":"e603cd79-2e05-4bfd-ba63-58e1b9ef169f","outcome":"completed","summary":"The review is complete and the findings file is written. No tracked files were modified.\n\n**Result: no defects found** in the control-flow area for `src/WindowShopperToken.sol`. The findings file holds an empty list and eight coverage rows, all `holds`.\n\nWhat I checked, per guide:\n\n- **Execution Trace.** Traced `approve`, `transfer` and `transferFrom` from entry to final state through the stock OpenZeppelin `_approve`, `_spendAllowance`, `_transfer` and `_update`. Every path either reverts cleanly or moves exactly the requested amount, with no partial state left behind on revert. There are no sentinel branches, no external calls, no hooks, and no mid-operation configuration to mutate. The constructor mints the whole supply once to the creator, which is the factory under CREATE2.\n- **Periphery.** The five vendored OpenZeppelin files hash byte-for-byte to the upstream v5.1.0 tag, so the base contract is unmodified. forge-std is used only by tests and the reference script.\n- **First Principles.** The runtime contains no CALL, STATICCALL, DELEGATECALL, CALLCODE, CREATE, CREATE2 or SELFDESTRUCT in reachable code, so there is no reentrancy or callback surface. Name, symbol, decimals, supply and the 18-character contract identifier match the brief and the manifest limits. The compiled ABI has no state-changing function beyond the three listed and no receive or fallback.\n\nTwo properties were confirmed and deliberately not reported as defects, since both are standard ERC-20 behaviour the README already documents: approve uses overwrite semantics, and tokens sent to the token contract are irrecoverable. One maintenance note is recorded in the coverage row rather than as a finding: the `DECIMALS` constant is not wired to `decimals()`, so they agree only by coincidence today and no failing input exists on the current code.\n\nVerification run: build succeeded, the existing 42 tests and my 5 scratch checks passed, and `forge fmt --check` was clean. The scratch test directory was removed afterwards.","treeHash":null,"usage":{"cachedInputTokens":521476,"cost":{"source":"runtime","usdMicros":2143868},"inputTokens":258,"model":"claude-fable-5-1","outputTokens":11082,"runtime":"claude","turns":23,"wallClockMs":239437}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"ee8bab8367ea6e91","findings":[{"citation":"resolved","description":"Asymmetry pass (approve <-> transferFrom pair). `approve` overwrites the allowance unconditionally while `transferFrom` (line 149) decrements it via `_spendAllowance` (line 301). The two sides are not atomic with respect to each other, so an already-approved spender who sees a holder's allowance-lowering `approve` in the mempool can spend the old allowance first and then the new one. This is the well-known ERC-20 approve race inherited unchanged from OpenZeppelin v5.1.0 (verified byte-identical to upstream: sha256 be0df7e4...cf64), which deliberately removed increaseAllowance/decreaseAllowance. It requires the holder to have previously trusted the spender, so by the Pashov validation gates it is at most a documented trust assumption for integrators, not a defect in WindowShopperToken. No change to the token is recommended; the token's own code (src/WindowShopperToken.sol) adds no permission surface beyond this. Reported so the author can document 'set allowance to 0 before changing it' guidance for holders if desired.","line":127,"path":"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol","reproduction":"State: holder H has 1000 WWW. 1) H calls approve(S, 100e18). 2) H broadcasts approve(S, 10e18) intending to lower. 3) S front-runs with transferFrom(H, S, 100e18) -> succeeds, allowance now 0. 4) H's approve(S, 10e18) executes -> allowance 10e18. 5) S calls transferFrom(H, S, 10e18) -> succeeds. Actual: S holds 110e18, H lost 110e18. Expected by H: at most 10e18 spendable after the lowering. Verified in test/scratch/Permissions.t.sol::test_approveRaceSpendsOldPlusNew (passes, i.e. the behaviour is present). Precondition: H previously approved S, so S is already a trusted counterparty; unprivileged strangers cannot reach it.","severity":"info","snippet":"    function approve(address spender, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, value);\n        return true;\n    }","title":"Inherited ERC-20 approve overwrite race: a spender front-running an allowance reduction can spend old plus new allowance (standard OpenZeppelin v5 behaviour, not a code defect)"}],"hash":"4124e202a4453514da6c34abed40ebb1255ec6e26b8636f2ab4a55a9eed9cf34","nodeId":"fb17e9a3-348d-4569-997d-229270bebfff","outcome":"completed","summary":"Review complete. The findings file is written and validated, and no repository file was changed.\n\n**Outcome: no defects in the permissions area.** The token is OpenZeppelin v5.1.0 `ERC20` with a constructor mint and nothing else, so the permission surface is the three standard writers plus the constructor. The file `.imd-findings.json` holds one info-level note and nine coverage rows.\n\n**What I verified**\n\n- **Access Control.** The compiled runtime's dispatcher contains exactly the eleven ABI selectors. Every other PUSH4 constant in the bytecode is an OpenZeppelin error selector, the Panic selector, or the literal 1e9, so there is no hidden function, receive, or fallback. Random-selector fuzzing reverts, and fourteen admin, mint, freeze and upgrade signatures revert from the deployer and from strangers. No caller class, including the factory and the token itself, can move a holder's balance without allowance.\n- **Trust Gap.** The vendored OpenZeppelin files hash byte-for-byte to upstream v5.1.0, so the claim \"ERC20 unchanged\" is true. The constructor hands out no role and mints only to the creating address, which under the launch is the factory.\n- **Asymmetry.** The approve and transferFrom pair mirrors correctly: fuzzing over allowance and amount shows the decrement equals the amount moved, the infinite-allowance path is the only non-decrement path, and a spender cannot self-grant another holder's allowance.\n\n**The one recorded item** is the standard ERC-20 approve overwrite race, inherited from OpenZeppelin and reported as info with a concrete sequence. It requires a holder to have already trusted the spender, so it is a documentation point for integrators and not a code change.\n\n**Coverage rows** mark all three listed entry points as `holds`, plus rows for the constructor, supply fixity, library provenance, forbidden opcodes and ether, and the reference deploy script. Nothing in my area was left unreached. The static-analysis lead about a large numeric literal is the supply constant and is not a defect.\n\nScratch tests live under `test/scratch/Permissions.t.sol`, which is gitignored and not submitted.","treeHash":null,"usage":{"cachedInputTokens":778825,"cost":{"source":"runtime","usdMicros":2685581},"inputTokens":322,"model":"claude-fable-5-1","outputTokens":15221,"runtime":"claude","turns":29,"wallClockMs":224499}},{"artifacts":[],"attempt":1,"bundleHash":"48a764885b8392d8a5e69efd9fae98fb9200aaf9443180a1a8f546d246e6bf0f","device":"fa99051b60a858d6","findings":[],"hash":"7db2455bc57ce3724f2a1adea7a374edcfd84616be808dd426f23b089f6afd6d","nodeId":"8d3adc6d-ad64-412d-b551-e56030d93cb2","outcome":"completed","summary":"The IMDwindowshopper (WWW) token is built, tested and committed on `main` as `da447a3`.\n\n**What was delivered**\n\n- `src/WindowShopperToken.sol`: a fixed-supply ERC-20 on OpenZeppelin v5.1.0. Name `IMDwindowshopper`, symbol `WWW`, 18 decimals. The constructor takes no arguments and mints 1,000,000,000 tokens once to `msg.sender`. There is no owner, mint, fee, pause, blocklist or upgrade path, so the launch floor's supply, exact-flow and privileged-call checks have nothing to trip on.\n- `test/WindowShopperToken.t.sol` and `test/WindowShopperTokenLaunch.t.sol`: 42 tests covering metadata, the one-time mint, transfer and allowance success paths, every ERC-20 revert path, fuzzed conservation of supply, rejection of mint and admin selectors from both deployer and strangers, CREATE2 deployment by a factory stand-in with the 10/70/20 launch shares arriving whole, and a reachable-opcode scan for DELEGATECALL, CALLCODE and SELFDESTRUCT.\n- `script/DeployWindowShopperToken.s.sol`: reference deploy script whose `deploy()` function is tested directly. It reads no environment.\n- `foundry.toml` pins `solc = \"0.8.26\"`, sets `bytecode_hash = \"none\"` and `cbor_metadata = false`, with no ffi or filesystem access. The built bytecode carries no metadata hash.\n- `lib/`: forge-std v1.9.7 and the OpenZeppelin ERC20 subset vendored as plain files. No submodules, so the offline verifier can build.\n- `README.md` documents behaviour, launch assumptions, manifest values, deployment parameters, and the operational responsibilities that remain with the deployer and requester.\n\n**Verification**\n\n`forge build`, `forge test` and `forge fmt --check` all pass. Tests were also run with an empty environment and with the verifier's fuzz seed, and all 42 passed. Slither is not on this machine, so it was not run.\n\n**Open items for others**\n\nExplorer verification and the independent adversarial review happen after the launch step. The token needs no post-launch configuration.","treeHash":"2735b191d22ce27ecb52a193af84e8a7fd2a9546","usage":{"cachedInputTokens":704297,"cost":{"source":"runtime","usdMicros":2383261},"inputTokens":450,"model":"claude-fable-5-1","outputTokens":22877,"runtime":"claude","turns":26,"wallClockMs":280978}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"f3b611cf8afb513f","findings":[{"citation":"resolved","description":"Kept from audit_math at its own severity (info). WindowShopperToken declares `DECIMALS = 18` (line 26) and scales `TOTAL_SUPPLY = 1_000_000_000 * 10 ** uint256(DECIMALS)` from it (line 28), but does not override `ERC20.decimals()`, which returns OpenZeppelin's own literal 18 (lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol:78-80, verified byte-identical to upstream v5.1.0). On the present tree decimals(), DECIMALS() and the supply scale all agree, the manifest's decimals (18) and totalSupply (1e27) match the contract, and the protected floor's decimals check passes. No input on the unmodified code triggers any failure, so this does not block release. It is a maintenance hazard only: a future edit of the constant would change the minted scale while decimals() stayed 18. Minimal, behaviour-preserving fix: `function decimals() public pure override returns (uint8) { return DECIMALS; }`.","line":26,"path":"src/WindowShopperToken.sol","reproduction":"Current tree (test/scratch/JudgeRepro.t.sol::test_decimalsAndConstantsAgreeOnCurrentTree, passes): deploy WindowShopperToken; token.decimals() == 18, token.DECIMALS() == 18, token.TOTAL_SUPPLY() == token.totalSupply() == 1000000000000000000000000000. Expected == actual. Latent only: changing line 26 to `uint8 public constant DECIMALS = 6;` and redeploying gives TOTAL_SUPPLY() == 1e15 while decimals() still returns 18. Nothing on the unmodified code fails.","severity":"info","snippet":"    uint8 public constant DECIMALS = 18;","title":"DECIMALS constant is not wired to decimals(); they agree only because both are the literal 18 (not a defect on the shipped tree)"},{"citation":"resolved","description":"Kept from audit_permissions at its own severity (info). `approve` overwrites the stored allowance unconditionally (ERC20.sol:127-131 and _approve at 280-291) while `transferFrom` decrements it through `_spendAllowance` (149-154, 301-311). The two are not atomic with each other, so a spender S that holder H has already approved can, on seeing H's allowance-lowering approve in the mempool, spend the old allowance first and then the new one. This is the well-known ERC-20 approve race, inherited unchanged from OpenZeppelin v5.1.0 (vendored ERC20.sol sha256 be0df7e4...cf64 matches upstream v5.1.0; upstream deliberately dropped increaseAllowance/decreaseAllowance). Precondition: H must already have approved S, so S is a counterparty H chose to trust; no unprivileged stranger and no privileged role can reach it, and WindowShopperToken adds no approval surface of its own. By the validation gates this is a documented trust assumption for holders and integrators, not a defect in the token. No code change recommended; holders who want to lower an allowance can set it to 0 first, or integrators can use permit-free patterns that spend exact amounts.","line":127,"path":"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol","reproduction":"State: H holds 1000e18 WWW. 1) H: approve(S, 100e18). 2) H broadcasts approve(S, 10e18) to lower it. 3) S front-runs: transferFrom(H, S, 100e18) -> succeeds, allowance(H,S) == 0. 4) H's approve(S, 10e18) executes -> allowance == 10e18. 5) S: transferFrom(H, S, 10e18) -> succeeds. Actual: balanceOf(S) == 110e18, balanceOf(H) == 890e18. H expected at most 10e18 spendable after step 2. Reproduced in test/scratch/JudgeRepro.t.sol::test_approveRaceSpendsOldPlusNew (passes, i.e. the behaviour is present).","severity":"info","snippet":"    function approve(address spender, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, value);\n        return true;\n    }","title":"Inherited ERC-20 approve overwrite race: a previously approved spender can front-run an allowance reduction and spend old plus new allowance (standard OpenZeppelin v5 behaviour, trust assumption for i"}],"hash":"92e3c5cfd0e5d8040bd3bf525386a12c226758efaabd769efec7072edf5025b6","nodeId":"f7e5bbe8-aa96-427f-afce-4f8d84b8c534","outcome":"completed","summary":"The review is complete and the report is written to `.imd-findings.json`. Nothing blocks this launch.\n\n**Outcome.** The token is a 40-line subclass of OpenZeppelin v5.1.0 `ERC20` with no overrides beyond name, symbol and a fixed one-time mint. I found no defect. Both specialist findings reproduce exactly as described, and both are correctly rated info: neither is a defect in the shipped code, so neither reopens the author's work.\n\n**What I verified**\n\n- Build and the project's own 57 tests pass, including a 128,000-call invariant run with zero reverts.\n- The vendored OpenZeppelin files are byte-identical to upstream v5.1.0, confirmed by fetching the tagged sources and comparing. The permissions specialist's hash claim holds.\n- The ABI has no mint, burn, owner, pause, blocklist, freeze or upgrade path. Creation and runtime bytecode are a few kilobytes, far under the deployment limits, with no DELEGATECALL, CALLCODE or SELFDESTRUCT.\n- The manifest matches the contract: no constructor arguments, decimals 18, supply 1e27, schema keys only, lowercase addresses.\n- A scratch test I wrote reproduces both specialist behaviours and confirms the factory cannot move a holder's balance without an allowance. It lives under test/scratch and is not kept.\n\n**Findings kept, both info**\n\n1. The `DECIMALS` constant drives the supply scale but `decimals()` still returns OpenZeppelin's own literal 18. They agree today, so nothing fails. It is a maintenance hazard only, with a one-line optional fix.\n2. The standard ERC-20 approve overwrite race, inherited unchanged. It needs a spender the holder already trusted, so it is a documented trust assumption for integrators, not a token defect.\n\n**Coverage.** All three listed entry points are marked holds, each with the trace behind it. I added rows for the constructor and the manifest, which I also checked. No row is unreached.","treeHash":null,"usage":{"cachedInputTokens":443344,"cost":{"source":"runtime","usdMicros":1658350},"inputTokens":258,"model":"claude-fable-5-1","outputTokens":9227,"runtime":"claude","turns":18,"wallClockMs":334207}},{"artifacts":[],"attempt":1,"bundleHash":"9af059475026c5118268a1c1538332f3be2a1e8903a1b30e79d795493c0df366","device":"da7ed792c3bf5b80","findings":[],"hash":"a96633bf0a86171e7b71cc96c929b6a65134a05b471eb7a078fb3356d21fba91","nodeId":"52490860-ac6f-491b-8ff7-2feb585d82ab","outcome":"completed","summary":"Only `launch.json` is new; nothing else changed.\n\n## Summary\n\nI wrote `launch.json` — a `custom_token` manifest for the accepted IMDwindowshopper (WWW) launch.\n\n**What I verified against the accepted tree:**\n- `src/WindowShopperToken.sol` is the only contract — a minimal fixed-supply OpenZeppelin v5 `ERC20`. No application contracts exist, so `contracts` is `[]`.\n- The constructor takes **no arguments** (`constructorArgs: []`) and mints the whole supply once to `msg.sender`.\n- Total minted = `1_000_000_000 * 10**18` = `1000000000000000000000000000` minor units → `token.totalSupply`.\n- `name` = `IMDwindowshopper`, `symbol` = `WWW`, `decimals` = 18, contract identifier `WindowShopperToken` (≤32 chars).\n\n**Manifest fields:**\n- `kind`: `\"custom_token\"`\n- `economics`: copied verbatim — `poolBps: 7000`, `initialMarketCapWei: \"2500000000000000000000\"`, `remainderTo: \"0xee2aaa315cf7ed169f93148d30d24af9318dbb66\"`.\n- `pool`: `pairedCurrency` the IMD token `0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7`, `fee: 12500`, `tickSpacing: 60`, `initialPrice` the 1:1 sqrtPriceX96 (provenance only).\n- `notes`: 1260 chars (≤4000), describing only the contract actually present.\n\n**Checks run:** `forge build` succeeds; `forge test` with the pinned `FOUNDRY_FUZZ_SEED` passes all 42 tests (including the protected token/owners checks). JSON validates and `git status` shows `launch.json` as the only change.","treeHash":"c9444384bcd6f40a5f7ed474b9fdb3a3f24e63de","usage":{"cachedInputTokens":82943,"cost":{"source":"runtime","usdMicros":115350},"inputTokens":16,"model":"claude-opus-5-5","outputTokens":1362,"runtime":"claude","turns":19,"wallClockMs":64075}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"c2e167266d13dcf4","findings":[{"citation":"resolved","description":"The contract declares `DECIMALS = 18` and derives `TOTAL_SUPPLY = 1_000_000_000 * 10 ** uint256(DECIMALS)` from it (line 28), but it does not override `ERC20.decimals()`, which returns its own hard-coded literal 18 (lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol:78-80). On the present tree both values are 18, so `decimals()`, `DECIMALS()` and the supply scale agree and no call fails; this is NOT a defect in the shipped code and should not block release. It is a latent scale-mismatch (Math Precision guide, 'Mismatch decimals'): if the constant were ever edited the minted supply would change scale while the reported decimals would not, and the manifest's `decimals` and `totalSupply` would disagree with the token. Minimal fix that preserves behaviour: add `function decimals() public pure override returns (uint8) { return DECIMALS; }` so the single constant drives both.","line":26,"path":"src/WindowShopperToken.sol","reproduction":"Current tree: `token.decimals()` == 18, `token.DECIMALS()` == 18, `token.TOTAL_SUPPLY()` == 1e27 — all consistent (verified in test/scratch/MathProbe.t.sol test_constantIsExactlyOneBillionTimesTenToEighteen). Latent state: change line 26 to `uint8 public constant DECIMALS = 6;` and redeploy — `TOTAL_SUPPLY()` becomes 1e15 while `decimals()` still returns 18, so a holder's displayed balance is off by 1e12. No input on the unmodified code triggers any failure.","severity":"info","snippet":"    uint8 public constant DECIMALS = 18;","title":"DECIMALS constant is not wired to decimals(); the two agree only because both are the literal 18"}],"hash":"c27ccf2dd5370d1bf0f7d825f2ddb1c0efab6a7d15da7ccbc9a4b7f1a7df4b52","nodeId":"9718ccd4-3c7c-4f09-be13-a7ccfd5b5a1a","outcome":"completed","summary":"The findings file is valid JSON, the quoted snippet matches line 26 of the source, and no tracked files were changed. Only `.imd-findings.json` and `test/scratch/MathProbe.t.sol` were written, both within the review's allowed output.\n\n## Result\n\n**No substantiated math defect.** The IMDwindowshopper token is an unchanged OpenZeppelin v5.1.0 `ERC20` plus one constant and one constructor mint. Across the Math Precision, Boundary and Numerical Gap guides, every failure mode either has no surface in this code or was probed and held.\n\n**What I verified**\n\n- **Library provenance.** All five vendored OpenZeppelin files diffed byte-identical against the upstream v5.1.0 tag, so the `unchecked` blocks under review are the audited ones.\n- **Transfer and allowance arithmetic.** Balance and allowance underflow are guarded before each unchecked subtract. The infinite-allowance sentinel fires only at exactly max uint and does not bypass the balance check. Max-uint transfer, whole-balance self-transfer, self-transferFrom with max allowance, and one-wei transfers all behave exactly.\n- **Supply conservation.** A Foundry invariant with five actors and 128,000 mixed in-range and out-of-range calls never broke sum of balances equals total supply equals 1e27.\n- **Constant and launch split.** The supply constant folds to exactly 1e27 with no truncation. The 10/70/20 split divides with no dust, and 7e26 fits Uniswap v4's int128 delta type. The aderyn large-literal lint is stylistic only.\n- **Boundary enumeration.** No external calls, no payable or receive paths, no bytes decoding. The only sentinel branches are the zero-address rejections, all of which revert rather than silently no-op.\n\n**One info note recorded.** The `DECIMALS` constant drives the supply scale but is not wired to `decimals()`, which returns OpenZeppelin's own literal 18. Both are 18 today so nothing fails and it should not block release. It is flagged because editing one without the other would desynchronise the minted scale from the reported decimals and the manifest. The one-line fix is an override returning the constant.\n\n**Coverage.** All three ABI entry points (`approve`, `transfer`, `transferFrom`) are `holds`, plus six invariant rows covering supply conservation, constant exactness, launch-share divisibility, boundary surfaces, library identity and the numerical-gap seams. Nothing was left unreached. The protected harness test could not be run locally because it depends on v4-core and launch environment variables that are not in this repository, but nothing in my area depends on it.","treeHash":null,"usage":{"cachedInputTokens":646000,"cost":{"source":"runtime","usdMicros":2380748},"inputTokens":290,"model":"claude-fable-5-1","outputTokens":14809,"runtime":"claude","turns":25,"wallClockMs":221503}},{"artifacts":[],"attempt":1,"bundleHash":"b14e9fba28f40618c3be3772f851cd40de7401ceaae2caa830759ddabddff993","device":"b4f6137e7c93a2b3","findings":[],"hash":"c40da8142cb6dfc0794cdfdc05998faf99c67c70cd3ed5f333db74ab1ac0857f","nodeId":"f9f5ae16-bf29-4ace-89c1-1b10ccf24fc1","outcome":"completed","summary":"I added two test files, and the full suite passes: `forge build` succeeds and `forge test` with the verifier's seed runs 57 tests, all passing. I found no defects, so there is no `.imd-findings.json`.\n\n**What's under test.** `src/WindowShopperToken.sol` is OpenZeppelin v5.1.0's standard ERC-20 plus a one-time mint of the full 1,000,000,000 WWW to whoever deploys it. I compared the bundled OpenZeppelin files with the official v5.1.0 release and they are byte-identical. The earlier contributors' 42 tests are unchanged.\n\n**`test/WindowShopperTokenInvariant.t.sol`** (the invariant tests the task asks for)\n- A handler makes random calls from five accounts and also targets the token's own address. It keeps its own record of what every balance and allowance should be.\n- It mixes valid transfers, approvals and `transferFrom` calls with calls that must fail: sending more than the balance, sending to the zero address, spending more than the allowance, spending more than the owner holds, and approving the zero address.\n- A failing call must revert with the exact OpenZeppelin error and leave balances and allowances unchanged.\n- Checked after every call:\n  - total supply never changes;\n  - balances add up to the supply;\n  - every balance and allowance matches the handler's own record;\n  - no spender moves more than it was approved for;\n  - the token never holds ETH, and the zero address never holds tokens.\n- One run is 256 sequences, about 128,000 calls, and takes about 70 seconds.\n- To show these checks can actually fail, I ran the same handler against a throwaway copy of the token that burns 1 wei per transfer. Both invariants failed straight away. That check was in `test/scratch/` and is not submitted.\n\n**`test/WindowShopperTokenEdges.t.sol`** (14 tests covering cases the first suite missed)\n- Sending 0 tokens to the zero address still reverts.\n- `transferFrom` from the zero address reverts, whatever the amount.\n- `transferFrom` of 0 succeeds even with no allowance, and moves nothing.\n- Spending an allowance emits only the `Transfer` event.\n- A revoked allowance can't be spent, and an allowance one below the maximum still goes down when used.\n- Tokens sent to the token contract itself are stuck there for good, as the README says.\n- Fuzz tests cover approvals and spending past the allowance or the owner's balance.\n\nOne of my own expectations was wrong at first: `transferFrom(address(0), …, 0)` reverts with OpenZeppelin's `ERC20InvalidApprover` error, not `ERC20InvalidSender`. That's normal OpenZeppelin behaviour, not a token bug, so I corrected the test. I also added a separate test that forces past the allowance step to confirm the sender check fires too.\n\nI haven't committed anything. The other untracked files in the repo root (`.bashrc`, `.claude/`, etc.) were already there and aren't part of this work.","treeHash":"c388a34e162cb8a1aeb180a042760958d0b2b9c6","usage":{"cachedInputTokens":786907,"cost":{"source":"runtime","usdMicros":926773},"inputTokens":32,"model":"claude-opus-5-5","outputTokens":17262,"runtime":"claude","turns":19,"wallClockMs":325730}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"96ecbe9236c400bb","findings":[],"hash":"cf994cdb0cd95b241eaa6bfa47c78de3b77971c616755dac91946186f9548134","nodeId":"a740c382-b6e3-4539-b9d6-32f919e4cd5f","outcome":"completed","summary":"Review complete. No economic defects found in IMDwindowshopper (WWW). The findings file holds an empty findings list and a 12-row coverage record.\n\n**What the token is.** A 40-line wrapper over OpenZeppelin v5.1.0 ERC20 that mints one billion tokens with 18 decimals to the deployer in the constructor. It has no owner, no mint, no burn, no fee, no hooks and no external calls.\n\n**What I verified for the economics area (Economic Security, Invariant, Flow Gap):**\n- The five vendored OpenZeppelin files are byte-identical to upstream v5.1.0, so the library is not a hidden attack surface.\n- Supply is constant forever. The only mint is in the constructor, no burn path is reachable, and transfers to the zero address revert.\n- Sum of balances equals total supply after every step of 1000 fuzzed random transfer and transferFrom sequences among seven actors.\n- Every launch flow arrives whole: factory to distributor, pool and remainder wallet, distributor to claimant, and the Uniswap v4 settle balance-delta pattern for any amount up to the supply.\n- No privileged selector exists. The only state-changing entry points are approve, transfer and transferFrom, and the runtime has no DELEGATECALL, CALLCODE or SELFDESTRUCT.\n- The one static-analysis lead, the large numeric literal, evaluates exactly to the manifest supply and is a style note only.\n- The existing 42-test suite passes and the formatter check is clean.\n\n**Noted but not reported as defects.** The standard ERC-20 approve race exists as in every ERC-20. The DECIMALS constant is not wired into decimals(), but both are 18, so there is no failing input today.\n\nThe scratch test I used for the fuzz evidence was removed, so the tree is unchanged apart from the findings file.","treeHash":null,"usage":{"cachedInputTokens":416647,"cost":{"source":"runtime","usdMicros":2191577},"inputTokens":194,"model":"claude-fable-5-1","outputTokens":11919,"runtime":"claude","turns":22,"wallClockMs":173824}}],"verification":[{"checks":[{"durationMs":2359,"exitCode":0,"name":"build","output":"Compiling 29 files with Solc 0.8.26\nSolc 0.8.26 finished in 2.12s\nCompiler run successful!\n","passed":true},{"durationMs":365,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 8 tests for test/WindowShopperTokenLaunch.t.sol:WindowShopperTokenLaunchTest\n[PASS] test_claimFromDistributorArrivesWhole() (gas: 129773)\n[PASS] test_create2AddressIsPredictable() (gas: 634387)\n[PASS] test_create2DeploymentMintsWholeSupplyToFactory() (gas: 31184)\n[PASS] test_deployScriptFunctionMintsToCaller() (gas: 1506235)\n[PASS] test_factoryCannotMoveAHolderBalanceAfterwards() (gas: 164601)\n[PASS] test_launchSharesArriveWholeAndSumToSupply() (gas: 225874)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 2940125)\n[PASS] test_supplyCannotGrow_fromFactoryOrStranger() (gas: 308858)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 41.27ms (23.80ms CPU time)\n\nRan 34 tests for test/WindowShopperToken.t.sol:WindowShopperTokenTest\n[PASS] testFuzz_transferAboveBalanceReverts(uint256) (runs: 256, μ: 42076, ~: 42396)\nLogs:\n  Bound result 3960517788903638498397296950570568638233108799587474373364006965179\n\n[PASS] testFuzz_transferConservesSupplyAndArrivesWhole(address,uint256) (runs: 256, μ: 99622, ~: 99824)\nLogs:\n  Bound result 24197\n\n[PASS] testFuzz_transferFromWithinAllowance(uint256,uint256) (runs: 256, μ: 157422, ~: 159038)\nLogs:\n  Bound result 84\n  Bound result 1\n\n[PASS] test_allowanceIsPerSpender_otherSpenderCannotUseIt() (gas: 87959)\n[PASS] test_approveOverwritesPreviousAllowance() (gas: 95585)\n[PASS] test_approveSetsAllowanceAndEmits() (gas: 68159)\n[PASS] test_approveZeroSpenderReverts() (gas: 32987)\n[PASS] test_chainedTransfersArriveWholeAndConserveSupply() (gas: 227986)\n[PASS] test_constructorEmitsTransferFromZeroAndSupplyMinted() (gas: 9291)\n[PASS] test_constructorHasNoArguments_rawCreationCodeDeploys() (gas: 663298)\n[PASS] test_constructorMintsWholeSupplyToDeployer() (gas: 33761)\n[PASS] test_contractRejectsPlainEther() (gas: 39670)\n[PASS] test_deployerHasNoPowerOverOtherHolders() (gas: 148695)\n[PASS] test_deployerIsWhoeverCreatesIt_contractDeployerHoldsSupply() (gas: 200989)\n[PASS] test_holderCanTransferFromItself_withSelfApproval() (gas: 119432)\n[PASS] test_infiniteAllowanceIsNotDecremented() (gas: 135951)\n[PASS] test_metadata() (gas: 40182)\n[PASS] test_noMintOrAdminSelectorIsCallable() (gas: 720201)\n[PASS] test_supportsIERC20Interface() (gas: 21061)\n[PASS] test_totalSupplyIsOneBillionWithEighteenDecimals() (gas: 29314)\n[PASS] test_transferFromAboveAllowanceReverts() (gas: 88099)\n[PASS] test_transferFromAboveOwnerBalanceReverts() (gas: 148502)\n[PASS] test_transferFromExactAllowanceLeavesZero() (gas: 121553)\n[PASS] test_transferFromSpendsAllowanceAndMovesTokens() (gas: 169064)\n[PASS] test_transferFromToZeroAddressReverts() (gas: 88781)\n[PASS] test_transferFromWithoutAllowanceReverts() (gas: 40409)\n[PASS] test_transferMovesExactAmountAndEmits() (gas: 95942)\n[PASS] test_transferRevertsFromEmptyAccount() (gas: 37815)\n[PASS] test_transferRevertsOnInsufficientBalance() (gas: 92756)\n[PASS] test_transferToSelfKeepsBalance() (gas: 98720)\n[PASS] test_transferToZeroAddressReverts() (gas: 32958)\n[PASS] test_transferWholeBalance() (gas: 78378)\n[PASS] test_transferZeroAmountSucceeds() (gas: 47824)\n[PASS] test_unknownSelectorReverts() (gas: 29490)\nSuite result: ok. 34 passed; 0 failed; 0 skipped; finished in 41.61ms (94.33ms CPU time)\n\nRan 2 test suites in 48.72ms (82.88ms CPU time): 42 tests passed, 0 failed, 0 skipped (42 total tests)\n","passed":true},{"durationMs":73,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"WindowShopperToken.approve(address,uint256)\",\"WindowShopperToken.transfer(address,uint256)\",\"WindowShopperToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":111,\"foundry.toml\":20,\"remappings.txt\":2,\"script/DeployWindowShopperToken.s.sol\":25,\"src/WindowShopperToken.sol\":40,\"test/WindowShopperToken.t.sol\":374,\"test/WindowShopperTokenLaunch.t.sol\":156},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":1769,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":1241,"exitCode":0,"name":"aderyn","output":"[low] large-numeric-literal at src/WindowShopperToken.sol:28: Large Numeric Literal","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"7db2455bc57ce3724f2a1adea7a374edcfd84616be808dd426f23b089f6afd6d","verifiedTreeHash":"2735b191d22ce27ecb52a193af84e8a7fd2a9546","verifierVersion":"0.1.0+89159ae2"},{"checks":[{"durationMs":1764,"exitCode":0,"name":"build","output":"Compiling 29 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.63s\nCompiler run successful!\n","passed":true},{"durationMs":181,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 8 tests for test/WindowShopperTokenLaunch.t.sol:WindowShopperTokenLaunchTest\n[PASS] test_claimFromDistributorArrivesWhole() (gas: 129773)\n[PASS] test_create2AddressIsPredictable() (gas: 634387)\n[PASS] test_create2DeploymentMintsWholeSupplyToFactory() (gas: 31184)\n[PASS] test_deployScriptFunctionMintsToCaller() (gas: 1506235)\n[PASS] test_factoryCannotMoveAHolderBalanceAfterwards() (gas: 164601)\n[PASS] test_launchSharesArriveWholeAndSumToSupply() (gas: 225874)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 2940125)\n[PASS] test_supplyCannotGrow_fromFactoryOrStranger() (gas: 308858)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 11.87ms (10.00ms CPU time)\n\nRan 34 tests for test/WindowShopperToken.t.sol:WindowShopperTokenTest\n[PASS] testFuzz_transferAboveBalanceReverts(uint256) (runs: 256, μ: 42076, ~: 42396)\nLogs:\n  Bound result 94213607912493791372527952841\n\n[PASS] testFuzz_transferConservesSupplyAndArrivesWhole(address,uint256) (runs: 256, μ: 99622, ~: 99824)\nLogs:\n  Bound result 50000000000000000000\n\n[PASS] testFuzz_transferFromWithinAllowance(uint256,uint256) (runs: 256, μ: 157422, ~: 159038)\nLogs:\n  Bound result 999999999999999999999999999\n  Bound result 36069088462977046052729\n\n[PASS] test_allowanceIsPerSpender_otherSpenderCannotUseIt() (gas: 87959)\n[PASS] test_approveOverwritesPreviousAllowance() (gas: 95585)\n[PASS] test_approveSetsAllowanceAndEmits() (gas: 68159)\n[PASS] test_approveZeroSpenderReverts() (gas: 32987)\n[PASS] test_chainedTransfersArriveWholeAndConserveSupply() (gas: 227986)\n[PASS] test_constructorEmitsTransferFromZeroAndSupplyMinted() (gas: 9291)\n[PASS] test_constructorHasNoArguments_rawCreationCodeDeploys() (gas: 663298)\n[PASS] test_constructorMintsWholeSupplyToDeployer() (gas: 33761)\n[PASS] test_contractRejectsPlainEther() (gas: 39670)\n[PASS] test_deployerHasNoPowerOverOtherHolders() (gas: 148695)\n[PASS] test_deployerIsWhoeverCreatesIt_contractDeployerHoldsSupply() (gas: 200989)\n[PASS] test_holderCanTransferFromItself_withSelfApproval() (gas: 119432)\n[PASS] test_infiniteAllowanceIsNotDecremented() (gas: 135951)\n[PASS] test_metadata() (gas: 40182)\n[PASS] test_noMintOrAdminSelectorIsCallable() (gas: 720201)\n[PASS] test_supportsIERC20Interface() (gas: 21061)\n[PASS] test_totalSupplyIsOneBillionWithEighteenDecimals() (gas: 29314)\n[PASS] test_transferFromAboveAllowanceReverts() (gas: 88099)\n[PASS] test_transferFromAboveOwnerBalanceReverts() (gas: 148502)\n[PASS] test_transferFromExactAllowanceLeavesZero() (gas: 121553)\n[PASS] test_transferFromSpendsAllowanceAndMovesTokens() (gas: 169064)\n[PASS] test_transferFromToZeroAddressReverts() (gas: 88781)\n[PASS] test_transferFromWithoutAllowanceReverts() (gas: 40409)\n[PASS] test_transferMovesExactAmountAndEmits() (gas: 95942)\n[PASS] test_transferRevertsFromEmptyAccount() (gas: 37815)\n[PASS] test_transferRevertsOnInsufficientBalance() (gas: 92756)\n[PASS] test_transferToSelfKeepsBalance() (gas: 98720)\n[PASS] test_transferToZeroAddressReverts() (gas: 32958)\n[PASS] test_transferWholeBalance() (gas: 78378)\n[PASS] test_transferZeroAmountSucceeds() (gas: 47824)\n[PASS] test_unknownSelectorReverts() (gas: 29490)\nSuite result: ok. 34 passed; 0 failed; 0 skipped; finished in 12.21ms (34.65ms CPU time)\n\nRan 2 test suites in 14.36ms (24.08ms CPU time): 42 tests passed, 0 failed, 0 skipped (42 total tests)\n","passed":true},{"durationMs":73,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"WindowShopperToken.approve(address,uint256)\",\"WindowShopperToken.transfer(address,uint256)\",\"WindowShopperToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":111,\"foundry.toml\":20,\"launch.json\":24,\"remappings.txt\":2,\"script/DeployWindowShopperToken.s.sol\":25,\"src/WindowShopperToken.sol\":40,\"test/WindowShopperToken.t.sol\":374,\"test/WindowShopperTokenLaunch.t.sol\":156},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"a96633bf0a86171e7b71cc96c929b6a65134a05b471eb7a078fb3356d21fba91","verifiedTreeHash":"c9444384bcd6f40a5f7ed474b9fdb3a3f24e63de","verifierVersion":"0.1.0+89159ae2"},{"checks":[{"durationMs":2738,"exitCode":0,"name":"build","output":"Compiling 31 files with Solc 0.8.26\nSolc 0.8.26 finished in 2.62s\nCompiler run successful!\n","passed":true},{"durationMs":115755,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 34 tests for test/WindowShopperToken.t.sol:WindowShopperTokenTest\n[PASS] testFuzz_transferAboveBalanceReverts(uint256) (runs: 256, μ: 42068, ~: 42396)\nLogs:\n  Bound result 115792089237316195423570985008687907853269984665639564039457584007913129640127\n\n[PASS] testFuzz_transferConservesSupplyAndArrivesWhole(address,uint256) (runs: 256, μ: 99632, ~: 99830)\nLogs:\n  Bound result 53591\n\n[PASS] testFuzz_transferFromWithinAllowance(uint256,uint256) (runs: 256, μ: 157336, ~: 159032)\nLogs:\n  Bound result 44\n  Bound result 22\n\n[PASS] test_allowanceIsPerSpender_otherSpenderCannotUseIt() (gas: 87959)\n[PASS] test_approveOverwritesPreviousAllowance() (gas: 95585)\n[PASS] test_approveSetsAllowanceAndEmits() (gas: 68159)\n[PASS] test_approveZeroSpenderReverts() (gas: 32987)\n[PASS] test_chainedTransfersArriveWholeAndConserveSupply() (gas: 227986)\n[PASS] test_constructorEmitsTransferFromZeroAndSupplyMinted() (gas: 9291)\n[PASS] test_constructorHasNoArguments_rawCreationCodeDeploys() (gas: 663298)\n[PASS] test_constructorMintsWholeSupplyToDeployer() (gas: 33761)\n[PASS] test_contractRejectsPlainEther() (gas: 39670)\n[PASS] test_deployerHasNoPowerOverOtherHolders() (gas: 148695)\n[PASS] test_deployerIsWhoeverCreatesIt_contractDeployerHoldsSupply() (gas: 200989)\n[PASS] test_holderCanTransferFromItself_withSelfApproval() (gas: 119432)\n[PASS] test_infiniteAllowanceIsNotDecremented() (gas: 135951)\n[PASS] test_metadata() (gas: 40182)\n[PASS] test_noMintOrAdminSelectorIsCallable() (gas: 720201)\n[PASS] test_supportsIERC20Interface() (gas: 21061)\n[PASS] test_totalSupplyIsOneBillionWithEighteenDecimals() (gas: 29314)\n[PASS] test_transferFromAboveAllowanceReverts() (gas: 88099)\n[PASS] test_transferFromAboveOwnerBalanceReverts() (gas: 148502)\n[PASS] test_transferFromExactAllowanceLeavesZero() (gas: 121553)\n[PASS] test_transferFromSpendsAllowanceAndMovesTokens() (gas: 169064)\n[PASS] test_transferFromToZeroAddressReverts() (gas: 88781)\n[PASS] test_transferFromWithoutAllowanceReverts() (gas: 40409)\n[PASS] test_transferMovesExactAmountAndEmits() (gas: 95942)\n[PASS] test_transferRevertsFromEmptyAccount() (gas: 37815)\n[PASS] test_transferRevertsOnInsufficientBalance() (gas: 92756)\n[PASS] test_transferToSelfKeepsBalance() (gas: 98720)\n[PASS] test_transferToZeroAddressReverts() (gas: 32958)\n[PASS] test_transferWholeBalance() (gas: 78378)\n[PASS] test_transferZeroAmountSucceeds() (gas: 47824)\n[PASS] test_unknownSelectorReverts() (gas: 29490)\nSuite result: ok. 34 passed; 0 failed; 0 skipped; finished in 69.95ms (144.05ms CPU time)\n\nRan 8 tests for test/WindowShopperTokenLaunch.t.sol:WindowShopperTokenLaunchTest\n[PASS] test_claimFromDistributorArrivesWhole() (gas: 129773)\n[PASS] test_create2AddressIsPredictable() (gas: 634387)\n[PASS] test_create2DeploymentMintsWholeSupplyToFactory() (gas: 31184)\n[PASS] test_deployScriptFunctionMintsToCaller() (gas: 1506235)\n[PASS] test_factoryCannotMoveAHolderBalanceAfterwards() (gas: 164601)\n[PASS] test_launchSharesArriveWholeAndSumToSupply() (gas: 225874)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 2940125)\n[PASS] test_supplyCannotGrow_fromFactoryOrStranger() (gas: 308858)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 71.24ms (21.13ms CPU time)\n\nRan 14 tests for test/WindowShopperTokenEdges.t.sol:WindowShopperTokenEdgesTest\n[PASS] testFuzz_approveStoresAnyValue(address,uint256) (runs: 1000, μ: 66181, ~: 66482)\n[PASS] testFuzz_splitTransfersConserveSupply(uint256,uint256) (runs: 1000, μ: 163210, ~: 164446)\nLogs:\n  Bound result 410218032998615883305\n  Bound result 609202162914917769453264291\n\n[PASS] testFuzz_transferFromOverAllowanceRevertsAndChangesNothing(uint256,uint256) (runs: 1000, μ: 115307, ~: 115798)\nLogs:\n  Bound result 91\n  Bound result 95\n\n[PASS] testFuzz_transferFromOverBalanceKeepsAllowance(uint256,uint256) (runs: 1000, μ: 174283, ~: 174519)\nLogs:\n  Bound result 91\n  Bound result 95\n\n[PASS] test_approveSelfAndZeroValue() (gas: 88492)\n[PASS] test_maxMinusOneAllowanceIsDecremented() (gas: 126750)\n[PASS] test_revokedAllowanceCannotBeSpent() (gas: 113340)\n[PASS] test_spendingFiniteAllowanceEmitsNoApproval() (gas: 130191)\n[PASS] test_transferFromZeroAddressRevertsEvenForZeroAmount() (gas: 37849)\n[PASS] test_transferFromZeroAddressWithAmountRevertsOnAllowance() (gas: 37975)\n[PASS] test_transferFromZeroAddressWithInfiniteAllowanceRevertsAsInvalidSender() (gas: 49326)\n[PASS] test_transferFromZeroAmountWithoutAllowanceSucceedsAndMovesNothing() (gas: 83175)\n[PASS] test_transferToTokenContractIsAcceptedAndStuck() (gas: 78167)\n[PASS] test_transferZeroToZeroAddressStillReverts() (gas: 32865)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 79.45ms (311.10ms CPU time)\n\nRan 1 test for test/WindowShopperTokenInvariant.t.sol:WindowShopperTokenInvariantTest\n[PASS]\nWindowShopperTokenInvariantTest invariants:\n[PASS] invariant_allowancesMatchModelAndPullsStayWithinGrants\n[PASS] invariant_balancesMatchModel\n[PASS] invariant_balancesSumToTotalSupply\n[PASS] invariant_noHandlerViolations\n[PASS] invariant_tokenHoldsNoEtherAndSupplyNeverReturnsToZeroAddress\n[PASS] invariant_totalSupplyNeverChanges\n WindowShopperTokenInvariantTest invariants (runs: 256, calls: 128000, reverts: 0)\n\n╭--------------+---------------------------+-------+---------+----------╮\n| Contract     | Selector                  | Calls | Reverts | Discards |\n+=======================================================================+\n| TokenHandler | approve                   | 14056 | 0       | 0        |\n|--------------+---------------------------+-------+---------+----------|\n| TokenHandler | approveZeroSpender        | 14254 | 0       | 0        |\n|--------------+---------------------------+-------+---------+----------|\n| TokenHandler | transfer                  | 28726 | 0       | 0        |\n|--------------+---------------------------+-------+---------+----------|\n| TokenHandler | transferFrom              | 14211 | 0       | 0        |\n|--------------+---------------------------+-------+---------+----------|\n| TokenHandler | transferFromOverAllowance | 14324 | 0       | 0        |\n|--------------+---------------------------+-------+---------+----------|\n| TokenHandler | transferFromOverBalance   | 14157 | 0       | 0        |\n|--------------+---------------------------+-------+---------+----------|\n| TokenHandler | transferToZero            | 14163 | 0       | 0        |\n|--------------+---------------------------+-------+---------+----------|\n| TokenHandler | transferTooMuch           | 14109 | 0       | 0        |\n╰--------------+---------------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 5615\n  Bound result 0\n  Bound result 9916\n  Bound result 0\n  Bound result 2\n  Bound result 11027\n  Bound result 0\n  Bound result 0\n  Bound result 4624\n  Bound result 0\n  Bound result 14\n  Bound result 242\n  Bound result 11652\n  Bound result 3\n  Bound result 0\n  Bound result 244\n  Bound result 606\n  Bound result 10689\n  Bound result 233\n  Bound result 240\n  Bound result 415\n  Bound result 0\n  Bound result 0\n  Bound result 849196097368235503513103684\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 3743\n  Bound result 9\n  Bound result 200000000000000000000\n  Bound result 1000000000000000000000000000\n  Bound result 36865\n  Bound result 2090358504\n  Bound result 285773982150076360115950401\n  Bound result 243\n  Bound result 255\n  Bound result 2552851541\n  Bound result 9690\n  Bound result 61377511379\n  Bound result 3281\n  Bound result 307\n  Bound result 7\n  Bound result 1000000000000000000000\n  Bound result 1082\n  Bound result 800364208823912072153\n  Bound result 100000000000000000000\n  Bound result 5000000000000000000\n  Bound result 86\n  Bound result 782041417413589446082938843\n  Bound result 10671\n  Bound result 9915\n  Bound result 1719639408\n  Bound result 0\n  Bound result 388837317430516394037633169\n  Bound result 0\n  Bound result 1\n  Bound result 2446\n  Bound result 6124\n  Bound result 62\n  Bound result 115795\n  Bound result 1516608481393923757308738083\n  Bound result 96\n  Bound result 0\n  Bound result 14\n  Bound result 147\n  Bound result 940397084746240072411991819\n  Bound result 14\n  Bound result 357\n  Bound result 253\n  Bound result 10358\n  Bound result 7000\n  Bound result 361\n  Bound result 999998999999999997447096702\n  Bound result 1\n  Bound result 2180\n  Bound result 1\n  Bound result 0\n  Bound result 66\n  Bound result 2758\n  Bound result 1175578170\n  Bound result 1675\n  Bound result 1934\n  Bound result 0\n  Bound result 628\n  Bound result 2021\n  Bound result 30454444\n  Bound result 1\n  Bound result 0\n  Bound result 0\n  Bound result 10000000000000000000\n  Bound result 52980802\n  Bound result 0\n  Bound result 254\n  Bound result 5506\n  Bound result 873\n  Bound result 7\n  Bound result 17318915980\n  Bound result 242\n  Bound result 234612730431341222569820733\n  Bound result 53591\n  Bound result 1001\n  Bound result 1000000000000000000\n  Bound result 9672\n  Bound result 1000000000\n  Bound result 28787652701\n  Bound result 218502016963355726858\n  Bound result 0\n  Bound result 0\n  Bound result 725\n  Bound result 5803\n  Bound result 112425813887778205656\n  Bound result 5000000000000000000\n  Bound result 42\n  Bound result 0\n  Bound result 2144\n  Bound result 0\n  Bound result 8188\n  Bound result 0\n  Bound result 5439\n  Bound result 48879\n  Bound result 3661\n  Bound result 125730279766022191041\n  Bound result 198862906718940596684476443\n  Bound result 555\n  Bound result 398785195490870931061\n  Bound result 53591\n  Bound result 3316\n  Bound result 520\n  Bound result 1000\n  Bound result 373917468282063392455167063\n  Bound result 39603324960979705\n  Bound result 2158831206\n  Bound result 651392191248991516617\n  Bound result 1\n  Bound result 1064470261\n  Bound result 1820\n  Bound result 8918\n  Bound result 91\n  Bound result 30000000000000000000\n  Bound result 5000000000000000000\n  Bound result 300000000000000000000\n  Bound result 427541303\n  Bound result 10000\n  Bound result 300000000000000000000\n  Bound result 424123591297468838530\n  Bound result 5277\n  Bound result 1901\n  Bound result 2056667052\n  Bound result 236\n  Bound result 872\n  Bound result 4517\n  Bound result 1000\n  Bound result 1696625525\n  Bound result 4245069511355882901\n  Bound result 482\n  Bound result 8291\n  Bound result 1236\n  Bound result 36865\n  Bound result 14\n  Bound result 53591\n  Bound result 100000000000000000000\n  Bound result 3\n  Bound result 4395\n  Bound result 0\n  Bound result 3617155993734787770\n  Bound result 500000000000000000000\n  Bound result 25737\n  Bound result 96\n  Bound result 5000000000000000000\n  Bound result 9032\n  Bound result 11192\n  Bound result 3\n  Bound result 582\n  Bound result 49569\n  Bound result 1193484386225944349460029126\n  Bound result 96\n  Bound result 1000\n  Bound result 19684525890\n  Bound result 6000000000000000000\n  Bound result 3041954472\n  Bound result 1634\n  Bound result 161510211829629259524\n  Bound result 96\n  Bound result 1000000000000000000000\n  Bound result 243\n  Bound result 96\n  Bound result 5\n  Bound result 91\n  Bound result 526\n  Bound result 127\n  Bound result 5537\n  Bound result 53591\n  Bound result 10\n  Bound result 304\n  Bound result 81008942\n  Bound result 2\n  Bound result 6610\n  Bound result 244\n  Bound result 243\n  Bound result 10000000000000000000\n  Bound result 781497983036644278624\n  Bound result 10000000000000000001\n  Bound result 2726\n  Bound result 1313373041\n  Bound result 3617155993734787768\n  Bound result 4723367\n  Bound result 4871\n  Bound result 874\n  Bound result 91947156456401172665401206\n  Bound result 36865\n  Bound result 49569\n  Bound result 11685\n  Bound result 884697241723088393386309925\n  Bound result 254\n  Bound result 511497983035330908787\n  Bound result 42\n  Bound result 2350\n  Bound result 1\n  Bound result 11262\n  Bound result 100000000000000000000\n  Bound result 607765960663587132498500815\n  Bound result 48879\n  Bound result 3041954229\n  Bound result 255\n  Bound result 11453\n  Bound result 96\n  Bound result 9558\n  Bound result 9577\n  Bound result 66\n  Bound result 1000000000000000000\n  Bound result 5596\n  Bound result 142017664134061292000\n  Bound result 0\n  Bound result 123895118609517581\n  Bound result 94577615434167650608\n  Bound result 0\n  Bound result 1848604115\n  Bound result 750342782598347555274660307\n  Bound result 999999999999999999999999997\n  Bound result 16413\n  Bound result 1000000000000000000000000000\n  Bound result 5\n  Bound result 305\n  Bound result 53591\n  Bound result 0\n  Bound result 24576\n  Bound result 79\n  Bound result 1561\n  Bound result 984958505662200075725826467\n  Bound result 3342\n  Bound result 4\n  Bound result 1000000000000000000\n  Bound result 768\n  Bound result 0\n  Bound result 6000000000000000000\n  Bound result 49569\n  Bound result 47862590311175737434736704\n  Bound result 74939326150891753181\n  Bound result 1\n  Bound result 2177275378\n  Bound result 22861\n  Bound result 42\n  Bound result 316\n  Bound result 8883\n  Bound result 77297537306135074290\n  Bound result 11422\n  Bound result 7036\n  Bound result 0\n  Bound result 10000\n  Bound result 30788098892295471516836713\n  Bound result 7664003602929380364\n  Bound result 1\n  Bound result 49569\n  Bound result 0\n  Bound result 4587713300248199305\n  Bound result 2283376\n  Bound result 255\n  Bound result 6000000000000000000\n  Bound result 49569\n  Bound result 8368\n  Bound result 20000000000000000000\n  Bound result 956654422668572808131\n  Bound result 95\n  Bound result 8995\n  Bound result 9784070908759721372\n  Bound result 1000000000000000000\n  Bound result 4373448709056643658\n  Bound result 253\n  Bound result 111547123446115251919\n  Bound result 2\n  Bound result 24576\n  Bound result 95\n  Bound result 72709824006672065461\n  Bound result 39472230196733459616\n  Bound result 7783\n  Bound result 0\n  Bound result 9090\n  Bound result 6\n  Bound result 180361710718037542512\n  Bound result 3336\n  Bound result 107224798\n  Bound result 276714894666008\n  Bound result 2\n  Bound result 94900937783934132707755715\n  Bound result 3302\n  Bound result 4853\n  Bound result 631577537495373904961367978\n  Bound result 5825\n  Bound result 617\n  Bound result 8919\n  Bound result 1000000000\n  Bound result 384868846285818\n  Bound result 7\n  Bound result 861923803337920464366459657\n  Bound result 598863171431508208342508367\n  Bound result 0\n  Bound result 5538\n  Bound result 1570\n  Bound result 1000000000000000000000\n  Bound result 2324\n  Bound result 10615\n  Bound result 95\n  Bound result 9464\n  Bound result 2358\n  Bound result 255\n  Bound result 5750\n  Bound result 8788\n  Bound result 2936\n  Bound result 5644\n  Bound result 1\n  Bound result 57197316355039981032\n  Bound result 243\n  Bound result 8655\n  Bound result 48879\n  Bound result 938463463374607431768211455\n  Bound result 0\n  Bound result 48624\n  Bound result 1174\n  Bound result 1976\n  Bound result 1179\n  Bound result 500000000000000000000\n  Bound result 840139107922945579822350335\n  Bound result 543\n  Bound result 1112\n  Bound result 261830057454026009429538989\n  Bound result 0\n  Bound result 4288775752\n  Bound result 11988\n  Bound result 7\n  Bound result 1000000000000000000000000000\n  Bound result 10000000000000000000\n  Bound result 96\n  Bound result 200316517723770249883229607\n  Bound result 684\n  Bound result 243\n  Bound result 7006\n  Bound result 91\n  Bound result 9786\n  Bound result 89034095384859508657324579\n  Bound result 29609\n  Bound result 24576\n  Bound result 336676564345950593702952\n  Bound result 4395\n  Bound result 89434910164978589000\n  Bound result 9779\n  Bound result 10993\n  Bound result 5165\n  Bound result 2045\n  Bound result 261830121658051476869588937\n  Bound result 5844890882888\n  Bound result 5131\n  Bound result 999998999999999997447075379\n  Bound result 529\n  Bound result 7092\n  Bound result 9240\n  Bound result 71056095519202227780794138\n  Bound result 200000000000000000000\n  Bound result 2852\n  Bound result 2000000000000000000000000000\n  Bound result 193738411455873370236669377\n  Bound result 1000000000000000000000\n  Bound result 1000000000000000000000\n  Bound result 2418890150\n  Bound result 4684\n  Bound result 10000000000000000000\n  Bound result 11006\n  Bound result 48625\n  Bound result 3316\n  Bound result 10\n  Bound result 36865\n  Bound result 16413\n  Bound result 9226\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 115.59s (115.58s CPU time)\n\nRan 4 test suites in 115.59s (115.81s CPU time): 57 tests passed, 0 failed, 0 skipped (57 total tests)\n","passed":true},{"durationMs":77,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"WindowShopperToken.approve(address,uint256)\",\"WindowShopperToken.transfer(address,uint256)\",\"WindowShopperToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":111,\"foundry.toml\":20,\"remappings.txt\":2,\"script/DeployWindowShopperToken.s.sol\":25,\"src/WindowShopperToken.sol\":40,\"test/WindowShopperToken.t.sol\":374,\"test/WindowShopperTokenEdges.t.sol\":170,\"test/WindowShopperTokenInvariant.t.sol\":334,\"test/WindowShopperTokenLaunch.t.sol\":156},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"c40da8142cb6dfc0794cdfdc05998faf99c67c70cd3ed5f333db74ab1ac0857f","verifiedTreeHash":"c388a34e162cb8a1aeb180a042760958d0b2b9c6","verifierVersion":"0.1.0+89159ae2"}]}