{"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":"995255d8-8d56-4024-9687-43d961aa7992","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"7c8ff59d6e8e1067017b13cca0d95a3b15d1bbdc134991ab5a765a5f246af715","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_economics","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"3a8c3ac642725b988aa9bb8cc292e9cdad7ff552b95d90e77dd2cb5be94169a3","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_flow","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"713b93b27a3bbe98ab143c699a696b48c00b81eae771798ca1b8e2f742bf4423","dependsOn":["build_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"af3aa01159bbf354f621cafa5c0006f6169e0938a8b015be508b7377dbf165bc","skillId":"audit-judge","tools":[]},"key":"audit_judge","kind":"code","role":"review","skillHash":"af3aa01159bbf354f621cafa5c0006f6169e0938a8b015be508b7377dbf165bc","skillId":"audit-judge","state":"accepted"},{"acceptedSubmissionHash":"12dde2f6268cf3f6f50fe00e067b0b7df129ec86f6cb68d15a0337a4ed2a12c0","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_math","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"6471c0ed935973f673eb73562ac388eacbb11b5e4482d7f917821bb1ad49780d","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_permissions","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"967f0d0474cb6ea14de112acd624ed350d7ed06d6547b7e68bec3e20ca04b877","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"d59561da3b378461b7c749f6bd5084477d44993aa94972ddea90f542535751df","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"d59561da3b378461b7c749f6bd5084477d44993aa94972ddea90f542535751df","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":"f361b883944e2474bdf1b56badafa81405ffcc5a13ae0916f8a8ed27a656ac28","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"1971a0ca9570b52af4930e161775b148a95607bc734a6c31b745c3070fd900ff","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"4c76766b00591dfe982fe85d3de589fdb2f810e5137c301155d1c5e36a1d3b23","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"4c76766b00591dfe982fe85d3de589fdb2f810e5137c301155d1c5e36a1d3b23","skillId":"write-foundry-tests","state":"accepted"}],"objective":"A custom token: StrataIMD (STRATA).\nToken name: StrataIMD\nToken symbol: STRATA\nToken supply: 1,000,000,000 with 18 decimals, all minted once to the deployer in the constructor.","parentJobId":null,"planHash":"a53ec793b912c065e2952c21e8c15f200efb513f62f074433abc719e32b28a26","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"995255d8-8d56-4024-9687-43d961aa7992","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1929-strataimd"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51468","feedbackHash":"a6dd2f781f4023cb4980ee31b3a781d650bb4336d4f2c1b338285a5ddcc3109e","nodeKey":"audit_economics","submissionHash":"7c8ff59d6e8e1067017b13cca0d95a3b15d1bbdc134991ab5a765a5f246af715","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52665","feedbackHash":"048fb52f1428c0ccbb6386b610195c479cf9be6fe79db679b1cbdf322a38d0fb","nodeKey":"audit_flow","submissionHash":"3a8c3ac642725b988aa9bb8cc292e9cdad7ff552b95d90e77dd2cb5be94169a3","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51162","feedbackHash":"59e5a2c0e58b04720fbe31cbbf0593ffc4abe11672d726875eb808a1d824e830","nodeKey":"audit_judge","submissionHash":"713b93b27a3bbe98ab143c699a696b48c00b81eae771798ca1b8e2f742bf4423","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52292","feedbackHash":"5d4d2ad317da8e0d2dd6af01c35369e76153b777c04e4b8a9536d324dfaeca37","nodeKey":"audit_math","submissionHash":"12dde2f6268cf3f6f50fe00e067b0b7df129ec86f6cb68d15a0337a4ed2a12c0","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52114","feedbackHash":"b751ca91309438ef67097dcb5124417c5a5b1200e7eb9d01bd0f8a916dd30d61","nodeKey":"audit_permissions","submissionHash":"6471c0ed935973f673eb73562ac388eacbb11b5e4482d7f917821bb1ad49780d","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52263","feedbackHash":"62ced196d4862b227943c575c570152cf264952b2c4417f202b2454e4ac0b3a4","nodeKey":"build_contract_project","submissionHash":"967f0d0474cb6ea14de112acd624ed350d7ed06d6547b7e68bec3e20ca04b877","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52121","feedbackHash":"4a0af5ec3adc7df451e8737bb5919260f11f8afc2f6d82473aa14f9572e34a99","nodeKey":"manifest","submissionHash":"f361b883944e2474bdf1b56badafa81405ffcc5a13ae0916f8a8ed27a656ac28","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51227","feedbackHash":"80fbfaac737dad2f564d88ea6c3256ae3b539be897cbd38ee3189bd1cb14b35c","nodeKey":"write_foundry_tests","submissionHash":"1971a0ca9570b52af4930e161775b148a95607bc734a6c31b745c3070fd900ff","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"9ce2b6e10031ca98ae2647a24871c7b331cb7b4c969bc790e1b5449fc5c8b2ae","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"ddcecd7483f623f7","findings":[{"citation":"resolved","description":"Boundary pass, approve/transferFrom pair. `approve` sets the allowance to `value` without reference to the current value, exactly as EIP-20 and OpenZeppelin ERC20 v5 do. The consequence is the well-known allowance race: when an owner lowers an existing allowance, the spender can spend the old allowance before the new approve lands and then spend the new one as well. This is a property of the ERC-20 standard, not of this implementation; the README documents that approve 'sets the allowance outright' and OpenZeppelin v5 deliberately ships the same semantics (it removed increaseAllowance/decreaseAllowance). No change is required to meet the brief; it is recorded so the judge and author have the concrete input on file. If the author wants to offer a safer path, adding non-standard increaseAllowance/decreaseAllowance helpers is the usual mitigation, and it would not alter supply, transfer or launch behaviour.","line":114,"path":"src/StrataToken.sol","reproduction":"State: ALICE holds 1_000 wei, ALICE has called approve(BOB, 100). ALICE now submits approve(BOB, 50) intending to reduce BOB's spending power. BOB observes the pending transaction and submits transferFrom(ALICE, BOB, 100) first: allowance 100 >= 100, succeeds, allowance becomes 0, BOB balance 100. ALICE's approve(BOB, 50) then executes and sets the allowance to 50 (line 114 writes the value with no dependence on the current 0). BOB calls transferFrom(ALICE, BOB, 50): succeeds. Expected by ALICE: BOB can move at most 100 in total (or 50 after the reduction). Actual: BOB moved 150. Verified in a scratch Foundry test (balanceOf(BOB) == 150 after the sequence).","severity":"info","snippet":"        _allowances[owner][spender] = value;","title":"approve() overwrites the allowance outright, so lowering an allowance can be front-run (inherent ERC-20 race, no code defect)"},{"citation":"resolved","description":"Boundary x invariant seam at the zero input. With value == 0 the allowance check `currentAllowance < value` is `0 < 0`, false, so an arbitrary caller passes `_spendAllowance` for any non-zero `from` it never received an allowance from; `_transfer` then passes `fromBalance < 0` (false) and emits `Transfer(from, to, 0)`. No balance or allowance changes, so the conservation invariant holds and no funds are at risk. EIP-20 requires zero-value transfers to be treated as normal transfers that fire Transfer, and OpenZeppelin ERC20 v5 behaves identically, so this is not a defect of the implementation. The only practical effect is the known 'address poisoning' pattern: a third party can make a Transfer event from a holder to a look-alike address appear in the holder's on-chain history. Recorded as information; no change is required and a change would deviate from the standard.","line":121,"path":"src/StrataToken.sol","reproduction":"State: fresh deployment, ALICE and CAROL hold 0, ALICE has never approved BOB. BOB calls transferFrom(ALICE, CAROL, 0). Expected (if one assumed allowance is always required): revert ERC20InsufficientAllowance(BOB, 0, 0). Actual: returns true and emits exactly one event Transfer(ALICE, CAROL, 0); allowance(ALICE, BOB) stays 0 and all balances are unchanged. Verified in a scratch Foundry test with vm.recordLogs (one log, topics[1] == ALICE, topics[2] == CAROL, data == 0). Related edge: transferFrom(address(0), CAROL, 0) reverts with ERC20InvalidApprover(address(0)) from `_approve` rather than ERC20InvalidSender, also identical to OpenZeppelin v5.","severity":"info","snippet":"            if (currentAllowance < value) revert ERC20InsufficientAllowance(spender, currentAllowance, value);","title":"transferFrom with value 0 succeeds for any `from` without an allowance and emits Transfer(from, to, 0) (standard ERC-20 behaviour, address-poisoning surface only)"}],"hash":"12dde2f6268cf3f6f50fe00e067b0b7df129ec86f6cb68d15a0337a4ed2a12c0","nodeId":"607b954c-89ec-4d4a-bdb9-5a940708c83d","outcome":"completed","summary":"The review is complete and `.imd-findings.json` is written and validated.\n\n**Result: no math defects in the StrataIMD token.** The Math Precision, Boundary and Numerical Gap passes found nothing that loses, misroutes or freezes value.\n\nWhat I checked in `src/StrataToken.sol`:\n- **Supply constant.** The literal flagged by aderyn folds to exactly 1e27, the manifest's minor units, minted once to the deployer. Lead dismissed.\n- **Transfer arithmetic.** The subtraction is guarded by the balance check, and the unchecked addition is bounded by the fixed supply, so neither can wrap. Self-transfer of the whole balance, zero value, balance plus one and max uint all behave correctly.\n- **Allowance arithmetic.** Max is treated as unlimited, max minus one decrements exactly, overspend and zero-address cases revert with the right ERC-6093 errors.\n- **Boundaries.** There are no divisions, casts, scaling, external calls, payable paths, receive or fallback, or bytes decoding, so the Boundary and Numerical Gap seams have no surface. The 10/80/10 launch split of 1e27 is exact and no flow arrives short.\n\nTwo items are recorded as **info**, both verified with a scratch Foundry test and both identical to EIP-20 and OpenZeppelin v5 semantics, so neither needs a fix:\n- The allowance-lowering race through `approve`, where a spender can move the old and the new allowance.\n- A zero-value `transferFrom` succeeding for any `from` without an allowance and emitting a Transfer event, which is only an address-poisoning surface.\n\nCoverage has rows for all three listed entry points plus five invariant rows. The existing 39 tests pass, `forge fmt --check` is clean, and the scratch directory was removed so no tracked file changed.","treeHash":null,"usage":{"cachedInputTokens":486327,"inputTokens":194,"model":"claude-fable-5-1","outputTokens":14954,"runtime":"claude","turns":25,"wallClockMs":220865}},{"artifacts":[],"attempt":1,"bundleHash":"393e092c5c0fdfa989624aad2d9bc4560ac46fe79e0c474c2475fc2b672fcc4e","device":"11e4593175677f7e","findings":[],"hash":"1971a0ca9570b52af4930e161775b148a95607bc734a6c31b745c3070fd900ff","nodeId":"040f5b9c-4375-4b73-ba4c-6c81944d8d8f","outcome":"completed","summary":"The findings file is excluded from git by the repository's own exclude list, so it is collected from disk as intended. Everything is done.\n\n**Outcome.** The suite now has 68 tests across four files and all pass with the verifier's fuzz seed. I found no defect in the token, so the findings file holds an empty list.\n\n**What I added, all under test/:**\n\n- `test/StrataTokenInvariant.t.sol` is the invariant suite the criteria required. A handler drives the token from six actors with bounded inputs through transfer, approve and transferFrom, plus four failure-path drivers: over-balance transfers, over-allowance pulls, sends to the zero address, and privileged selectors tried by every actor including the deployer. Each driver asserts the exact ERC-6093 revert. Seven invariants run after every call: fixed supply, balances summing to the supply, balances and allowances matching a ghost ledger, flow accounting, the zero address and harness holding nothing, constant metadata, and every holder still being able to transfer. The run is 256 sequences of depth 64 with fail-on-revert on, so an escaped revert fails the test.\n- `test/StrataTokenEdges.t.sol` pins the branches the existing suite left untested: the zero address as caller, approver and transferFrom source, the allowance one below the unlimited sentinel, repeated unlimited spends, the maximum as a value, self-approval, transferFrom back to the owner, tokens sent to the token contract, unknown selectors and empty calldata, ether sent with a call, and four fuzz properties that use bound rather than assume.\n\n**One thing worth knowing.** A zero-value transferFrom from the zero address reverts with the approver error, not the sender error, because the allowance write-back runs first. That matches OpenZeppelin v5 and the call still reverts, so I pinned the real error rather than reporting it.\n\nThe working tree contains only the two new test files plus the findings file, with no scratch files or changes outside the allowed paths.","treeHash":"7e20ec0ee0b079bb6289363c4d9c75c16e3fe969","usage":{"cachedInputTokens":761945,"inputTokens":354,"model":"claude-fable-5-1","outputTokens":23954,"runtime":"claude","turns":22,"wallClockMs":325003}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"0ef0cddb99617930","findings":[],"hash":"3a8c3ac642725b988aa9bb8cc292e9cdad7ff552b95d90e77dd2cb5be94169a3","nodeId":"e85dddc7-2690-4343-adec-477ec82b567b","outcome":"completed","summary":"The review is complete. The findings file is written and the tree is otherwise unchanged.\n\n**Result: no defects found.** `.imd-findings.json` holds an empty findings list and ten coverage rows, one for each of the three state-changing entry points plus the invariants I checked.\n\n**What I covered**, against the Execution Trace, Periphery and First Principles guides and the Senior Auditor's Mindset:\n\n- **Execution flow** of `approve`, `transfer` and `transferFrom`: guard order, the max-allowance sentinel, `from == address(0)`, self-transfer through an allowance, zero values, and allowance at max minus one. Every path matches OpenZeppelin v5 semantics and ERC-6093 errors.\n- **Conservation**: a fuzzed random walk of mixed operations across four actors kept the balance sum equal to the fixed supply in every run. There is no mint, burn or supply-changing path in the compiled ABI.\n- **Launch flows**: balance delta equals the requested amount in both directions for every amount up to the full supply, so the distributor, pool manager and remainder transfers arrive whole.\n- **Runtime bytecode**: disassembled and found no DELEGATECALL, CALLCODE, SELFDESTRUCT, CALL, STATICCALL, CREATE, CREATE2 or transient-storage opcodes.\n- **Periphery**: the interface file and the two test utilities are consistent with forge's cheatcode ABI and the ERC-20 standard. All 39 project tests pass under forge 1.8.3, and formatting is clean.\n\n**Documented, not reported**: the standard ERC-20 approve front-running property is recorded as a trust assumption in the coverage record, since the brief asks for a plain standard token.\n\n**Outside my area and unverified**: the README's deployment table names Ethereum mainnet and a specific IMD pair address. No network file is present in this tree to confirm either, and the manifest step owns those values.","treeHash":null,"usage":{"cachedInputTokens":748951,"inputTokens":290,"model":"claude-fable-5-1","outputTokens":15926,"runtime":"claude","turns":31,"wallClockMs":232730}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"918f8261a6fd589c","findings":[{"citation":"resolved","description":"Access-control / asymmetry pass. approve() sets the spender's allowance outright rather than adjusting it relative to what has already been spent, and there is no increaseAllowance/decreaseAllowance or permit path. This is exactly the OpenZeppelin v5 semantics the README and NatSpec say the token follows, and the ERC-20 standard itself has this property, so it is not a defect in the commissioned design. It is recorded so the author and integrators know the only privilege asymmetry in the contract: an approved spender's authority is bounded by the sum of consecutive approvals if the spender observes the mempool, not by the latest value. Fix is a design choice (add increaseAllowance/decreaseAllowance helpers, or leave as is and tell integrators to approve 0 before setting a new non-zero value); the current code is consistent with its stated reference and with the protected floor tests. No other access-control, trust-gap or asymmetry defect was found: there is no owner, minter, pauser, blocklist, upgrade, delegatecall, receive or fallback; transfer and transferFrom share one _transfer path with identical checks; approve and _spendAllowance share one _approve path; the unchecked balance arithmetic is bounded by the fixed immutable supply; and the deployer (the factory) has no power beyond holding the initial balance.","line":114,"path":"src/StrataToken.sol","reproduction":"State: deployer gives ALICE 1000 STRATA; ALICE calls approve(BOB, 100). ALICE later decides to reduce and sends approve(BOB, 50). BOB sees that in the mempool and gets transferFrom(ALICE, CAROL, 100) mined first (allowance 100 -> 0), then ALICE's approve(BOB, 50) lands (allowance 0 -> 50), then BOB calls transferFrom(ALICE, CAROL, 50). Expected by ALICE: BOB moves at most 100 in total. Actual: CAROL holds 150 and balanceOf(ALICE) == 850. Verified with test/scratch/Probe.t.sol test_approveRaceSpends150 (passes, i.e. the 150 outcome is reachable). Same sequence behaves identically on OpenZeppelin ERC20 v5.","severity":"info","snippet":"        _allowances[owner][spender] = value;","title":"approve() overwrites the allowance, so a spender can front-run a reduction and spend old plus new allowance (standard ERC-20 / OZ v5 behaviour, documented trust note, not a deviation)"}],"hash":"6471c0ed935973f673eb73562ac388eacbb11b5e4482d7f917821bb1ad49780d","nodeId":"aec667f2-d748-4155-acff-da769439a887","outcome":"completed","summary":"The review is complete and the findings file is written and validated. The working tree is clean apart from the ignored scratch test and the findings file.\n\n**Outcome: no access-control, trust-gap or asymmetry defect found.** The file `.imd-findings.json` holds one info-level note and ten coverage rows.\n\n**What I checked, in my area:**\n- Permission map: the token has no owner, roles, modifiers, settable state, mint, burn, pause, blocklist, upgrade, receive or fallback. The ABI exposes only the nine ERC-20 methods and the supply constant getter.\n- Trust gap: the deployer, which is the factory, holds the initial balance and nothing else. After payout it cannot pull, freeze, dilute or redirect value. Correct distribution is a launch-level trust assumption, recorded as such.\n- Asymmetry: both transfer variants share one internal transfer path with identical checks, and both allowance writers share one internal approve path. The unchecked balance arithmetic is bounded by the immutable fixed supply, including self-transfers of the whole balance.\n- Launch flows: no address is treated specially and no fee or burn exists, so distributor, pool seed and trader flows move exactly what they state.\n\n**The one recorded item** is informational. The allowance is set by overwrite, so a spender watching the mempool can spend an old allowance and a reduced new one in sequence. This matches the OpenZeppelin v5 semantics the author deliberately chose and is standard ERC-20 behaviour, so it is a design note rather than a defect. The reproduction in the file was verified with a scratch test.\n\n**Verification run:**\n- The project's 39 tests pass, and the delivered files pass `forge fmt --check`.\n- Five scratch probes under `test/scratch/` confirmed the allowance race, the zero-sender revert path, whole-balance self-transfer, approve isolation per caller, and that admin-style selectors revert.\n- Static analysis leads were a single low-severity large-literal note, which is the intended supply constant and not a defect.\n\n**Coverage:** all three listed entry points have rows. One is marked `finding` for the info note, and the other two `holds`. Seven further rows record the invariants traced.","treeHash":null,"usage":{"cachedInputTokens":551716,"inputTokens":226,"model":"claude-fable-5-1","outputTokens":10589,"runtime":"claude","turns":21,"wallClockMs":150415}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"771f83f312eace21","findings":[{"citation":"resolved","description":"Merged from audit_permissions and audit_math, which reported the same root cause: `approve` writes `value` into the allowance slot with no reference to the current value, and the contract offers no increaseAllowance/decreaseAllowance or permit path. A spender watching the mempool can spend the old allowance before an owner's reduction lands and then spend the new one, so its total authority is the sum of consecutive approvals rather than the latest one. This is exactly the behaviour of EIP-20 and of OpenZeppelin ERC20 v5, which the README and NatSpec state the token follows, and the protected floor does not require anything else. It is recorded as a trust note for integrators, not as a defect; the only mitigation (non-standard increase/decrease helpers, or approving 0 before a new non-zero value) is a design choice for the author.","line":114,"path":"src/StrataToken.sol","reproduction":"Reproduced with test/scratch/Review.t.sol test_approveRaceSpends150 (passes, so the outcome is reachable). State: deployer transfers 1000 to ALICE; ALICE calls approve(BOB, 100). ALICE then submits approve(BOB, 50). BOB has transferFrom(ALICE, CAROL, 100) mined first: allowance 100 -> 0, CAROL 100. ALICE's approve(BOB, 50) lands: line 114 sets allowance 0 -> 50. BOB calls transferFrom(ALICE, CAROL, 50): succeeds. Expected by ALICE: BOB moves at most 100 (or 50 after the reduction). Actual: balanceOf(CAROL) == 150 and balanceOf(ALICE) == 850.","severity":"info","snippet":"        _allowances[owner][spender] = value;","title":"approve() overwrites the allowance, so lowering an allowance can be front-run (inherent EIP-20 / OpenZeppelin v5 semantics, documented; no change required)"},{"citation":"resolved","description":"Reported by audit_math. With value == 0 the allowance check at line 121 is `0 < 0`, false, so any caller passes `_spendAllowance` for any non-zero `from` that never approved it; `_transfer` then passes `fromBalance < 0` (false) and emits `Transfer(from, to, 0)`. No balance or allowance changes and the supply conservation invariant holds, so no funds are at risk. EIP-20 requires zero-value transfers to be treated as normal transfers that fire the Transfer event, and OpenZeppelin ERC20 v5 behaves identically, so this is not a defect of the implementation. The practical effect is that a third party can place a zero-value Transfer event from a holder to a look-alike address in the holder's on-chain history. No change is required; a change would deviate from the standard.","line":121,"path":"src/StrataToken.sol","reproduction":"Reproduced with test/scratch/Review.t.sol test_zeroValueTransferFromNoAllowance (passes). State: fresh deployment, ALICE and CAROL hold 0, ALICE has never approved BOB. BOB calls transferFrom(ALICE, CAROL, 0). Expected if an allowance were always required: revert ERC20InsufficientAllowance(BOB, 0, 0). Actual: returns true and emits exactly one log, Transfer with topics[1] == ALICE and topics[2] == CAROL and data 0; allowance(ALICE, BOB) stays 0 and all balances are unchanged. Related edge, also standard: transferFrom(address(0), CAROL, 0) reverts with ERC20InvalidApprover(address(0)) from `_approve` at line 112.","severity":"info","snippet":"            if (currentAllowance < value) revert ERC20InsufficientAllowance(spender, currentAllowance, value);","title":"transferFrom with value 0 succeeds for any non-zero `from` without an allowance and emits Transfer(from, to, 0) (standard EIP-20 / OpenZeppelin v5 behaviour; address-poisoning event surface only)"}],"hash":"713b93b27a3bbe98ab143c699a696b48c00b81eae771798ca1b8e2f742bf4423","nodeId":"45a97c42-59d8-4349-8dfa-92809fd7c578","outcome":"completed","summary":"Review complete. The findings file is written and validated, the snippets match the tree, and the scratch directory is removed so no repository file is changed.\n\n**Outcome: no defects.** StrataIMD is a plain fixed-supply ERC-20 and behaves as the brief specifies. The build succeeds and the project's 68 tests pass, including the invariant suite.\n\n**Specialist findings settled.** Three were reported across the four areas, all info-level, and all three reproduce.\n- The approve overwrite race was reported by both the permissions and math specialists with the same root cause, so I merged it into one finding. It is standard EIP-20 and OpenZeppelin v5 behaviour, documented in the README, and I reproduced it: after approve 100, a front-run spend, approve 50 and a second spend, the recipient holds 150.\n- The zero-value transferFrom without an allowance is also standard behaviour. I reproduced the single Transfer event with no balance or allowance change.\n- The static-analysis line about a large numeric literal is a style note on the supply constant and is not a defect.\n\n**My own pass.** I traced all three entry points, the constructor and the launch flows. The runtime bytecode contains no DELEGATECALL, CALLCODE or SELFDESTRUCT, and runtime and creation sizes are far below the protocol limits. Ether and unknown selectors are refused. Whole amounts move through the swarm share and claim path. The manifest matches the constructor: no arguments, supply and decimals agree, and the contract name is within the 32-character limit.\n\n**Not run here.** The protected floor tests need the verifier's harness with forge-std and v4-core, which is not vendored in this tree, so I checked their properties directly rather than executing them.\n\n**Coverage.** All three listed entry points are answered, two pointing at the info findings and one holding, plus three invariant rows.","treeHash":null,"usage":{"cachedInputTokens":538670,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":8810,"runtime":"claude","turns":11,"wallClockMs":157414}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"ea62f3bebece9304","findings":[],"hash":"7c8ff59d6e8e1067017b13cca0d95a3b15d1bbdc134991ab5a765a5f246af715","nodeId":"aeb97716-734a-41d0-a730-c3d6a1222ca9","outcome":"completed","summary":"I found no defects in `src/StrataToken.sol` from the economics side. `.imd-findings.json` holds an empty findings list and a coverage record, the JSON parses, and no tracked file changed. The project's existing 39 tests all pass.\n\n**What I checked, using the Economic Security, Invariant and Flow Gap guides:**\n- **Launch flows:** every transfer moves exactly the amount asked for. There is no fee, tax, burn, rebase or hook. So the factory's payment to the distributor, the distributor's payouts to claimants, the pool seed, and swaps through the Uniswap v4 PoolManager all arrive in full.\n- **Fixed supply:** the supply is 1e27 minor units, set once in the constructor and stored as an immutable. There is no mint, owner, roles, pause, blocklist, DELEGATECALL or SELFDESTRUCT. One section of `unchecked` code is safe, because no balance can exceed the fixed supply.\n- **Edge cases:**\n  - A transfer to yourself and a transfer of zero leave balances unchanged.\n  - `transferFrom` from the zero address always reverts.\n  - An allowance of `type(uint256).max` is treated as unlimited and is not reduced.\n  - `transferFrom` charges the allowance before checking the balance, and a revert undoes both.\n- **Static analysis:** Aderyn flagged a \"large numeric literal\" at line 27, which is just the supply constant `1_000_000_000 * 10 ** 18`. That is style, not a defect.\n\n**Coverage:** `approve`, `transfer` and `transferFrom` are each marked `holds`. I added three more rows for the supply, privilege and fee-on-transfer checks. Nothing was left unreached.\n\nI did not run the network's protected launch tests, because their supporting libraries (forge-std, v4-core) aren't in this repository. Following those tests, I traced the flows by hand instead. A plain ERC-20 with no transfer side effects should pass them.","treeHash":null,"usage":{"cachedInputTokens":313902,"inputTokens":14,"model":"claude-opus-5-5","outputTokens":3056,"runtime":"claude","turns":7,"wallClockMs":38275}},{"artifacts":[],"attempt":1,"bundleHash":"55af24d1226949d6d0d9fa33080604f5da8599cd8fc0b5f982f72c562983495a","device":"6b16b4979d227241","findings":[],"hash":"967f0d0474cb6ea14de112acd624ed350d7ed06d6547b7e68bec3e20ca04b877","nodeId":"793faf88-2389-42b4-8b07-26398a5363c8","outcome":"completed","summary":"The sources read clean. The shell never came back, so the final state is as follows.\n\n**What was delivered** (all at the repository root, self-contained, no external dependencies):\n\n- `foundry.toml` pins solc 0.8.26, cancun, optimizer 200 runs, `bytecode_hash = \"none\"`, no ffi, no fs permissions.\n- `src/StrataToken.sol` is `contract StrataToken`, a plain fixed-supply ERC-20 returning name `StrataIMD`, symbol `STRATA`, 18 decimals. The constructor mints 1,000,000,000 tokens once to `msg.sender` and takes no arguments. There is no owner, mint, burn, pause, blocklist, fallback or receive, and no delegatecall or selfdestruct. It follows OpenZeppelin ERC20 v5 semantics with ERC-6093 errors, written directly so nothing is linked or vendored.\n- `src/interfaces/IERC20.sol` holds the ERC-20 interface and the ERC-6093 error set.\n- `test/StrataToken.t.sol` covers metadata, the one-time mint and its single Transfer event, every transfer, approve and transferFrom success and failure path with exact error data, the unlimited allowance, the absence of any admin or mint surface using the same selector lists as the protected floor test, the bytecode opcode scan, and five fuzz tests that bound their own inputs.\n- `test/StrataTokenLaunch.t.sol` deploys through a factory-like contract and checks the swarm share, pool share and remainder move and add up exactly, that the factory cannot overspend, pull from a holder or mint afterwards.\n- `test/utils/Vm.sol` and `test/utils/TestBase.sol` declare the few forge cheatcodes and reverting assertions the tests use, since forge-std could not be fetched.\n- `README.md` documents assumptions, deployment parameters, named constants, the empty \"After launch\" section, operational responsibilities and security notes.\n\n**What could not be verified.** Every shell command in this session, including a bare `echo`, failed before running with this sandbox error, and the sandbox override is disabled here:\n\n```\napply-seccomp: write /proc/self/setgroups (nested userns is capability-restricted; caller must provide CAP_SYS_ADMIN): Permission denied\n```\n\nSo `forge build`, `forge test` and `forge fmt --check` were not run, no dependencies could be installed, and nothing was committed. The code was written to compile under 0.8.26 and reviewed by hand against the protected floor tests, but its pass status rests on the verifier's run. The next step is to run the three checks on a machine whose shell works and repair anything they report.","treeHash":"f4e5c30f24b5173ab62586f34cf8f0693e5e315b","usage":{"cachedInputTokens":757277,"inputTokens":386,"model":"claude-fable-5-1","outputTokens":41415,"runtime":"claude","turns":24,"wallClockMs":487596}},{"artifacts":[],"attempt":1,"bundleHash":"07f869a91370b11a0b6620255f50eaf1f6c67d2ddd4af95fac1408a331418d27","device":"bdd9b74dce66953d","findings":[],"hash":"f361b883944e2474bdf1b56badafa81405ffcc5a13ae0916f8a8ed27a656ac28","nodeId":"755a96fe-ec6f-4499-b450-896b60dbfeeb","outcome":"completed","summary":"`launch.json` is written and verified. It is the only file added, and the working tree is otherwise clean.\n\n**What the manifest says**\n\n- **kind** is `custom_token`. The token entry names the Solidity contract `StrataToken` from `src/StrataToken.sol`, with name StrataIMD, symbol STRATA and 18 decimals.\n- **constructorArgs** is empty, matching the accepted constructor, which takes no parameters and mints the whole supply once to the deployer.\n- **totalSupply** is the exact minor-unit amount the constructor mints, which equals the contract's `INITIAL_SUPPLY` constant.\n- **contracts** is empty. The accepted tree has no application contracts, so none are described.\n- **pool** and **economics** are copied verbatim from the launch reference: IMD as the paired currency, fee 12500, tick spacing 60, the one-to-one provenance price, and the requester's economics object.\n- **notes** describes only what is in the tree: a fixed-supply ERC-20 with no fees, no admin paths and no linked code. It is well under the 4,000 character limit.\n\n**Checks run**\n\n- `forge build` compiles cleanly with solc 0.8.26.\n- `forge test` with the verifier's fuzz seed passes all 39 tests across both suites.\n- A scratch script confirmed the manifest uses only schema keys, that the supply and economics match, and that addresses are lowercase.\n\nNo protected invariant in the token floor test depends on manifest content beyond supply and decimals, and both match the contract.","treeHash":"9422f8ea84d93fa9f694dbf62a1c5a3f4a0e93a3","usage":{"cachedInputTokens":190707,"inputTokens":130,"model":"claude-fable-5-1","outputTokens":2971,"runtime":"claude","turns":9,"wallClockMs":46783}}],"verification":[{"checks":[{"durationMs":846,"exitCode":0,"name":"build","output":"Compiling 8 files with Solc 0.8.26\nSolc 0.8.26 finished in 802.04ms\nCompiler run successful!\n","passed":true},{"durationMs":14021,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 6 tests for test/StrataTokenLaunch.t.sol:StrataTokenLaunchTest\n[PASS] testFuzz_anySplitOfTheSupplyIsExact(uint256,uint256) (runs: 256, μ: 201240, ~: 202138)\n[PASS] test_contractDeployerReceivesTheWholeSupply() (gas: 28199)\n[PASS] test_launchSharesAddUpExactly() (gas: 201713)\n[PASS] test_theFactoryCannotPayOutMoreThanTheSupply() (gas: 44805)\n[PASS] test_theFactoryHasNoPowerOverHoldersAfterPayout() (gas: 127923)\n[PASS] test_theSwarmShareArrivesWholeAndIsClaimableWhole() (gas: 135808)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 36.98ms (37.56ms CPU time)\n\nRan 28 tests for test/StrataTokenEdges.t.sol:StrataTokenEdgesTest\n[PASS] testFuzz_approveAnyPairAnyValueIsExact(address,address,uint256) (runs: 1000, μ: 66818, ~: 67223)\n[PASS] testFuzz_chainedTransfersConserveTheSupply(uint256,uint256,uint256) (runs: 1000, μ: 217516, ~: 221630)\n[PASS] testFuzz_finiteAllowanceDecreasesByExactlyWhatMoves(uint256,uint256,uint256) (runs: 1000, μ: 194301, ~: 198476)\n[PASS] testFuzz_transferFromRevertsWhenBalanceIsTheBindingLimit(uint256,uint256,uint256) (runs: 1000, μ: 151465, ~: 151961)\n[PASS] testFuzz_transferToAnyNonZeroAddressDeliversExactly(address,uint256) (runs: 1000, μ: 78643, ~: 79069)\n[PASS] test_allowanceOneBelowUnlimitedIsFinite() (gas: 168357)\n[PASS] test_approveZeroEmitsApproval() (gas: 36674)\n[PASS] test_balanceCannotBeDoubledByReceivingTheSupplyTwice() (gas: 84687)\n[PASS] test_nobodyCanPullFromTheZeroAddress() (gas: 33558)\n[PASS] test_reapprovingAfterAPartialSpendResetsOutright() (gas: 277048)\n[PASS] test_selfApprovalLetsAnOwnerPullFromItself() (gas: 178377)\n[PASS] test_spentAllowanceCannotBeSpentAgain() (gas: 185889)\n[PASS] test_tokensSentToTheTokenContractStayThere() (gas: 124891)\n[PASS] test_transferFromBackToTheOwnerSpendsAllowanceWithoutMovingBalance() (gas: 146549)\n[PASS] test_transferFromOfMaxValueWithUnlimitedAllowanceReverts() (gas: 87523)\n[PASS] test_transferOfMaxValueRevertsWithExactError() (gas: 33530)\n[PASS] test_transferRejectsValueWithEther() (gas: 62867)\n[PASS] test_unknownSelectorAndEmptyCalldataRevert() (gas: 69872)\n[PASS] test_unlimitedAllowanceDoesNotBypassTheBalanceCheck() (gas: 135365)\n[PASS] test_unlimitedAllowanceEmitsNoApprovalOnSpend() (gas: 164558)\n[PASS] test_unlimitedAllowanceSurvivesRepeatedSpends() (gas: 213132)\n[PASS] test_viewFunctionsAnswerThroughStaticcall() (gas: 17903)\n[PASS] test_zeroAddressAsBothEndsReverts() (gas: 30695)\n[PASS] test_zeroAddressCannotApprove() (gas: 35051)\n[PASS] test_zeroAddressCannotApproveItself() (gas: 30655)\n[PASS] test_zeroAddressCannotSendEvenNothing() (gas: 30748)\n[PASS] test_zeroValuePullFromTheZeroAddressStillReverts() (gas: 33347)\n[PASS] test_zeroValueTransferFromNeedsNoAllowance() (gas: 103075)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 40.20ms (195.46ms CPU time)\n\nRan 33 tests for test/StrataToken.t.sol:StrataTokenTest\n[PASS] testFuzz_approveSetsExactly(address,uint256) (runs: 256, μ: 58452, ~: 58600)\n[PASS] testFuzz_transferAboveBalanceReverts(uint256,uint256) (runs: 256, μ: 90299, ~: 90664)\n[PASS] testFuzz_transferConservesBalances(address,uint256) (runs: 256, μ: 101957, ~: 102228)\n[PASS] testFuzz_transferFromAboveAllowanceReverts(uint256,uint256) (runs: 256, μ: 93466, ~: 93787)\n[PASS] testFuzz_transferFromSpendsExactlyWhatMoves(uint256,uint256,uint256) (runs: 256, μ: 187733, ~: 190708)\n[PASS] test_approveDoesNotNeedABalance() (gas: 57951)\n[PASS] test_approveOverwritesRatherThanAccumulates() (gas: 87586)\n[PASS] test_approveRevertsForTheZeroSpender() (gas: 30746)\n[PASS] test_approveSetsAllowanceAndEmits() (gas: 68220)\n[PASS] test_constructorEmitsASingleMintTransfer() (gas: 16400)\n[PASS] test_constructorMintsTheWholeSupplyToTheDeployer() (gas: 33888)\n[PASS] test_eachDeploymentHasItsOwnFixedSupply() (gas: 22457)\n[PASS] test_metadata() (gas: 17668)\n[PASS] test_noMintOrOwnershipCallIncreasesSupply() (gas: 618045)\n[PASS] test_noOwnerAndNoEtherAccepted() (gas: 76940)\n[PASS] test_noPrivilegedCallMovesOrFreezesAHolder() (gas: 439834)\n[PASS] test_runtimeCodeHasNoDelegatecallOrSelfdestruct() (gas: 591976)\n[PASS] test_transferFromByTheOwnerStillNeedsAnAllowance() (gas: 85675)\n[PASS] test_transferFromDoesNotEmitApprovalWhenSpending() (gas: 167422)\n[PASS] test_transferFromExactAllowanceLeavesZero() (gas: 165907)\n[PASS] test_transferFromRevertsBeyondAllowance() (gas: 136964)\n[PASS] test_transferFromRevertsBeyondBalanceEvenWithAllowance() (gas: 142649)\n[PASS] test_transferFromRevertsToTheZeroAddress() (gas: 135782)\n[PASS] test_transferFromRevertsWithoutAllowance() (gas: 89752)\n[PASS] test_transferFromSpendsAllowanceAndEmits() (gas: 198679)\n[PASS] test_transferFromWithUnlimitedAllowanceKeepsIt() (gas: 167809)\n[PASS] test_transferMovesBalanceAndEmits() (gas: 78230)\n[PASS] test_transferRevertsFromAnEmptyAccount() (gas: 33272)\n[PASS] test_transferRevertsToTheZeroAddress() (gas: 40120)\n[PASS] test_transferRevertsWhenBalanceIsInsufficient() (gas: 96992)\n[PASS] test_transferToSelfKeepsBalance() (gas: 89952)\n[PASS] test_transferWholeBalance() (gas: 65442)\n[PASS] test_transferZeroSucceedsAndEmits() (gas: 49986)\nSuite result: ok. 33 passed; 0 failed; 0 skipped; finished in 40.22ms (195.45ms CPU time)\n\nRan 1 test for test/StrataTokenInvariant.t.sol:StrataTokenInvariantTest\n[PASS]\nStrataTokenInvariantTest invariants:\n[PASS] invariant_allowancesMatchTheLedger\n[PASS] invariant_balancesMatchTheLedger\n[PASS] invariant_balancesSumToSupply\n[PASS] invariant_everyHolderCanStillTransfer\n[PASS] invariant_metadataIsConstant\n[PASS] invariant_totalSupplyIsFixed\n[PASS] invariant_zeroAddressHoldsNothing\n StrataTokenInvariantTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭--------------------+------------------------+-------+---------+----------╮\n| Contract           | Selector               | Calls | Reverts | Discards |\n+==========================================================================+\n| StrataTokenHandler | adminCall              | 2309  | 0       | 0        |\n|--------------------+------------------------+-------+---------+----------|\n| StrataTokenHandler | approve                | 2300  | 0       | 0        |\n|--------------------+------------------------+-------+---------+----------|\n| StrataTokenHandler | transfer               | 2371  | 0       | 0        |\n|--------------------+------------------------+-------+---------+----------|\n| StrataTokenHandler | transferAboveBalance   | 2291  | 0       | 0        |\n|--------------------+------------------------+-------+---------+----------|\n| StrataTokenHandler | transferFrom           | 2351  | 0       | 0        |\n|--------------------+------------------------+-------+---------+----------|\n| StrataTokenHandler | transferFromAboveLimit | 2323  | 0       | 0        |\n|--------------------+------------------------+-------+---------+----------|\n| StrataTokenHandler | transferToZero         | 2439  | 0       | 0        |\n╰--------------------+------------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 13.97s (13.96s CPU time)\n\nRan 4 test suites in 13.97s (14.08s CPU time): 68 tests passed, 0 failed, 0 skipped (68 total tests)\n","passed":true},{"durationMs":30,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"StrataToken.approve(address,uint256)\",\"StrataToken.transfer(address,uint256)\",\"StrataToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":6,\"README.md\":130,\"foundry.toml\":24,\"src/StrataToken.sol\":127,\"src/interfaces/IERC20.sol\":40,\"test/StrataToken.t.sol\":424,\"test/StrataTokenEdges.t.sol\":352,\"test/StrataTokenInvariant.t.sol\":375,\"test/StrataTokenLaunch.t.sol\":117,\"test/utils/TestBase.sol\":65,\"test/utils/Vm.sol\":46},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"1971a0ca9570b52af4930e161775b148a95607bc734a6c31b745c3070fd900ff","verifiedTreeHash":"7e20ec0ee0b079bb6289363c4d9c75c16e3fe969","verifierVersion":"0.1.0+63e0a393"},{"checks":[{"durationMs":461,"exitCode":0,"name":"build","output":"Compiling 6 files with Solc 0.8.26\nSolc 0.8.26 finished in 414.94ms\nCompiler run successful!\n","passed":true},{"durationMs":79,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 6 tests for test/StrataTokenLaunch.t.sol:StrataTokenLaunchTest\n[PASS] testFuzz_anySplitOfTheSupplyIsExact(uint256,uint256) (runs: 256, μ: 201153, ~: 202138)\n[PASS] test_contractDeployerReceivesTheWholeSupply() (gas: 28199)\n[PASS] test_launchSharesAddUpExactly() (gas: 201713)\n[PASS] test_theFactoryCannotPayOutMoreThanTheSupply() (gas: 44805)\n[PASS] test_theFactoryHasNoPowerOverHoldersAfterPayout() (gas: 127923)\n[PASS] test_theSwarmShareArrivesWholeAndIsClaimableWhole() (gas: 135808)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 8.03ms (8.07ms CPU time)\n\nRan 33 tests for test/StrataToken.t.sol:StrataTokenTest\n[PASS] testFuzz_approveSetsExactly(address,uint256) (runs: 256, μ: 58378, ~: 58606)\n[PASS] testFuzz_transferAboveBalanceReverts(uint256,uint256) (runs: 256, μ: 90031, ~: 90652)\n[PASS] testFuzz_transferConservesBalances(address,uint256) (runs: 256, μ: 101890, ~: 102240)\n[PASS] testFuzz_transferFromAboveAllowanceReverts(uint256,uint256) (runs: 256, μ: 93230, ~: 93775)\n[PASS] testFuzz_transferFromSpendsExactlyWhatMoves(uint256,uint256,uint256) (runs: 256, μ: 187695, ~: 190708)\n[PASS] test_approveDoesNotNeedABalance() (gas: 57951)\n[PASS] test_approveOverwritesRatherThanAccumulates() (gas: 87586)\n[PASS] test_approveRevertsForTheZeroSpender() (gas: 30746)\n[PASS] test_approveSetsAllowanceAndEmits() (gas: 68220)\n[PASS] test_constructorEmitsASingleMintTransfer() (gas: 16400)\n[PASS] test_constructorMintsTheWholeSupplyToTheDeployer() (gas: 33888)\n[PASS] test_eachDeploymentHasItsOwnFixedSupply() (gas: 22457)\n[PASS] test_metadata() (gas: 17668)\n[PASS] test_noMintOrOwnershipCallIncreasesSupply() (gas: 618045)\n[PASS] test_noOwnerAndNoEtherAccepted() (gas: 76940)\n[PASS] test_noPrivilegedCallMovesOrFreezesAHolder() (gas: 439834)\n[PASS] test_runtimeCodeHasNoDelegatecallOrSelfdestruct() (gas: 591976)\n[PASS] test_transferFromByTheOwnerStillNeedsAnAllowance() (gas: 85675)\n[PASS] test_transferFromDoesNotEmitApprovalWhenSpending() (gas: 167422)\n[PASS] test_transferFromExactAllowanceLeavesZero() (gas: 165907)\n[PASS] test_transferFromRevertsBeyondAllowance() (gas: 136964)\n[PASS] test_transferFromRevertsBeyondBalanceEvenWithAllowance() (gas: 142649)\n[PASS] test_transferFromRevertsToTheZeroAddress() (gas: 135782)\n[PASS] test_transferFromRevertsWithoutAllowance() (gas: 89752)\n[PASS] test_transferFromSpendsAllowanceAndEmits() (gas: 198679)\n[PASS] test_transferFromWithUnlimitedAllowanceKeepsIt() (gas: 167809)\n[PASS] test_transferMovesBalanceAndEmits() (gas: 78230)\n[PASS] test_transferRevertsFromAnEmptyAccount() (gas: 33272)\n[PASS] test_transferRevertsToTheZeroAddress() (gas: 40120)\n[PASS] test_transferRevertsWhenBalanceIsInsufficient() (gas: 96992)\n[PASS] test_transferToSelfKeepsBalance() (gas: 89952)\n[PASS] test_transferWholeBalance() (gas: 65442)\n[PASS] test_transferZeroSucceedsAndEmits() (gas: 49986)\nSuite result: ok. 33 passed; 0 failed; 0 skipped; finished in 15.50ms (57.45ms CPU time)\n\nRan 2 test suites in 16.22ms (23.53ms CPU time): 39 tests passed, 0 failed, 0 skipped (39 total tests)\n","passed":true},{"durationMs":20,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"StrataToken.approve(address,uint256)\",\"StrataToken.transfer(address,uint256)\",\"StrataToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":6,\"README.md\":130,\"foundry.toml\":24,\"src/StrataToken.sol\":127,\"src/interfaces/IERC20.sol\":40,\"test/StrataToken.t.sol\":424,\"test/StrataTokenLaunch.t.sol\":117,\"test/utils/TestBase.sol\":65,\"test/utils/Vm.sol\":46},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":320,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":195,"exitCode":0,"name":"aderyn","output":"[low] large-numeric-literal at src/StrataToken.sol:27: Large Numeric Literal","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"967f0d0474cb6ea14de112acd624ed350d7ed06d6547b7e68bec3e20ca04b877","verifiedTreeHash":"f4e5c30f24b5173ab62586f34cf8f0693e5e315b","verifierVersion":"0.1.0+63e0a393"},{"checks":[{"durationMs":408,"exitCode":0,"name":"build","output":"Compiling 6 files with Solc 0.8.26\nSolc 0.8.26 finished in 367.10ms\nCompiler run successful!\n","passed":true},{"durationMs":63,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 6 tests for test/StrataTokenLaunch.t.sol:StrataTokenLaunchTest\n[PASS] testFuzz_anySplitOfTheSupplyIsExact(uint256,uint256) (runs: 256, μ: 201153, ~: 202138)\n[PASS] test_contractDeployerReceivesTheWholeSupply() (gas: 28199)\n[PASS] test_launchSharesAddUpExactly() (gas: 201713)\n[PASS] test_theFactoryCannotPayOutMoreThanTheSupply() (gas: 44805)\n[PASS] test_theFactoryHasNoPowerOverHoldersAfterPayout() (gas: 127923)\n[PASS] test_theSwarmShareArrivesWholeAndIsClaimableWhole() (gas: 135808)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 11.29ms (11.78ms CPU time)\n\nRan 33 tests for test/StrataToken.t.sol:StrataTokenTest\n[PASS] testFuzz_approveSetsExactly(address,uint256) (runs: 256, μ: 58378, ~: 58606)\n[PASS] testFuzz_transferAboveBalanceReverts(uint256,uint256) (runs: 256, μ: 90031, ~: 90652)\n[PASS] testFuzz_transferConservesBalances(address,uint256) (runs: 256, μ: 101890, ~: 102240)\n[PASS] testFuzz_transferFromAboveAllowanceReverts(uint256,uint256) (runs: 256, μ: 93230, ~: 93775)\n[PASS] testFuzz_transferFromSpendsExactlyWhatMoves(uint256,uint256,uint256) (runs: 256, μ: 187695, ~: 190708)\n[PASS] test_approveDoesNotNeedABalance() (gas: 57951)\n[PASS] test_approveOverwritesRatherThanAccumulates() (gas: 87586)\n[PASS] test_approveRevertsForTheZeroSpender() (gas: 30746)\n[PASS] test_approveSetsAllowanceAndEmits() (gas: 68220)\n[PASS] test_constructorEmitsASingleMintTransfer() (gas: 16400)\n[PASS] test_constructorMintsTheWholeSupplyToTheDeployer() (gas: 33888)\n[PASS] test_eachDeploymentHasItsOwnFixedSupply() (gas: 22457)\n[PASS] test_metadata() (gas: 17668)\n[PASS] test_noMintOrOwnershipCallIncreasesSupply() (gas: 618045)\n[PASS] test_noOwnerAndNoEtherAccepted() (gas: 76940)\n[PASS] test_noPrivilegedCallMovesOrFreezesAHolder() (gas: 439834)\n[PASS] test_runtimeCodeHasNoDelegatecallOrSelfdestruct() (gas: 591976)\n[PASS] test_transferFromByTheOwnerStillNeedsAnAllowance() (gas: 85675)\n[PASS] test_transferFromDoesNotEmitApprovalWhenSpending() (gas: 167422)\n[PASS] test_transferFromExactAllowanceLeavesZero() (gas: 165907)\n[PASS] test_transferFromRevertsBeyondAllowance() (gas: 136964)\n[PASS] test_transferFromRevertsBeyondBalanceEvenWithAllowance() (gas: 142649)\n[PASS] test_transferFromRevertsToTheZeroAddress() (gas: 135782)\n[PASS] test_transferFromRevertsWithoutAllowance() (gas: 89752)\n[PASS] test_transferFromSpendsAllowanceAndEmits() (gas: 198679)\n[PASS] test_transferFromWithUnlimitedAllowanceKeepsIt() (gas: 167809)\n[PASS] test_transferMovesBalanceAndEmits() (gas: 78230)\n[PASS] test_transferRevertsFromAnEmptyAccount() (gas: 33272)\n[PASS] test_transferRevertsToTheZeroAddress() (gas: 40120)\n[PASS] test_transferRevertsWhenBalanceIsInsufficient() (gas: 96992)\n[PASS] test_transferToSelfKeepsBalance() (gas: 89952)\n[PASS] test_transferWholeBalance() (gas: 65442)\n[PASS] test_transferZeroSucceedsAndEmits() (gas: 49986)\nSuite result: ok. 33 passed; 0 failed; 0 skipped; finished in 11.13ms (59.79ms CPU time)\n\nRan 2 test suites in 15.08ms (22.42ms CPU time): 39 tests passed, 0 failed, 0 skipped (39 total tests)\n","passed":true},{"durationMs":21,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"StrataToken.approve(address,uint256)\",\"StrataToken.transfer(address,uint256)\",\"StrataToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":6,\"README.md\":130,\"foundry.toml\":24,\"launch.json\":24,\"src/StrataToken.sol\":127,\"src/interfaces/IERC20.sol\":40,\"test/StrataToken.t.sol\":424,\"test/StrataTokenLaunch.t.sol\":117,\"test/utils/TestBase.sol\":65,\"test/utils/Vm.sol\":46},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"f361b883944e2474bdf1b56badafa81405ffcc5a13ae0916f8a8ed27a656ac28","verifiedTreeHash":"9422f8ea84d93fa9f694dbf62a1c5a3f4a0e93a3","verifierVersion":"0.1.0+63e0a393"}]}