{"assessments":[],"deployments":[{"attestationHash":"9c02e928ded87428618ee4c0c8b96289825a266275f143b66dce7d9aa185b995","chainId":1,"contracts":[{"address":"0x0969d6dac05490f2241c01366612f7a689039b30","blockNumber":26292123,"name":"PleaToken","role":"token","txHash":"0x1535406546c9ed6daf9004915ca80321098e1a7c7456cd98b5baf97c7fc3efc4"},{"address":"0x954f204bbed49f381bbf8ee97370a0a668807f92","blockNumber":26292123,"name":"MerkleDistributor","role":"distributor","txHash":"0x1535406546c9ed6daf9004915ca80321098e1a7c7456cd98b5baf97c7fc3efc4"},{"address":"0x784ff9a3ac5d88a30bfff6f7f2a270161fbe6000","blockNumber":26292123,"name":"PoolInitializationGuard","role":"hook","txHash":"0x1535406546c9ed6daf9004915ca80321098e1a7c7456cd98b5baf97c7fc3efc4"}],"id":"184a0210-adcb-4889-aaa8-acc73b2d8bce","manifestHash":"0612bb81fe364d951ba71092ef3327caffc368b587e8d6265b0415e7e164bb99","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":"2d3cecca-8359-48d9-87fd-35f1ba6a1df4","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"fab92ca2d2af7e55711ca6a455f0e77302a23830f16ab0fa0c467ebbb52e2999","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":"d6786b56456094686c400561351d3658a391fea0ac31d33e9b520ffb63f70d67","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":"efae99a62227fbf94d7d21d4ef4da071c5cb2cb3c340be4a466cc910a4c38e59","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":"4f95428dde690bce774874b552baf910a9061cea76357dc6358b337ea0b573a5","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":"13340f4b8b348af70f64df5c820781d77df70a29941b4498dfc45e71c577b686","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":"72f73175ddebbed38b6fb453aa022ffe44a9d3ea4b45bad25b951c9486dc811c","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":"9f42d264be99b3badcdf1ba2dab2908eebb703644525f2b40febd32ef3883a79","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"bb315cc5a3b0ae4f2228b0d5bbcf24d2743ce436d6632abf43a9987abda7fc78","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"606842ccca0e7c5d3017a54684625438eab9b351eb51dcf0cf88c43d1ea41464","skillId":"write-foundry-tests","subagents":4,"tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"606842ccca0e7c5d3017a54684625438eab9b351eb51dcf0cf88c43d1ea41464","skillId":"write-foundry-tests","state":"accepted"}],"objective":"A custom token: pleaimd (PLEA).\nToken name: pleaimd\nToken symbol: PLEA\nToken supply: 1,000,000,000 with 18 decimals, all minted once to the deployer in the constructor.","parentJobId":null,"planHash":"7d1478c44ef60da0da38a0831b743f5d90058896b0a0243be5ca756b0c77c425","previousHash":"6eb1523e623bdcb6e299844d4e78496f75175fb7f5b26272577543e4a19e94a4","projectId":"2d3cecca-8359-48d9-87fd-35f1ba6a1df4","publication":{"commit":"309eaab50adc44cdb14aa668689969130e0f55fa","deliveredAt":"2026-10-28T15:25:40.704Z","repoUrl":"https://github.com/identity-md-launches/launch-2636-pleaimd"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[],"site":null,"snapshotHash":"7b06346f7d12de9c6993c4e9bd3213b328d1d4c0de7ee5dcdb3dbf2e8a43892a","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"0b0761c9b10fe0bb","findings":[{"citation":"resolved","description":"Trust-assumption note for holders, not a defect in PleaToken. `approve` overwrites the allowance (ERC20.sol:280) and `transferFrom` spends from whatever allowance is current (ERC20.sol:294-304). A spender who sees a holder's pending `approve(spender, lower)` can front-run it with `transferFrom` for the old allowance, then spend the new one too. This is the well-known ERC-20 approve race; OpenZeppelin v5 deliberately removed increaseAllowance/decreaseAllowance, and the token is specified as a plain fixed-supply ERC-20 with no owner, so there is nothing to fix without changing the agreed design. The README already warns holders about infinite approvals; this note extends that warning to allowance reductions (set to 0 first, then to the new value). Reported so the judge has the only allowance-related behaviour of the permission model on record; vendored ERC20.sol, Context.sol, IERC20.sol, IERC20Metadata.sol and draft-IERC6093.sol were diffed byte-for-byte against upstream OpenZeppelin v5.4.0 and are identical.","line":280,"path":"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol","reproduction":"State: holder H deployed the token (holds 1e27). 1) H calls approve(S, 100e18). 2) H submits approve(S, 50e18); S observes it in the mempool and front-runs with transferFrom(H, S, 100e18) -> succeeds, S holds 100e18. 3) H's approve(S, 50e18) lands. 4) S calls transferFrom(H, S, 50e18) -> succeeds. Expected by H: at most 100e18 ever moved. Actual: S holds 150e18. Verified with a scratch Foundry test (holder=makeAddr('holder'), spender=makeAddr('spender'), sequence above, assertEq(balanceOf(spender), 150 ether) passes). Mitigation is operational: approve 0 before setting a new non-zero allowance.","severity":"info","snippet":"        _allowances[owner][spender] = value;","title":"Standard ERC-20 approve front-running: a spender can move old + new allowance when a holder lowers an approval (inherent to the agreed plain-ERC20 design, no code change recommended)"}],"hash":"13340f4b8b348af70f64df5c820781d77df70a29941b4498dfc45e71c577b686","nodeId":"1113fecc-237f-4acd-97b1-93f4abe8b3ef","outcome":"completed","summary":"The permissions review is complete and the findings file is written. The tree is otherwise unchanged (the scratch test was removed and the findings file is git-ignored by the harness).\n\n**Outcome: no defects in the permission model.** PleaToken is a plain OpenZeppelin v5.4.0 ERC20 with a single constructor mint. The only finding is an informational note, not a fix request.\n\n**What I checked, across the Access Control, Trust Gap and Asymmetry guides:**\n- Permission map: no roles, owner, initializer, upgrade path, pause, blacklist or burn. The compiled ABI exposes exactly approve, transfer and transferFrom as state-changing selectors.\n- Constructor hands out no persistent privilege. It mints exactly the manifest supply to the factory via CREATE2 and takes no arguments, so no exempt list can be misconfigured.\n- Confused deputy: Context is unmodified, so transferFrom authorises against the real caller. The deployer cannot pull from a holder without approval.\n- Asymmetry: transfer and transferFrom share the same _transfer/_update path. The mint and burn internals are unreachable after construction.\n- Vendored library integrity: ERC20.sol, Context.sol and the three interfaces are byte-identical to upstream v5.4.0. Storage layout is the standard five slots.\n- Runtime bytecode: no DELEGATECALL, CALLCODE or SELFDESTRUCT on reachable paths.\n- Build, the 43 project tests, the formatter check and the verifier-seeded fuzz run all pass.\n\n**The one recorded item (info):** the standard ERC-20 approve race. A spender who front-runs a holder lowering an allowance from 100 to 50 can move 150. I reproduced it in a scratch test. It is inherent to the agreed plain-ERC20 design, so I recommend no code change, only the operational advice to approve zero before setting a new value.\n\n**Static-analysis leads:** Slither reported nothing. Aderyn's large-literal note on line 26 is stylistic. The constant evaluates to exactly 1e27, which matches the brief.\n\n**Not reviewable:** launch.json is not yet in the tree, as the README states. The README's intended manifest values match the code.\n\n**Coverage record:** all three listed entry points marked holds, plus six invariant rows (constructor, no admin surface, library integrity, fixed supply, manifest, deploy script).","treeHash":null,"usage":{"cachedInputTokens":558594,"inputTokens":226,"model":"claude-fable-5-1","outputTokens":10729,"runtime":"claude","turns":26,"wallClockMs":160796}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"7f1dec5ffcbde1d8","findings":[],"hash":"4f95428dde690bce774874b552baf910a9061cea76357dc6358b337ea0b573a5","nodeId":"33caaa87-2acd-467b-9cb4-a9b50c66ec32","outcome":"completed","summary":"The math review of PleaToken found no defects. The findings file is written with an empty findings list and eight coverage rows, and the working tree is otherwise untouched.\n\n**What the token is.** `src/PleaToken.sol` is a bare OpenZeppelin v5.4.0 ERC20 with one constructor mint of the whole supply to the deployer. It has no fee, burn, owner, pause, external call, payable path, receive or fallback. All arithmetic that moves value lives in the vendored library.\n\n**What I checked, per guide:**\n\n- **Math Precision.** The supply constant evaluates to exactly 10^27, which also resolves the aderyn large-literal lead. The only unchecked blocks are OpenZeppelin's, each preceded by a checked bound. Self-transfers over the full range 0 to 10^27 leave the balance unchanged. Allowance at max is never decremented, and at max minus one it is decremented exactly. The supply fits in int128, so a Uniswap v4 balance delta cannot truncate it.\n- **Boundary.** There are no external call sites, payable functions, bytes decoding or sentinel branches other than the library's zero-address reverts. Max-uint and supply-plus-one transfers revert with the expected insufficient-balance error. A `transferFrom` from the zero address reverts, so no mint path exists through it.\n- **Numerical Gap.** The conservation invariant holds under an 8-step random-transfer fuzz among four parties. The launch split of 10%, 70% and 20% divides 10^27 with zero remainder.\n\n**Verification steps.** All five vendored OpenZeppelin files hash identically to the files at upstream tag v5.4.0. The existing 43-test suite passes, including with the verifier's fuzz seed. My scratch probes passed except one whose expectation I had written wrong, and that case still reverts correctly. The scratch directory has been removed.\n\n**Not covered.** Nothing in my area was left unreached. The three ABI entry points and the constructor each have a coverage row, plus rows for the conservation invariant, the launch split arithmetic, the boundary inventory and the dependency integrity check.","treeHash":null,"usage":{"cachedInputTokens":505520,"inputTokens":226,"model":"claude-fable-5-1","outputTokens":11283,"runtime":"claude","turns":23,"wallClockMs":152789}},{"artifacts":[],"attempt":1,"bundleHash":"ba50ad1801f832c918a5d5d91a088587cea0346f934aa350d13656b1e70e03b0","device":"20e8e883cb88740a","findings":[],"hash":"72f73175ddebbed38b6fb453aa022ffe44a9d3ea4b45bad25b951c9486dc811c","nodeId":"31607f7b-3fbc-4314-be47-014790193c4f","outcome":"completed","summary":"The pleaimd (PLEA) token is implemented, tested, documented and committed at the repository root as a Foundry project.\n\n**What was built**\n\n- `src/PleaToken.sol` is a plain OpenZeppelin v5.4.0 `ERC20` whose constructor mints the whole supply once to the deployer. It takes no constructor arguments, makes no external calls, and has no owner, mint, burn, pause, blacklist, fee or upgrade path.\n- Name is `pleaimd`, symbol `PLEA`, 18 decimals, supply 1,000,000,000 tokens. The Solidity contract name `PleaToken` is 9 characters, well under the launch's 32-character limit.\n- `script/DeployPleaToken.s.sol` is a local deployment script whose `deploy()` function is tested directly and reads no environment.\n- `foundry.toml` pins solc 0.8.26, sets `bytecode_hash = \"none\"`, enables the optimizer, and leaves ffi off with no filesystem permissions.\n- forge-std v1.9.7 and the OpenZeppelin token, utils and interfaces trees are vendored as ordinary files under `lib/`, with no git submodule.\n- `README.md` documents behaviour, assumptions, the expected manifest token fields, that nothing needs setting after launch, operational responsibilities, and security notes.\n\n**Checks run locally**\n\n| Check | Result |\n|-------|--------|\n| `forge build` | passes |\n| `forge test` with the verifier's fuzz seed | 43 passed, 0 failed |\n| `forge test` with an empty environment | 43 passed, 0 failed |\n| `forge fmt --check` | passes |\n\nThe tests cover metadata, the one-time mint and its events, transfer and transferFrom success and failure paths with exact OpenZeppelin custom errors, allowance handling including the infinite-allowance case, rejection of every common mint and admin selector, a bytecode walk confirming no DELEGATECALL, CALLCODE or SELFDESTRUCT, and a launch-flow suite that deploys via CREATE2 from a factory stand-in and checks the 10/70/20 split arrives whole. Fuzz tests check supply conservation and over-balance and over-allowance reverts.\n\n**Not done here**\n\nSlither is not available on this machine, so it was not run. The design avoids its six hard-fail detectors. No manifest was written, as the brief directs.","treeHash":"700dc15dc398aa69f1486124f273ec5c13318686","usage":{"cachedInputTokens":994020,"inputTokens":610,"model":"claude-fable-5-1","outputTokens":28333,"runtime":"claude","turns":37,"wallClockMs":372749}},{"artifacts":[],"attempt":1,"bundleHash":"0e4d399c0a99d94a3f91b33ef240a8809b9a11ddd2ddb3cf71d3cc159969c1b8","device":"a0f4c3f900dedd4a","findings":[],"hash":"9f42d264be99b3badcdf1ba2dab2908eebb703644525f2b40febd32ef3883a79","nodeId":"332533ec-ce26-4a37-a4bc-84024c433d36","outcome":"completed","summary":"Done. `launch.json` is written and is the only change in the tree.\n\n**What the manifest says**\n- Kind `custom_token`, token contract `PleaToken` with name pleaimd, symbol PLEA, 18 decimals, empty constructorArgs and totalSupply equal to the one billion tokens the constructor mints to msg.sender.\n- An empty contracts list, since the accepted tree contains only the token and no application contracts.\n- The pool block as the launch fixes it: IMD at 0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7 as the paired currency, fee 12500, tick spacing 60, and the one-to-one sqrtPriceX96 as provenance.\n- The requester's economics object copied verbatim.\n- Notes describing the token's fixed supply, lack of any admin path, untaxed transfers, and the absence of application contracts or initialization calls.\n\n**Checks**\n- `forge build` compiles cleanly on solc 0.8.26.\n- `forge test` with the verifier's fuzz seed passes all 43 tests across the three suites.\n- A scratch check confirmed the manifest parses, uses only the schema's top-level keys, matches the compiled ABI's zero constructor parameters, and keeps notes under the limit.\n- `git status` shows launch.json as the only new or changed file.","treeHash":"b769a48dc203e6eaf5acbc3d5045725ffc66baf5","usage":{"cachedInputTokens":134925,"inputTokens":130,"model":"claude-fable-5-1","outputTokens":3236,"runtime":"claude","turns":10,"wallClockMs":63124}},{"artifacts":[],"attempt":1,"bundleHash":"dab85784719e03ec6d48d7ac3a97c8eba479f49a79dbbeb143a5ce215a518909","device":"9506ecec995bdbf9","findings":[],"hash":"bb315cc5a3b0ae4f2228b0d5bbcf24d2743ce436d6632abf43a9987abda7fc78","nodeId":"3036cd51-919d-4b17-ba5a-d704ee73a9e5","outcome":"completed","summary":"I added random-sequence (invariant) tests and edge-case tests for `PleaToken`. I found no defects, so there's no `.imd-findings.json`. With the verifier's fuzz seed, `forge test` passes all 58 tests across 5 test files.\n\n**What I found:** `src/PleaToken.sol` is a plain OpenZeppelin ERC-20. Its constructor mints 1,000,000,000 × 10¹⁸ to the deployer once. It has no owner, no second way to mint, no pause, no fee and no burn. The tests already in the repo cover the basic behaviour, the failure paths and the launch payout steps, but had no invariant tests. I added two files:\n\n- **`test/PleaTokenInvariant.t.sol`**: a helper contract makes random calls with five accounts: transfer, approve, transferFrom, a transfer to the zero address, and a pull by an account with no allowance. Each call is bounded so it sometimes goes one wei past the balance or allowance, so success and failure both get exercised. Each expected failure must revert with OpenZeppelin's exact error. A separate record of balances and allowances is updated only from the call inputs, not from what the token reports. After every sequence these must hold:\n  - total supply stays at 1e27, and the five accounts' balances add up to it;\n  - the zero address, the account with no allowance and the token contract itself hold nothing;\n  - every balance and allowance matches the separate record;\n  - every successful call returned true;\n  - name, symbol and decimals stay fixed.\n\n  It ran 256 runs × 64 calls (16,384 calls), with zero unexpected reverts and no inputs thrown away.\n- **`test/PleaTokenEdges.t.sol`**: cases the existing tests didn't pin down:\n  - the zero address can neither send (even 0) nor approve;\n  - `transfer` of `type(uint256).max` and of the full supply plus one both revert;\n  - an unlimited allowance is still limited by the owner's balance;\n  - an owner calling `transferFrom` on their own balance still needs an allowance;\n  - pulling 0 needs no allowance;\n  - approving 0 revokes an allowance;\n  - repeating a transfer after the balance is spent fails.\n\n  It also has three fuzz tests (1,000 runs each): sending to yourself, a there-and-back transfer, and an allowance spent in two pulls.\n\nOne behaviour worth knowing, not a defect: tokens sent to the token's own address are accepted and can never be moved out, which is standard ERC-20. I wrote a test for it so any change shows up.\n\n**Not committed:** this machine has no git user name or email, and I didn't set one. Both files are staged but not committed. If the upload needs a commit, someone with a git identity has to make it.\n\nI didn't run the two protected launch tests in `.imd/reads/protected/custom_token/`. They need the verifier's environment settings and Uniswap v4 sources that aren't in this repo.","treeHash":"a9b89d27865766c05ae9dd2991dae2019f11bf32","usage":{"cachedInputTokens":273539,"inputTokens":18,"model":"claude-opus-5-5","outputTokens":9539,"runtime":"claude","turns":11,"wallClockMs":99041}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"8ec0eeb0fd2a5504","findings":[],"hash":"d6786b56456094686c400561351d3658a391fea0ac31d33e9b520ffb63f70d67","nodeId":"abba33bb-8445-4d59-9681-76f993f15b9b","outcome":"completed","summary":"I found no defects in my area (Execution Trace, Periphery, First Principles). `.imd-findings.json` has an empty findings list and a coverage row for each of the three entry points, all marked `holds`. I changed no repository files.\n\n**What the code is:** `src/PleaToken.sol` is a plain token built on OpenZeppelin's standard ERC20 (v5.4.0). It doesn't override any of the library's functions and adds no hooks. Its constructor takes no arguments, makes no outside calls, and mints 1,000,000,000 × 10^18 tokens once to the deployer. I compiled the contract's function list: it has only the standard ERC20 functions and four constant getters. There is no mint, burn, owner, pause, upgrade, receive or fallback function. The vendored OpenZeppelin copy has no local changes.\n\n**What I checked:**\n- **Execution Trace:**\n  - **`transfer`:** it rejects a zero sender or recipient, rejects a balance that is too low, and moves exactly the amount asked. So the factory → distributor, distributor → claimant and PoolManager flows arrive whole.\n  - **`transferFrom`:** it rejects a spend above the allowance and leaves an unlimited (maximum) allowance untouched.\n  - **`approve`:** it rejects a zero owner or spender. There are no external calls or callbacks anywhere, so nothing can re-enter.\n- **Periphery:** nothing deploys alongside the token, and the deploy script only creates it.\n- **First Principles:**\n  - **Supply can't grow:** the constructor's mint is the only one.\n  - **No privileged power:** no one can freeze or move a holder's balance.\n  - **Decimals:** they are 18, as stated.\n  - **Exact transfers:** nothing takes a fee or burns on transfer, so seeding the pool and swapping both ways should work.\n- **Static-analysis lead:** aderyn flagged the large number at `src/PleaToken.sol:26`. It works out to 1e27, which matches the stated supply, so it's a style note, not a defect.\n- **Tests:** `forge test` passes all 43 tests. I couldn't run the two supplied launch checks here: they need launch settings this machine doesn't have and contracts that aren't in this tree.\n\n**Known risk, not a defect:** the usual ERC20 `approve` race exists here as in every standard token. Someone holding an allowance can spend the old amount before a change lands. It is standard behaviour, so I didn't report it.","treeHash":null,"usage":{"cachedInputTokens":177639,"inputTokens":12,"model":"claude-opus-5-5","outputTokens":2492,"runtime":"claude","turns":7,"wallClockMs":41620}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"6b0a28df3d585600","findings":[{"citation":"resolved","description":"Merged from audit_permissions (the only specialist finding; audit_flow, audit_math, audit_economics and the tester reported none). Reproduced. `approve` overwrites the allowance (ERC20.sol:280) and `transferFrom` spends whatever allowance is current via `_spendAllowance` (ERC20.sol:294-304), so a spender who sees a holder's pending allowance reduction in the mempool can spend the old allowance first and the new one afterwards. This is the well-known ERC-20 approve race, present in every unmodified OpenZeppelin v5 ERC20; v5 deliberately dropped increaseAllowance/decreaseAllowance. The token is specified as a plain fixed-supply ERC-20 with no owner, and the vendored ERC20.sol, Context.sol, IERC20.sol, IERC20Metadata.sol and draft-IERC6093.sol are byte-identical (sha256) to upstream OpenZeppelin v5.4.0, so there is nothing to fix without changing the agreed design. Kept at info as a holder trust assumption: set an allowance to 0 before setting a new non-zero value, or approve only the amount about to be spent. The README's approvals note (line 68-70) could mention this. Not a defect; does not block the launch.","line":280,"path":"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol","reproduction":"Deploy PleaToken from `holder` (holder receives 1e27). 1) holder.approve(spender, 100e18). 2) holder submits approve(spender, 50e18); spender front-runs with transferFrom(holder, spender, 100e18) -> succeeds. 3) approve(spender, 50e18) lands. 4) spender.transferFrom(holder, spender, 50e18) -> succeeds. Expected by the holder: at most 100e18 ever moved. Actual: balanceOf(spender) == 150e18. Verified with a scratch Foundry test (vm.prank holder/spender for the four calls above, assertEq(token.balanceOf(spender), 150 ether)) which passes on this tree.","severity":"info","snippet":"        _allowances[owner][spender] = value;","title":"Standard ERC-20 approve race: lowering an allowance can be front-run so the spender moves old + new (inherent to the agreed plain-ERC20 design; trust note, no code change)"}],"hash":"efae99a62227fbf94d7d21d4ef4da071c5cb2cb3c340be4a466cc910a4c38e59","nodeId":"57741486-607b-430c-8062-683bc95da898","outcome":"completed","summary":"Review is complete and `.imd-findings.json` is written. The tree is otherwise unchanged (scratch test removed, git status clean).\n\n**Outcome:** no defects. The token is an unmodified OpenZeppelin v5.4.0 ERC20 with a one-time constructor mint, and every check I ran against it holds.\n\n**Specialist findings settled**\n- The one finding, from the permissions specialist, is the standard ERC-20 approve race when a holder lowers an allowance. I reproduced it with a scratch Foundry test: the spender ends with 150e18 after a 100e18 then 50e18 approval. It is inherent to the agreed plain-ERC20 design, so I kept it at info as a holder trust note that does not block the launch. The other three specialists and the tester reported nothing, so there was nothing to merge.\n\n**My own pass**\n- All five vendored OpenZeppelin files the token compiles against hash identically to the upstream v5.4.0 tag.\n- The constant supply equals the manifest's totalSupply exactly, is minted once to msg.sender, and the ABI exposes no mint, owner, pause or burn selector. Decimals match the manifest.\n- A reachable-opcode walk of the compiled runtime finds no DELEGATECALL, CALLCODE, SELFDESTRUCT or any external call. Creation and runtime sizes are far under the limits, so the CREATE2 deployment with an empty argument list works.\n- The full existing suite passes, including the invariant run and the launch-flow test with a CREATE2 factory stand-in.\n- The manifest uses only schema keys, lowercase addresses and correct types, with an empty constructorArgs list matching the zero-parameter constructor.\n- Static analysis leads: slither had nothing. Aderyn's large-numeric-literal line is the supply constant written with underscores and a power of ten, which is correct, so it is not reported.\n\n**Coverage:** all three entry points answered `holds`, plus four invariant rows for the supply mint, bytecode, vendored sources and manifest.","treeHash":null,"usage":{"cachedInputTokens":357841,"inputTokens":226,"model":"claude-fable-5-1","outputTokens":10212,"runtime":"claude","turns":20,"wallClockMs":144778}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"f5666f1d1aa75678","findings":[],"hash":"fab92ca2d2af7e55711ca6a455f0e77302a23830f16ab0fa0c467ebbb52e2999","nodeId":"6d25647f-4d40-4546-9784-eb2d828b20f4","outcome":"completed","summary":"The review found no defects in PLEA's economics. The findings file is written with an empty list and ten coverage rows, and no tracked file changed.\n\n**What was checked, against the Economic Security, Invariant and Flow Gap guides:**\n\n- **Conservation and supply fixity.** The only mint is in the constructor at `src/PleaToken.sol:35`. No burn, mint, owner, pause or upgrade selector exists in the compiled ABI, and transfers to the zero address revert, so supply can neither grow nor shrink. A stateful invariant test with random transfers, approvals and transferFroms kept the sum of balances equal to the fixed supply across 64 runs of depth 64.\n- **Launch flows.** The 10% swarm share, 70% pool seed and 20% requester remainder all arrive whole. A trader buy and sell through a Uniswap v4 style balance-delta settle sees received amounts equal to claimed amounts. The claim from the distributor is exact.\n- **Economic dependencies and token misbehavior.** The token has no fees, hooks, exemptions, external calls or sentinel paths. The compiled runtime and creation code contain no CALL, CREATE, DELEGATECALL, CALLCODE or SELFDESTRUCT opcodes.\n- **Library integrity.** The five vendored OpenZeppelin files the token imports are byte-identical to upstream v5.4.0. The two vendored files containing `delegatecall` are not imported.\n- **Trust assumptions.** Whoever deploys receives the whole supply. In the launch that is the factory by CREATE2 construction. No privileged role survives deployment. The ERC-20 approve race and infinite allowance are inherent to the standard and documented in the README.\n\n**Not reached:** the real v4-core protected harness could not be run locally because v4-core is not vendored here. Its flows were reproduced with a balance-delta stand-in, and the token has no code path that could make a delta differ. The scratch test is in `test/scratch/EconomicsReview.t.sol`, which is gitignored and not submitted.","treeHash":null,"usage":{"cachedInputTokens":622875,"inputTokens":290,"model":"claude-fable-5-1","outputTokens":14765,"runtime":"claude","turns":25,"wallClockMs":253142}}],"verification":[{"checks":[{"durationMs":2037,"exitCode":0,"name":"build","output":"Compiling 30 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.84s\nCompiler run successful!\n","passed":true},{"durationMs":276,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 2 tests for test/DeployPleaToken.t.sol:DeployPleaTokenTest\n[PASS] test_deployMintsSupplyToTheScriptAsDeployer() (gas: 1564046)\n[PASS] test_deployTwiceGivesTwoIndependentTokens() (gas: 2125073)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 12.46ms (12.22ms CPU time)\n\nRan 8 tests for test/PleaTokenLaunch.t.sol:PleaTokenLaunchTest\n[PASS] testFuzz_launchSplitConservesSupply(uint16,uint16) (runs: 256, μ: 240952, ~: 244247)\nLogs:\n  Bound result 1000\n  Bound result 3271\n\n[PASS] test_create2DeploymentMintsToTheFactory() (gas: 34433)\n[PASS] test_creationCodeHasNoConstructorArguments() (gas: 667571)\n[PASS] test_deploymentAddressIsDeterministic() (gas: 660887)\n[PASS] test_factoryCannotMoveOrFreezeAHolderAfterwards() (gas: 176159)\n[PASS] test_fullLaunchSplitLeavesTheFactoryEmpty() (gas: 226196)\n[PASS] test_poolLikeRoundTripMovesExactAmounts() (gas: 198546)\n[PASS] test_swarmShareArrivesWholeAndIsClaimableWhole() (gas: 152549)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 35.01ms (29.08ms CPU time)\n\nRan 33 tests for test/PleaToken.t.sol:PleaTokenTest\n[PASS] testFuzz_anyDeployerReceivesWholeSupply(address) (runs: 256, μ: 21790, ~: 21790)\n[PASS] testFuzz_transferAboveBalanceReverts(address,uint256,uint256) (runs: 256, μ: 102954, ~: 103210)\nLogs:\n  Bound result 18026\n  Bound result 999999999999999999999981992\n\n[PASS] testFuzz_transferFromRespectsAllowance(uint256,uint256) (runs: 256, μ: 136676, ~: 159342)\nLogs:\n  Bound result 36865\n  Bound result 162\n\n[PASS] testFuzz_transferMovesExactlyAmountAndConservesSupply(address,uint256) (runs: 256, μ: 121635, ~: 121574)\nLogs:\n  Bound result 3162\n\n[PASS] test_approveOverwritesPreviousAllowance() (gas: 95868)\n[PASS] test_approveRevertsForZeroSpender() (gas: 32987)\n[PASS] test_approveSetsAllowanceAndEmits() (gas: 68735)\n[PASS] test_chainOfTransfersConservesSupply() (gas: 219234)\n[PASS] test_constructorEmitsTransferFromZeroAndSupplyMinted() (gas: 9292)\n[PASS] test_constructorMakesNoExternalCallsAndNeedsNoCode() (gas: 14606)\n[PASS] test_constructorMintsWholeSupplyToDeployer() (gas: 34746)\n[PASS] test_eachDeploymentMintsToItsOwnDeployer() (gas: 43371)\n[PASS] test_infiniteAllowanceIsNotDecremented() (gas: 136487)\n[PASS] test_metadata() (gas: 59684)\n[PASS] test_noMintOrAdminSelectorExists() (gas: 367901)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 3070640)\n[PASS] test_supportsIERC20Interface() (gas: 21567)\n[PASS] test_totalSupplyConstantMatchesBrief() (gas: 28431)\n[PASS] test_transferFromCannotMoveSomeoneElsesTokensWithoutApproval() (gas: 98579)\n[PASS] test_transferFromExactAllowanceSpendsItAll() (gas: 159391)\n[PASS] test_transferFromRevertsAboveAllowance() (gas: 95660)\n[PASS] test_transferFromRevertsToZeroAddress() (gas: 88819)\n[PASS] test_transferFromRevertsWhenOwnerBalanceTooLow() (gas: 148484)\n[PASS] test_transferFromRevertsWithoutAllowance() (gas: 47770)\n[PASS] test_transferFromWithinAllowanceMovesTokensAndDecrementsAllowance() (gas: 170490)\n[PASS] test_transferMovesExactAmount() (gas: 97066)\n[PASS] test_transferRevertsFromEmptyAccount() (gas: 37777)\n[PASS] test_transferRevertsOnInsufficientBalance() (gas: 112916)\n[PASS] test_transferRevertsToZeroAddress() (gas: 39932)\n[PASS] test_transferToSelfKeepsBalance() (gas: 44519)\n[PASS] test_transferWholeBalance() (gas: 79302)\n[PASS] test_transferZeroAmountSucceeds() (gas: 48305)\n[PASS] test_unknownCalldataAndPlainEtherAreRejected() (gas: 62282)\nSuite result: ok. 33 passed; 0 failed; 0 skipped; finished in 35.07ms (93.87ms CPU time)\n\nRan 3 test suites in 37.98ms (82.54ms CPU time): 43 tests passed, 0 failed, 0 skipped (43 total tests)\n","passed":true},{"durationMs":71,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"PleaToken.approve(address,uint256)\",\"PleaToken.transfer(address,uint256)\",\"PleaToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":11,\"README.md\":122,\"foundry.toml\":23,\"remappings.txt\":2,\"script/DeployPleaToken.s.sol\":27,\"src/PleaToken.sol\":38,\"test/DeployPleaToken.t.sol\":31,\"test/PleaToken.t.sol\":401,\"test/PleaTokenLaunch.t.sol\":147},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":1291,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":841,"exitCode":0,"name":"aderyn","output":"[low] large-numeric-literal at src/PleaToken.sol:26: Large Numeric Literal","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"72f73175ddebbed38b6fb453aa022ffe44a9d3ea4b45bad25b951c9486dc811c","verifiedTreeHash":"700dc15dc398aa69f1486124f273ec5c13318686","verifierVersion":"0.1.0+1d98f47e"},{"checks":[{"durationMs":1753,"exitCode":0,"name":"build","output":"Compiling 30 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.65s\nCompiler run successful!\n","passed":true},{"durationMs":144,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 2 tests for test/DeployPleaToken.t.sol:DeployPleaTokenTest\n[PASS] test_deployMintsSupplyToTheScriptAsDeployer() (gas: 1564046)\n[PASS] test_deployTwiceGivesTwoIndependentTokens() (gas: 2125073)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 761.67µs (459.94µs CPU time)\n\nRan 8 tests for test/PleaTokenLaunch.t.sol:PleaTokenLaunchTest\n[PASS] testFuzz_launchSplitConservesSupply(uint16,uint16) (runs: 256, μ: 240952, ~: 244247)\nLogs:\n  Bound result 6862\n  Bound result 2169\n\n[PASS] test_create2DeploymentMintsToTheFactory() (gas: 34433)\n[PASS] test_creationCodeHasNoConstructorArguments() (gas: 667571)\n[PASS] test_deploymentAddressIsDeterministic() (gas: 660887)\n[PASS] test_factoryCannotMoveOrFreezeAHolderAfterwards() (gas: 176159)\n[PASS] test_fullLaunchSplitLeavesTheFactoryEmpty() (gas: 226196)\n[PASS] test_poolLikeRoundTripMovesExactAmounts() (gas: 198546)\n[PASS] test_swarmShareArrivesWholeAndIsClaimableWhole() (gas: 152549)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 11.77ms (12.76ms CPU time)\n\nRan 33 tests for test/PleaToken.t.sol:PleaTokenTest\n[PASS] testFuzz_anyDeployerReceivesWholeSupply(address) (runs: 256, μ: 21790, ~: 21790)\n[PASS] testFuzz_transferAboveBalanceReverts(address,uint256,uint256) (runs: 256, μ: 102954, ~: 103210)\nLogs:\n  Bound result 69430031416885364719005511\n  Bound result 208329974163022348762977308\n\n[PASS] testFuzz_transferFromRespectsAllowance(uint256,uint256) (runs: 256, μ: 136676, ~: 159342)\nLogs:\n  Bound result 36865\n  Bound result 162\n\n[PASS] testFuzz_transferMovesExactlyAmountAndConservesSupply(address,uint256) (runs: 256, μ: 121635, ~: 121574)\nLogs:\n  Bound result 639781600401806223032403351\n\n[PASS] test_approveOverwritesPreviousAllowance() (gas: 95868)\n[PASS] test_approveRevertsForZeroSpender() (gas: 32987)\n[PASS] test_approveSetsAllowanceAndEmits() (gas: 68735)\n[PASS] test_chainOfTransfersConservesSupply() (gas: 219234)\n[PASS] test_constructorEmitsTransferFromZeroAndSupplyMinted() (gas: 9292)\n[PASS] test_constructorMakesNoExternalCallsAndNeedsNoCode() (gas: 14606)\n[PASS] test_constructorMintsWholeSupplyToDeployer() (gas: 34746)\n[PASS] test_eachDeploymentMintsToItsOwnDeployer() (gas: 43371)\n[PASS] test_infiniteAllowanceIsNotDecremented() (gas: 136487)\n[PASS] test_metadata() (gas: 59684)\n[PASS] test_noMintOrAdminSelectorExists() (gas: 367901)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 3070640)\n[PASS] test_supportsIERC20Interface() (gas: 21567)\n[PASS] test_totalSupplyConstantMatchesBrief() (gas: 28431)\n[PASS] test_transferFromCannotMoveSomeoneElsesTokensWithoutApproval() (gas: 98579)\n[PASS] test_transferFromExactAllowanceSpendsItAll() (gas: 159391)\n[PASS] test_transferFromRevertsAboveAllowance() (gas: 95660)\n[PASS] test_transferFromRevertsToZeroAddress() (gas: 88819)\n[PASS] test_transferFromRevertsWhenOwnerBalanceTooLow() (gas: 148484)\n[PASS] test_transferFromRevertsWithoutAllowance() (gas: 47770)\n[PASS] test_transferFromWithinAllowanceMovesTokensAndDecrementsAllowance() (gas: 170490)\n[PASS] test_transferMovesExactAmount() (gas: 97066)\n[PASS] test_transferRevertsFromEmptyAccount() (gas: 37777)\n[PASS] test_transferRevertsOnInsufficientBalance() (gas: 112916)\n[PASS] test_transferRevertsToZeroAddress() (gas: 39932)\n[PASS] test_transferToSelfKeepsBalance() (gas: 44519)\n[PASS] test_transferWholeBalance() (gas: 79302)\n[PASS] test_transferZeroAmountSucceeds() (gas: 48305)\n[PASS] test_unknownCalldataAndPlainEtherAreRejected() (gas: 62282)\nSuite result: ok. 33 passed; 0 failed; 0 skipped; finished in 16.31ms (61.87ms CPU time)\n\nRan 3 test suites in 17.98ms (28.84ms CPU time): 43 tests passed, 0 failed, 0 skipped (43 total tests)\n","passed":true},{"durationMs":54,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"PleaToken.approve(address,uint256)\",\"PleaToken.transfer(address,uint256)\",\"PleaToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":11,\"README.md\":122,\"foundry.toml\":23,\"launch.json\":24,\"remappings.txt\":2,\"script/DeployPleaToken.s.sol\":27,\"src/PleaToken.sol\":38,\"test/DeployPleaToken.t.sol\":31,\"test/PleaToken.t.sol\":401,\"test/PleaTokenLaunch.t.sol\":147},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"9f42d264be99b3badcdf1ba2dab2908eebb703644525f2b40febd32ef3883a79","verifiedTreeHash":"b769a48dc203e6eaf5acbc3d5045725ffc66baf5","verifierVersion":"0.1.0+1d98f47e"},{"checks":[{"durationMs":2502,"exitCode":0,"name":"build","output":"Compiling 32 files with Solc 0.8.26\nSolc 0.8.26 finished in 2.39s\nCompiler run successful!\n","passed":true},{"durationMs":9117,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 2 tests for test/DeployPleaToken.t.sol:DeployPleaTokenTest\n[PASS] test_deployMintsSupplyToTheScriptAsDeployer() (gas: 1564046)\n[PASS] test_deployTwiceGivesTwoIndependentTokens() (gas: 2125073)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 636.24µs (597.59µs CPU time)\n\nRan 8 tests for test/PleaTokenLaunch.t.sol:PleaTokenLaunchTest\n[PASS] testFuzz_launchSplitConservesSupply(uint16,uint16) (runs: 256, μ: 240420, ~: 244247)\nLogs:\n  Bound result 7000\n  Bound result 2583\n\n[PASS] test_create2DeploymentMintsToTheFactory() (gas: 34433)\n[PASS] test_creationCodeHasNoConstructorArguments() (gas: 667571)\n[PASS] test_deploymentAddressIsDeterministic() (gas: 660887)\n[PASS] test_factoryCannotMoveOrFreezeAHolderAfterwards() (gas: 176159)\n[PASS] test_fullLaunchSplitLeavesTheFactoryEmpty() (gas: 226196)\n[PASS] test_poolLikeRoundTripMovesExactAmounts() (gas: 198546)\n[PASS] test_swarmShareArrivesWholeAndIsClaimableWhole() (gas: 152549)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 31.38ms (32.43ms CPU time)\n\nRan 33 tests for test/PleaToken.t.sol:PleaTokenTest\n[PASS] testFuzz_anyDeployerReceivesWholeSupply(address) (runs: 256, μ: 21790, ~: 21790)\n[PASS] testFuzz_transferAboveBalanceReverts(address,uint256,uint256) (runs: 256, μ: 102935, ~: 103199)\nLogs:\n  Bound result 15385\n  Bound result 999999999999999999999984620\n\n[PASS] testFuzz_transferFromRespectsAllowance(uint256,uint256) (runs: 256, μ: 136296, ~: 146640)\nLogs:\n  Bound result 1000\n  Bound result 162\n\n[PASS] testFuzz_transferMovesExactlyAmountAndConservesSupply(address,uint256) (runs: 256, μ: 121638, ~: 121568)\nLogs:\n  Bound result 3162\n\n[PASS] test_approveOverwritesPreviousAllowance() (gas: 95868)\n[PASS] test_approveRevertsForZeroSpender() (gas: 32987)\n[PASS] test_approveSetsAllowanceAndEmits() (gas: 68735)\n[PASS] test_chainOfTransfersConservesSupply() (gas: 219234)\n[PASS] test_constructorEmitsTransferFromZeroAndSupplyMinted() (gas: 9292)\n[PASS] test_constructorMakesNoExternalCallsAndNeedsNoCode() (gas: 14606)\n[PASS] test_constructorMintsWholeSupplyToDeployer() (gas: 34746)\n[PASS] test_eachDeploymentMintsToItsOwnDeployer() (gas: 43371)\n[PASS] test_infiniteAllowanceIsNotDecremented() (gas: 136487)\n[PASS] test_metadata() (gas: 59684)\n[PASS] test_noMintOrAdminSelectorExists() (gas: 367901)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 3070640)\n[PASS] test_supportsIERC20Interface() (gas: 21567)\n[PASS] test_totalSupplyConstantMatchesBrief() (gas: 28431)\n[PASS] test_transferFromCannotMoveSomeoneElsesTokensWithoutApproval() (gas: 98579)\n[PASS] test_transferFromExactAllowanceSpendsItAll() (gas: 159391)\n[PASS] test_transferFromRevertsAboveAllowance() (gas: 95660)\n[PASS] test_transferFromRevertsToZeroAddress() (gas: 88819)\n[PASS] test_transferFromRevertsWhenOwnerBalanceTooLow() (gas: 148484)\n[PASS] test_transferFromRevertsWithoutAllowance() (gas: 47770)\n[PASS] test_transferFromWithinAllowanceMovesTokensAndDecrementsAllowance() (gas: 170490)\n[PASS] test_transferMovesExactAmount() (gas: 97066)\n[PASS] test_transferRevertsFromEmptyAccount() (gas: 37777)\n[PASS] test_transferRevertsOnInsufficientBalance() (gas: 112916)\n[PASS] test_transferRevertsToZeroAddress() (gas: 39932)\n[PASS] test_transferToSelfKeepsBalance() (gas: 44519)\n[PASS] test_transferWholeBalance() (gas: 79302)\n[PASS] test_transferZeroAmountSucceeds() (gas: 48305)\n[PASS] test_unknownCalldataAndPlainEtherAreRejected() (gas: 62282)\nSuite result: ok. 33 passed; 0 failed; 0 skipped; finished in 37.94ms (131.18ms CPU time)\n\nRan 14 tests for test/PleaTokenEdges.t.sol:PleaTokenEdgesTest\n[PASS] testFuzz_roundTripRestoresBalances(uint256) (runs: 1000, μ: 117692, ~: 117707)\nLogs:\n  Bound result 906825359882796071125543706\n\n[PASS] testFuzz_selfTransferNeverChangesBalance(uint256) (runs: 1000, μ: 47433, ~: 47182)\nLogs:\n  Bound result 906825359882796071125543706\n\n[PASS] testFuzz_splitPullsSpendAllowanceAdditively(uint256,uint256,uint256) (runs: 1000, μ: 190801, ~: 192537)\nLogs:\n  Bound result 33750275552890492118756427\n  Bound result 14032903329958371610920544\n  Bound result 12346173476778650126358391\n\n[PASS] test_approveToZeroRevokes() (gas: 111541)\n[PASS] test_infiniteAllowanceStillBoundByBalance() (gas: 151077)\n[PASS] test_ownerNeedsAllowanceToTransferFromSelf() (gas: 160478)\n[PASS] test_sameTransferTwiceFailsWhenBalanceExhausted() (gas: 147923)\n[PASS] test_transferFromZeroAddressOwnerReverts() (gas: 35956)\n[PASS] test_transferMaxUintReverts() (gas: 38175)\n[PASS] test_transferOneMoreThanSupplyReverts() (gas: 38083)\n[PASS] test_transferToTokenContractIsAcceptedButStuck() (gas: 78752)\n[PASS] test_zeroAddressCannotApprove() (gas: 33042)\n[PASS] test_zeroAddressCannotSendEvenZero() (gas: 33088)\n[PASS] test_zeroAmountTransferFromNeedsNoAllowance() (gas: 68967)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 37.98ms (112.91ms CPU time)\n\nRan 1 test for test/PleaTokenInvariant.t.sol:PleaTokenInvariantTest\n[PASS]\nPleaTokenInvariantTest invariants:\n[PASS] invariant_allowancesMatchModel\n[PASS] invariant_balancesMatchModel\n[PASS] invariant_balancesSumToSupply\n[PASS] invariant_everySuccessfulCallReturnedTrue\n[PASS] invariant_metadataIsFixed\n[PASS] invariant_totalSupplyNeverChanges\n PleaTokenInvariantTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭------------------+----------------+-------+---------+----------╮\n| Contract         | Selector       | Calls | Reverts | Discards |\n+================================================================+\n| PleaTokenHandler | approve        | 3250  | 0       | 0        |\n|------------------+----------------+-------+---------+----------|\n| PleaTokenHandler | strangerPull   | 3305  | 0       | 0        |\n|------------------+----------------+-------+---------+----------|\n| PleaTokenHandler | transfer       | 3341  | 0       | 0        |\n|------------------+----------------+-------+---------+----------|\n| PleaTokenHandler | transferFrom   | 3237  | 0       | 0        |\n|------------------+----------------+-------+---------+----------|\n| PleaTokenHandler | transferToZero | 3251  | 0       | 0        |\n╰------------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 1\n  Bound result 1000000000000000000000\n  Bound result 47866516957\n  Bound result 5202\n  Bound result 700000000000000000000000000\n  Bound result 0\n  Bound result 938479751506293095479340055\n  Bound result 1\n  Bound result 1\n  Bound result 95\n  Bound result 0\n  Bound result 5762\n  Bound result 410\n  Bound result 0\n  Bound result 1\n  Bound result 29072187250\n  Bound result 16154916129\n  Bound result 3909881379\n  Bound result 243\n  Bound result 24576\n  Bound result 5\n  Bound result 100000000000000000000000000\n  Bound result 36865\n  Bound result 10\n  Bound result 285\n  Bound result 10000\n  Bound result 469\n  Bound result 772\n  Bound result 65535\n  Bound result 2\n  Bound result 3714247999\n  Bound result 548\n  Bound result 3225522\n  Bound result 4063\n  Bound result 596\n  Bound result 6570\n  Bound result 7397\n  Bound result 14\n  Bound result 127\n  Bound result 873778254177194297221512596\n  Bound result 413\n  Bound result 7000000000000000000\n  Bound result 10000\n  Bound result 86843643312234242567221225\n  Bound result 180000000000000000000\n  Bound result 481042353298047820791327225\n  Bound result 7000\n  Bound result 390395118\n  Bound result 2989\n  Bound result 1\n  Bound result 25162305582\n  Bound result 7293\n  Bound result 254\n  Bound result 1862\n  Bound result 6613\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 8.97s (8.97s CPU time)\n\nRan 5 test suites in 8.98s (9.08s CPU time): 58 tests passed, 0 failed, 0 skipped (58 total tests)\n","passed":true},{"durationMs":61,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"PleaToken.approve(address,uint256)\",\"PleaToken.transfer(address,uint256)\",\"PleaToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":11,\"README.md\":122,\"foundry.toml\":23,\"remappings.txt\":2,\"script/DeployPleaToken.s.sol\":27,\"src/PleaToken.sol\":38,\"test/DeployPleaToken.t.sol\":31,\"test/PleaToken.t.sol\":401,\"test/PleaTokenEdges.t.sol\":154,\"test/PleaTokenInvariant.t.sol\":207,\"test/PleaTokenLaunch.t.sol\":147},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"bb315cc5a3b0ae4f2228b0d5bbcf24d2743ce436d6632abf43a9987abda7fc78","verifiedTreeHash":"a9b89d27865766c05ae9dd2991dae2019f11bf32","verifierVersion":"0.1.0+1d98f47e"}]}