{"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":"3ec54033-a3ee-4cad-b1bf-88c18633d2e3","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"1e20e67b90747874b9fa1c6035d5258e15b1fd28f696d4ef3525b5a790f7fb5e","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":"60479a57d31bf3cf9656a38874f921dd3d0b59cd60c029e1db79e19feb43cf17","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":"74ede07cbcb17a7fc0d63c03564eda375875b3c299007c244e173b5c9adecfa4","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":"7ef302c021e7e0ee00f6ee024ee17db88b8316e12a929ab7068117801c271dec","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":"71de1c7b579b707c37fe40f455bdaed5cfd64b4092c94e6c63b2dd0878cff9a0","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":"d5d59a1dc23bf74d6ffc704b7cd57135c6ba8a62be48177d56fa1de34c754e7c","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":"544cce18d232911ffa58752cc4a0ff89bc508a24fe376f6204e7f15f1d4f8cee","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"65201c7a77d7e2900ae4094a87507484c07b0ca0e014a758ed931d1a3fb1cadb","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: IMDBlackout (IMDBLACKOUT).\nToken name: IMDBlackout\nToken symbol: IMDBLACKOUT\nToken supply: 1,000,000,000 with 18 decimals, all minted once to the deployer in the constructor.\n\nTransfer rules: 0x6616Cb624cec0B46C9718D423098150587D1272b","parentJobId":null,"planHash":"1854bacd8fe7e97ffb2032628e7a59d4eb51071d7c9198490d8f6df583949b8f","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"3ec54033-a3ee-4cad-b1bf-88c18633d2e3","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1338-imdblackout"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"52158","feedbackHash":"0fadfe5178f25d5286cd7397d495a5c8439bcf38eff375bdcf23023aa231f8b6","nodeKey":"audit_economics","submissionHash":"1e20e67b90747874b9fa1c6035d5258e15b1fd28f696d4ef3525b5a790f7fb5e","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51382","feedbackHash":"b615788afb12e1b59419eb626e42402ed960a8867ea9670a7682191d23b1f666","nodeKey":"audit_flow","submissionHash":"60479a57d31bf3cf9656a38874f921dd3d0b59cd60c029e1db79e19feb43cf17","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51027","feedbackHash":"e920330e93db2a1dd073078717f4f73de61e8400f5368572be83b80f7f07a0e0","nodeKey":"audit_judge","submissionHash":"74ede07cbcb17a7fc0d63c03564eda375875b3c299007c244e173b5c9adecfa4","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52253","feedbackHash":"6a6ec886f0c686a793fc6cf09bc5860c405dfce0d7ed885cbe48fea59a34b9a5","nodeKey":"audit_math","submissionHash":"7ef302c021e7e0ee00f6ee024ee17db88b8316e12a929ab7068117801c271dec","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52163","feedbackHash":"c3954351a58290b2459bfb246bce255fe2e4d9beaedf2209da42e690fc147c61","nodeKey":"audit_permissions","submissionHash":"71de1c7b579b707c37fe40f455bdaed5cfd64b4092c94e6c63b2dd0878cff9a0","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52611","feedbackHash":"f5e560e06b39d662be621e191d91f4f43a88174958a5299943c6e72e1087de4c","nodeKey":"build_contract_project","submissionHash":"d5d59a1dc23bf74d6ffc704b7cd57135c6ba8a62be48177d56fa1de34c754e7c","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52614","feedbackHash":"50b57625b54c5c3f2e0d0ff7d27805a23df7bc23119cb852f27c3a8e47011d67","nodeKey":"manifest","submissionHash":"544cce18d232911ffa58752cc4a0ff89bc508a24fe376f6204e7f15f1d4f8cee","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52609","feedbackHash":"98f59f87e9ed65f6600b0575ea87ab2b72fa42758776d6a2183a9433be42198e","nodeKey":"write_foundry_tests","submissionHash":"65201c7a77d7e2900ae4094a87507484c07b0ca0e014a758ed931d1a3fb1cadb","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"a4a3a8dc61a7c9855b4539207de69fe76e6b91526719778b7b02ca7628cf64ba","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"4dd67dae195771b6","findings":[{"citation":"resolved","description":"The job's 'Transfer rules' field contains only the requester wallet 0x6616Cb624cec0B46C9718D423098150587D1272b and no rule text. The implementation records that address as an informational constant and applies plain OpenZeppelin ERC-20 semantics to every transfer: no tax, cap, cooldown, exemption or special handling to or from that address. The README states this assumption explicitly. This is not a code defect in my area (economic security, invariants, flow gaps all hold under the 'no rule' reading), and the launch flows (factory -> distributor -> claimant, seed, buy/sell through the PoolManager) move exactly what they say. It is recorded so the judge and requester can confirm the reading before launch, because the token has no setters and cannot be changed after deployment: if a rule involving that address was intended (for example, a tax paid to it, or a per-wallet cap it is exempt from), the token must be re-issued.","line":45,"path":"src/IMDBlackoutToken.sol","reproduction":"State: token deployed by any deployer; deployer transfers 100e18 to REQUESTER (0x6616Cb624cec0B46C9718D423098150587D1272b). Call: vm.prank(REQUESTER); token.transfer(alice, 60e18). Actual: alice receives exactly 60e18, REQUESTER keeps 40e18, totalSupply unchanged, no fee, no revert, no distinct branch executed (ERC20._update is the only path). Expected under the 'no rule' reading: identical. Expected if a rule was intended: some observable difference, of which there is none. Covered by test/IMDBlackoutToken.t.sol test_requesterIsAnOrdinaryHolder.","severity":"info","snippet":"    address public constant REQUESTER = 0x6616Cb624cec0B46C9718D423098150587D1272b;","title":"Brief's 'Transfer rules' field (an address) is implemented as 'no rule'; the requester address has no effect on any transfer"},{"citation":"resolved","description":"Invariant-lens note (view/write divergence). The ABI exposes two supply getters: the constant TOTAL_SUPPLY() (the amount minted once) and the live ERC-20 totalSupply(). Because burn(uint256) permanently reduces the live supply, the two diverge after any burn. No funds are at risk and no launch flow reads TOTAL_SUPPLY, but an integrator or analytics tool that treats TOTAL_SUPPLY() as the circulating supply will over-report it by the cumulative burned amount. The NatSpec does say 'minted once in the constructor'; renaming the constant to INITIAL_SUPPLY or documenting it as a cap-at-mint would remove the ambiguity. Design is otherwise intended: the floor allows supply to shrink.","line":42,"path":"src/IMDBlackoutToken.sol","reproduction":"State: fresh deployment, deployer holds 1e27. Call: token.burn(1). Actual: token.TOTAL_SUPPLY() == 1000000000000000000000000000 while token.totalSupply() == 999999999999999999999999999. Expected: the two values to agree, or the constant's name to make clear it is the initial, not current, supply. Verified in a scratch test (test_constantTotalSupplyDivergesFromLiveSupplyAfterBurn).","severity":"info","snippet":"    uint256 public constant TOTAL_SUPPLY = SUPPLY_WHOLE_TOKENS * 10 ** 18;","title":"Public constant TOTAL_SUPPLY stops matching totalSupply() after the first burn"}],"hash":"1e20e67b90747874b9fa1c6035d5258e15b1fd28f696d4ef3525b5a790f7fb5e","nodeId":"fb3013d3-8afd-4241-859f-1353d095d250","outcome":"completed","summary":"The review is complete and the findings file is written. Working tree is clean apart from `.imd-findings.json` and my gitignored scratch test.\n\n**Outcome: no defects of severity found in the economics area.** The token is an unmodified OpenZeppelin v5.1.0 ERC-20 with a self-only burn, no constructor arguments, no owner, and no transfer rules.\n\nWhat I checked, against the Economic Security, Invariant and Flow Gap guides:\n\n- **Dependency integrity.** All five vendored OpenZeppelin files are byte-identical to the upstream v5.1.0 tag. This was the one place a plain token could hide a defect, and it is clean.\n- **Conservation invariants.** A scratch Foundry invariant run of 128,000 handler calls over all four entry points held sum of balances equals total supply equals minted minus burned, with zero reverts.\n- **Launch flows.** No path deducts anything, so the swarm share, claims, seed and PoolManager swap legs move exactly what they say. The constructor takes no arguments and mints exactly the manifest supply to msg.sender.\n- **Privileged powers.** None exist. The requester address is a constant with no effect on any branch.\n- **Entry points.** All four listed entry points received a `holds` row with reasons, plus four invariant rows.\n\nTwo informational notes are recorded, each with a concrete reproduction, so the judge can decide whether they matter:\n\n1. The brief's \"Transfer rules\" field was only the requester's address, and the implementation treats that as \"no rule\". The README documents this reading. If a rule involving that address was intended, the token must be re-issued since it is immutable.\n2. The public constant named `TOTAL_SUPPLY` diverges from the live `totalSupply()` after any burn. Harmless to funds, but an integrator reading the constant as circulating supply would over-report it.\n\nNo critical or high findings, so no proof test files were attached. No `launch.json` exists in the tree yet, so there was no manifest to review.","treeHash":null,"usage":{"cachedInputTokens":485130,"inputTokens":226,"model":"claude-fable-5-1","outputTokens":12102,"runtime":"claude","turns":20,"wallClockMs":223117}},{"artifacts":[],"attempt":1,"bundleHash":"6e1127d706b372196b3ae3110e715960d6e13bbefc0179a82d300009140d8c0e","device":"9506ecec995bdbf9","findings":[],"hash":"544cce18d232911ffa58752cc4a0ff89bc508a24fe376f6204e7f15f1d4f8cee","nodeId":"6cf83a88-2aaf-4441-83c9-c7dcc9e561f5","outcome":"completed","summary":"Done. I wrote launch.json as the only new file, and the build and all 29 tests pass.\n\n**What the manifest says**\n\n- Kind is custom_token. The token contract is IMDBlackoutToken, with name IMDBlackout, symbol IMDBLACKOUT and 18 decimals.\n- Constructor arguments are the empty list, matching the accepted constructor, which takes nothing and mints the whole supply to msg.sender.\n- totalSupply is the constructor's mint in minor units, 1,000,000,000 tokens times 10^18.\n- contracts is empty, since the accepted tree has no application contracts and no initialization calls.\n- pool and economics are copied exactly as the launch reference gives them: IMD pair address, fee 12500, tick spacing 60, the one-to-one provenance price, and the requester's economics object verbatim.\n- notes describe the fixed supply, self-only burn, plain ERC-20 transfers with no privileged powers, and the brief's transfer rules field naming only the requester's wallet.\n\n**Checks run**\n\n- forge build compiled cleanly and forge test passed every test in the existing suite.\n- A local script confirmed the manifest has only the schema's top-level keys, the economics object is byte-identical to the job's, totalSupply equals 10^27, and the contract name fits 32 characters.\n- git status shows launch.json as the only change.","treeHash":"04dcbc399a05a80d33c3ebb4bb9d7cd62d1980a9","usage":{"cachedInputTokens":165900,"inputTokens":130,"model":"claude-fable-5-1","outputTokens":2618,"runtime":"claude","turns":8,"wallClockMs":35687}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"85f29f4c09dba910","findings":[{"citation":"resolved","description":"The job's \"Transfer rules\" field contains only the requester wallet 0x6616Cb624cec0B46C9718D423098150587D1272b and no rule. The implementation reads this as \"no transfer restrictions\": REQUESTER is a constant exposed for reference and is never consulted by transfer, transferFrom, approve or burn, so the requester is an ordinary holder with no exemption, cap, tax or privilege. This is not a code defect (the README states the assumption, and the token is correct under it), but the token has no owner, setter or upgrade path, so if the requester intended a rule involving that address (for example a per-wallet cap with the requester exempt, or a tax that excludes it) the only remedy is to re-issue the token before launch. Reported at info so the judge can confirm the reading with the requester; no change is needed if \"no rule\" is the intent.","line":45,"path":"src/IMDBlackoutToken.sol","reproduction":"State: factory holds the supply after construction. Call factory.transfer(REQUESTER, 100e18); then vm.prank(REQUESTER); token.transfer(alice, 60e18). Observed: alice receives exactly 60e18, REQUESTER keeps 40e18, and a further transfer of 41e18 from REQUESTER reverts with ERC20InsufficientBalance(REQUESTER, 40e18, 41e18), identical to any other holder (test_requesterIsAnOrdinaryHolder in test/IMDBlackoutToken.t.sol). No code path reads REQUESTER. Expected under the \"no rule\" reading: exactly this. If the requester expected a rule keyed to that address, there is none and none can be added.","severity":"info","snippet":"    address public constant REQUESTER = 0x6616Cb624cec0B46C9718D423098150587D1272b;","title":"Brief's \"Transfer rules\" field is an address only; the token applies no rule to it and nothing can be added after deployment"}],"hash":"60479a57d31bf3cf9656a38874f921dd3d0b59cd60c029e1db79e19feb43cf17","nodeId":"be9642d4-06ea-4c3d-88b7-bed6ef8f6b61","outcome":"completed","summary":"Review complete. The findings record is written to `.imd-findings.json` and the working tree is otherwise untouched.\n\n**Outcome: no defects found.** The token is a plain OpenZeppelin v5.1.0 ERC-20 with a self-only `burn`, and every path I traced in my area behaves as intended.\n\nWhat I covered, against the Execution Trace, Periphery and First Principles guides:\n\n- **Execution trace.** Traced approve, transfer, transferFrom and burn from entry to final storage through the vendored ERC20. Zero sender or receiver reverts, balance and allowance checks precede every write, infinite allowance is not decremented, self-transfer and whole-supply moves are exact. No stale reads, partial updates or sentinel paths exist.\n- **Periphery.** All five vendored OpenZeppelin files are sha256-identical to upstream v5.1.0. The deploy script only runs the constructor and holds no configuration. The runtime has no DELEGATECALL, CALLCODE or SELFDESTRUCT and fits EIP-170.\n- **First principles.** The constructor mints exactly one billion tokens with 18 decimals to the deployer once, takes no arguments and makes no external calls. The ABI exposes thirteen methods, none privileged, so no mint, pause, freeze or seize path exists. Sum of balances equals total supply before and after burns.\n- **Launch floor.** No fee or exemption list, so the swarm share, pool seed, remainder and swaps all move exactly what they say.\n\nI ran the project's 29 tests plus a scratch probe of boundary cases, all passing, and removed the scratch file afterwards.\n\nThe one entry in the record is informational, not a defect: the brief's \"Transfer rules\" field holds only the requester wallet, and the token applies no rule to it. The requester is an ordinary holder, which the README documents as the intended reading. Since the contract has no setters or upgrade path, a rule intended for that address would need the token re-issued before launch. The coverage record marks all four listed entry points as holding, with four extra rows for the constructor and supply invariant, the vendored library, the deploy script and the bytecode checks.","treeHash":null,"usage":{"cachedInputTokens":408888,"inputTokens":194,"model":"claude-fable-5-1","outputTokens":9551,"runtime":"claude","turns":18,"wallClockMs":175116}},{"artifacts":[],"attempt":1,"bundleHash":"ff8209af88488e041a0bb082db9d58de5a78bf4ffd837f0aa885e100143ee206","device":"8e25456c4ae69acf","findings":[{"description":"The brief's \"Transfer rules\" field contains only the wallet 0x6616Cb624cec0B46C9718D423098150587D1272b and no rule. The accepted implementation reads this as \"no restriction\" and ships plain ERC-20 transfers: no cap, tax, cooldown, whitelist or any role for that address, which is recorded as the informational REQUESTER constant. The tests confirm that reading (the address is an ordinary holder, every transfer delivers exactly what was sent, nothing can be minted, paused, frozen or seized, and the launch flows arrive whole). This is not a code defect and no test fails. It is flagged because if the requester intended a rule for that wallet, nothing can be changed after deployment and the token would need re-issuing before launch. No proof is attached because there is no failing input: the implementation is self-consistent with its documented assumption.","line":45,"path":"src/IMDBlackoutToken.sol","reproduction":"Expected: whatever transfer rule the requester meant by naming that wallet. Actual: transfers from, to and by 0x6616Cb624cec0B46C9718D423098150587D1272b behave exactly like any other holder's (see test_requesterIsAnOrdinaryHolder in test/IMDBlackoutToken.t.sol, and the REQUESTER actor in the invariant handler), and the address has no special power. If that is the intent, nothing needs to change.","severity":"info","title":"The brief's \"Transfer rules\" field names only an address; the token implements no transfer rule"}],"hash":"65201c7a77d7e2900ae4094a87507484c07b0ca0e014a758ed931d1a3fb1cadb","nodeId":"2f4b4173-3975-416a-acfe-be2f7f94be96","outcome":"completed","summary":"The findings file is in place and valid JSON. It is excluded from git by the harness's own `.git/info/exclude`, which is expected since the harness collects it from the repository root rather than from the commit.\n\n## Recap\n\n**Outcome:** two new test files under `test/`, all 62 tests across 4 suites pass, `forge build` is warning-free, and `forge fmt --check` is clean. No defect was found in the token. One info-level note was recorded in `.imd-findings.json`.\n\n**What was already there.** The accepted implementation is a plain fixed-supply OpenZeppelin ERC-20 with a self-only `burn`, and the existing `test/IMDBlackoutToken.t.sol` already covered metadata, revert paths, privileged selectors, bytecode opcodes and the launch flows. It had no invariant tests, which the acceptance criteria require.\n\n**What I added.**\n\n- `test/IMDBlackoutToken.invariant.t.sol`. A handler with seven actors, including the deployer as factory and the requester wallet, drives random sequences of transfer, approve, transferFrom and burn with bounded inputs, plus seven failure-path functions that attempt over-balance transfers, over-allowance and unapproved transferFrom, transfers to zero, over-burns, unknown selectors and ether, asserting each is refused and moves nothing. Ten invariants check conservation against ghost accounting: supply equals minted minus burned, sum of balances equals supply, every balance and allowance matches its ghost, nothing leaks to bystanders or the zero address, metadata is fixed, and only the known paths move tokens. It runs with `fail-on-revert` on, 256 runs at depth 64. A second contract fuzzes the token's raw ABI directly from random senders with reverts allowed, checking the supply never grows.\n- `test/IMDBlackoutToken.properties.t.sol`. Thirty-one stateless tests at 1000 fuzz runs: exact-balance and balance-plus-one transfers, self-transfers, additivity, a conservation chain through four holders, approve overwrite semantics, a transferFrom oracle over all three outcomes, allowance consumption to the last wei, self-spending still needing an allowance, burn edges from zero to the whole supply, burn by an approved spender touching only its own tokens, random unknown selectors, truncated calldata, ether refusal, and view purity. Zero, one wei, full supply, max uint and the zero-address deployer are pinned as unit tests.\n\n**Verification of the suite itself.** I ran the invariant file against a deliberately broken mutant token in `test/scratch` that skimmed one wei per transfer and exposed a mint. The handler postconditions caught the skim and the open-surface invariant caught the mint, so the properties are not vacuous. The scratch directory has been removed.\n\n**The info finding.** The brief's \"Transfer rules\" field contained only the requester's wallet address and no rule. The implementation treats it as \"no restriction\" and documents that. The tests confirm the address is an ordinary holder with no power. If the requester intended an actual rule for that wallet, the token would need re-issuing before launch, since nothing is changeable after deployment. No proof is attached because no input fails.","treeHash":"fc86c61059f7978265863660eb234369733ef60a","usage":{"cachedInputTokens":1214548,"inputTokens":546,"model":"claude-fable-5-1","outputTokens":31746,"runtime":"claude","turns":30,"wallClockMs":599827}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"52c98c0dc01791cd","findings":[],"hash":"71de1c7b579b707c37fe40f455bdaed5cfd64b4092c94e6c63b2dd0878cff9a0","nodeId":"a2555049-9f23-419b-a685-3eee6d1df785","outcome":"completed","summary":"The review is complete. The findings file is written, the scratch test is removed, and the working tree is clean apart from the ignored findings file.\n\n**Result: no defects found in the Access Control, Trust Gap or Asymmetry area.** `.imd-findings.json` holds an empty findings list and ten coverage rows, one for each of the four entry points plus six invariants I checked.\n\nWhat I verified, in `src/IMDBlackoutToken.sol`:\n\n- **Permission model is empty by design.** The compiled ABI has exactly four state-changing functions, all stock OpenZeppelin v5.1.0 ERC20 scoped to `msg.sender` or to an explicit allowance. There is no owner, role, initializer, setter, pause, mint, upgrade, `receive` or `fallback`. The requester address is a constant that no code path reads.\n- **No pull path onto a holder.** The deployer and the requester both revert with `ERC20InsufficientAllowance` when pulling 1 wei from a holder without approval. A third party approving itself gains nothing on another holder's balance. Allowance gives no burn power because `burn` only touches the caller.\n- **Mint/burn asymmetry is the intended one.** Mint happens once in the constructor to the factory. Only self-burn exists, so supply can shrink but never grow. Conservation of `sum(balances) == totalSupply` held under fuzzing with transfers and burns mixed.\n- **No external surface.** The 2060-byte runtime contains zero CALL, STATICCALL, DELEGATECALL, CALLCODE, CREATE, CREATE2, SELFDESTRUCT or ORIGIN opcodes.\n- **Vendored dependencies are genuine.** Every OpenZeppelin file is byte-identical to upstream v5.1.0, and `lib/forge-std/src` is byte-identical to v1.9.7, so neither the token nor the verifier's floor tests are built on altered library code. All library files are plain mode-644 files, no submodule.\n- **Launch floor compatibility.** The constructor takes no arguments, mints the manifest supply to the factory, and every launch leg moves exact amounts, matching what the protected test demands.\n\nTwo items worth the requester's attention, neither reproducible as a defect:\n\n- The brief's \"Transfer rules\" field contained only the requester's address. The build treated it as \"no restrictions\" and documented that assumption in the README. If a tax, cap or cooldown was intended, it must be stated before launch since nothing is changeable afterwards.\n- `burn(uint256)` was not requested in the brief. It is self-only and harmless to other holders, but it is an added feature.\n\nTools run: `forge build`, `forge test` (29 existing tests plus 7 scratch traces, all passing), `forge fmt --check`, an opcode scan of the deployed bytecode, and byte-level diffs against upstream OpenZeppelin and forge-std. Slither and aderyn output had no lead above the line-39 numeric literal, which I confirmed evaluates to exactly 1e27.","treeHash":null,"usage":{"cachedInputTokens":738034,"inputTokens":290,"model":"claude-fable-5-1","outputTokens":15122,"runtime":"claude","turns":31,"wallClockMs":249895}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"61b4050710026370","findings":[{"citation":"resolved","description":"Merged from write_foundry_tests, audit_economics and audit_flow (same root cause, three reports). The job's \"Transfer rules\" field contains the wallet 0x6616Cb624cec0B46C9718D423098150587D1272b and no rule text. The accepted implementation reads that as \"no transfer restrictions\": REQUESTER is a public constant that no code path reads, and transfer, transferFrom, approve and burn are plain OpenZeppelin v5.1.0 ERC-20 (vendored files verified byte-identical to upstream v5.1.0). The README and launch.json notes state this assumption. Reproduced: the address behaves exactly like any other holder. This is not a code defect and does not block admission; under the stated reading the code is correct and the launch flows (factory to distributor, claim, seed, buy, sell) move exactly what they say. It is kept at info so the requester confirms the reading before launch, because the token has no owner, setter or upgrade path: if a rule keyed to that wallet (tax, cap, cooldown, exemption) was intended, the only remedy is re-issuing the token before launch.","line":45,"path":"src/IMDBlackoutToken.sol","reproduction":"State: token deployed via CREATE2 from a factory stub, which holds 1e27. Calls: factory transfers 100e18 to REQUESTER; vm.prank(REQUESTER); token.transfer(alice, 60e18). Actual: alice holds exactly 60e18, REQUESTER holds 40e18, totalSupply unchanged, no fee. A further vm.prank(REQUESTER); token.transfer(alice, 41e18) reverts with ERC20InsufficientBalance(REQUESTER, 40e18, 41e18), identical to any other holder. Searching src/ shows REQUESTER appears only in its declaration at line 45 and is never read. Expected under the 'no rule' reading: exactly this. Expected if a rule was intended: some observable difference, of which there is none. Verified in a scratch test (test_requesterOrdinary) and by the existing test/IMDBlackoutToken.t.sol test_requesterIsAnOrdinaryHolder.","severity":"info","snippet":"    address public constant REQUESTER = 0x6616Cb624cec0B46C9718D423098150587D1272b;","title":"Brief's \"Transfer rules\" field names only an address; the token implements no rule and none can be added after deployment"},{"citation":"resolved","description":"From audit_economics; reproduced. The ABI exposes two supply getters: TOTAL_SUPPLY() (the amount minted once, a constant) and the live ERC-20 totalSupply(). Since burn(uint256) permanently reduces the live supply, the two diverge after any burn. No funds are at risk, no launch flow or test reads TOTAL_SUPPLY, and the NatSpec at line 41 says 'minted once in the constructor', so this is a naming ambiguity for integrators and analytics that might read TOTAL_SUPPLY() as the circulating supply. Renaming to INITIAL_SUPPLY or documenting it as the initial mint would remove the ambiguity. Not blocking.","line":42,"path":"src/IMDBlackoutToken.sol","reproduction":"State: fresh deployment, deployer holds 1e27. Call: vm.prank(deployer); token.burn(1). Actual: token.TOTAL_SUPPLY() == 1000000000000000000000000000 while token.totalSupply() == 999999999999999999999999999. Expected: the two agree, or the constant's name makes clear it is the initial, not current, supply. Verified in a scratch test (test_constantDiverges).","severity":"info","snippet":"    uint256 public constant TOTAL_SUPPLY = SUPPLY_WHOLE_TOKENS * 10 ** 18;","title":"Public constant TOTAL_SUPPLY stops matching totalSupply() after the first burn"}],"hash":"74ede07cbcb17a7fc0d63c03564eda375875b3c299007c244e173b5c9adecfa4","nodeId":"4607ab77-340d-4721-9891-cfac7f64ae8c","outcome":"completed","summary":"The review is complete and the findings file is written. No blocking defects.\n\n**Outcome.** The IMDBlackout token is a plain fixed-supply OpenZeppelin v5.1.0 ERC-20 with a self-only burn. I found no defect that opens a revision. The findings file holds two informational notes, both reproduced, and a coverage record for all four entry points plus four invariants.\n\n**What I checked**\n- Built with solc 0.8.26 and ran the existing suite: 62 tests passed, including the 256-run invariant campaign.\n- Diffed every vendored OpenZeppelin file against upstream v5.1.0: all byte-identical, no submodules.\n- Wrote and ran a scratch test confirming the mint goes to the CREATE2 deployer, runtime is 2,060 bytes with no DELEGATECALL, CALLCODE or SELFDESTRUCT, burn only touches the caller, and no burnFrom selector exists.\n- Checked launch.json against the schema rules: schema keys only, lowercase addresses, empty constructorArgs matching the no-argument constructor, supply equal to the mint, notes under the limit.\n\n**Specialist findings settled**\n- Three specialists reported the same item, that the brief's \"Transfer rules\" field names only an address and the token applies no rule to it. Merged into one info finding with a reproduction showing the requester wallet behaves like any holder. Kept at info because the token has no setters, so if a rule was intended the token must be re-issued before launch.\n- The TOTAL_SUPPLY constant diverging from totalSupply after a burn reproduces exactly as described. Kept at info as a naming ambiguity.\n- The aderyn large-numeric-literal lead is the underscored `1_000_000_000` constant and is not a defect, so it was dropped.\n\nThe scratch test directory was removed, so the only change in the tree is `.imd-findings.json`.","treeHash":null,"usage":{"cachedInputTokens":388518,"inputTokens":226,"model":"claude-fable-5-1","outputTokens":9052,"runtime":"claude","turns":17,"wallClockMs":173430}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"7591760a616c6429","findings":[],"hash":"7ef302c021e7e0ee00f6ee024ee17db88b8316e12a929ab7068117801c271dec","nodeId":"92eea116-8b4c-458d-a568-55c0fd54a27f","outcome":"completed","summary":"The review is complete. No defects were found in the Math Precision, Boundary or Numerical Gap areas, and `.imd-findings.json` holds an empty findings list with nine coverage rows.\n\n**What was reviewed**\n\n- `src/IMDBlackoutToken.sol` is a plain OpenZeppelin v5.1.0 ERC20 with a self-only `burn`. It has no fee, tax, scaling, division, cast, external call, payable path or sentinel branch, so most failure modes in the three guides have nothing to attach to.\n- The vendored OpenZeppelin files are byte-identical to the upstream v5.1.0 tags by SHA-256, so the `unchecked` subtractions in `_update` and `_spendAllowance` are the audited originals, each guarded by a prior balance or allowance check.\n- The supply constant folds to exactly 1e27, well under the uint128 and int128 limits a Uniswap v4 pool uses, and divisible by 10 to the decimals. This closes the aderyn large-literal lead as not a defect.\n\n**How it was checked**\n\n- The project's own 29 tests pass.\n- A scratch suite of 23 boundary tests under `test/scratch/` passed, covering 1 wei, whole-supply, supply plus one, max uint, self-transfer, burn to zero supply, exact allowance consumption, the max and max-minus-one allowance sentinels, zero-value `transferFrom` without allowance, and the zero-address paths on every entry point.\n- A Foundry stateful invariant run over random transfer, transferFrom and burn sequences across six actors held both that the sum of balances equals the total supply and that the supply only ever shrinks by what was burned.\n\n**Coverage**\n\nAll four listed entry points are marked `holds`, with five extra rows for the invariants checked. Nothing in the assigned area was left unreached. Tools that ran: forge build, forge test with fuzzing and invariant mode. Slither was not run here beyond the verifier's supplied output.","treeHash":null,"usage":{"cachedInputTokens":740557,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":13021,"runtime":"claude","turns":21,"wallClockMs":191423}},{"artifacts":[],"attempt":1,"bundleHash":"ac736110c248a79a0a212ae61bd03a1544f03c8f25874ce4f70ecd376b77c8b3","device":"2a4ad9be53991100","findings":[],"hash":"d5d59a1dc23bf74d6ffc704b7cd57135c6ba8a62be48177d56fa1de34c754e7c","nodeId":"801aa4a7-b9d9-434c-97ec-8906d6ab0fa3","outcome":"completed","summary":"The deliverable is complete and committed as a Foundry project at the repository root.\n\n**What was built**\n\n- `src/IMDBlackoutToken.sol` is a fixed-supply ERC-20 on OpenZeppelin v5.1.0. It returns the name IMDBlackout and symbol IMDBLACKOUT with 18 decimals. The constructor takes no arguments, calls no contract, and mints the entire supply of one billion tokens once to the deployer. Holders can burn their own tokens, and nothing else exists: no mint, owner, pause, blacklist, freeze, seize, proxy or upgrade path.\n- `script/Deploy.s.sol` exposes a `deploy()` function with no configuration and a broadcast wrapper, as the reference asks.\n- `test/IMDBlackoutToken.t.sol` holds 29 tests that deploy through a CREATE2 factory stub the way the launch does. They cover metadata, the one-time mint, transfer and approval success and revert paths, burning, every admin selector the protected floor probes from a stranger, the factory and the requester, the bytecode opcode scan, EIP-170 size, the script function, and a simulation of the launch flows checking each leg arrives whole.\n- `README.md` documents behaviour, assumptions, deployment parameters, after-launch steps, and operational responsibilities.\n- forge-std v1.9.7 and the ERC20 subset of OpenZeppelin v5.1.0 are vendored under `lib/` as plain files with no submodules. `foundry.toml` pins solc 0.8.26 and sets `bytecode_hash = \"none\"`.\n\n**Checks run**\n\n```\nforge build --offline   Compiler run successful\nforge test --offline    29 passed, 0 failed\nforge fmt --check       clean\n```\n\n**One assumption to flag.** The brief's \"Transfer rules\" field contained only the requester's wallet address and no rule. I implemented unrestricted ERC-20 transfers and recorded that address as an informational `REQUESTER` constant with no power. This satisfies the protected floor, which refuses any privileged power over balances. If the requester intended a specific rule such as a tax, cap or cooldown, that must be stated and the token re-issued before launch, since nothing is changeable afterwards. The README states this explicitly.","treeHash":"1c5010025f78a893792fa2c96676253f9a55adcc","usage":{"cachedInputTokens":682207,"inputTokens":482,"model":"claude-fable-5-1","outputTokens":17880,"runtime":"claude","turns":16,"wallClockMs":263935}}],"verification":[{"checks":[{"durationMs":937,"exitCode":0,"name":"build","output":"Compiling 28 files with Solc 0.8.26\nSolc 0.8.26 finished in 818.45ms\nCompiler run successful!\n","passed":true},{"durationMs":82,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 29 tests for test/IMDBlackoutToken.t.sol:IMDBlackoutTokenTest\n[PASS] testFuzz_transferConservesSupplyAndDeliversExactly(uint256,uint256) (runs: 256, μ: 189374, ~: 191283)\nLogs:\n  Bound result 1234000000000000000000\n  Bound result 255\n\n[PASS] test_approveAndTransferFrom() (gas: 229884)\n[PASS] test_approveZeroAddressSpenderReverts() (gas: 32919)\n[PASS] test_burnOnlyTouchesTheCaller() (gas: 176182)\n[PASS] test_burnReducesHolderAndSupply() (gas: 124523)\n[PASS] test_burnRevertsOnInsufficientBalance() (gas: 93435)\n[PASS] test_constantsMatchTheBrief() (gas: 33219)\n[PASS] test_constructorEmitsTransferFromZeroAndSupplyMinted() (gas: 7436)\n[PASS] test_creationCodeTakesNoConstructorArguments() (gas: 627008)\n[PASS] test_deployScriptFunctionMintsToItsCaller() (gas: 1435126)\n[PASS] test_infiniteAllowanceIsNotDecremented() (gas: 181601)\n[PASS] test_launchFlowsMoveExactlyWhatTheySay() (gas: 425564)\n[PASS] test_metadata() (gas: 31923)\n[PASS] test_mintsWholeSupplyOnceToDeployer() (gas: 44375)\n[PASS] test_noBurnFromExists() (gas: 157354)\n[PASS] test_noMintOrAdminCallGrowsSupply() (gas: 1616989)\n[PASS] test_noPrivilegedCallMovesOrFreezesAHolder() (gas: 759714)\n[PASS] test_requesterIsAnOrdinaryHolder() (gas: 171883)\n[PASS] test_runtimeFitsEip170() (gas: 7880)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 2566610)\n[PASS] test_transferFromRevertsOnInsufficientAllowance() (gas: 146250)\n[PASS] test_transferFromRevertsOnInsufficientBalanceEvenWithAllowance() (gas: 148971)\n[PASS] test_transferFromWithoutApprovalReverts() (gas: 96550)\n[PASS] test_transferMovesExactAmount() (gas: 154026)\n[PASS] test_transferOfZeroSucceeds() (gas: 47801)\n[PASS] test_transferRevertsOnInsufficientBalance() (gas: 96127)\n[PASS] test_transferRevertsToZeroAddress() (gas: 91122)\n[PASS] test_transferToSelfKeepsBalance() (gas: 102036)\n[PASS] test_unknownSelectorAndPlainEtherRevert() (gas: 58270)\nSuite result: ok. 29 passed; 0 failed; 0 skipped; finished in 9.83ms (23.61ms CPU time)\n\nRan 1 test suite in 10.60ms (9.83ms CPU time): 29 tests passed, 0 failed, 0 skipped (29 total tests)\n","passed":true},{"durationMs":49,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"IMDBlackoutToken.approve(address,uint256)\",\"IMDBlackoutToken.burn(uint256)\",\"IMDBlackoutToken.transfer(address,uint256)\",\"IMDBlackoutToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":102,\"foundry.toml\":20,\"launch.json\":24,\"remappings.txt\":2,\"script/Deploy.s.sol\":24,\"src/IMDBlackoutToken.sol\":67,\"test/IMDBlackoutToken.t.sol\":383},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"544cce18d232911ffa58752cc4a0ff89bc508a24fe376f6204e7f15f1d4f8cee","verifiedTreeHash":"04dcbc399a05a80d33c3ebb4bb9d7cd62d1980a9","verifierVersion":"0.1.0+fb8278c5"},{"checks":[{"durationMs":1764,"exitCode":0,"name":"build","output":"Compiling 30 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.66s\nCompiler run successful!\n","passed":true},{"durationMs":16110,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 29 tests for test/IMDBlackoutToken.t.sol:IMDBlackoutTokenTest\n[PASS] testFuzz_transferConservesSupplyAndDeliversExactly(uint256,uint256) (runs: 256, μ: 189569, ~: 191283)\nLogs:\n  Bound result 117300739\n  Bound result 242\n\n[PASS] test_approveAndTransferFrom() (gas: 229884)\n[PASS] test_approveZeroAddressSpenderReverts() (gas: 32919)\n[PASS] test_burnOnlyTouchesTheCaller() (gas: 176182)\n[PASS] test_burnReducesHolderAndSupply() (gas: 124523)\n[PASS] test_burnRevertsOnInsufficientBalance() (gas: 93435)\n[PASS] test_constantsMatchTheBrief() (gas: 33219)\n[PASS] test_constructorEmitsTransferFromZeroAndSupplyMinted() (gas: 7436)\n[PASS] test_creationCodeTakesNoConstructorArguments() (gas: 627008)\n[PASS] test_deployScriptFunctionMintsToItsCaller() (gas: 1435126)\n[PASS] test_infiniteAllowanceIsNotDecremented() (gas: 181601)\n[PASS] test_launchFlowsMoveExactlyWhatTheySay() (gas: 425564)\n[PASS] test_metadata() (gas: 31923)\n[PASS] test_mintsWholeSupplyOnceToDeployer() (gas: 44375)\n[PASS] test_noBurnFromExists() (gas: 157354)\n[PASS] test_noMintOrAdminCallGrowsSupply() (gas: 1616989)\n[PASS] test_noPrivilegedCallMovesOrFreezesAHolder() (gas: 759714)\n[PASS] test_requesterIsAnOrdinaryHolder() (gas: 171883)\n[PASS] test_runtimeFitsEip170() (gas: 7880)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 2566610)\n[PASS] test_transferFromRevertsOnInsufficientAllowance() (gas: 146250)\n[PASS] test_transferFromRevertsOnInsufficientBalanceEvenWithAllowance() (gas: 148971)\n[PASS] test_transferFromWithoutApprovalReverts() (gas: 96550)\n[PASS] test_transferMovesExactAmount() (gas: 154026)\n[PASS] test_transferOfZeroSucceeds() (gas: 47801)\n[PASS] test_transferRevertsOnInsufficientBalance() (gas: 96127)\n[PASS] test_transferRevertsToZeroAddress() (gas: 91122)\n[PASS] test_transferToSelfKeepsBalance() (gas: 102036)\n[PASS] test_unknownSelectorAndPlainEtherRevert() (gas: 58270)\nSuite result: ok. 29 passed; 0 failed; 0 skipped; finished in 154.26ms (39.01ms CPU time)\n\nRan 31 tests for test/IMDBlackoutToken.properties.t.sol:IMDBlackoutTokenPropertiesTest\n[PASS] testFuzz_allowanceDoesNotFollowTheBalance(uint256) (runs: 1000, μ: 213114, ~: 212901)\nLogs:\n  Bound result 853006926277697386027682752\n\n[PASS] testFuzz_allowanceIsConsumedExactly(uint256,uint256) (runs: 1000, μ: 275035, ~: 276471)\nLogs:\n  Bound result 0\n  Bound result 0\n\n[PASS] testFuzz_anyDeployerReceivesTheWholeSupply(address) (runs: 1000, μ: 25314, ~: 26828)\n[PASS] testFuzz_approveNeverMovesTokens(uint256) (runs: 1000, μ: 87765, ~: 87955)\n[PASS] testFuzz_approveOverwritesNotAccumulates(uint256,uint256) (runs: 1000, μ: 141887, ~: 141970)\n[PASS] testFuzz_burnByAnApprovedSpenderBurnsOnlyItsOwn(uint256,uint256) (runs: 1000, μ: 247341, ~: 248042)\nLogs:\n  Bound result 32871320\n  Bound result 16709953601325643093625709\n\n[PASS] testFuzz_burnReducesExactlyAndOverBurnReverts(uint256,uint256,uint256) (runs: 1000, μ: 176465, ~: 177255)\nLogs:\n  Bound result 344\n  Bound result 340\n  Bound result 874\n\n[PASS] testFuzz_burnsFromSeveralHoldersAddUp(uint256,uint256,uint256) (runs: 1000, μ: 300022, ~: 301109)\nLogs:\n  Bound result 755852377752255852281\n  Bound result 1\n  Bound result 6841996296677323457448843\n\n[PASS] testFuzz_etherIsAlwaysRefused(uint256,bytes4) (runs: 1000, μ: 102117, ~: 101860)\nLogs:\n  Bound result 262937983786438772968920\n\n[PASS] testFuzz_selfTransferIsANoOp(uint256,uint256) (runs: 1000, μ: 114005, ~: 114331)\nLogs:\n  Bound result 32871320\n  Bound result 18342282\n\n[PASS] testFuzz_transferChainConservesEveryWei(uint256) (runs: 1000, μ: 289383, ~: 289914)\nLogs:\n  Bound result 852907682505313143867852779\n\n[PASS] testFuzz_transferExactBalanceEmptiesSender(uint256) (runs: 1000, μ: 134232, ~: 134508)\nLogs:\n  Bound result 852907682505313143867852779\n\n[PASS] testFuzz_transferFromBySelfStillNeedsAllowance(uint256,uint256) (runs: 1000, μ: 220238, ~: 220488)\nLogs:\n  Bound result 913768451219217582654247265\n  Bound result 1166\n\n[PASS] testFuzz_transferFromOutcomeMatchesAllowanceAndBalance(uint256,uint256,uint256) (runs: 1000, μ: 186876, ~: 175850)\nLogs:\n  Bound result 51269462388923019525943199\n\n[PASS] testFuzz_transferIsAdditive(uint256,uint256) (runs: 1000, μ: 172679, ~: 173628)\nLogs:\n  Bound result 5\n  Bound result 2\n\n[PASS] testFuzz_transferOverBalanceRevertsAndMovesNothing(uint256,uint256) (runs: 1000, μ: 117263, ~: 117388)\nLogs:\n  Bound result 461883638360191700438263680\n  Bound result 13443989\n\n[PASS] testFuzz_transferToZeroAddressAlwaysReverts(uint256,uint256) (runs: 1000, μ: 109900, ~: 110060)\nLogs:\n  Bound result 32871320\n  Bound result 1805722244297576677929977740190650263969670065813556798801505176458\n\n[PASS] testFuzz_truncatedCalldataReverts(uint8) (runs: 1000, μ: 50299, ~: 47878)\nLogs:\n  Bound result 5\n\n[PASS] testFuzz_unknownSelectorRevertsAndChangesNothing(address,bytes4,bytes) (runs: 1000, μ: 129696, ~: 129470)\n[PASS] testFuzz_viewsNeverMutate(address,address,address) (runs: 1000, μ: 167044, ~: 167044)\n[PASS] test_burnOneWei() (gas: 109837)\n[PASS] test_burnWholeSupplyLeavesNothingToMove() (gas: 111709)\n[PASS] test_burnWithNoBalanceReverts() (gas: 35167)\n[PASS] test_burnZeroIsANoOp() (gas: 151836)\n[PASS] test_deployingFromZeroAddressReverts() (gas: 4174)\n[PASS] test_deploymentsAreIndependent() (gas: 87489)\n[PASS] test_transferFromToZeroAddressReverts() (gas: 148976)\n[PASS] test_transferFromZeroAddressOwnerReverts() (gas: 36108)\n[PASS] test_transferMaxUintRevertsEvenForTheWholeSupplyHolder() (gas: 35642)\n[PASS] test_transferOneWei() (gas: 131041)\n[PASS] test_transferWholeSupplyInOneCall() (gas: 106296)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 154.90ms (2.73s CPU time)\n\nRan 1 test for test/IMDBlackoutToken.invariant.t.sol:IMDBlackoutTokenOpenSurfaceInvariantTest\n[PASS]\nIMDBlackoutTokenOpenSurfaceInvariantTest invariants:\n[PASS] invariant_open_deployerPlusStrangersNeverExceedSupply\n[PASS] invariant_open_supplyNeverGrows\n[PASS] invariant_open_zeroAddressHoldsNothing\n IMDBlackoutTokenOpenSurfaceInvariantTest invariants (runs: 128, calls: 4096, reverts: 2529)\n\n╭------------------+--------------+-------+---------+----------╮\n| Contract         | Selector     | Calls | Reverts | Discards |\n+==============================================================+\n| IMDBlackoutToken | approve      | 1012  | 14      | 0        |\n|------------------+--------------+-------+---------+----------|\n| IMDBlackoutToken | burn         | 1028  | 755     | 0        |\n|------------------+--------------+-------+---------+----------|\n| IMDBlackoutToken | transfer     | 1047  | 765     | 0        |\n|------------------+--------------+-------+---------+----------|\n| IMDBlackoutToken | transferFrom | 1009  | 995     | 0        |\n╰------------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 170.42ms (168.55ms CPU time)\n\nRan 1 test for test/IMDBlackoutToken.invariant.t.sol:IMDBlackoutTokenInvariantTest\n[PASS]\nIMDBlackoutTokenInvariantTest invariants:\n[PASS] invariant_allowancesMatchGhostAccounting\n[PASS] invariant_balancesMatchGhostAccounting\n[PASS] invariant_callSummary\n[PASS] invariant_metadataIsFixed\n[PASS] invariant_noBalanceExceedsSupply\n[PASS] invariant_nothingLeaksToBystanders\n[PASS] invariant_onlyKnownPathsMoveTokens\n[PASS] invariant_sumOfBalancesEqualsSupply\n[PASS] invariant_supplyEqualsInitialMinusBurned\n[PASS] invariant_supplyNeverGrows\n IMDBlackoutTokenInvariantTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭--------------+-----------------------------+-------+---------+----------╮\n| Contract     | Selector                    | Calls | Reverts | Discards |\n+=========================================================================+\n| TokenHandler | approve                     | 1504  | 0       | 0        |\n|--------------+-----------------------------+-------+---------+----------|\n| TokenHandler | burn                        | 1425  | 0       | 0        |\n|--------------+-----------------------------+-------+---------+----------|\n| TokenHandler | burnOverBalance             | 1494  | 0       | 0        |\n|--------------+-----------------------------+-------+---------+----------|\n| TokenHandler | callUnknownSelector         | 1444  | 0       | 0        |\n|--------------+-----------------------------+-------+---------+----------|\n| TokenHandler | sendEther                   | 1501  | 0       | 0        |\n|--------------+-----------------------------+-------+---------+----------|\n| TokenHandler | transfer                    | 1508  | 0       | 0        |\n|--------------+-----------------------------+-------+---------+----------|\n| TokenHandler | transferFrom                | 1530  | 0       | 0        |\n|--------------+-----------------------------+-------+---------+----------|\n| TokenHandler | transferFromOverAllowance   | 1510  | 0       | 0        |\n|--------------+-----------------------------+-------+---------+----------|\n| TokenHandler | transferFromWithoutApproval | 1546  | 0       | 0        |\n|--------------+-----------------------------+-------+---------+----------|\n| TokenHandler | transferOverBalance         | 1460  | 0       | 0        |\n|--------------+-----------------------------+-------+---------+----------|\n| TokenHandler | transferToZero              | 1462  | 0       | 0        |\n╰--------------+-----------------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 3\n  Bound result 5\n  Bound result 0\n  Bound result 6\n  Bound result 2\n  Bound result 2\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 0\n  Bound result 2\n  Bound result 0\n  Bound result 6\n  Bound result 4\n  Bound result 0\n  Bound result 4\n  Bound result 573410637323163733498696175871623760057399019195480954871129376198133497273\n  Bound result 3\n  Bound result 0\n  Bound result 4\n  Bound result 2000000000000000000\n  Bound result 1\n  Bound result 2\n  Bound result 0\n  Bound result 2\n  Bound result 1\n  Bound result 6\n  Bound result 0\n  Bound result 3\n  Bound result 0\n  Bound result 10\n  Bound result 1\n  Bound result 2\n  Bound result 3\n  Bound result 0\n  Bound result 4\n  Bound result 6\n  Bound result 0\n  Bound result 5\n  Bound result 3\n  Bound result 1000000000000000000000000\n  Bound result 6\n  Bound result 0\n  Bound result 3\n  Bound result 0\n  Bound result 2\n  Bound result 1\n  Bound result 30000000000000000000\n  Bound result 11000000000000000000\n  Bound result 4\n  Bound result 1\n  Bound result 5\n  Bound result 11000000000000000000\n  Bound result 52832318671884573758\n  Bound result 3\n  Bound result 1\n  Bound result 2\n  Bound result 4\n  Bound result 2\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 6\n  Bound result 2\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 41000000000000000000\n  Bound result 1\n  Bound result 1\n  Bound result 100000000000000000000\n  Bound result 5\n  Bound result 2\n  Bound result 7489\n  Bound result 1\n  Bound result 5\n  Bound result 0\n  Bound result 6\n  Bound result 0\n  Bound result 2\n  Bound result 0\n  Bound result 4\n  Bound result 5\n  Bound result 4\n  Bound result 1\n  Bound result 6\n  Bound result 1\n  Bound result 6\n  Bound result 0\n  Bound result 1\n  Bound result 17128\n  Bound result 4\n  Bound result 6\n  Bound result 0\n  Bound result 257\n  Bound result 1\n  Bound result 5\n  Bound result 3368592276519\n  Bound result 6\n  Bound result 0\n  Bound result 2\n  Bound result 5\n  Bound result 3\n  Bound result 0\n  Bound result 3412299263\n  Bound result 4\n  Bound result 1\n  Bound result 6\n  Bound result 0\n  Bound result 14588\n  Bound result 6\n  Bound result 3\n  Bound result 3\n  Bound result 0\n  Bound result 4\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 1\n  Bound result 7\n  Bound result 4\n  Bound result 4\n  Bound result 2\n  Bound result 1000000000000000000000\n  Bound result 60782\n  Bound result 3\n  Bound result 5\n  Bound result 0\n  Bound result 100000000000000000000\n  Bound result 6\n  Bound result 3\n  Bound result 12\n  Bound result 0\n  Bound result 313838549751852106296010405\n  Bound result 6\n  Bound result 3\n  Bound result 9\n  Bound result 5\n  Bound result 1\n  Bound result 2281\n  Bound result 4\n  Bound result 6\n  Bound result 4\n  Bound result 1119\n  Bound result 2\n  Bound result 0\n  Bound result 55987755373464221693\n  Bound result 2\n  Bound result 1\n  Bound result 100000000000000000000\n  Bound result 1\n  Bound result 40000000000000000000\n  Bound result 4\n  Bound result 4\n  Bound result 4\n  Bound result 0\n  Bound result 4\n  Bound result 4\n  Bound result 5\n  Bound result 0\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 16.02s (16.02s CPU time)\n\nRan 4 test suites in 16.03s (16.50s CPU time): 62 tests passed, 0 failed, 0 skipped (62 total tests)\n","passed":true},{"durationMs":46,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"IMDBlackoutToken.approve(address,uint256)\",\"IMDBlackoutToken.burn(uint256)\",\"IMDBlackoutToken.transfer(address,uint256)\",\"IMDBlackoutToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":102,\"foundry.toml\":20,\"remappings.txt\":2,\"script/Deploy.s.sol\":24,\"src/IMDBlackoutToken.sol\":67,\"test/IMDBlackoutToken.invariant.t.sol\":452,\"test/IMDBlackoutToken.properties.t.sol\":480,\"test/IMDBlackoutToken.t.sol\":383},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"65201c7a77d7e2900ae4094a87507484c07b0ca0e014a758ed931d1a3fb1cadb","verifiedTreeHash":"fc86c61059f7978265863660eb234369733ef60a","verifierVersion":"0.1.0+fb8278c5"},{"checks":[{"durationMs":942,"exitCode":0,"name":"build","output":"Compiling 28 files with Solc 0.8.26\nSolc 0.8.26 finished in 841.64ms\nCompiler run successful!\n","passed":true},{"durationMs":109,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 29 tests for test/IMDBlackoutToken.t.sol:IMDBlackoutTokenTest\n[PASS] testFuzz_transferConservesSupplyAndDeliversExactly(uint256,uint256) (runs: 256, μ: 189004, ~: 191283)\nLogs:\n  Bound result 32\n  Bound result 0\n\n[PASS] test_approveAndTransferFrom() (gas: 229884)\n[PASS] test_approveZeroAddressSpenderReverts() (gas: 32919)\n[PASS] test_burnOnlyTouchesTheCaller() (gas: 176182)\n[PASS] test_burnReducesHolderAndSupply() (gas: 124523)\n[PASS] test_burnRevertsOnInsufficientBalance() (gas: 93435)\n[PASS] test_constantsMatchTheBrief() (gas: 33219)\n[PASS] test_constructorEmitsTransferFromZeroAndSupplyMinted() (gas: 7436)\n[PASS] test_creationCodeTakesNoConstructorArguments() (gas: 627008)\n[PASS] test_deployScriptFunctionMintsToItsCaller() (gas: 1435126)\n[PASS] test_infiniteAllowanceIsNotDecremented() (gas: 181601)\n[PASS] test_launchFlowsMoveExactlyWhatTheySay() (gas: 425564)\n[PASS] test_metadata() (gas: 31923)\n[PASS] test_mintsWholeSupplyOnceToDeployer() (gas: 44375)\n[PASS] test_noBurnFromExists() (gas: 157354)\n[PASS] test_noMintOrAdminCallGrowsSupply() (gas: 1616989)\n[PASS] test_noPrivilegedCallMovesOrFreezesAHolder() (gas: 759714)\n[PASS] test_requesterIsAnOrdinaryHolder() (gas: 171883)\n[PASS] test_runtimeFitsEip170() (gas: 7880)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 2566610)\n[PASS] test_transferFromRevertsOnInsufficientAllowance() (gas: 146250)\n[PASS] test_transferFromRevertsOnInsufficientBalanceEvenWithAllowance() (gas: 148971)\n[PASS] test_transferFromWithoutApprovalReverts() (gas: 96550)\n[PASS] test_transferMovesExactAmount() (gas: 154026)\n[PASS] test_transferOfZeroSucceeds() (gas: 47801)\n[PASS] test_transferRevertsOnInsufficientBalance() (gas: 96127)\n[PASS] test_transferRevertsToZeroAddress() (gas: 91122)\n[PASS] test_transferToSelfKeepsBalance() (gas: 102036)\n[PASS] test_unknownSelectorAndPlainEtherRevert() (gas: 58270)\nSuite result: ok. 29 passed; 0 failed; 0 skipped; finished in 6.95ms (22.46ms CPU time)\n\nRan 1 test suite in 7.39ms (6.95ms CPU time): 29 tests passed, 0 failed, 0 skipped (29 total tests)\n","passed":true},{"durationMs":32,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"IMDBlackoutToken.approve(address,uint256)\",\"IMDBlackoutToken.burn(uint256)\",\"IMDBlackoutToken.transfer(address,uint256)\",\"IMDBlackoutToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":102,\"foundry.toml\":20,\"remappings.txt\":2,\"script/Deploy.s.sol\":24,\"src/IMDBlackoutToken.sol\":67,\"test/IMDBlackoutToken.t.sol\":383},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":417,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":243,"exitCode":0,"name":"aderyn","output":"[low] large-numeric-literal at src/IMDBlackoutToken.sol:39: Large Numeric Literal","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"d5d59a1dc23bf74d6ffc704b7cd57135c6ba8a62be48177d56fa1de34c754e7c","verifiedTreeHash":"1c5010025f78a893792fa2c96676253f9a55adcc","verifierVersion":"0.1.0+fb8278c5"}]}