{"assessments":[],"deployments":[],"fuzz":[],"identity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"interpretation":"Records acceptance and evidence. Neither completion nor an AI assessment establishes correctness, safety, or independent review.","jobId":"95813114-cb44-45b1-ace2-bf0ef2212d8b","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"d6a894e3cb9bd61959338a7d7d8e0a5895752e62b4d2c10c8ef31644d98c6961","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":"ab6ff696096a94d10552ac8463c38b7e4eb5d353386321a8a597849729977c74","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":"bce70948bda67d5b222d68b4cdca0fb791ce25900f651563370e6b18a0c18512","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":"11f61a0964c24c306fd91cad694d68b2735d9a6c808df21d7f0ddd2c18463f45","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":"5ba9aafa7b2a4f32ccccce0249fb22ff89b8b00290c10c9b47dec2e1dd871da7","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":"0084fb29c5b409180eb91ca252d0da8fc3d9657ab093126a138144abcabc1512","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":"7dba48074ec1b4ed44fb6062d10cf890ee8352476b6baa949fd1945323257e4c","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"00ff0225a32c1d793b0376449c4a7a0f8e99b47b1bdb18d8f57c3620e97faaf2","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: plea (PLEA).\nToken name: plea\nToken symbol: PLEA\nToken supply: 1,000,000,000 with 18 decimals, all minted once to the deployer in the constructor.","parentJobId":null,"planHash":"d6399218c935f670f34db8a43c3d3dcab088a2f59999a031d52fdaf6c142d36c","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"95813114-cb44-45b1-ace2-bf0ef2212d8b","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-2649-plea"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"50903","feedbackHash":"943ad383531c3fcfe69393585478deb70d03cb38cbacfbae849d128fa1318b8c","nodeKey":"audit_economics","submissionHash":"d6a894e3cb9bd61959338a7d7d8e0a5895752e62b4d2c10c8ef31644d98c6961","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52587","feedbackHash":"a74a4db51fdbfc3d4773705e19b8bb6d53d46d578c199f9facfcc8d21a410da8","nodeKey":"audit_flow","submissionHash":"ab6ff696096a94d10552ac8463c38b7e4eb5d353386321a8a597849729977c74","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52127","feedbackHash":"a66cd8e69733c75253e2f363ae6a074298e76a9690ee99d2a9cd9657e18b2646","nodeKey":"audit_judge","submissionHash":"bce70948bda67d5b222d68b4cdca0fb791ce25900f651563370e6b18a0c18512","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"50966","feedbackHash":"b94480f76dc79f961e36cdd1eba5db22dceb61dfa43406549662d144b496a26b","nodeKey":"audit_math","submissionHash":"11f61a0964c24c306fd91cad694d68b2735d9a6c808df21d7f0ddd2c18463f45","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52162","feedbackHash":"9717551eb5f8d7870827fad1e6f5964347c02b75bddd0820f67db4fd9d87a98a","nodeKey":"audit_permissions","submissionHash":"5ba9aafa7b2a4f32ccccce0249fb22ff89b8b00290c10c9b47dec2e1dd871da7","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"53925","feedbackHash":"d25d4759a6ef23c0c7f57c6884e0771b6822848530da16c14ec2139f46e35a34","nodeKey":"build_contract_project","submissionHash":"0084fb29c5b409180eb91ca252d0da8fc3d9657ab093126a138144abcabc1512","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51522","feedbackHash":"a7a73be398b1d3e09d304c7011c42d23f63aeb0fe6e640f0e7555a79a331031f","nodeKey":"manifest","submissionHash":"7dba48074ec1b4ed44fb6062d10cf890ee8352476b6baa949fd1945323257e4c","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52214","feedbackHash":"ae7487083fd895c1bd59a9f99181a5f86ddb4e165b659d5c6ef70e994ac456b8","nodeKey":"write_foundry_tests","submissionHash":"00ff0225a32c1d793b0376449c4a7a0f8e99b47b1bdb18d8f57c3620e97faaf2","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"08351ec673bbeccd31c5b656cdc8d3cae5d0bab92ca9086bc1e4de8bcd7b9f2a","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":"abdcb50746b00b5165810615e6924d18b009ff16343cc437e9c15fe0e3e0669e","device":"96ecbe9236c400bb","findings":[],"hash":"0084fb29c5b409180eb91ca252d0da8fc3d9657ab093126a138144abcabc1512","nodeId":"63576e87-db2c-414d-aeae-d711873c8f39","outcome":"completed","summary":"The plea (PLEA) token is built, tested, documented and committed as commit 8612830 on main.\n\n**What was delivered**\n\n- `src/PleaToken.sol` is a self-contained fixed-supply ERC-20. The constructor mints 1,000,000,000 PLEA with 18 decimals to `msg.sender` once and emits the mint Transfer. There is no owner, mint, burn, pause, blocklist, proxy, fallback or receive, and transfers carry no fee, so the launch flows the protected floor exercises move exactly what they say.\n- `foundry.toml` pins `solc = \"0.8.26\"`, sets `bytecode_hash = \"none\"`, leaves ffi off and grants no filesystem permissions. forge-std v1.9.6 is vendored under `lib/forge-std` as ordinary files with its git metadata stripped, so no submodule and no network is needed.\n- `README.md` documents the token's behaviour, the launch parameters as given, the assumptions made, operational responsibilities after launch, and the security checklist items that apply.\n\n**Verification**\n\n| Check | Result |\n| --- | --- |\n| forge build (clean, offline, empty env) | success |\n| forge test with the verifier's fuzz seed | 36 passed, 0 failed |\n| forge fmt --check | clean |\n\nThe tests cover metadata and supply, the mint to both an EOA and a contract deployer with the factory paying out whole, every transfer, approve and transferFrom success path with events, every revert path with its exact custom error, the absence of mint, admin, pause and freeze entry points from a stranger and from the deployer, ETH and unknown-call rejection, an opcode scan for DELEGATECALL, CALLCODE and SELFDESTRUCT, five fuzz tests, and a handler-driven invariant suite checking constant supply, balances summing to supply and no stray balances.\n\n**Not run.** Slither is not available on this machine, so it was not run. The code avoids the patterns its blocking detectors flag, and the README says so. The commit was authored under the workspace's existing identity because no git identity was configured here.","treeHash":"5d85fa0812882523d18acb8e5d8d8fc85665b636","usage":{"cachedInputTokens":740716,"inputTokens":418,"model":"claude-fable-5-1","outputTokens":22738,"runtime":"claude","turns":26,"wallClockMs":268250}},{"artifacts":[],"attempt":1,"bundleHash":"1917b1454e48e5817bda5456706d07e845762f609a9a5b290902141334b81c60","device":"6b47d1bf92391c22","findings":[],"hash":"00ff0225a32c1d793b0376449c4a7a0f8e99b47b1bdb18d8f57c3620e97faaf2","nodeId":"06c6cb6c-ba33-40b6-9319-e627f9649fa3","outcome":"completed","summary":"I added `test/PleaToken.model.t.sol` and left the earlier contributors' tests untouched. `forge build` succeeds and `forge test` with the verifier's seed passes all 50 tests (36 existing, 14 new), with 0 reverts in either invariant run.\n\n**What the new file adds:**\n- **Model-based invariant tests** (256 runs, depth 64, set inline in the file): the test handler keeps its own copy of every balance and allowance across five holders, including the token's own address. After every random call sequence the tests check three things:\n  - every balance and allowance matches that copy;\n  - balances add up to exactly 1,000,000,000 × 10¹⁸ and the supply never changes;\n  - nothing ends up at addresses outside the five holders.\n- **Failing calls inside the random sequences:** sending more than you hold, sending to the zero address, approving the zero address, spending past an allowance, and spending within an allowance but past the owner's balance. Each must fail with the exact error and values and change nothing; in particular, a failed `transferFrom` must not use up the allowance.\n- **Edge-case unit tests:**\n  - the launch payout (10% to the distributor, paid out to claimants down to the last unit, then the pool share and the remainder);\n  - an unlimited allowance is still limited by the owner's balance;\n  - an allowance of max − 1 counts down like any other;\n  - a holder needs an allowance to `transferFrom` their own tokens;\n  - `transferFrom` from an owner to themselves keeps the balance but still uses the allowance;\n  - a zero-amount `transferFrom` works without an allowance;\n  - nobody can pull tokens from the zero address;\n  - a zero-amount transfer to the zero address is refused;\n  - tokens sent to the token contract stay there.\n- **Fuzz tests (1000 runs each):** a token passed along two holders keeps the total intact; a failed over-balance `transferFrom` leaves the allowance alone; repeated spending never goes past the approved amount.\n\n**No defects found.** `src/PleaToken.sol` is a plain fixed-supply ERC-20 with no owner or admin functions, no fees and no mint after deployment. Every property I tested holds, so there was nothing to report and I didn't create `.imd-findings.json`. I installed no dependencies and made no commits.","treeHash":"66614f6dd11e578e1b62216d7e8e12050b04fb8f","usage":{"cachedInputTokens":250618,"inputTokens":16,"model":"claude-opus-5-5","outputTokens":9768,"runtime":"claude","turns":9,"wallClockMs":105946}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"759c614fdc84ff66","findings":[],"hash":"11f61a0964c24c306fd91cad694d68b2735d9a6c808df21d7f0ddd2c18463f45","nodeId":"6196f6a2-05d6-4f33-a946-2531366cfd4e","outcome":"completed","summary":"I found no math, boundary or numerical defects in the PLEA token (`src/PleaToken.sol`), so the findings list in `.imd-findings.json` is empty. All three entry points (`approve`, `transfer`, `transferFrom`) are marked `holds`, along with two invariant rows. No repository files were changed; I deleted my scratch test file afterwards.\n\n**Coverage.** I checked the contract against the Math Precision, Boundary and Numerical Gap guides from the Pashov reference:\n- **Math Precision:** the contract has no division, scaling, downcast or rounding. The total supply constant works out to exactly 10^27 (1,000,000,000 with 18 decimals), which matches the brief and `decimals() = 18`.\n- **Unchecked arithmetic:** both unchecked subtractions are guarded by a check just before them, so they can't underflow. The unchecked `balanceOf[to] += amount` can't overflow because all balances always add up to the fixed 10^27 supply.\n- **Boundary:** I tested amounts of 0, the whole balance, and one more than the balance (it reverts). I also tested allowances at the maximum (treated as unlimited, never reduced), maximum minus 1 (reduced normally to maximum minus 2), exactly enough, and one short (it reverts). The contract makes no external calls and has no payable functions or input decoding.\n- **Numerical Gap:** sending to yourself, including through `transferFrom` where the spender, sender and receiver are the same address, leaves the balance unchanged and reduces the allowance correctly. Zero-amount transfers can't break the supply total.\n\n**Tests.** The project's own 43 tests pass, including the invariant suite (64 runs, 2,048 calls, no reverts). My extra fuzz tests covering the cases above also passed.\n\n**Static analysis.** Aderyn's only flag, a large number in the supply constant at line 29, is a style warning. The value is correct, so I didn't report it.\n\n**Not reported:** anyone can call `transferFrom(address(0), x, 0)` and `transferFrom(victim, x, 0)` without an allowance. That emits a Transfer event worth 0 tokens, which can look like a mint to block explorers or be used for address-poisoning spam. This is allowed by the ERC-20 standard and changes no state. One difference: OpenZeppelin's version rejects a sender of `address(0)`, and this contract doesn't. I left it out because it isn't a defect that can be reproduced.\n\n**Outside my area:** I skimmed access control and the launch flow. The contract has no owner and no way to mint, pause or freeze, and nothing is charged on transfers, so the factory, distributor and pool transfers arrive in full. I didn't run the launch harness tests, because they need the launch's environment variables and contracts that aren't in this tree.","treeHash":null,"usage":{"cachedInputTokens":225815,"inputTokens":14,"model":"claude-opus-5-5","outputTokens":4877,"runtime":"claude","turns":7,"wallClockMs":80480}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"f9cb4fd544aa3c68","findings":[{"citation":"resolved","description":"Asymmetry pass (branch/validation diff). `_transfer` rejects `to == address(0)` (InvalidReceiver) but has no mirror check on `from`. `transfer` always passes `msg.sender`, which can never be the zero address on chain, but `transferFrom` passes a caller-chosen `from`. For `from = address(0)` the allowance read at line 110 is `allowance[address(0)][msg.sender]`, which is always 0 because `approve` can only be called with `msg.sender` as the owner. A 0-value transfer needs a 0 allowance, so `transferFrom(address(0), to, 0)` clears the allowance check (line 112: `0 < 0` is false), clears the balance check (line 128: `balanceOf[address(0)]` is 0, `0 < 0` is false) and reaches `emit Transfer(address(0), to, 0)` at line 134. The NatSpec on the Transfer event (line 35-36) says the constructor mint is the event with `from == address(0)`; in fact any unprivileged caller can emit that event shape at will, against any recipient. OpenZeppelin's `_transfer` rejects a zero `from` with `ERC20InvalidSender`, so this deviates from the reference behaviour the code says it follows. Balances and totalSupply are untouched, so the impact is limited to off-chain consumers: an indexer, explorer or airdrop-eligibility script that classifies `Transfer` logs with `from == address(0)` as mints, or that counts mint events per address, sees spurious zero-value mints that no privileged actor produced. Reported as low because no value moves. Minimal fix that preserves intended behaviour: add `if (from == address(0)) revert InvalidSender(from);` (new error) at the top of `_transfer`, mirroring the receiver check; `transfer` is unaffected because `msg.sender` is never zero, and `transferFrom` only loses the zero-sender path.","line":126,"path":"src/PleaToken.sol","reproduction":"State: freshly deployed PleaToken, any account `attacker` with no balance and no allowance from anyone. Call, from `attacker`: `token.transferFrom(address(0), attacker, 0)`. Expected (per OpenZeppelin semantics and the contract's own NatSpec that only the constructor mint carries `from == address(0)`): revert with an invalid-sender error. Actual: the call returns true and emits `Transfer(from=0x0000000000000000000000000000000000000000, to=attacker, value=0)`; `allowance[address(0)][attacker]` is written back as 0 and `balanceOf[address(0)]` as 0 (no-ops); `totalSupply()` stays 1000000000000000000000000000 and `balanceOf(attacker)` stays 0. Verified with a scratch Foundry test (test/scratch/ZeroSender.t.sol, not kept): `vm.recordLogs(); vm.prank(attacker); token.transferFrom(address(0), attacker, 0);` records exactly one log with topic0 = keccak256(\"Transfer(address,address,uint256)\"), topic1 = address(0), topic2 = attacker, data = 0. A test asserting the call reverts fails on the current code and passes once `_transfer` rejects `from == address(0)`.","severity":"low","snippet":"        if (to == address(0)) revert InvalidReceiver(to);\n        uint256 fromBalance = balanceOf[from];\n        if (fromBalance < amount) revert InsufficientBalance(from, fromBalance, amount);","title":"_transfer validates the receiver but not the sender: anyone can emit a mint-shaped Transfer(address(0), to, 0) through transferFrom"}],"hash":"5ba9aafa7b2a4f32ccccce0249fb22ff89b8b00290c10c9b47dec2e1dd871da7","nodeId":"b9dc2037-a3b3-4b84-880f-d2c9263e6e0a","outcome":"completed","summary":"Review complete. The findings file is written and validated, and the scratch tests are removed. Git status is clean apart from the ignored findings file.\n\n**Outcome.** The permissions audit of `src/PleaToken.sol` found one low-severity defect and no access-control, trust-gap or privilege issue. The contract has no owner, no modifier, no initializer, no external call and no receive or fallback. The compiled ABI confirms the only state-changing entry points are approve, transfer and transferFrom.\n\n**Finding 1 (low).** The internal transfer helper rejects a zero receiver but never checks the sender. Through transferFrom, any account can pass the zero address as the sender with a zero amount. The allowance from the zero address is always zero, and a zero-value transfer needs only a zero allowance, so the call succeeds and emits a Transfer event from the zero address. That is the exact event shape the contract documents as the constructor mint. Balances and supply are untouched, so the harm is limited to indexers or airdrop scripts that classify such logs as mints. OpenZeppelin rejects this case with an invalid-sender error. The minimal fix is a mirror check on the sender at the top of the transfer helper. I reproduced it with a Foundry test that fails on the current code and would pass with that check.\n\n**Coverage.** Seven rows are recorded. The three listed entry points and the constructor are each traced. approve and transfer hold. transferFrom carries the finding. Three invariant rows cover the Access Control, Trust Gap and Asymmetry passes, with the Asymmetry row pointing to the same finding. I also verified by test that a max allowance still enforces balance, that max minus one is decremented, that allowances are per spender, and that self-transfer through an allowance does not double-count.\n\n**Not reached.** Nothing in the assigned area was left unverified. The existing test suite passes, with every test and the invariant run green. Items outside my area such as pool seeding and the manifest were not examined, since no manifest exists yet in this tree and the token takes no constructor arguments.","treeHash":null,"usage":{"cachedInputTokens":641185,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":14294,"runtime":"claude","turns":27,"wallClockMs":218403}},{"artifacts":[],"attempt":1,"bundleHash":"63a6fc66bea6d8ef7093925e7e2677eec34a2c9cb05d1283acc8e4e93e717be0","device":"fd7c32744e171d7d","findings":[],"hash":"7dba48074ec1b4ed44fb6062d10cf890ee8352476b6baa949fd1945323257e4c","nodeId":"45910984-31e2-4164-b3ba-1ec32024ea7d","outcome":"completed","summary":"Created [launch.json](/home/imd1161/.identitymd/work/95813114-cb44-45b1-ace2-bf0ef2212d8b/45910984-31e2-4164-b3ba-1ec32024ea7d/launch.json) with the accepted `PleaToken` metadata, exact supply, empty constructor arguments, and required pool and economics values.\n\n`forge build` succeeded. `forge test` passed all 36 tests with the supplied fuzz seed. Only `launch.json` is included in the deliverable changes.","treeHash":"b7b7ec1b5870e4c0347445f5ec4679ddafc16b52","usage":{"cachedInputTokens":129280,"inputTokens":31877,"model":"gpt-6-astra","outputTokens":2304,"runtime":"codex","turns":3,"wallClockMs":44517}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"fb1af3f11ddf6470","findings":[],"hash":"ab6ff696096a94d10552ac8463c38b7e4eb5d353386321a8a597849729977c74","nodeId":"6bca06c6-8dae-4cfc-9901-ca1b0fd5cb78","outcome":"completed","summary":"I found no defects I can back up with a failing input in `src/PleaToken.sol`, the only production file. `.imd-findings.json` contains `{\"findings\":[]}` and coverage rows for all three entry points, plus two rows for the supply and \"no privileged hand\" invariants.\n\n**What I checked, guide by guide:**\n- **Execution Trace:**\n  - **`transfer`:** it rejects a transfer to the zero address or for more than the sender's balance before it writes anything.\n  - **`transferFrom`:** it checks the allowance before reducing it. An allowance of `type(uint256).max` means unlimited and is never reduced.\n  - **Arithmetic and reverts:** `balanceOf[to] += amount` skips overflow checks, but the sum of all balances is fixed at 1e27, so it can't overflow. A failed transfer reverts the whole call, including the allowance change.\n  - **Edge cases:** sending to yourself leaves your balance unchanged, and zero-amount transfers work on both functions. I fuzzed both in a scratch test, which I then deleted.\n- **Periphery:** The contract makes no external calls and has no hooks, `receive` or `fallback`; sending it ETH or an unknown function call reverts. There is no fee or burn on transfer, so all four launch flows move exactly the stated amount: the factory paying the distributor, distributor claims, the pool seed, and swaps through the pool manager. The constructor takes no arguments, which matches the README's `constructorArgs: []` and the plan to take no exemptions.\n- **First Principles:** The whole supply of 1,000,000,000 × 10¹⁸ is minted once, to the deployer (the factory, which deploys it at a precomputed address). Nothing can mint more: there is no mint, burn, owner, pause, blocklist or upgrade path, and no assembly. Decimals is the constant 18.\n\n**Checks run:** the repository's own tests (35 unit tests and an invariant suite of 2,048 calls) and my scratch edge-case tests all passed, 42 in total. I did not run the protected launch test (`Token.protected.t.sol`): it needs the floor harness and environment variables, and this tree has neither.\n\n**Static analysis:**\n- **slither:** reported nothing.\n- **aderyn:** its one low note, a large number written out at line 29, is just the supply constant and not a defect.\n\n**Not reported:** `transferFrom(address(0), to, 0)` succeeds and emits a zero-value `Transfer` event from the zero address. It moves nothing, so I left it out as harmless. Other contracts and checks were out of reach: there are no application contracts, and no `launch.json` exists yet.","treeHash":null,"usage":{"cachedInputTokens":147900,"inputTokens":10,"model":"claude-opus-5-5","outputTokens":4013,"runtime":"claude","turns":5,"wallClockMs":55571}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"fd5402086dce252e","findings":[{"citation":"resolved","description":"Merged from audit_permissions (its only finding; economics, flow, math and the tester reported nothing). Reproduced against the code. `_transfer` (src/PleaToken.sol:125-135) rejects `to == address(0)` but has no mirror check on `from`. `transfer` always passes `msg.sender`, which cannot be zero, but `transferFrom` (line 109) passes a caller-chosen `from`. With `from = address(0)`, `allowance[address(0)][msg.sender]` at line 110 is always 0 because `approve` only ever writes `allowance[msg.sender][...]`; a zero amount satisfies `allowed < amount` (line 112, `0 < 0` is false) and `fromBalance < amount` (line 128, `balanceOf[address(0)]` is 0 and `0 < 0` is false), so execution reaches `emit Transfer(address(0), to, 0)` at line 134. The NatSpec on the event (lines 35-36) says the constructor mint is the Transfer with `from == address(0)`; in fact any unprivileged caller can emit that shape at will toward any recipient. OpenZeppelin's `_transfer`, which the code says it follows, reverts with `ERC20InvalidSender` here. No balance, allowance or supply changes (the writes at lines 114 and 131 store 0 over 0), so the impact is confined to off-chain consumers that classify `Transfer` logs with `from == address(0)` as mints (indexers, explorers, airdrop-eligibility scripts). Severity stays low: no value moves and no launch flow or protected invariant is affected. Minimal fix preserving intended behaviour: add `error InvalidSender(address sender);` and `if (from == address(0)) revert InvalidSender(from);` as the first line of `_transfer`. `transfer` is unaffected because `msg.sender` is never zero.","line":126,"path":"src/PleaToken.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {PleaToken} from \"src/PleaToken.sol\";\n\n/// @notice Fails on the current code: an unprivileged caller with no balance and no allowance can\n///         call transferFrom(address(0), self, 0), which succeeds and emits a mint-shaped\n///         Transfer(address(0), self, 0). Passes once _transfer rejects from == address(0).\ncontract ZeroSenderProof is Test {\n    PleaToken token;\n    address attacker = address(0xA77);\n\n    function setUp() public {\n        token = new PleaToken();\n    }\n\n    function test_transferFromZeroSenderMustRevert() public {\n        vm.prank(attacker);\n        (bool ok,) = address(token).call(abi.encodeCall(PleaToken.transferFrom, (address(0), attacker, 0)));\n        assertFalse(ok, \"transferFrom with from == address(0) succeeded and emitted Transfer(0x0, attacker, 0)\");\n    }\n}","reproduction":"State: freshly deployed PleaToken (any deployer); `attacker` = 0x0A77 holds no tokens and has no allowance from anyone. Call from `attacker`: `token.transferFrom(address(0), attacker, 0)`. Expected (per the contract's own NatSpec and the OpenZeppelin semantics it cites): revert with an invalid-sender error. Actual: returns true and emits exactly one log with topic0 = keccak256(\"Transfer(address,address,uint256)\"), topic1 = 0x0000000000000000000000000000000000000000, topic2 = attacker, data = 0; `totalSupply()` stays 1000000000000000000000000000 and `balanceOf(attacker)` stays 0. Verified with a scratch Foundry test using vm.recordLogs (passes on current code, asserting the spurious event) and with the attached proof test, which asserts the call reverts: it fails on the current code with the message `transferFrom with from == address(0) succeeded and emitted Transfer(0x0, attacker, 0)` and passes once `_transfer` rejects `from == address(0)`. With a non-zero amount the call reverts with InsufficientAllowance(attacker, 0, 1), so only the zero-value shape is reachable.","severity":"low","snippet":"        if (to == address(0)) revert InvalidReceiver(to);","title":"_transfer validates the receiver but not the sender: anyone can emit a mint-shaped Transfer(address(0), to, 0) via transferFrom"}],"hash":"bce70948bda67d5b222d68b4cdca0fb791ce25900f651563370e6b18a0c18512","nodeId":"33b0f63d-fb30-4118-9a97-9a5e8efebf29","outcome":"completed","summary":"Review complete. The findings file is written at `.imd-findings.json` with one finding and eight coverage rows. No repository files were changed. The scratch directory was removed after use.\n\n**Outcome:** PleaToken is a 136-line self-contained fixed-supply ERC-20 with no owner, mint, burn, pause or external call. The project's own suite of 50 tests, including the invariant suite, passes. One specialist finding was kept at low severity. Nothing was found that affects funds, launch flows or the protected floor.\n\n**Finding kept (low):** `_transfer` in src/PleaToken.sol checks the receiver but not the sender. Because `approve` only ever writes the caller's own allowance row, the allowance from the zero address is always zero, so an unprivileged caller can run `transferFrom(address(0), self, 0)` and emit a mint-shaped `Transfer(0x0, self, 0)` event. Balances, allowances and supply do not change. The impact is confined to off-chain indexers that treat zero-sender transfers as mints. I reproduced it two ways:\n\n- A scratch test with `vm.recordLogs` confirmed exactly one Transfer log with sender zero and value zero, and that a non-zero amount reverts with InsufficientAllowance.\n- The attached proof test asserts the call reverts. It fails on the current code and passes once `_transfer` rejects a zero sender, which is the minimal fix.\n\n**Specialists:** permissions reported this one finding, and economics, flow, math and the tester reported none, so there were no duplicates to merge. The aderyn large-literal lead is a compile-time constant that the project test confirms equals 1e27, so it was dropped.\n\n**Coverage:** all three entry points answered. `approve` and `transfer` hold. `transferFrom` carries finding 1. Additional rows record the constant supply, the argument-free constructor mint matching launch.json, the absence of privileged functions and forbidden opcodes, the balance-sum invariant, and the manifest's schema validity. Creation code is 2064 bytes and runtime 1619 bytes, well inside the deployment limits.","treeHash":null,"usage":{"cachedInputTokens":372018,"inputTokens":226,"model":"claude-fable-5-1","outputTokens":8698,"runtime":"claude","turns":17,"wallClockMs":132475}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"523ef565dd740e25","findings":[],"hash":"d6a894e3cb9bd61959338a7d7d8e0a5895752e62b4d2c10c8ef31644d98c6961","nodeId":"ce8eca7a-a47e-46f9-b3ed-28fba676e4ad","outcome":"completed","summary":"I found no defects in my area: the economic-security, invariant and flow-gap review of `src/PleaToken.sol`. `.imd-findings.json` has an empty findings list and a coverage row for each of the three entry points, all marked `holds`.\n\n**What I checked:**\n- **Supply and conservation:** only the constructor sets balances, crediting exactly 1,000,000,000 × 10^18 to the deployer. There is no mint, burn, owner, pause, blocklist, proxy, `receive` or `fallback`. The unchecked addition in `_transfer` can't overflow because the sum of all balances never exceeds that fixed supply.\n- **Launch flows:** transfers charge no fee, burn or tax, and no address gets special treatment. The factory's transfer to the distributor, the claim payouts, the pool seed through the PoolManager and later trades all move exactly the amount stated, so the token doesn't need any constructor arguments to exempt launch addresses.\n- **`transferFrom`:** the allowance is checked before the unchecked subtraction, and an unlimited (`type(uint256).max`) allowance is never reduced. Sending to yourself, or a holder acting as their own spender, leaves both the balance and the allowance correct.\n- **Edge cases:** I looked at zero amounts, zero-address receivers and spenders, overspending, and ETH sent to the contract. Each either reverts or does nothing.\n- **Known ERC-20 quirks:** two standard behaviours don't amount to findings:\n  - **Allowance overwrite race:** `approve` replaces an allowance rather than adding to it, so a spender can use the old allowance and then the new one. This is standard ERC-20 and the code's comments document it.\n  - **Zero-value call:** anyone can call `transferFrom(address(0), x, 0)`. It succeeds, moves nothing and only emits a zero-value `Transfer` event.\n- **Static analysis:** the one tool warning (a large number written out at line 29) is just the supply constant and isn't a defect.\n\n**Tests:** all 36 existing tests pass, including the invariant suite. I also wrote fuzz tests in `test/scratch/` for self-transfers, exact delivery, allowance accounting, rejection of overspending and invalid calls, and a 10% distributor flow. All passed, and I deleted them afterwards, so `.imd-findings.json` is the only file I created.\n\n**Not covered:**\n- I couldn't run the supplied launch tests (`Token.protected.t.sol` and `Owners.protected.t.sol`). They need `src/LaunchLiquidity.sol`, `PoolInitializationGuard`, `HookFlags` and `floor/OwnerChecks.sol`, which aren't in this tree, so the Uniswap v4 seed-and-swap check wasn't executed. I reached that conclusion by reading the code instead.\n- I did confirm that the pair token address the README gives (`0xd34a…63b7`) holds a contract with symbol `IMD` on chain 1, the chain the README names.","treeHash":null,"usage":{"cachedInputTokens":254689,"inputTokens":14,"model":"claude-opus-5-5","outputTokens":5061,"runtime":"claude","turns":7,"wallClockMs":59853}}],"verification":[{"checks":[{"durationMs":1236,"exitCode":0,"name":"build","output":"Compiling 21 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.14s\nCompiler run successful!\n","passed":true},{"durationMs":277,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 35 tests for test/PleaToken.t.sol:PleaTokenTest\n[PASS] testFuzz_approveRoundTrips(address,uint256) (runs: 256, μ: 76448, ~: 76773)\n[PASS] testFuzz_transferAboveBalanceReverts(uint256,uint256) (runs: 256, μ: 99989, ~: 100270)\nLogs:\n  Bound result 11726\n  Bound result 60000000000000000000\n\n[PASS] testFuzz_transferConservesSupply(address,uint256) (runs: 256, μ: 95799, ~: 95970)\nLogs:\n  Bound result 230904708412089464196671298\n\n[PASS] testFuzz_transferFromAboveAllowanceReverts(uint256,uint256) (runs: 256, μ: 95213, ~: 95288)\nLogs:\n  Bound result 227916475439545970971808774556\n  Bound result 115792089237316195423570985008687907853269984665412647564020714307442779857996\n\n[PASS] testFuzz_transferFromWithinAllowance(uint256,uint256) (runs: 256, μ: 155938, ~: 156770)\nLogs:\n  Bound result 678261869442345110682950725\n  Bound result 343705073273114794185592480\n\n[PASS] test_allowanceIsPerSpender() (gas: 87788)\n[PASS] test_approveCanExceedBalance() (gas: 65704)\n[PASS] test_approveOverwritesRatherThanAdds() (gas: 95161)\n[PASS] test_approveRevertsForZeroSpender() (gas: 32803)\n[PASS] test_approveSetsAllowanceAndEmits() (gas: 68021)\n[PASS] test_constructorEmitsMintTransfer() (gas: 8052)\n[PASS] test_constructorMintsWholeSupplyToDeployer() (gas: 23287)\n[PASS] test_contractDeployerReceivesSupplyNotTxOrigin() (gas: 366696)\n[PASS] test_deployerCannotPullFromHolder() (gas: 97791)\n[PASS] test_metadata() (gas: 26726)\n[PASS] test_noMintOrAdminFunctionExists() (gas: 989388)\n[PASS] test_noPauseOrFreezeFunctionExists() (gas: 426145)\n[PASS] test_rejectsEtherAndUnknownCalls() (gas: 61346)\n[PASS] test_runtimeCodeHasNoDelegatecallOrSelfdestruct() (gas: 2311612)\n[PASS] test_supplyIsOneBillionWithEighteenDecimals() (gas: 26181)\n[PASS] test_transferFromExactAllowanceLeavesZero() (gas: 120945)\n[PASS] test_transferFromRevertsToZeroAddress() (gas: 88291)\n[PASS] test_transferFromRevertsWhenAllowanceTooSmall() (gas: 107756)\n[PASS] test_transferFromRevertsWhenOwnerBalanceTooSmall() (gas: 155503)\n[PASS] test_transferFromRevertsWithoutAllowance() (gas: 40358)\n[PASS] test_transferFromSpendsAllowanceAndMovesTokens() (gas: 168556)\n[PASS] test_transferFromUnlimitedAllowanceIsNotDecremented() (gas: 135408)\n[PASS] test_transferHasNoFeeAlongAChainOfHolders() (gas: 188717)\n[PASS] test_transferMovesExactAmountAndEmits() (gas: 94000)\n[PASS] test_transferRevertsFromEmptyAccount() (gas: 37663)\n[PASS] test_transferRevertsOnInsufficientBalance() (gas: 92513)\n[PASS] test_transferRevertsToZeroAddress() (gas: 32968)\n[PASS] test_transferToSelfKeepsBalance() (gas: 43620)\n[PASS] test_transferWholeBalance() (gas: 77710)\n[PASS] test_transferZeroAmountSucceeds() (gas: 47465)\nSuite result: ok. 35 passed; 0 failed; 0 skipped; finished in 10.37ms (53.49ms CPU time)\n\nRan 1 test for test/PleaToken.invariant.t.sol:PleaTokenInvariantTest\n[PASS]\nPleaTokenInvariantTest invariants:\n[PASS] invariant_balancesSumToSupply\n[PASS] invariant_noStrayBalances\n[PASS] invariant_totalSupplyIsConstant\n PleaTokenInvariantTest invariants (runs: 64, calls: 2048, reverts: 0)\n\n╭------------------+--------------+-------+---------+----------╮\n| Contract         | Selector     | Calls | Reverts | Discards |\n+==============================================================+\n| PleaTokenHandler | approve      | 638   | 0       | 0        |\n|------------------+--------------+-------+---------+----------|\n| PleaTokenHandler | transfer     | 701   | 0       | 0        |\n|------------------+--------------+-------+---------+----------|\n| PleaTokenHandler | transferFrom | 709   | 0       | 0        |\n╰------------------+--------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 18\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 86\n  Bound result 0\n  Bound result 12\n  Bound result 4628\n  Bound result 1\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 177.09ms (175.28ms CPU time)\n\nRan 2 test suites in 178.55ms (187.45ms CPU time): 36 tests passed, 0 failed, 0 skipped (36 total tests)\n","passed":true},{"durationMs":49,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"PleaToken.approve(address,uint256)\",\"PleaToken.transfer(address,uint256)\",\"PleaToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":107,\"foundry.toml\":27,\"remappings.txt\":1,\"src/PleaToken.sol\":136,\"test/PleaToken.invariant.t.sol\":102,\"test/PleaToken.t.sol\":428},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":425,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":238,"exitCode":0,"name":"aderyn","output":"[low] large-numeric-literal at src/PleaToken.sol:29: Large Numeric Literal","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"0084fb29c5b409180eb91ca252d0da8fc3d9657ab093126a138144abcabc1512","verifiedTreeHash":"5d85fa0812882523d18acb8e5d8d8fc85665b636","verifierVersion":"0.1.0+d372f99e"},{"checks":[{"durationMs":1600,"exitCode":0,"name":"build","output":"Compiling 22 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.52s\nCompiler run successful!\n","passed":true},{"durationMs":5878,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 35 tests for test/PleaToken.t.sol:PleaTokenTest\n[PASS] testFuzz_approveRoundTrips(address,uint256) (runs: 256, μ: 76373, ~: 76785)\n[PASS] testFuzz_transferAboveBalanceReverts(uint256,uint256) (runs: 256, μ: 99688, ~: 100226)\nLogs:\n  Bound result 743717981190319213302937830\n  Bound result 115792089237316195423570985008687907853269984665639820321476393688699826704676\n\n[PASS] testFuzz_transferConservesSupply(address,uint256) (runs: 256, μ: 95713, ~: 96158)\nLogs:\n  Bound result 573106118657402156221765345\n\n[PASS] testFuzz_transferFromAboveAllowanceReverts(uint256,uint256) (runs: 256, μ: 95019, ~: 95144)\nLogs:\n  Bound result 202319090743717981190319213302937830\n  Bound result 115792089237316195423570985008687907853269782346549820321476393688699826704676\n\n[PASS] testFuzz_transferFromWithinAllowance(uint256,uint256) (runs: 256, μ: 155214, ~: 156786)\nLogs:\n  Bound result 743717981190319213100618740\n  Bound result 2571\n\n[PASS] test_allowanceIsPerSpender() (gas: 87788)\n[PASS] test_approveCanExceedBalance() (gas: 65704)\n[PASS] test_approveOverwritesRatherThanAdds() (gas: 95161)\n[PASS] test_approveRevertsForZeroSpender() (gas: 32803)\n[PASS] test_approveSetsAllowanceAndEmits() (gas: 68021)\n[PASS] test_constructorEmitsMintTransfer() (gas: 8052)\n[PASS] test_constructorMintsWholeSupplyToDeployer() (gas: 23287)\n[PASS] test_contractDeployerReceivesSupplyNotTxOrigin() (gas: 366696)\n[PASS] test_deployerCannotPullFromHolder() (gas: 97791)\n[PASS] test_metadata() (gas: 26726)\n[PASS] test_noMintOrAdminFunctionExists() (gas: 989388)\n[PASS] test_noPauseOrFreezeFunctionExists() (gas: 426145)\n[PASS] test_rejectsEtherAndUnknownCalls() (gas: 61346)\n[PASS] test_runtimeCodeHasNoDelegatecallOrSelfdestruct() (gas: 2311612)\n[PASS] test_supplyIsOneBillionWithEighteenDecimals() (gas: 26181)\n[PASS] test_transferFromExactAllowanceLeavesZero() (gas: 120945)\n[PASS] test_transferFromRevertsToZeroAddress() (gas: 88291)\n[PASS] test_transferFromRevertsWhenAllowanceTooSmall() (gas: 107756)\n[PASS] test_transferFromRevertsWhenOwnerBalanceTooSmall() (gas: 155503)\n[PASS] test_transferFromRevertsWithoutAllowance() (gas: 40358)\n[PASS] test_transferFromSpendsAllowanceAndMovesTokens() (gas: 168556)\n[PASS] test_transferFromUnlimitedAllowanceIsNotDecremented() (gas: 135408)\n[PASS] test_transferHasNoFeeAlongAChainOfHolders() (gas: 188717)\n[PASS] test_transferMovesExactAmountAndEmits() (gas: 94000)\n[PASS] test_transferRevertsFromEmptyAccount() (gas: 37663)\n[PASS] test_transferRevertsOnInsufficientBalance() (gas: 92513)\n[PASS] test_transferRevertsToZeroAddress() (gas: 32968)\n[PASS] test_transferToSelfKeepsBalance() (gas: 43620)\n[PASS] test_transferWholeBalance() (gas: 77710)\n[PASS] test_transferZeroAmountSucceeds() (gas: 47465)\nSuite result: ok. 35 passed; 0 failed; 0 skipped; finished in 41.40ms (167.15ms CPU time)\n\nRan 13 tests for test/PleaToken.model.t.sol:PleaTokenEdgeTest\n[PASS] testFuzz_repeatedSpendsNeverExceedAllowance(uint256,uint256) (runs: 1000, μ: 392129, ~: 381686)\nLogs:\n  Bound result 10578925031186897620516689\n  Bound result 3686699\n\n[PASS] testFuzz_transferFromOverBalanceKeepsAllowance(uint256,uint256,uint256) (runs: 1000, μ: 178699, ~: 179086)\nLogs:\n  Bound result 288889468798990706391752567\n  Bound result 1303031458363953012366656352\n  Bound result 1303031458363953012366656350\n\n[PASS] testFuzz_twoHopTransferConserves(uint256,uint256,uint160) (runs: 1000, μ: 182555, ~: 184323)\nLogs:\n  Bound result 1461501637330902918203684832716283019655932542972\n  Bound result 2\n  Bound result 2\n\n[PASS] test_allowanceOneBelowMaxIsDecremented() (gas: 126080)\n[PASS] test_cannotPullFromZeroAddress() (gas: 44803)\n[PASS] test_failedTransferChangesNothing() (gas: 110635)\n[PASS] test_launchPayoutArrivesWhole() (gas: 671170)\n[PASS] test_tokensSentToTokenAreHeldNotBurned() (gas: 76257)\n[PASS] test_transferFromSelfRequiresAllowance() (gas: 159364)\n[PASS] test_transferFromToOwnerKeepsBalanceSpendsAllowance() (gas: 113408)\n[PASS] test_transferFromZeroWithoutAllowance() (gas: 55598)\n[PASS] test_unlimitedAllowanceStillBoundByBalance() (gas: 230051)\n[PASS] test_zeroAmountToZeroAddressReverts() (gas: 32868)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 42.78ms (126.73ms CPU time)\n\nRan 1 test for test/PleaToken.invariant.t.sol:PleaTokenInvariantTest\n[PASS]\nPleaTokenInvariantTest invariants:\n[PASS] invariant_balancesSumToSupply\n[PASS] invariant_noStrayBalances\n[PASS] invariant_totalSupplyIsConstant\n PleaTokenInvariantTest invariants (runs: 64, calls: 2048, reverts: 0)\n\n╭------------------+--------------+-------+---------+----------╮\n| Contract         | Selector     | Calls | Reverts | Discards |\n+==============================================================+\n| PleaTokenHandler | approve      | 638   | 0       | 0        |\n|------------------+--------------+-------+---------+----------|\n| PleaTokenHandler | transfer     | 701   | 0       | 0        |\n|------------------+--------------+-------+---------+----------|\n| PleaTokenHandler | transferFrom | 709   | 0       | 0        |\n╰------------------+--------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 1000000000\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 4471\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 242\n  Bound result 0\n  Bound result 0\n  Bound result 6076\n  Bound result 2287400826\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 218.80ms (216.83ms CPU time)\n\nRan 1 test for test/PleaToken.model.t.sol:PleaTokenModelInvariantTest\n[PASS]\nPleaTokenModelInvariantTest invariants:\n[PASS] invariant_allowancesMatchModel\n[PASS] invariant_balancesMatchModel\n[PASS] invariant_nothingLeaksOutsideActors\n PleaTokenModelInvariantTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭------------------+---------------------------+-------+---------+----------╮\n| Contract         | Selector                  | Calls | Reverts | Discards |\n+===========================================================================+\n| PleaModelHandler | approve                   | 2008  | 0       | 0        |\n|------------------+---------------------------+-------+---------+----------|\n| PleaModelHandler | approveZeroSpender        | 2022  | 0       | 0        |\n|------------------+---------------------------+-------+---------+----------|\n| PleaModelHandler | transfer                  | 2019  | 0       | 0        |\n|------------------+---------------------------+-------+---------+----------|\n| PleaModelHandler | transferFrom              | 2008  | 0       | 0        |\n|------------------+---------------------------+-------+---------+----------|\n| PleaModelHandler | transferFromOverAllowance | 2102  | 0       | 0        |\n|------------------+---------------------------+-------+---------+----------|\n| PleaModelHandler | transferFromOverBalance   | 2090  | 0       | 0        |\n|------------------+---------------------------+-------+---------+----------|\n| PleaModelHandler | transferOverBalance       | 2062  | 0       | 0        |\n|------------------+---------------------------+-------+---------+----------|\n| PleaModelHandler | transferToZero            | 2073  | 0       | 0        |\n╰------------------+---------------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 12\n  Bound result 0\n  Bound result 737\n  Bound result 5824\n  Bound result 0\n  Bound result 8444\n  Bound result 941019141680909968780127143276093569571278013043\n  Bound result 8684\n  Bound result 50000000000000000000\n  Bound result 3041954473\n  Bound result 1\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 8443\n  Bound result 2581\n  Bound result 674\n  Bound result 1499\n  Bound result 0\n  Bound result 2418890148\n  Bound result 0\n  Bound result 1747\n  Bound result 1\n  Bound result 2666\n  Bound result 255\n  Bound result 0\n  Bound result 2816\n  Bound result 3178526340051931201050207027156\n  Bound result 448723259223866566398790637107202401550177221\n  Bound result 1\n  Bound result 25000000000000000000\n  Bound result 242\n  Bound result 894429716693400986249502676\n  Bound result 0\n  Bound result 2439649223\n  Bound result 1319\n  Bound result 967\n  Bound result 0\n  Bound result 3441\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 5.78s (5.78s CPU time)\n\nRan 4 test suites in 5.79s (6.09s CPU time): 50 tests passed, 0 failed, 0 skipped (50 total tests)\n","passed":true},{"durationMs":38,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"PleaToken.approve(address,uint256)\",\"PleaToken.transfer(address,uint256)\",\"PleaToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":107,\"foundry.toml\":27,\"remappings.txt\":1,\"src/PleaToken.sol\":136,\"test/PleaToken.invariant.t.sol\":102,\"test/PleaToken.model.t.sol\":403,\"test/PleaToken.t.sol\":428},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"00ff0225a32c1d793b0376449c4a7a0f8e99b47b1bdb18d8f57c3620e97faaf2","verifiedTreeHash":"66614f6dd11e578e1b62216d7e8e12050b04fb8f","verifierVersion":"0.1.0+d372f99e"},{"checks":[{"durationMs":1088,"exitCode":0,"name":"build","output":"Compiling 21 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.01s\nCompiler run successful!\n","passed":true},{"durationMs":281,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 35 tests for test/PleaToken.t.sol:PleaTokenTest\n[PASS] testFuzz_approveRoundTrips(address,uint256) (runs: 256, μ: 76448, ~: 76773)\n[PASS] testFuzz_transferAboveBalanceReverts(uint256,uint256) (runs: 256, μ: 99989, ~: 100270)\nLogs:\n  Bound result 11726\n  Bound result 60000000000000000000\n\n[PASS] testFuzz_transferConservesSupply(address,uint256) (runs: 256, μ: 95799, ~: 95970)\nLogs:\n  Bound result 573106118657402156221765345\n\n[PASS] testFuzz_transferFromAboveAllowanceReverts(uint256,uint256) (runs: 256, μ: 95213, ~: 95288)\nLogs:\n  Bound result 202319090743717981190319213302937830\n  Bound result 115792089237316195423570985008687907853269782346549820321476393688699826704676\n\n[PASS] testFuzz_transferFromWithinAllowance(uint256,uint256) (runs: 256, μ: 155938, ~: 156770)\nLogs:\n  Bound result 11726\n  Bound result 9474\n\n[PASS] test_allowanceIsPerSpender() (gas: 87788)\n[PASS] test_approveCanExceedBalance() (gas: 65704)\n[PASS] test_approveOverwritesRatherThanAdds() (gas: 95161)\n[PASS] test_approveRevertsForZeroSpender() (gas: 32803)\n[PASS] test_approveSetsAllowanceAndEmits() (gas: 68021)\n[PASS] test_constructorEmitsMintTransfer() (gas: 8052)\n[PASS] test_constructorMintsWholeSupplyToDeployer() (gas: 23287)\n[PASS] test_contractDeployerReceivesSupplyNotTxOrigin() (gas: 366696)\n[PASS] test_deployerCannotPullFromHolder() (gas: 97791)\n[PASS] test_metadata() (gas: 26726)\n[PASS] test_noMintOrAdminFunctionExists() (gas: 989388)\n[PASS] test_noPauseOrFreezeFunctionExists() (gas: 426145)\n[PASS] test_rejectsEtherAndUnknownCalls() (gas: 61346)\n[PASS] test_runtimeCodeHasNoDelegatecallOrSelfdestruct() (gas: 2311612)\n[PASS] test_supplyIsOneBillionWithEighteenDecimals() (gas: 26181)\n[PASS] test_transferFromExactAllowanceLeavesZero() (gas: 120945)\n[PASS] test_transferFromRevertsToZeroAddress() (gas: 88291)\n[PASS] test_transferFromRevertsWhenAllowanceTooSmall() (gas: 107756)\n[PASS] test_transferFromRevertsWhenOwnerBalanceTooSmall() (gas: 155503)\n[PASS] test_transferFromRevertsWithoutAllowance() (gas: 40358)\n[PASS] test_transferFromSpendsAllowanceAndMovesTokens() (gas: 168556)\n[PASS] test_transferFromUnlimitedAllowanceIsNotDecremented() (gas: 135408)\n[PASS] test_transferHasNoFeeAlongAChainOfHolders() (gas: 188717)\n[PASS] test_transferMovesExactAmountAndEmits() (gas: 94000)\n[PASS] test_transferRevertsFromEmptyAccount() (gas: 37663)\n[PASS] test_transferRevertsOnInsufficientBalance() (gas: 92513)\n[PASS] test_transferRevertsToZeroAddress() (gas: 32968)\n[PASS] test_transferToSelfKeepsBalance() (gas: 43620)\n[PASS] test_transferWholeBalance() (gas: 77710)\n[PASS] test_transferZeroAmountSucceeds() (gas: 47465)\nSuite result: ok. 35 passed; 0 failed; 0 skipped; finished in 13.45ms (61.74ms CPU time)\n\nRan 1 test for test/PleaToken.invariant.t.sol:PleaTokenInvariantTest\n[PASS]\nPleaTokenInvariantTest invariants:\n[PASS] invariant_balancesSumToSupply\n[PASS] invariant_noStrayBalances\n[PASS] invariant_totalSupplyIsConstant\n PleaTokenInvariantTest invariants (runs: 64, calls: 2048, reverts: 0)\n\n╭------------------+--------------+-------+---------+----------╮\n| Contract         | Selector     | Calls | Reverts | Discards |\n+==============================================================+\n| PleaTokenHandler | approve      | 638   | 0       | 0        |\n|------------------+--------------+-------+---------+----------|\n| PleaTokenHandler | transfer     | 701   | 0       | 0        |\n|------------------+--------------+-------+---------+----------|\n| PleaTokenHandler | transferFrom | 709   | 0       | 0        |\n╰------------------+--------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 18\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 86\n  Bound result 0\n  Bound result 12\n  Bound result 4628\n  Bound result 43\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 174.23ms (168.13ms CPU time)\n\nRan 2 test suites in 175.43ms (187.68ms CPU time): 36 tests passed, 0 failed, 0 skipped (36 total tests)\n","passed":true},{"durationMs":42,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"PleaToken.approve(address,uint256)\",\"PleaToken.transfer(address,uint256)\",\"PleaToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":107,\"foundry.toml\":27,\"launch.json\":20,\"remappings.txt\":1,\"src/PleaToken.sol\":136,\"test/PleaToken.invariant.t.sol\":102,\"test/PleaToken.t.sol\":428},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"7dba48074ec1b4ed44fb6062d10cf890ee8352476b6baa949fd1945323257e4c","verifiedTreeHash":"b7b7ec1b5870e4c0347445f5ec4679ddafc16b52","verifierVersion":"0.1.0+d372f99e"}]}