{"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":"f708c332-034f-47b3-b204-318734811863","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"39f75fda95e509fbae293e585b23ecf7cd149de772b22bca82d4b99e40a59e62","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":"4317dfa295f549e54d418a0ea2ce92dac9bd20a4d5f5f4c798d125d5c5c2ba43","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":"abc6a0f88d3174c52b20197f2be69fd3776dc950ced90a765ad2e8dee981dc73","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":"dce7912fc446c070102160ed7b658bb80da738ccb17001ec4eaf54a83df7f296","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":"10fe4e569cdf73efdc3aa76db1b816ff6acb6f9c85d67c3174530622e22189bb","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":"a3fa1f732fc8c53aa02324ff507af97146b3531b75894cac69232f8b53446165","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"6b8d2c2ebd3301cff2be8edb1e1cc6ba65c858c02fe7247be81722b969842265","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"6b8d2c2ebd3301cff2be8edb1e1cc6ba65c858c02fe7247be81722b969842265","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":"7a3223c845fe0d44ec7daeffe0a2033bfa1cbdb955f85824ebf1a1bcd0378a0c","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"410061bb2d89a5cef97d41341a0d1044299f2cef27fa7b2f2b9d774d231375a3","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","state":"accepted"}],"objective":"A custom token: Starknet (STARKNET).\nToken name: Starknet\nToken symbol: STARKNET\nToken supply: 1,000,000,000 with 18 decimals, all minted once to the deployer in the constructor.","parentJobId":null,"planHash":"75ea0cadac11debc989f12874ad7329f605bcfd51a000296113da9e6d81b4688","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"f708c332-034f-47b3-b204-318734811863","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1566-starknet"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"52082","feedbackHash":"dd8bafeabf5033675ebda469629f5c8a15b89bed475bb24e943637ea5cd4e7ad","nodeKey":"audit_economics","submissionHash":"39f75fda95e509fbae293e585b23ecf7cd149de772b22bca82d4b99e40a59e62","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52157","feedbackHash":"57c5ba3302330dc7686a8524cc1e4de8b20b5c606b592c95c98731aa7ce24cf6","nodeKey":"audit_flow","submissionHash":"4317dfa295f549e54d418a0ea2ce92dac9bd20a4d5f5f4c798d125d5c5c2ba43","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52176","feedbackHash":"505fefe108a343bf8a1d1b4dd8c1eaafc4c995697a8a7bd51c6c4894b57c25e1","nodeKey":"audit_judge","submissionHash":"abc6a0f88d3174c52b20197f2be69fd3776dc950ced90a765ad2e8dee981dc73","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52129","feedbackHash":"da2446a136ef0116e4f4b40e10d57b5236a28dc6e922cd2b8a3e34696214f74b","nodeKey":"audit_math","submissionHash":"dce7912fc446c070102160ed7b658bb80da738ccb17001ec4eaf54a83df7f296","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52167","feedbackHash":"90694515da7ae2fd53f53cfd7cbbcd9115b61ae9be329fae3aeb748f5354dfa6","nodeKey":"audit_permissions","submissionHash":"10fe4e569cdf73efdc3aa76db1b816ff6acb6f9c85d67c3174530622e22189bb","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52257","feedbackHash":"2e547515046cda372a220c383fb2e99eb9200242b643ddb0178d8ce0330897d9","nodeKey":"build_contract_project","submissionHash":"a3fa1f732fc8c53aa02324ff507af97146b3531b75894cac69232f8b53446165","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52258","feedbackHash":"a4bab24230b0833707d8a178cb803d83890d21af7753f8fe57b0e84e3fda0198","nodeKey":"manifest","submissionHash":"7a3223c845fe0d44ec7daeffe0a2033bfa1cbdb955f85824ebf1a1bcd0378a0c","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52590","feedbackHash":"a1ab9b002799cc4721152ba68f4e5ef8aea979f9d50da440629ca0342a5857e2","nodeKey":"write_foundry_tests","submissionHash":"410061bb2d89a5cef97d41341a0d1044299f2cef27fa7b2f2b9d774d231375a3","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"3d2d649bcf9a32d205ac26fd9a9b9f4fb5e745bf8bcbdeab04ed896b6b5cf9d1","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"1ca477e8d9b58040","findings":[],"hash":"10fe4e569cdf73efdc3aa76db1b816ff6acb6f9c85d67c3174530622e22189bb","nodeId":"89e18b4a-7955-4536-be11-c588981a1942","outcome":"completed","summary":"The review is complete and found no defects in the permission model. The findings file is written with an empty list and a full coverage record, and the working tree is unchanged apart from that file.\n\n**What I checked, from the Access Control, Trust Gap and Asymmetry guides**\n\n- **Permission map.** The token has no owner, admin, minter, pauser or blocklist. The constructor's only effect is minting the full supply to the creator, which is the factory in production. A CREATE2 deployment lands everything on the factory and nothing on the transaction origin.\n- **Entry points.** The compiled ABI exposes exactly three state-changing functions: approve, transfer and transferFrom. There is no fallback, no receive, and the runtime contains zero CALL, DELEGATECALL, CALLCODE, STATICCALL, SELFDESTRUCT, CREATE or ORIGIN opcodes.\n- **Inherited code.** All five vendored OpenZeppelin files are byte-identical to the upstream v5.1.0 tag, so no backdoor is hidden in the base contract or in the sender resolution.\n- **Guards and asymmetry.** Every storage slot has a single guard shape. The approve and spend paths write the same allowance slot with matching bounds, mint is reachable only from the constructor, and burn is unreachable. The decimals constant and the inherited decimals function agree.\n- **Trust gap.** With no privileged actor, no economic formula and no caller-class branch inside the token, none of the guide's seams can be constructed.\n\n**Verification run**\n\n- The existing suite builds and passes: 30 tests including the invariant run with supply conservation.\n- A scratch suite I wrote and then deleted fuzzed arbitrary callers and the deployer against a holder's balance, fuzzed allowance spending, fuzzed unknown selectors with value, and a factory-style CREATE2 deployment. All four passed at 512 runs.\n- Static analysis leads: slither reported nothing. aderyn's large-literal note is style only, and the literal evaluates to the exact manifest supply.\n\n**Noted but not reported as defects**\n\n- The standard ERC-20 approve overwrite race is inherited unchanged and already documented in the README. It is recorded in the coverage file as a trust assumption for integrators, not as a finding.\n\nAll three listed entry points are marked as holding, with ten further rows covering the constructor, the ABI surface, the vendored library, each guide, the supply invariant and the launch flows.","treeHash":null,"usage":{"cachedInputTokens":597544,"inputTokens":258,"model":"claude-fable-5-1","outputTokens":12433,"runtime":"claude","turns":24,"wallClockMs":174802}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"077d2937780a81bc","findings":[{"citation":"resolved","description":"Trust assumption, documented for the author, not a defect to fix. The token inherits OpenZeppelin v5 ERC20 unchanged, and OZ v5 removed increaseAllowance/decreaseAllowance. approve(spender, n) overwrites the allowance, so an owner who lowers an existing allowance can be front-run by the spender spending the old allowance first and then the new one. This is the ERC-20 standard's own property and the brief asks for a plain fixed-supply ERC-20, so no change to the agreed design is proposed. Holders should set an allowance to 0 before setting a new non-zero one, or use permit-style flows in integrating contracts. Everything else in the Economic Security, Invariant and Flow Gap guides was checked and holds: no external dependencies, no fee/rebasing/pausable paths, launch legs (factory -> distributor -> claimant, factory -> pool, factory -> remainder) move exactly the requested amount, totalSupply is constant and equals the sum of balances, decimals() == DECIMALS == 18, TOTAL_SUPPLY == totalSupply(), and the only revert paths are OZ's insufficient-balance, insufficient-allowance and zero-address checks.","line":17,"path":"src/StarknetToken.sol","reproduction":"Deploy via a CREATE2 factory (factory holds 1e27). factory.transfer(owner, 1000). owner: approve(spender, 100). spender: transferFrom(owner, spender, 100). owner intends to reduce to 50 and calls approve(spender, 50). spender: transferFrom(owner, spender, 50). Expected by the owner: spender gets at most 100 total. Actual: spender holds 150 (verified in test/scratch/EconProbe.t.sol test_approveRaceSpends150, which passes on the current code, i.e. the behaviour is present). Inherent to ERC-20 approve semantics.","severity":"info","snippet":"contract StarknetToken is ERC20 {","title":"Inherited ERC-20 approve race: no increase/decreaseAllowance, so a re-approval can be front-run (standard behaviour, not a defect of this code)"}],"hash":"39f75fda95e509fbae293e585b23ecf7cd149de772b22bca82d4b99e40a59e62","nodeId":"de661aa6-2080-4be5-ae70-5f788497b341","outcome":"completed","summary":"Review complete. No defects found in the assigned area. The findings file is written at the repository root with one informational entry and a full coverage record.\n\n**What I reviewed.** The token at `src/StarknetToken.sol` is a 30-line OpenZeppelin v5.1.0 ERC-20 with no custom logic. It has no owner, no mint or burn, no fee, no hooks and no external calls. I checked it against the Economic Security, Invariant and Flow Gap guides in the Pashov reference, plus the protected launch floor test.\n\n**What I verified.**\n- The project's own 30 tests pass, including the handler-driven invariant suite with zero reverts.\n- A scratch probe under `test/scratch/` confirmed the launch legs move exact amounts. Factory to distributor, distributor to claimant, factory to pool and factory to remainder all arrive whole, and total supply stays constant.\n- Allowance accounting decrements exactly, infinite allowance never decrements, and overspend reverts. Zero-address transfer and approve revert, self-transfer keeps the balance, and ETH sent to the contract reverts.\n- The constants agree with the manifest. Decimals read 18 and the minted amount equals the declared supply.\n- The aderyn \"large numeric literal\" lead is style only. Slither reported nothing.\n\n**What I reported.** One info-level entry documents the inherent ERC-20 approve race, since OZ v5 dropped increaseAllowance. It is a trust assumption, not a defect, and I said no change to the agreed design is needed. The judge can drop it.\n\n**Coverage.** All three listed entry points are marked `holds`, with four extra rows for the supply invariant, the decimals and constant equality, constructor deployment behaviour, and the receive/rescue surface. Nothing was left unreached.\n\n**Not done.** The scratch test file is left under `test/scratch/`, which the task says is discarded. No other file was changed.","treeHash":null,"usage":{"cachedInputTokens":669309,"inputTokens":354,"model":"claude-fable-5-1","outputTokens":8713,"runtime":"claude","turns":12,"wallClockMs":132830}},{"artifacts":[],"attempt":1,"bundleHash":"a6863a67bbeb894a2981eef6569745a6f1ec524bf802419672ec1ce4a07b7dc9","device":"99e4819277ea59fc","findings":[],"hash":"410061bb2d89a5cef97d41341a0d1044299f2cef27fa7b2f2b9d774d231375a3","nodeId":"63abfb66-7119-4b67-89d3-6bb824f1a883","outcome":"completed","summary":"The failing check is repaired. The suite now passes on the recorded seed and on two further seeds, with the build clean.\n\n**What was wrong.** The fuzz test `testFuzz_approveSetsExactlyTheLastValue` in `test/StarknetToken.edges.t.sol` asserted that the reverse-direction allowance stays zero after the deployer approves a spender. The fuzzer chose a spender seed that resolved to the deployer's own address. In that case the \"reverse\" allowance is the very same storage slot, so it legitimately equals the approved value. This was a harness assumption error, not a token defect. The token's approve is not symmetric, and the owner-as-own-spender case is already pinned by a separate unit test.\n\n**What I changed.** One line in that test now steers the fuzzed spender off the deployer address, so the reverse-slot assertion always inspects a distinct slot. No other test or file was touched.\n\n**Verification.**\n\n| Check | Result |\n|---|---|\n| `forge build` | clean, no changes needed |\n| `forge test` with the failing seed | 1000 runs pass |\n| `forge test` full suite, default seed | 67 passed, 0 failed |\n| `forge test` with two extra seeds | 67 passed each |\n\nNo new defects were found in the token, so no `.imd-findings.json` was written. The only modified path is `test/StarknetToken.edges.t.sol`, inside the allowed scope.","treeHash":"0f2fe3267705cb21b2624f45659560970258dc7f","usage":{"cachedInputTokens":1223219,"inputTokens":580,"model":"claude-fable-5-1","outputTokens":38901,"runtime":"claude","turns":33,"wallClockMs":581915}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"37eed9f56188ea8b","findings":[],"hash":"4317dfa295f549e54d418a0ea2ce92dac9bd20a4d5f5f4c798d125d5c5c2ba43","nodeId":"57d9b781-dc12-483f-b455-d3c117c61acf","outcome":"completed","summary":"The review is complete. The findings file is written and the working tree is clean apart from it.\n\n**Result: no defects found.** `.imd-findings.json` holds an empty findings list and ten coverage rows, every one `holds`. All three listed entry points are covered.\n\n**What I checked, for the Execution Trace, Periphery and First Principles guides**\n\n- **Token body.** `src/StarknetToken.sol` is two constants and a constructor over OpenZeppelin v5.1.0 ERC20. The supply constant equals 10^27, minted once to the constructor's caller with no arguments and no external calls, so a CREATE2 factory receives all of it.\n- **Entry points.** I traced approve, transfer and transferFrom with concrete values in a scratch Foundry probe: zero and max allowances, max-minus-one decrementing, from equal to to, zero amount without allowance, zero sender and receiver, and the full launch flow in miniature (factory to distributor to claimant, factory to pool, factory to remainder). Every amount arrived whole and the supply stayed constant. The scratch file has been removed.\n- **Surface.** The compiled ABI exposes exactly three nonpayable functions and no receive, fallback, payable or admin selector. The repo's own opcode scan for DELEGATECALL, CALLCODE and SELFDESTRUCT passes.\n- **Periphery.** All five vendored OpenZeppelin files are sha256-identical to the upstream v5.1.0 tag, so the inherited library is untampered.\n- **Repo health.** The full suite passes (30 tests plus a 64-run invariant campaign), `forge fmt --check` is clean, and the runtime is well within EIP-170.\n\n**Observations that are not defects**\n\n- The standard ERC-20 approve race exists, as in every OpenZeppelin token. The README documents the overwrite semantics, so I did not report it.\n- `decimals()` is OpenZeppelin's default rather than returning the `DECIMALS` constant. Both are compile-time 18, so no deployed state can diverge. Recorded as a coverage row.\n- The protected launch floor test was read but could not be run here, since it needs v4-core sources and environment the repo lacks. Every flow it drives is a plain transfer with no exemptions required, which the probe replayed.\n\n**Not reached:** nothing within my area. Tooling run was forge build, forge test and forge fmt; Slither and Aderyn output supplied to me contained no medium-or-higher leads.","treeHash":null,"usage":{"cachedInputTokens":706384,"inputTokens":290,"model":"claude-fable-5-1","outputTokens":14709,"runtime":"claude","turns":27,"wallClockMs":216875}},{"artifacts":[],"attempt":1,"bundleHash":"34dfb1ff6c2ce4b163eb42e23fa003d0f967f27005a138667eb3c1f260836984","device":"76f57db4177175be","findings":[],"hash":"7a3223c845fe0d44ec7daeffe0a2033bfa1cbdb955f85824ebf1a1bcd0378a0c","nodeId":"a42619d1-80ba-41a1-a168-ce0295c47733","outcome":"completed","summary":"Done. I wrote the manifest for the accepted Starknet token launch and verified the tree.\n\n**What the accepted tree contains**\n\nThe only deployable contract is the token at `src/StarknetToken.sol`. It is a plain OpenZeppelin v5.1.0 ERC-20 with a no-argument constructor that mints the whole supply to msg.sender once. There are no application contracts, no owner, no mint or burn, and no transfer hooks, so there is nothing else to name in the manifest.\n\n**What launch.json says**\n\n- Kind is custom_token, with the token contract named StarknetToken, name Starknet, symbol STARKNET, 18 decimals and an empty constructorArgs list to match the parameterless constructor.\n- totalSupply is the constructor's exact mint in minor units: 1,000,000,000 tokens times 10 to the 18.\n- contracts is an empty list, since the accepted tree has no application contracts.\n- pool and economics are copied verbatim from the launch terms: IMD as the paired currency, fee 12500, tick spacing 60, the one-to-one provenance price, and the requester's 8800 bps, 2,500 IMD cap and remainder address.\n- notes describe only the token actually present and run 985 characters.\n\n**Verification**\n\n- The build compiles cleanly and the full suite passes 30 tests across 3 suites, invariants included.\n- A JSON check confirmed the manifest uses only the schema's six top-level keys, the supply string equals the constructor's mint and economics matches the job's object exactly.\n- Git shows launch.json as the only new or changed file. No configuration, library or source file was touched.","treeHash":"1443490d164b36c07aca9dadc8518d9d1f7a5ecf","usage":{"cachedInputTokens":171959,"inputTokens":130,"model":"claude-fable-5-1","outputTokens":2777,"runtime":"claude","turns":9,"wallClockMs":36887}},{"artifacts":[],"attempt":1,"bundleHash":"18dc7ae7859fc562c8c4ef3d220014fd8d105805de2cbf9ca9be9be0a9461feb","device":"22c9b760d0a15149","findings":[],"hash":"a3fa1f732fc8c53aa02324ff507af97146b3531b75894cac69232f8b53446165","nodeId":"180d8bc9-7e18-40a0-b44c-f6e81627518e","outcome":"completed","summary":"The deliverable is complete and verified. Nothing else is pending, so no further tool calls are needed.\n\n**Outcome:** a Foundry project at the repository root implementing the Starknet (STARKNET) fixed-supply token. `forge build`, `forge test` (30 tests, all passing, also with an empty environment) and `forge fmt --check` all pass with solc 0.8.26 pinned.\n\n**What was built**\n\n- `src/StarknetToken.sol`: contract `StarknetToken` inheriting OpenZeppelin v5.1.0 ERC20. The constructor takes no arguments and mints 1,000,000,000 × 10^18 to `msg.sender` once. No owner, mint, burn, pause, blocklist, fee or upgrade path, so the supply is constant and no privileged hand can touch a holder.\n- `foundry.toml`: solc 0.8.26, optimizer on, `bytecode_hash = \"none\"` and CBOR metadata off (I confirmed the artifact ends without a metadata marker), ffi off, no fs permissions.\n- Dependencies vendored as plain files in `lib/` (forge-std commit 0258fe8, and only the five OpenZeppelin files ERC20 imports). No submodules.\n- `script/DeployStarknetToken.s.sol` with a `deploy()` function tested directly and a `run()` for local use. It reads no environment.\n- Tests in `test/`: success paths (metadata, exact supply, mint event, CREATE2 deployment lands the supply on the creating contract and nothing on the EOA, transfers, approvals, infinite allowance), failure paths (insufficient balance and allowance with the ERC-6093 errors, zero-address receiver and spender, rejected ether and unknown selectors, every mint/admin/pause/blocklist/seize selector from the protected test failing from both a stranger and the deployer), an opcode scan for DELEGATECALL/CALLCODE/SELFDESTRUCT, fuzz tests, and a handler-driven invariant suite for supply conservation.\n- `README.md` documenting assumptions, deployment parameters (no constructor arguments, contract name 13 chars), the launch's pool and economics values as the manifest step's responsibility, an \"After launch\" section (nothing to configure), and operational responsibilities.\n\n**Notes**\n\n- The protected test's seed and swap through Uniswap v4 could not be replicated locally because its harness sources (LaunchLiquidity, HookFlags, PoolInitializationGuard) are the verifier's and not in the reads. A plain OpenZeppelin ERC20 with no transfer hooks has no path to fail those flows, and every other check in that file is mirrored in my own tests.\n- I did not write launch.json and did not commit, since `.git/` is off limits. All deliverables are untracked files in the working tree, ready for the upload step.","treeHash":"654ba194133fc86b085f13af7782ed0f4c5b2065","usage":{"cachedInputTokens":523961,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":20613,"runtime":"claude","turns":23,"wallClockMs":286671}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"ee2cc12e7dfe571a","findings":[{"citation":"resolved","description":"Merged from audit_economics (sole reporter). The token inherits OpenZeppelin v5.1.0 ERC20 unchanged; v5 has no increaseAllowance/decreaseAllowance, and approve(spender, n) overwrites the allowance. An owner lowering a non-zero allowance can be front-run by the spender, who spends the old allowance and then the new one. This is the ERC-20 standard's own property, the brief asks for a plain fixed-supply ERC-20, and no change to the agreed design is proposed. Trust assumption for integrators: set an allowance to 0 before changing it, or rely on a single-use flow. Reproduced against the code; recorded for the author, does not open a revision.","line":17,"path":"src/StarknetToken.sol","reproduction":"Deploy StarknetToken through a CREATE2 factory (factory holds 1e27). factory: transfer(owner, 1000). owner: approve(spender, 100). spender: transferFrom(owner, spender, 100). owner: approve(spender, 50) intending to reduce the remaining allowance. spender: transferFrom(owner, spender, 50). Expected by the owner: spender receives at most 100 in total. Actual: balanceOf(spender) == 150. Verified in test/scratch/Judge.t.sol test_approveRace, which passes on the current code (the behaviour is present). Inherent to ERC-20 approve semantics.","severity":"info","snippet":"contract StarknetToken is ERC20 {","title":"Inherited ERC-20 approve overwrite race (standard ERC-20 behaviour, not a defect of this code)"},{"citation":"resolved","description":"Merged from audit_math (sole reporter). TOTAL_SUPPLY at line 22 is scaled by the constant DECIMALS, while decimals() is OpenZeppelin's hard-coded literal 18 in ERC20.sol line 78 and is not overridden to return DECIMALS. Both are 18 today, so there is no defect: decimals() == DECIMALS == 18 and TOTAL_SUPPLY == 1e27, which the manifest's totalSupply and decimals match. The note is a latent coupling gap: a future edit of DECIMALS alone would mint a supply at a different scale than decimals() reports, and only the manifest check would catch it. Optional one-line tightening that preserves behaviour: `function decimals() public pure override returns (uint8) { return DECIMALS; }`. No action required for this launch; does not open a revision.","line":19,"path":"src/StarknetToken.sol","reproduction":"Current state: deploy StarknetToken; DECIMALS() returns 18, decimals() returns 18, TOTAL_SUPPLY() returns 1000000000000000000000000000, totalSupply() equals TOTAL_SUPPLY(). Nothing fails (verified in test/scratch/Judge.t.sol test_create2MintsToFactory, passing). Hypothetical drift only: change line 19 to `uint8 public constant DECIMALS = 6;` and redeploy; TOTAL_SUPPLY() returns 1000000000000000 while decimals() still returns 18.","severity":"info","snippet":"    uint8 public constant DECIMALS = 18;","title":"DECIMALS constant is not what decimals() returns: two independent declarations of the same value 18"}],"hash":"abc6a0f88d3174c52b20197f2be69fd3776dc950ced90a765ad2e8dee981dc73","nodeId":"a89c55cd-a863-4a5f-ab90-ea4b599d8487","outcome":"completed","summary":"The review is complete. The findings file is valid JSON, the git tree is unchanged, and the only files I created are the ignored findings file and a scratch test.\n\n**Outcome: no defects.** The token is an unmodified OpenZeppelin v5.1.0 ERC20 with a parameterless constructor that mints 1e27 to the deployer. Nothing a specialist reported is a defect, and my own pass found nothing either.\n\n**What I verified**\n\n- All 67 existing tests pass, including the invariant suites and the opcode scan.\n- Deploying through a CREATE2 factory mints the full supply to the factory, with name, symbol and 18 decimals matching the manifest. Creation and runtime bytecode are far under the protocol size limits.\n- Transfers to the zero address revert, ETH sent to the token reverts, and there is no mint, burn, owner, pause or blocklist selector in the ABI.\n- The manifest keys, lowercase addresses, empty constructor arguments and supply string all match the code.\n\n**Specialist findings, judged**\n\n- The approve overwrite race from the economics specialist reproduces exactly as stated. Spender ends with 150 after allowances of 100 then 50. It is standard ERC-20 behaviour, so I kept it as an info trust assumption.\n- The decimals coupling note from the math specialist also reproduces as stated: both declarations return 18 and nothing fails today. Kept as info, with the optional one-line override recorded for the author.\n- The permissions and flow specialists and the test writer reported nothing, and my traces agree.\n\n**Coverage.** All three entry points hold, plus three invariant rows covering supply, privileged surface and deployability. No row is unreached.","treeHash":null,"usage":{"cachedInputTokens":408668,"inputTokens":258,"model":"claude-fable-5-1","outputTokens":7020,"runtime":"claude","turns":9,"wallClockMs":105076}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"63c29c49a249ab7e","findings":[{"citation":"resolved","description":"Not a defect in the code as it stands: DECIMALS and the inherited ERC20.decimals() both return 18, and TOTAL_SUPPLY = 1_000_000_000 * 10 ** uint256(DECIMALS) = 1e27 is correct (verified with a scratch test: token.DECIMALS() == token.decimals() == 18 and TOTAL_SUPPLY == 1e27). The note is a latent coupling gap from the Math Precision pass (\"map the fixed-point systems\"): TOTAL_SUPPLY is scaled by the constant DECIMALS, while decimals() is OpenZeppelin's hard-coded literal 18, and decimals() is not overridden to return DECIMALS. The contract therefore has two separate declarations of the token's scale that nothing ties together. If DECIMALS were ever edited (for example to 6), the supply would be minted at 1e15 minor units while decimals() kept reporting 18, and the manifest/protected test check `decimals disagree with the manifest` would be the only thing catching it. A one-line `function decimals() public pure override returns (uint8) { return DECIMALS; }` removes the second declaration. No action is required for this launch.","line":19,"path":"src/StarknetToken.sol","reproduction":"Current state: deploy StarknetToken; DECIMALS() returns 18, decimals() returns 18, TOTAL_SUPPLY() returns 1000000000000000000000000000. Nothing fails today. Hypothetical drift: change line 19 to `uint8 public constant DECIMALS = 6;` and redeploy; TOTAL_SUPPLY() returns 1000000000000000 (1e15) while decimals() still returns 18, so the displayed supply becomes 0.000001 tokens instead of 1,000,000,000.","severity":"info","snippet":"    uint8 public constant DECIMALS = 18;","title":"DECIMALS constant is not the source of decimals(): two independent declarations of the same value"}],"hash":"dce7912fc446c070102160ed7b658bb80da738ccb17001ec4eaf54a83df7f296","nodeId":"bbffdd1b-dbc2-4e90-98ea-ccad1c21850e","outcome":"completed","summary":"The review is complete and the findings file is written. No source files were changed. Only test/scratch/ (mine, not kept) and .imd-findings.json were created.\n\n**Outcome: no math defects found.** The token is an unmodified OpenZeppelin v5.1.0 ERC20 with a single constructor mint, and nothing in the Math Precision, Boundary or Numerical Gap guides applies to a defect here.\n\n**What I verified**\n\n- **Vendored library integrity.** All five OpenZeppelin files under lib/ match the upstream v5.1.0 release byte for byte by SHA-256. Context returns plain msg.sender. So the arithmetic in _update and _spendAllowance is the audited upstream code.\n- **Supply constant.** The expression at src/StarknetToken.sol:22 evaluates to exactly 1e27 at compile time, fits uint128 (relevant to the v4 seed), and equals 1,000,000,000 times 10 to the decimals() power. The aderyn \"large numeric literal\" lead is a readability lint only.\n- **Launch split.** 10% swarm, 88% pool and 2% remainder in basis points of 1e27 divide with no remainder and sum exactly to the supply. No intermediate overflow.\n- **Entry-point boundaries.** Scratch tests exercised max-uint transfer, exact-allowance boundary, infinite allowance over the whole supply, self transferFrom of the full balance, zero-value calls with zero allowance, and both burn paths through the zero address. All behave as the OZ contract documents. The existing 30 project tests, including the 64-run invariant suite, also pass.\n- **No boundary surface.** The token has no external calls, no payable or fallback functions, no sentinel branches, no bytes decoding, and the ABI holds only approve, transfer and transferFrom as state-changing functions.\n\n**One informational note, not a defect.** DECIMALS at line 19 scales TOTAL_SUPPLY, but decimals() is OpenZeppelin's literal 18 and is not overridden to return the constant. They agree today. If DECIMALS were ever edited, the supply and reported decimals would drift apart. Overriding decimals() to return DECIMALS closes the gap.\n\n**Coverage.** All three listed entry points are marked `holds`, plus rows for the constructor, the supply-conservation invariant, the launch split, the decimals coupling (ref finding 1), the absent boundary surface, and the static-analysis lead. Nothing in my area was left unreached.","treeHash":null,"usage":{"cachedInputTokens":602047,"inputTokens":258,"model":"claude-fable-5-1","outputTokens":12135,"runtime":"claude","turns":21,"wallClockMs":189106}}],"verification":[{"checks":[{"durationMs":2279,"exitCode":0,"name":"build","output":"Compiling 34 files with Solc 0.8.26\nSolc 0.8.26 finished in 2.16s\nCompiler run successful!\n","passed":true},{"durationMs":4189,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 2 tests for test/DeployStarknetToken.t.sol:DeployStarknetTokenTest\n[PASS] test_deployMintsSupplyToTheScriptCaller() (gas: 1484197)\n[PASS] test_deployTwiceGivesIndependentTokens() (gas: 2030767)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 454.23µs (264.22µs CPU time)\n\nRan 2 tests for test/DeployStarknetToken.run.t.sol:DeployStarknetTokenRunTest\n[PASS] test_runMintsTheWholeSupplyToTheBroadcaster() (gas: 1499518)\n[PASS] test_runTwiceGivesTwoIndependentTokensWithTheSameHolder() (gas: 2044901)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 659.70µs (496.85µs CPU time)\n\nRan 27 tests for test/StarknetToken.t.sol:StarknetTokenTest\n[PASS] testFuzz_transferAboveBalanceReverts(uint256) (runs: 256, μ: 38865, ~: 39208)\n[PASS] testFuzz_transferConservesSupply(address,uint256) (runs: 256, μ: 81043, ~: 81139)\n[PASS] testFuzz_transferFromAboveAllowanceReverts(uint256,uint256) (runs: 256, μ: 89163, ~: 89412)\n[PASS] testFuzz_transferFromWithinAllowance(uint256,uint256) (runs: 256, μ: 134478, ~: 136329)\n[PASS] test_approveAndTransferFrom() (gas: 159722)\n[PASS] test_approveOverwritesPreviousAllowance() (gas: 92792)\n[PASS] test_approveZeroSpenderReverts() (gas: 32883)\n[PASS] test_constructorEmitsSingleMintTransfer() (gas: 8193)\n[PASS] test_create2DeploymentMintsToTheCreatingContract() (gas: 801198)\n[PASS] test_creationCodeHasNoConstructorArguments() (gas: 793295)\n[PASS] test_infiniteAllowanceIsNotDecremented() (gas: 120465)\n[PASS] test_metadata() (gas: 34684)\n[PASS] test_noCallIncreasesSupplyOrMintsToCaller() (gas: 664005)\n[PASS] test_noPrivilegedCallMovesOrFreezesAHolder() (gas: 444166)\n[PASS] test_rejectsEtherAndUnknownCalls() (gas: 54856)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 868112)\n[PASS] test_supplyIsOneBillionWithEighteenDecimals() (gas: 26501)\n[PASS] test_transferFromRevertsBeyondAllowance() (gas: 92486)\n[PASS] test_transferFromRevertsWhenOwnerLacksBalance() (gas: 93535)\n[PASS] test_transferFromRevertsWithoutAllowance() (gas: 40484)\n[PASS] test_transferMovesBalance() (gas: 87047)\n[PASS] test_transferRevertsOnInsufficientBalance() (gas: 37951)\n[PASS] test_transferRevertsOnMoreThanWholeBalance() (gas: 38118)\n[PASS] test_transferToSelfKeepsBalance() (gas: 40600)\n[PASS] test_transferToZeroAddressReverts() (gas: 36874)\n[PASS] test_transferWholeBalanceAndZeroAmount() (gas: 114437)\n[PASS] test_wholeSupplyMintedToDeployer() (gas: 17556)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 83.16ms (142.03ms CPU time)\n\nRan 33 tests for test/StarknetToken.edges.t.sol:StarknetTokenEdgeTest\n[PASS] testFuzz_allowanceErrorFiresFirstWhenBothAreShort(uint256,uint256) (runs: 1000, μ: 91916, ~: 93605)\n[PASS] testFuzz_approveSetsExactlyTheLastValue(uint256,uint256,uint256) (runs: 1000, μ: 123700, ~: 123635)\n[PASS] testFuzz_balanceErrorFiresWhenOnlyTheBalanceIsShort(uint256,uint256,uint256) (runs: 1000, μ: 164292, ~: 165283)\n[PASS] testFuzz_chainOfTransfersConservesSupply(uint256[8],uint256[8]) (runs: 1000, μ: 417710, ~: 419902)\n[PASS] testFuzz_infiniteAllowanceSurvivesAnySpend(uint256) (runs: 1000, μ: 130449, ~: 130629)\n[PASS] testFuzz_roundTripRestoresBalancesExactly(uint256) (runs: 1000, μ: 108353, ~: 108258)\n[PASS] testFuzz_splittingATransferDeliversTheSameTotal(uint256,uint256) (runs: 1000, μ: 112994, ~: 113917)\n[PASS] testFuzz_transferFromAnEmptyAccountAlwaysReverts(uint256,address,uint256) (runs: 1000, μ: 43636, ~: 44011)\n[PASS] testFuzz_transferToTheZeroAddressAlwaysReverts(uint256) (runs: 1000, μ: 46705, ~: 46656)\n[PASS] testFuzz_unknownSelectorsAlwaysRevert(bytes4,bytes,uint256) (runs: 1000, μ: 46846, ~: 47231)\n[PASS] test_aRevertedTransferLeavesNoTrace() (gas: 99341)\n[PASS] test_allowanceMayExceedBalanceAndTheBalanceCheckStopsTheSpend() (gas: 112928)\n[PASS] test_approveFromTheZeroAddressReverts() (gas: 33119)\n[PASS] test_approveZeroClearsTheAllowance() (gas: 130584)\n[PASS] test_constructorRefusesToMintToTheZeroAddress() (gas: 4153)\n[PASS] test_distributorPaysEveryClaimWholeDownToZero() (gas: 781376)\n[PASS] test_launchSplitArrivesWholeAndLeavesNoDust() (gas: 1131683)\n[PASS] test_metadataThroughTheStandardInterface() (gas: 30320)\n[PASS] test_ownerMayBeItsOwnSpender() (gas: 126039)\n[PASS] test_reducingAnInfiniteAllowanceMakesItFinite() (gas: 154089)\n[PASS] test_spenderMayBeTheRecipient() (gas: 128253)\n[PASS] test_spendingTheWholeAllowanceLeavesZeroAndTheNextWeiReverts() (gas: 162838)\n[PASS] test_supplyIsExactlyTenToTheTwentySeven() (gas: 20781)\n[PASS] test_transferFromEmitsExactlyOneTransferAndNoApproval() (gas: 127564)\n[PASS] test_transferFromOwnerToItselfKeepsBalanceAndSpendsAllowance() (gas: 103976)\n[PASS] test_transferFromTheZeroAddressRevertsEvenForZeroAmount() (gas: 33166)\n[PASS] test_transferFromTheZeroOwnerReverts() (gas: 79437)\n[PASS] test_transferFromToTheZeroAddressRevertsAndKeepsTheAllowance() (gas: 110488)\n[PASS] test_truncatedCalldataRevertsWithoutMovingAnything() (gas: 70265)\n[PASS] test_whenBothAllowanceAndBalanceAreShortTheAllowanceErrorFires() (gas: 88014)\n[PASS] test_zeroAddressHoldsNothingAndAllowsNothing() (gas: 35610)\n[PASS] test_zeroAmountTransferEmitsTransfer() (gas: 43864)\n[PASS] test_zeroAmountTransferFromNeedsNoAllowance() (gas: 74224)\nSuite result: ok. 33 passed; 0 failed; 0 skipped; finished in 83.19ms (760.01ms CPU time)\n\nRan 1 test for test/StarknetToken.raw.invariant.t.sol:StarknetTokenRawInvariantTest\n[PASS]\nStarknetTokenRawInvariantTest invariants:\n[PASS] invariant_knownHoldersNeverExceedSupply\n[PASS] invariant_metadataIsImmutableUnderRandomCalls\n[PASS] invariant_totalSupplyIsFixedUnderRandomCalls\n[PASS] invariant_zeroAddressNeverHoldsTokens\n StarknetTokenRawInvariantTest invariants (runs: 64, calls: 4096, reverts: 2460)\n\n╭---------------+--------------+-------+---------+----------╮\n| Contract      | Selector     | Calls | Reverts | Discards |\n+===========================================================+\n| StarknetToken | approve      | 1382  | 10      | 0        |\n|---------------+--------------+-------+---------+----------|\n| StarknetToken | transfer     | 1326  | 1077    | 0        |\n|---------------+--------------+-------+---------+----------|\n| StarknetToken | transferFrom | 1388  | 1373    | 0        |\n╰---------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 177.56ms (174.59ms CPU time)\n\nRan 1 test for test/StarknetToken.invariant.t.sol:StarknetTokenInvariantTest\n[PASS]\nStarknetTokenInvariantTest invariants:\n[PASS] invariant_balancesSumToSupply\n[PASS] invariant_noActorExceedsSupply\n[PASS] invariant_totalSupplyIsConstant\n StarknetTokenInvariantTest invariants (runs: 64, calls: 2048, reverts: 0)\n\n╭--------------+--------------+-------+---------+----------╮\n| Contract     | Selector     | Calls | Reverts | Discards |\n+==========================================================+\n| TokenHandler | approve      | 694   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| TokenHandler | transfer     | 683   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| TokenHandler | transferFrom | 671   | 0       | 0        |\n╰--------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 197.63ms (196.26ms CPU time)\n\nRan 1 test for test/StarknetToken.ghost.invariant.t.sol:StarknetTokenGhostInvariantTest\n[PASS]\nStarknetTokenGhostInvariantTest invariants:\n[PASS] invariant_actorBalancesSumToSupply\n[PASS] invariant_allowancesMatchGhost\n[PASS] invariant_balancesMatchGhostFlows\n[PASS] invariant_metadataIsImmutable\n[PASS] invariant_outsidersHoldNothing\n[PASS] invariant_tokenHoldsNoEther\n[PASS] invariant_totalSupplyNeverChanges\n StarknetTokenGhostInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭--------------+----------------------------+-------+---------+----------╮\n| Contract     | Selector                   | Calls | Reverts | Discards |\n+========================================================================+\n| GhostHandler | approve                    | 711   | 0       | 0        |\n|--------------+----------------------------+-------+---------+----------|\n| GhostHandler | approveMax                 | 750   | 0       | 0        |\n|--------------+----------------------------+-------+---------+----------|\n| GhostHandler | approveZeroSpender         | 763   | 0       | 0        |\n|--------------+----------------------------+-------+---------+----------|\n| GhostHandler | attemptMint                | 722   | 0       | 0        |\n|--------------+----------------------------+-------+---------+----------|\n| GhostHandler | donateEther                | 728   | 0       | 0        |\n|--------------+----------------------------+-------+---------+----------|\n| GhostHandler | transfer                   | 716   | 0       | 0        |\n|--------------+----------------------------+-------+---------+----------|\n| GhostHandler | transferAboveBalance       | 753   | 0       | 0        |\n|--------------+----------------------------+-------+---------+----------|\n| GhostHandler | transferFrom               | 814   | 0       | 0        |\n|--------------+----------------------------+-------+---------+----------|\n| GhostHandler | transferFromAboveAllowance | 736   | 0       | 0        |\n|--------------+----------------------------+-------+---------+----------|\n| GhostHandler | transferFromToZeroAddress  | 754   | 0       | 0        |\n|--------------+----------------------------+-------+---------+----------|\n| GhostHandler | transferToZeroAddress      | 745   | 0       | 0        |\n╰--------------+----------------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 4.08s (4.07s CPU time)\n\nRan 7 test suites in 4.08s (4.62s CPU time): 67 tests passed, 0 failed, 0 skipped (67 total tests)\n","passed":true},{"durationMs":77,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"StarknetToken.approve(address,uint256)\",\"StarknetToken.transfer(address,uint256)\",\"StarknetToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":120,\"foundry.toml\":23,\"remappings.txt\":2,\"script/DeployStarknetToken.s.sol\":25,\"src/StarknetToken.sol\":30,\"test/DeployStarknetToken.run.t.sol\":56,\"test/DeployStarknetToken.t.sol\":32,\"test/StarknetToken.edges.t.sol\":479,\"test/StarknetToken.ghost.invariant.t.sol\":347,\"test/StarknetToken.invariant.t.sol\":83,\"test/StarknetToken.raw.invariant.t.sol\":60,\"test/StarknetToken.t.sol\":321},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"410061bb2d89a5cef97d41341a0d1044299f2cef27fa7b2f2b9d774d231375a3","verifiedTreeHash":"0f2fe3267705cb21b2624f45659560970258dc7f","verifierVersion":"0.1.0+327e1e9f"},{"checks":[{"durationMs":1938,"exitCode":0,"name":"build","output":"Compiling 30 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.76s\nCompiler run successful!\n","passed":true},{"durationMs":346,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 2 tests for test/DeployStarknetToken.t.sol:DeployStarknetTokenTest\n[PASS] test_deployMintsSupplyToTheScriptCaller() (gas: 1484197)\n[PASS] test_deployTwiceGivesIndependentTokens() (gas: 2030767)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 715.88µs (640.54µs CPU time)\n\nRan 27 tests for test/StarknetToken.t.sol:StarknetTokenTest\n[PASS] testFuzz_transferAboveBalanceReverts(uint256) (runs: 256, μ: 38909, ~: 39208)\n[PASS] testFuzz_transferConservesSupply(address,uint256) (runs: 256, μ: 80504, ~: 81115)\n[PASS] testFuzz_transferFromAboveAllowanceReverts(uint256,uint256) (runs: 256, μ: 89292, ~: 89424)\n[PASS] testFuzz_transferFromWithinAllowance(uint256,uint256) (runs: 256, μ: 135112, ~: 136353)\n[PASS] test_approveAndTransferFrom() (gas: 159722)\n[PASS] test_approveOverwritesPreviousAllowance() (gas: 92792)\n[PASS] test_approveZeroSpenderReverts() (gas: 32883)\n[PASS] test_constructorEmitsSingleMintTransfer() (gas: 8193)\n[PASS] test_create2DeploymentMintsToTheCreatingContract() (gas: 801198)\n[PASS] test_creationCodeHasNoConstructorArguments() (gas: 793295)\n[PASS] test_infiniteAllowanceIsNotDecremented() (gas: 120465)\n[PASS] test_metadata() (gas: 34684)\n[PASS] test_noCallIncreasesSupplyOrMintsToCaller() (gas: 664005)\n[PASS] test_noPrivilegedCallMovesOrFreezesAHolder() (gas: 444166)\n[PASS] test_rejectsEtherAndUnknownCalls() (gas: 54856)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 868112)\n[PASS] test_supplyIsOneBillionWithEighteenDecimals() (gas: 26501)\n[PASS] test_transferFromRevertsBeyondAllowance() (gas: 92486)\n[PASS] test_transferFromRevertsWhenOwnerLacksBalance() (gas: 93535)\n[PASS] test_transferFromRevertsWithoutAllowance() (gas: 40484)\n[PASS] test_transferMovesBalance() (gas: 87047)\n[PASS] test_transferRevertsOnInsufficientBalance() (gas: 37951)\n[PASS] test_transferRevertsOnMoreThanWholeBalance() (gas: 38118)\n[PASS] test_transferToSelfKeepsBalance() (gas: 40600)\n[PASS] test_transferToZeroAddressReverts() (gas: 36874)\n[PASS] test_transferWholeBalanceAndZeroAmount() (gas: 114437)\n[PASS] test_wholeSupplyMintedToDeployer() (gas: 17556)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 12.62ms (48.96ms CPU time)\n\nRan 1 test for test/StarknetToken.invariant.t.sol:StarknetTokenInvariantTest\n[PASS]\nStarknetTokenInvariantTest invariants:\n[PASS] invariant_balancesSumToSupply\n[PASS] invariant_noActorExceedsSupply\n[PASS] invariant_totalSupplyIsConstant\n StarknetTokenInvariantTest invariants (runs: 64, calls: 2048, reverts: 0)\n\n╭--------------+--------------+-------+---------+----------╮\n| Contract     | Selector     | Calls | Reverts | Discards |\n+==========================================================+\n| TokenHandler | approve      | 683   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| TokenHandler | transfer     | 711   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| TokenHandler | transferFrom | 654   | 0       | 0        |\n╰--------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 202.62ms (200.40ms CPU time)\n\nRan 3 test suites in 206.23ms (215.95ms CPU time): 30 tests passed, 0 failed, 0 skipped (30 total tests)\n","passed":true},{"durationMs":82,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"StarknetToken.approve(address,uint256)\",\"StarknetToken.transfer(address,uint256)\",\"StarknetToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":120,\"foundry.toml\":23,\"launch.json\":24,\"remappings.txt\":2,\"script/DeployStarknetToken.s.sol\":25,\"src/StarknetToken.sol\":30,\"test/DeployStarknetToken.t.sol\":32,\"test/StarknetToken.invariant.t.sol\":83,\"test/StarknetToken.t.sol\":321},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"7a3223c845fe0d44ec7daeffe0a2033bfa1cbdb955f85824ebf1a1bcd0378a0c","verifiedTreeHash":"1443490d164b36c07aca9dadc8518d9d1f7a5ecf","verifierVersion":"0.1.0+327e1e9f"},{"checks":[{"durationMs":1241,"exitCode":0,"name":"build","output":"Compiling 30 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.13s\nCompiler run successful!\n","passed":true},{"durationMs":281,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 2 tests for test/DeployStarknetToken.t.sol:DeployStarknetTokenTest\n[PASS] test_deployMintsSupplyToTheScriptCaller() (gas: 1484197)\n[PASS] test_deployTwiceGivesIndependentTokens() (gas: 2030767)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 479.06µs (281.30µs CPU time)\n\nRan 27 tests for test/StarknetToken.t.sol:StarknetTokenTest\n[PASS] testFuzz_transferAboveBalanceReverts(uint256) (runs: 256, μ: 38880, ~: 39208)\n[PASS] testFuzz_transferConservesSupply(address,uint256) (runs: 256, μ: 80796, ~: 81115)\n[PASS] testFuzz_transferFromAboveAllowanceReverts(uint256,uint256) (runs: 256, μ: 88884, ~: 89411)\n[PASS] testFuzz_transferFromWithinAllowance(uint256,uint256) (runs: 256, μ: 134333, ~: 136353)\n[PASS] test_approveAndTransferFrom() (gas: 159722)\n[PASS] test_approveOverwritesPreviousAllowance() (gas: 92792)\n[PASS] test_approveZeroSpenderReverts() (gas: 32883)\n[PASS] test_constructorEmitsSingleMintTransfer() (gas: 8193)\n[PASS] test_create2DeploymentMintsToTheCreatingContract() (gas: 801198)\n[PASS] test_creationCodeHasNoConstructorArguments() (gas: 793295)\n[PASS] test_infiniteAllowanceIsNotDecremented() (gas: 120465)\n[PASS] test_metadata() (gas: 34684)\n[PASS] test_noCallIncreasesSupplyOrMintsToCaller() (gas: 664005)\n[PASS] test_noPrivilegedCallMovesOrFreezesAHolder() (gas: 444166)\n[PASS] test_rejectsEtherAndUnknownCalls() (gas: 54856)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 868112)\n[PASS] test_supplyIsOneBillionWithEighteenDecimals() (gas: 26501)\n[PASS] test_transferFromRevertsBeyondAllowance() (gas: 92486)\n[PASS] test_transferFromRevertsWhenOwnerLacksBalance() (gas: 93535)\n[PASS] test_transferFromRevertsWithoutAllowance() (gas: 40484)\n[PASS] test_transferMovesBalance() (gas: 87047)\n[PASS] test_transferRevertsOnInsufficientBalance() (gas: 37951)\n[PASS] test_transferRevertsOnMoreThanWholeBalance() (gas: 38118)\n[PASS] test_transferToSelfKeepsBalance() (gas: 40600)\n[PASS] test_transferToZeroAddressReverts() (gas: 36874)\n[PASS] test_transferWholeBalanceAndZeroAmount() (gas: 114437)\n[PASS] test_wholeSupplyMintedToDeployer() (gas: 17556)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 11.68ms (37.88ms CPU time)\n\nRan 1 test for test/StarknetToken.invariant.t.sol:StarknetTokenInvariantTest\n[PASS]\nStarknetTokenInvariantTest invariants:\n[PASS] invariant_balancesSumToSupply\n[PASS] invariant_noActorExceedsSupply\n[PASS] invariant_totalSupplyIsConstant\n StarknetTokenInvariantTest invariants (runs: 64, calls: 2048, reverts: 0)\n\n╭--------------+--------------+-------+---------+----------╮\n| Contract     | Selector     | Calls | Reverts | Discards |\n+==========================================================+\n| TokenHandler | approve      | 647   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| TokenHandler | transfer     | 691   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| TokenHandler | transferFrom | 710   | 0       | 0        |\n╰--------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 187.83ms (185.54ms CPU time)\n\nRan 3 test suites in 189.68ms (199.99ms CPU time): 30 tests passed, 0 failed, 0 skipped (30 total tests)\n","passed":true},{"durationMs":54,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"StarknetToken.approve(address,uint256)\",\"StarknetToken.transfer(address,uint256)\",\"StarknetToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":120,\"foundry.toml\":23,\"remappings.txt\":2,\"script/DeployStarknetToken.s.sol\":25,\"src/StarknetToken.sol\":30,\"test/DeployStarknetToken.t.sol\":32,\"test/StarknetToken.invariant.t.sol\":83,\"test/StarknetToken.t.sol\":321},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":456,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":211,"exitCode":0,"name":"aderyn","output":"[low] large-numeric-literal at src/StarknetToken.sol:22: Large Numeric Literal","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"a3fa1f732fc8c53aa02324ff507af97146b3531b75894cac69232f8b53446165","verifiedTreeHash":"654ba194133fc86b085f13af7782ed0f4c5b2065","verifierVersion":"0.1.0+327e1e9f"}]}