{"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":"ae8a24f3-a95d-4905-aff8-222404e085e6","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"5070d048cacbc57d085e34ed1ad1c5bc83108c9db61db5d677ecf1283e22ce4e","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":"21d4ce20ef99924162d8b351724bb90547f317d93a089ce0dce60996718752a0","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":"41b00719a3fda268948870997c4f93a802fe90a04305da723b2087463911fd09","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":"6ebc52c6ef3803dbc7ed12e26256b789bd54b031cf44a2f0e09dc52ca4671ba3","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":"1fd522128b765ff049828ebaf0b0d5bcd2d8f99048ff94bc777f597e3fb829fe","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":"f1313384c98108e81ed01d61bcc8d0d3d9a891d577ff85e3e151a462f96422d5","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"d59561da3b378461b7c749f6bd5084477d44993aa94972ddea90f542535751df","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"d59561da3b378461b7c749f6bd5084477d44993aa94972ddea90f542535751df","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":"8890803e92c401ae93cc97ba33a2151e441705a0bb52bad46b553739b4d77580","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"de8c5afd7843c94e5fed2eacf56e4549c5444b2e13b11b8a800dc34d9dd87fbe","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"4c76766b00591dfe982fe85d3de589fdb2f810e5137c301155d1c5e36a1d3b23","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"4c76766b00591dfe982fe85d3de589fdb2f810e5137c301155d1c5e36a1d3b23","skillId":"write-foundry-tests","state":"accepted"}],"objective":"Build, test, review and DEPLOY THE IMD DAILY collectible newspaper contracts on Ethereum mainnet. Publish the source on GitHub and verify deployed source on Etherscan. This is a NEW independent project. Never modify UNLOCK or its websites/contracts. No new ERC20, trading pool or liquidity. This job is CONTRACTS ONLY. A separate website job will later provide public PDF reading and the publisher dashboard.\n\nToken name: The IMD Daily\nToken symbol: IMDDAILY\nTotal supply: 0 at deployment; uncapped ERC1155 open editions, mintable only during each issue's 24-hour window. These fields describe the NFT collection, NOT an ERC20.\n\nPublisher and sole revenue withdrawal authority: 0x48E4E74fE1d0c14404cEB57B9fec5b21329C6ec9. Hardcode this authority or pass it explicitly; never leave authority with a factory or service wallet. Payment token is existing Ethereum IMD at 0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7. Verify its decimals onchain. Price is exactly 0.1 IMD per copy, immutable. ETH is for transaction gas only.\n\nCOLLECTION: Use non-upgradeable ERC1155. One sequential token ID per newspaper issue; identical collectible copies share that issue's metadata. Only the publisher can create an issue, recording its title, editorial date, PDF URL, cover URL, metadata URI and immutable content hashes. Metadata must identify the issue, link its PDF and use its cover as the image. Edition date does not control mint eligibility. The window starts at the successful publication transaction's block.timestamp and closes exactly 86400 seconds later. Mint requires start <= block.timestamp < close. No reopening, extending, backdating eligibility, changing published files/URIs/hashes or price, and no free/owner minting. No upgrade, hidden bypass or mutable base URI.\n\nUnlimited issues over time. No per-issue supply cap or wallet cap during the window. Users may repeatedly mint any positive quantity they can afford and fit within transaction gas limits. After expiry that issue's supply can never increase, while transfers and public metadata remain available. Include per-issue totalSupply, timestamps, price and availability views plus publication/mint events suitable for paginated indexing. No secondary royalties. NFT ownership is a collectible, not copyright or a financial-return entitlement.\n\nPAYMENT/VAULT: A distinct vault receives IMD mint proceeds atomically with safe minting. Use SafeERC20 and reentrancy protection, including malicious ERC1155 receiver callbacks; failed payment or mint rolls back everything. Check amount multiplication, zero quantity, nonexistent IDs, insufficient balance/approval and deadline. Reject native ETH payments. Only the publisher wallet may withdraw vault funds to that same wallet; no other payout destination or administrator. Provide reliable collected/withdrawn counters and actual IMD balance; direct donations must not be counted as mint revenue. Emit withdrawal events and permit partial withdrawal.\n\nNO STORAGE BLOCKER: PDFs, covers and metadata will be uploaded by the publisher AFTER deployment using a later VPS-backed website. Do not require sample PDFs, IPFS pins, a domain, storage credentials or the first issue before delivering these contracts. Do not publish dummy or real issues on mainnet. The later publisher UI must verify public URLs/hashes before submitting createIssue; contracts record commitments, they cannot fetch files. Provide an exact integration guide: ABI, hash algorithms, metadata JSON schema, issue discovery, publish/mint/approve/withdraw examples and chain/address configuration. Durable hosting remains the publisher's responsibility; keep URL origins replaceable by server/DNS migration without changing published paths or bytes.\n\nRELEASE: Use the supported IMD deployment manifest and dependency ordering; respect EIP-170/initcode limits. No unsupported post-deployment setup dependency. Test with local mocks AND an Ethereum fork using real IMD: payment arithmetic, repeated/multi-copy mints, exact closing boundary, multiple independent issues, unauthorized publication/withdrawal, reentrancy, atomic rollback, immutable fields, donations and transfers after expiry. No real-fund test purchases. Deliver deployed contract addresses, transaction receipts, verified source links, ABIs, pinned source commit, reproducible results and integration documentation. Clearly separate fork results from real deployment. Do not call code publication alone deployment; report any remaining release blocker explicitly.","parentJobId":null,"planHash":"470e308ca2cd908638c5d0606067df86dc5ffb3a63cd3a80c7e4cb56e15a418c","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"ae8a24f3-a95d-4905-aff8-222404e085e6","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-2368-the-imd-daily"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51081","feedbackHash":"8344cd8dc2a20e716628440c764b01e5b346cc1bb1b533ee85d37d9f8f879dc7","nodeKey":"audit_economics","submissionHash":"5070d048cacbc57d085e34ed1ad1c5bc83108c9db61db5d677ecf1283e22ce4e","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52666","feedbackHash":"462c2454c6369e416cec0fba3cbc341df35eae1efadaca895aed78d710ac250b","nodeKey":"audit_flow","submissionHash":"21d4ce20ef99924162d8b351724bb90547f317d93a089ce0dce60996718752a0","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52286","feedbackHash":"5fd3602aaa3204cb8578a51343ce169f18fcd1a3dc13dd8e50f2b6e068d8f469","nodeKey":"audit_judge","submissionHash":"41b00719a3fda268948870997c4f93a802fe90a04305da723b2087463911fd09","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52130","feedbackHash":"fd12e76758cc9a53a3c2e47a8a6a21ca809a43517c6612dfe25d2e0cdce20f9e","nodeKey":"audit_math","submissionHash":"6ebc52c6ef3803dbc7ed12e26256b789bd54b031cf44a2f0e09dc52ca4671ba3","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"53924","feedbackHash":"ba5ee306decc55a29c1bb719288a335cd207dec8a9e6723687011d3136bb5196","nodeKey":"audit_permissions","submissionHash":"1fd522128b765ff049828ebaf0b0d5bcd2d8f99048ff94bc777f597e3fb829fe","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51332","feedbackHash":"8bb0d53515953669e27e045abcfbf274ed67864726206e595679921648efcdd6","nodeKey":"build_contract_project","submissionHash":"f1313384c98108e81ed01d61bcc8d0d3d9a891d577ff85e3e151a462f96422d5","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"50974","feedbackHash":"e71653ad27077cd8f9e0565e69244db70817fe07def30c413582cc9ccf3bede6","nodeKey":"manifest","submissionHash":"8890803e92c401ae93cc97ba33a2151e441705a0bb52bad46b553739b4d77580","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52120","feedbackHash":"d19f44c996a2b9a47bd6ccf8c06f861883b85e49fd472b6f9512b312349d9373","nodeKey":"write_foundry_tests","submissionHash":"de8c5afd7843c94e5fed2eacf56e4549c5444b2e13b11b8a800dc34d9dd87fbe","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"1fdc447c4e84718a745f3ddc10c8add72fe741e05e2f575974390e7157bbbc08","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"a7ac9f7a7687c25e","findings":[{"citation":"resolved","description":"Access-control trust assumption, not a code defect. On Ethereum mainnet the hardcoded publisher 0x48E4E74fE1d0c14404cEB57B9fec5b21329C6ec9 is not a plain EOA: cast code returns 0xef0100 63c0c19a282a1b52b07dd5a65b58948a07dae32b, an EIP-7702 delegation to MetaMask EIP7702StatelessDeleGator v1.3.0 (delegationManager 0xdb9B1e94B5b69Df7e401DDbedE43491141047dB3, entryPoint 0x0000000071727De22E5E9d8BAf0edAc6f37da032). Every call made by that account's code, whether triggered by the EOA key, by a 4337 userOp through the EntryPoint, or by any third party redeeming a delegation the publisher signed via DelegationManager.redeemDelegations, reaches createIssue and withdraw with msg.sender == PUBLISHER and passes this check. 'Only the publisher wallet' therefore means 'anything the publisher's smart-account configuration authorizes'. Secondary consequence checked and currently fine: ERC1155 mints or transfers to PUBLISHER go through OZ ERC1155Utils.checkOnERC1155Received because to.code.length is 23; the current delegate answers onERC1155Received with 0xf23a6e61 (verified by eth_call), so mint(id, q, PUBLISHER, d) succeeds on a live fork. If the publisher later re-delegates to code without that hook, every mint or safeTransferFrom whose recipient is PUBLISHER reverts with ERC1155InvalidReceiver while withdraw (plain ERC20 transfer) keeps working. The brief mandates the hardcoded authority and no transfer function, so no code change is proposed; the release documentation should record these facts so the operator does not assume a key-only trust boundary.","line":14,"path":"src/DailyAuthority.sol","reproduction":"State: Ethereum mainnet, block 26239294. Call: cast code 0x48E4E74fE1d0c14404cEB57B9fec5b21329C6ec9 -> 0xef010063c0c19a282a1b52b07dd5a65b58948a07dae32b; cast call 0x63c0...e32b 'NAME()(string)' -> EIP7702StatelessDeleGator; cast call 0x48E4...6ec9 'onERC1155Received(address,address,uint256,uint256,bytes)(bytes4)' -> 0xf23a6e61. Expected by the brief's wording: a single wallet key is the sole withdrawal authority. Actual: any execution path of the MetaMask delegator (EOA tx, EntryPoint userOp, DelegationManager redemption of a publisher-signed delegation) satisfies onlyPublisher in createIssue and withdraw.","severity":"info","snippet":"        if (msg.sender != PUBLISHER) revert OnlyPublisher();","title":"Sole publisher authority is an EIP-7702 smart account; onlyPublisher also admits ERC-4337 userOps and MetaMask delegations redeemed through its DelegationManager"},{"citation":"resolved","description":"Access x economics trust assumption inherent to the requested design (price fixed, proceeds to the publisher's own vault, no owner-mint path). The 'no free/owner minting' guarantee holds only in form: the publisher can mint any quantity to itself for gas alone because the 0.1 IMD per copy it pays is immediately withdrawable by the same account. Such mints raise totalSupply(id) and totalCollected exactly like collector purchases, so the 'reliable collected counter' includes publisher self-purchases and cannot distinguish them. Not fixable without changing the agreed economics (e.g. burning or escrowing publisher payments), so this is documented for the operator and for the website's revenue dashboard, which should subtract CopiesMinted events whose payer == PUBLISHER if it wants collector-only revenue. Verified in test/scratch/Review.t.sol::test_publisherSelfMintIsFreeInIMDTerms (passes on current code).","line":132,"path":"src/IMDDaily.sol","reproduction":"State: issue 1 open, PUBLISHER holds 1 IMD and approved IMDDaily. Calls from PUBLISHER: mint(1, 10, PUBLISHER, now) then vault.withdraw(1e18). Expected if 'no owner minting' were economic: publisher cannot grow supply without net payment. Actual: totalSupply(1)=10, totalCollected=1e18, publisher IMD balance back to 1 IMD; net IMD cost 0, only gas.","severity":"info","snippet":"        totalCollected += amount;\n        token.safeTransferFrom(msg.sender, address(vault), amount);","title":"Publisher self-mints cost zero IMD (pays its own vault, withdraws it back) and are counted in totalCollected as mint revenue"},{"citation":"resolved","description":"Release hazard for the manifest step, not a code defect: the evm_contracts recipe forbids constructors that require code at a dependency address, so the collection validates the vault only at use (mint calls vault.PUBLISHER()/PAYMENT_TOKEN()). Consequences: (a) if constructorArgs for IMDDaily is any address other than $contract:IMDDailyVault (a typo, $owner would be rejected but a hex literal would not), construction succeeds, createIssue works, and every mint reverts forever, since vault is immutable and there is no setter by design; (b) the getter checks accept any IMDDailyVault instance, including one from a different deployment, so the manifest reference is the only thing binding this collection to its reviewed vault. No launch.json exists in the tree yet (docs/RELEASE.md documents the required order: IMDDailyVault first, then IMDDaily with $contract:IMDDailyVault). The judge/manifest author should treat that argument as the single irreversible input of this launch. Verified in test/scratch/Review.t.sol::test_wrongVaultArgumentBricksMintPermanently.","line":78,"path":"src/IMDDaily.sol","reproduction":"State: new IMDDaily(0x0000000000000000000000000000000000001234) deploys successfully (no revert). Calls: PUBLISHER createIssue(valid content) -> id 1; alice approves and calls mint(1, 1, alice, now). Expected for a correct launch: copy minted, 0.1 IMD in vault. Actual: mint reverts (staticcall to PUBLISHER() on an address without code), and will revert for every issue forever; no function can change vault.","severity":"info","snippet":"        if (vault_ == address(0) || vault_ == PUBLISHER || vault_ == PAYMENT_TOKEN) revert InvalidVault();","title":"Constructor accepts any non-sentinel vault address; a wrong launch.json argument leaves mint permanently reverting with no recovery path"},{"citation":"resolved","description":"Access x asymmetry trust assumption. Per-issue immutability and the 86400-second window are enforced for a given ID, but createIssue does not reject pdfHash/coverHash/metadataHash values already committed by an earlier issue. After issue N closes, the publisher can call createIssue with identical title, URLs and hashes and obtain issue N+1 with a fresh 24-hour window; collectors of issue N see an identical-content edition reopened under a different token ID, diluting the 'supply can never increase after expiry' guarantee at the content level while keeping it true at the ID level. The brief defines issues by sequential ID and leaves editorial decisions to the publisher, so this is reported as a documented power rather than a defect; a minimal optional hardening that preserves the design would be a mapping(bytes32 => bool) over pdfHash rejecting duplicates, but that is a scope decision for the requester (a corrected re-issue with the same PDF would then be impossible).","line":98,"path":"src/IMDDaily.sol","reproduction":"State: issue 1 published at T with hashes H. Warp to T+86400: mint(1,...) reverts MintClosed(1). PUBLISHER calls createIssue(same content with hashes H) -> returns 2, isAvailable(2)=true, mint(2, q, alice, now) succeeds. Expected under a content-level reading of 'no reopening': second publication of identical commitments rejected. Actual: accepted as a new issue with a new window.","severity":"info","snippet":"        id = ++issueCount;","title":"No uniqueness check on content hashes: the publisher can republish an expired issue's exact files under a new sequential ID, an economic reopening"}],"hash":"1fd522128b765ff049828ebaf0b0d5bcd2d8f99048ff94bc777f597e3fb829fe","nodeId":"37f8bf30-17bf-440f-bb4f-d9dc5b7155c7","outcome":"completed","summary":"The review is complete. The findings file is written and every snippet matches the tree. No tracked file was modified.\n\n**Outcome: no exploitable defect in the Access Control, Trust Gap or Asymmetry area.** The permission model is two hardcoded constants and one modifier, with no initializer, role transfer, upgrade path, URI or price setter, owner mint or burn. I reported four info-level items, each a trust assumption or release hazard with a concrete reproduction, rather than a code bug.\n\nWhat I verified:\n- **Local suite** of 43 tests passes, including the invariant conservation and permanence checks.\n- **Fork suite** of 28 tests passes against live Ethereum mainnet through publicnode. The pinned-block RPC error noted in the evidence did not recur at the latest block.\n- **IMD token** at 0xd34a…63b7 is a non-proxy LayerZero OFT. Its 45 selectors are standard ERC20, Ownable and OFT. No pause, blocklist or fee logic exists, so the exact-balance assertions in mint and withdraw are safe against the token owner.\n- **Publisher wallet** is not a plain EOA. It carries an EIP-7702 delegation to MetaMask's EIP7702StatelessDeleGator v1.3.0 with a DelegationManager. The delegate answers the ERC1155 receiver hook, so mints to the publisher work today.\n\nFindings written to `.imd-findings.json`, all info severity:\n1. **Publisher authority is a smart account.** Any path the MetaMask delegator authorizes, including EntryPoint userOps and redeemed delegations, satisfies the publisher check in createIssue and withdraw. The brief mandates the hardcoded authority, so this is documented, not fixed.\n2. **Publisher self-mints cost zero IMD.** The publisher pays its own vault and withdraws it back, and those mints inflate totalCollected. Verified in a scratch test.\n3. **Wrong vault constructor argument is irreversible.** The recipe forbids code checks in constructors, so a bad manifest argument other than the vault reference bricks mint forever. No launch.json exists yet. Verified in a scratch test.\n4. **No content-hash uniqueness.** The publisher can republish an expired issue's exact files under a new ID, which is an economic reopening at the content level.\n\nCoverage has ten rows: all six listed entry points plus four invariants. Three entry points hold outright and three carry the info findings above, with reasons per row.\n\nNot reached within budget: the Pashov Boundary and Numerical Gap passes beyond what overlaps my three guides, and a full line-by-line read of the vendored OpenZeppelin ERC1155Supply override, which I treated as unmodified v5.4 per dependencies.json.","treeHash":null,"usage":{"cachedInputTokens":939373,"inputTokens":386,"model":"claude-fable-5-1","outputTokens":30331,"runtime":"claude","turns":36,"wallClockMs":457835}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"30bcdea6dcb9ee40","findings":[{"citation":"resolved","description":"dependencies.json pins openzeppelin-contracts v5.4.0 and forge-std v1.9.7 by archive SHA-256 and states the vendored files are 'Unmodified'. They are not: 10 of the 28 vendored OpenZeppelin files and 19 forge-std files differ from the files in those archives. The differences are line-wrapping only (the project's `forge fmt` with line_length = 110 rewrote them: the upstream copy of ERC1155.sol fails `forge fmt --check`, the vendored copy passes) and a whitespace-stripped comparison of every vendored file against its archive counterpart is identical, so compiled runtime bytecode and behaviour are unchanged. The defect is provenance: the release handoff, the pinned-source commit and any reviewer or verifier that checks the base contracts (ERC1155, ERC1155Supply, SafeERC20, Math, Arrays, ERC1155Utils) against the pinned archive hash by byte comparison gets a mismatch on exactly the files that implement the mint, supply accounting and payment path, and has to re-diff them by hand to rule out a semantic edit. Minimal fix: restore the archive bytes for lib/ (and exclude lib/ from fmt via the `[fmt] ignore` list, or run fmt only on src/ and test/), or change the dependencies.json scope text to say the files were reformatted and document how to verify equivalence.","line":9,"path":"dependencies.json","reproduction":"1) `curl -sSL -o oz.tgz https://codeload.github.com/OpenZeppelin/openzeppelin-contracts/tar.gz/refs/tags/v5.4.0 && sha256sum oz.tgz` -> b89829be48bc501051002191733268a93ef6e238a4bb65d8fd1cbdf3969050d1 (matches dependencies.json). 2) `tar xzf oz.tgz && cmp openzeppelin-contracts-5.4.0/contracts/token/ERC1155/ERC1155.sol lib/openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sol` -> expected: identical; actual: 'differ: byte 1130'. Same for contracts/token/ERC1155/extensions/ERC1155Supply.sol, contracts/token/ERC20/utils/SafeERC20.sol, contracts/utils/math/Math.sol, contracts/utils/Arrays.sol, contracts/token/ERC1155/utils/ERC1155Utils.sol, contracts/token/ERC1155/utils/ERC1155Holder.sol, contracts/token/ERC1155/IERC1155.sol, contracts/token/ERC1155/IERC1155Receiver.sol, contracts/interfaces/IERC1363.sol. 3) forge-std v1.9.7 archive (sha256 45157353ab49...) : 19 of its vendored src files differ the same way (Vm.sol, StdCheats.sol, StdStorage.sol, ...). 4) `forge fmt --check` on the upstream ERC1155.sol copy exits 1; on the vendored copy exits 0. 5) Stripping all whitespace from each pair yields identical strings, so the change is formatting only.","severity":"low","snippet":"    \"scope\": \"Unmodified transitive Solidity imports used by src/ and test/, plus LICENSE.\"","title":"Vendored OpenZeppelin and forge-std files are not the bytes of the pinned archives (reformatted by forge fmt), contradicting dependencies.json"},{"citation":"resolved","description":"The collection never holds IMD on the intended path (mint pulls from msg.sender straight into the vault), but it exposes no function that can move an ERC20 balance it receives, and the vault only ever reads its own balance. A collector who follows the brief's 'pay 0.1 IMD per copy' and transfers IMD to the collection address instead of approving and calling mint loses those tokens with no recovery path. The author already documents this in docs/SECURITY_REVIEW.md and README.md, and the brief forbids any payout destination other than the publisher, so this is recorded as a known limitation rather than a defect to block on. If a fix is wanted that preserves the design, a permissionless `sweepToVault()` that forwards the collection's IMD balance to the fixed vault (no caller-chosen destination) keeps the single-authority rule intact; it would need to leave totalCollected untouched so swept tokens are not counted as mint revenue.","line":15,"path":"src/IMDDaily.sol","reproduction":"State: IMDDaily deployed with vault V; alice holds 1 IMD. Call: alice -> IMD.transfer(address(IMDDaily), 1e18). Observe: IMD.balanceOf(IMDDaily) == 1e18 forever; vault.balance() unchanged; daily.totalCollected() unchanged; no selector on IMDDaily or IMDDailyVault can transfer that balance (the ABI in abi/IMDDaily.json has no sweep/rescue/withdraw). Expected by a careless payer: a copy or a refund. Actual: tokens unrecoverable.","severity":"info","snippet":"contract IMDDaily is ERC1155Supply, DailyAuthority, ReentrancyGuard {","title":"IMD sent directly to the collection contract (not the vault) is permanently stuck"},{"citation":"resolved","description":"Trust assumption, documented per the review methodology rather than a code defect. The pinned IMD contract at 0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7 is not a plain ERC20: its runtime exposes the LayerZero OFT surface (lzReceive, send, setPeer, setEnforcedOptions, setDelegate, setPreCrime, setMsgInspector) plus owner-only updateName(string) and updateSymbol(string), with owner() = 0x047F606fD5b2BaA5f5C6c4aB8958E45CB6B054B7. It has no EIP-1967 proxy slots, no pause/blacklist selectors and no transfer hooks, so the mint/withdraw paths (SafeERC20 transferFrom/transfer plus exact before/after balance checks) are sound against it and decimals() cannot change. What the owner and the configured LayerZero peers can do is mint IMD on Ethereum via bridged lzReceive credits (supply inflation is outside this project's control) and rename the token. The one concrete consequence inside this repository is test fragility: test/IMDDailyFork.t.sol asserts symbol() == \"IMD\" in setUp, so after an updateSymbol call the whole 28-test fork suite fails at any later block even though both application contracts are unaffected. The pinned block 26239078 still reproduces today.","line":8,"path":"src/DailyAuthority.sol","reproduction":"Precondition: IMD owner 0x047F606fD5b2BaA5f5C6c4aB8958E45CB6B054B7 calls updateSymbol(\"IMDX\") on mainnet (selector 0x537f5312 is present in the runtime; owner() returns that address). Then `forge test --match-contract IMDDailyForkTest --fork-url <rpc>` at any block after that transaction: expected 28 passes (contracts unchanged); actual: every test fails in setUp at test/IMDDailyFork.t.sol:18 `assertEq(IERC20Metadata(IMD).symbol(), \"IMD\")`. Contracts themselves: IMDDaily.mint still succeeds because only decimals() (immutable 18) is checked.","severity":"info","snippet":"    address public constant PAYMENT_TOKEN = 0xD34a99Bc0f67aE1bbd63C660e6d0b0dd03E263B7;","title":"Payment token is a LayerZero OFT with an active owner; fork-suite setUp asserts a symbol that owner can change"}],"hash":"21d4ce20ef99924162d8b351724bb90547f317d93a089ce0dce60996718752a0","nodeId":"290ab05e-3525-4126-bbf2-a588e9b810f2","outcome":"completed","summary":"The review is complete and recorded in `.imd-findings.json` at the repository root. No repository file was changed.\n\n**Outcome: no funds-at-risk defect found in the assigned area.** I traced every entry point through the Execution Trace, Periphery and First Principles checklists, re-ran the 43 local tests and the 128x48 invariant campaign (all pass), and cross-checked the periphery against upstream sources and the live mainnet token.\n\nFindings written, ranked by severity:\n\n- **Low, dependency provenance.** The vendored OpenZeppelin v5.4.0 and forge-std v1.9.7 files are not the bytes of the pinned archives. The project's own `forge fmt` rewrapped 10 OpenZeppelin and 19 forge-std files, yet dependencies.json calls them \"Unmodified\". A whitespace-stripped comparison is identical, so bytecode and behaviour are unaffected, but anyone verifying the base contracts against the archive hash gets a mismatch on exactly the files that implement mint, supply and payment.\n- **Info, known limitation.** IMD transferred straight to the collection contract instead of through `mint` is unrecoverable. The author documents this already; a fix that keeps the single-authority design would be a permissionless sweep to the fixed vault.\n- **Info, trust assumption.** The payment token is a LayerZero OFT with an active owner who can rename it and whose bridge peers can mint on Ethereum. It has no proxy, pause, blacklist or transfer hooks, so the contracts are sound against it. The one in-repo consequence is that the fork suite's setUp asserts the symbol, which that owner can change.\n\nCoverage record: all six listed entry points are `holds`, with reasons, plus six invariant and periphery rows. The mint path's reentrancy argument was confirmed against the vendored ERC1155 source, which settles balances and supply before the receiver callback. Static-analysis leads (timestamp comparisons, state change after external call) were checked and are the intended eligibility rule and guarded view calls, not defects.\n\nNot reached: the launch manifest itself, since no launch.json exists yet at this stage, and the docs and metadata schema beyond cross-checking the call examples against the compiled ABI, which match.","treeHash":null,"usage":{"cachedInputTokens":1315981,"inputTokens":418,"model":"claude-fable-5-1","outputTokens":31826,"runtime":"claude","turns":33,"wallClockMs":464066}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"fcb71e606c933181","findings":[{"citation":"resolved","description":"Collectors are told to approve the collection address (docs/INTEGRATION.md line 104), so the collection is the address most likely to receive a mistaken direct IMD transfer. IMDDaily exposes no function that moves an ERC20 balance it holds (all 28 ABI entries checked: mint only pulls msg.sender's allowance straight into the vault), and IMDDailyVault.withdraw reads only the vault's own balance. Any IMD whose recipient is the collection is therefore locked forever: it is correctly excluded from totalCollected, but it never reaches the publisher either. Four specialists reported the same root cause; merged here at low because the loss is self-inflicted by the sender and the brief's 'no payout destination other than the publisher' rule is not violated. README.md and docs/SECURITY_REVIEW.md document it as a known limitation. A minimal in-design fix is a sweep on IMDDaily that forwards its IMD balance only to the fixed vault (no caller-chosen destination) without touching totalCollected, so swept tokens are treated as a donation; alternatively keep the documented limitation and have the website warn against direct transfers.","line":15,"path":"src/IMDDaily.sol","reproduction":"Local OpenZeppelin ERC20 etched at 0xD34a99Bc0f67aE1bbd63C660e6d0b0dd03E263B7; vault = new IMDDailyVault(); daily = new IMDDaily(vault); publisher publishes issue 1; alice holds 10e18 IMD. (1) alice: IMD.transfer(address(daily), 1e18). (2) PUBLISHER: vault.withdraw(1e18) -> reverts InsufficientFunds(0, 1e18). (3) alice approves PRICE and calls daily.mint(1, 1, alice, block.timestamp) -> succeeds; daily.totalCollected() == 1e17, vault.balance() == 1e17, IMD.balanceOf(address(daily)) == 1e18 and no function on either contract can move it. Expected: the 1e18 reaches the vault or is otherwise recoverable by the publisher. Actual: permanently locked. Verified with test/scratch/Judge.t.sol::test_imdSentToCollectionIsStranded (passes on current code, i.e. the stranding is observed).","severity":"low","snippet":"contract IMDDaily is ERC1155Supply, DailyAuthority, ReentrancyGuard {","title":"IMD transferred directly to the IMDDaily collection contract is permanently unrecoverable (merged: audit_math, audit_economics, audit_flow, write_foundry_tests)"},{"citation":"resolved","description":"The release provenance record pins openzeppelin-contracts v5.4.0 and forge-std v1.9.7 by archive SHA-256 and claims the vendored files are unmodified. They are not: 10 of 28 vendored OpenZeppelin files and 19 vendored forge-std files differ from the archive contents. I downloaded both archives (hashes match dependencies.json) and compared every file: each difference disappears when all whitespace is stripped, so it is `forge fmt` line-wrapping (line_length = 110) with no semantic change and no bytecode impact. The defect is provenance only: a reviewer, the source-publication step or an Etherscan multi-file verification that checks the base contracts implementing the mint, supply accounting and payment path (ERC1155.sol, ERC1155Supply.sol, SafeERC20.sol, ERC1155Utils.sol, Math.sol, Arrays.sol) against the pinned archive by byte comparison gets a mismatch and must re-diff by hand. Minimal fix: restore the archive bytes under lib/ and add lib/ to the [fmt] ignore list, or change the dependencies.json scope text to state that the files were reformatted with `forge fmt` and that a whitespace-stripped comparison is the equivalence check. (Reported by audit_flow; reproduced.)","line":9,"path":"dependencies.json","reproduction":"curl -sSL -o oz.tgz https://codeload.github.com/OpenZeppelin/openzeppelin-contracts/tar.gz/refs/tags/v5.4.0; sha256sum oz.tgz -> b89829be48bc501051002191733268a93ef6e238a4bb65d8fd1cbdf3969050d1 (matches). tar xzf; cmp openzeppelin-contracts-5.4.0/contracts/token/ERC1155/ERC1155.sol lib/openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sol -> expected identical, actual 'differ'. Files that differ: interfaces/IERC1363.sol, token/ERC20/utils/SafeERC20.sol, token/ERC1155/extensions/ERC1155Supply.sol, token/ERC1155/ERC1155.sol, token/ERC1155/IERC1155Receiver.sol, token/ERC1155/utils/ERC1155Holder.sol, token/ERC1155/utils/ERC1155Utils.sol, token/ERC1155/IERC1155.sol, utils/Arrays.sol, utils/math/Math.sol. forge-std v1.9.7 archive sha256 45157353ab49eab01d294565866731e599b32401757229689ee459aa26b7ee94 (matches): 19 of its vendored src files differ the same way. For every differing pair, `tr -d ' \\t\\n\\r' < file | sha256sum` is identical on both sides, so the changes are whitespace only.","severity":"low","snippet":"    \"scope\": \"Unmodified transitive Solidity imports used by src/ and test/, plus LICENSE.\"","title":"dependencies.json states the vendored OpenZeppelin and forge-std files are 'Unmodified', but 29 of them are reformatted and do not match the pinned archives byte-for-byte"},{"citation":"resolved","description":"Not a code defect; the brief mandates this hardcoded authority. On Ethereum mainnet today the publisher address carries an EIP-7702 delegation designator (0xef0100 + 0x63c0c19a282a1b52b07dd5a65b58948a07dae32b, the MetaMask EIP7702StatelessDeleGator). Any call that account's code makes, whether from the EOA key, from an ERC-4337 userOp through the EntryPoint, or from a third party redeeming a delegation the publisher signed through the DelegationManager, reaches createIssue and withdraw with msg.sender == PUBLISHER. 'Only the publisher wallet' therefore means 'whatever the publisher's smart-account configuration authorizes'. Mints or transfers to PUBLISHER go through the ERC1155 receiver check because the address has code; the current delegate answers onERC1155Received (audit_permissions verified this by eth_call), so they succeed today, but a later re-delegation to code without that hook would make every mint or safeTransferFrom whose recipient is PUBLISHER revert with ERC1155InvalidReceiver while withdraw keeps working. Record this in the release/operator documentation; no contract change is proposed. (Reported by audit_permissions; reproduced.)","line":14,"path":"src/DailyAuthority.sol","reproduction":"cast code 0x48E4E74fE1d0c14404cEB57B9fec5b21329C6ec9 --rpc-url https://ethereum-rpc.publicnode.com (run 2026-10-21 at the chain head) -> 0xef010063c0c19a282a1b52b07dd5a65b58948a07dae32b. Expected by a plain reading of the brief: a single key is the only authority. Actual: onlyPublisher passes for any call originating from that delegated code, including userOps and redeemed delegations.","severity":"info","snippet":"        if (msg.sender != PUBLISHER) revert OnlyPublisher();","title":"Trust assumption: the hardcoded publisher is an EIP-7702 delegated MetaMask smart account, so onlyPublisher admits every execution path that account's code authorizes"},{"citation":"resolved","description":"Inherent to the requested economics (fixed price, proceeds to the publisher's own vault). 'No free/owner minting' holds in form only: the publisher can grow any open issue's supply for gas alone because every 0.1 IMD it pays is immediately withdrawable by the same account, and such mints increase totalSupply(id) and totalCollected exactly like collector purchases. Not fixable without changing the agreed design; the website's revenue dashboard should subtract CopiesMinted events whose payer == PUBLISHER if it wants collector-only revenue. (Reported by audit_permissions; reproduced.)","line":132,"path":"src/IMDDaily.sol","reproduction":"Issue 1 open; PUBLISHER holds 1e18 IMD and approved IMDDaily. PUBLISHER: mint(1, 10, PUBLISHER, block.timestamp) then vault.withdraw(1e18). Expected if the guarantee were economic: supply cannot grow without net payment. Actual: totalSupply(1) == 10, totalCollected == 1e18, PUBLISHER IMD balance back to 1e18. Verified with test/scratch/Judge.t.sol::test_publisherSelfMintIsNetZero.","severity":"info","snippet":"        totalCollected += amount;","title":"Trust assumption: publisher self-mints cost zero IMD net (pays its own vault, withdraws it back) and are counted in totalCollected as mint revenue"},{"citation":"resolved","description":"Per-ID immutability and the 86400-second window hold, but createIssue does not reject pdfHash/coverHash/metadataHash values already committed by an earlier issue. After issue N closes the publisher can publish identical content as issue N+1 and sell it again, which is an economic reopening at the content level while 'supply can never increase after expiry' stays true at the ID level. The brief defines issues by sequential ID and leaves editorial decisions to the publisher, so this is a documented power rather than a defect; rejecting duplicate pdfHash values would also block a legitimately corrected re-issue of the same PDF, so it is a scope decision for the requester. (Reported by audit_permissions; reproduced.)","line":98,"path":"src/IMDDaily.sol","reproduction":"Issue 1 published at T with hashes H. Warp to T+86400: alice mint(1, 1, alice, now) -> reverts MintClosed(1). PUBLISHER createIssue(same eight fields including H) -> returns 2; isAvailable(2) == true; alice mint(2, 1, alice, now) succeeds; totalSupply(2) == 1, totalSupply(1) unchanged. Verified with test/scratch/Judge.t.sol::test_identicalContentRepublishedAfterExpiry.","severity":"info","snippet":"        id = ++issueCount;","title":"Trust assumption: no uniqueness check on content hashes, so an expired issue's exact files can be republished under a new sequential ID with a fresh 24-hour window"},{"citation":"resolved","description":"The pinned payment token is a LayerZero OFT with an active owner (owner() == 0x047F606fD5b2BaA5f5C6c4aB8958E45CB6B054B7) and owner-only updateSymbol (selector 0x537f5312 present in the runtime recorded in evidence/imd-mainnet.json). It has no proxy slots, pause, blacklist or transfer hooks, so mint and withdraw (SafeERC20 plus exact before/after balance checks) are sound against it and decimals() is fixed at 18. The single consequence inside this repository is test fragility: if the owner renames the token, every test in the 28-test fork suite fails in setUp at this line even though IMDDaily and IMDDailyVault are unaffected. Suggested: drop or soften the symbol assertion (decimals and code presence are the checks that matter). Also a documented trust assumption: the token owner and its LayerZero peers can mint IMD on Ethereum outside this project's control. (Reported by audit_flow; reproduced.)","line":18,"path":"test/IMDDailyFork.t.sol","reproduction":"cast call 0xD34a99Bc0f67aE1bbd63C660e6d0b0dd03E263B7 'owner()(address)' --rpc-url https://ethereum-rpc.publicnode.com -> 0x047F606fD5b2BaA5f5C6c4aB8958E45CB6B054B7; evidence/imd-mainnet.json runtime_code contains selector 537f5312 (updateSymbol(string)). Precondition for the failure: that owner calls updateSymbol(\"IMDX\"). Then `forge test --match-contract IMDDailyForkTest --fork-url <mainnet rpc>` at a later block: expected 28 passes (contracts unchanged), actual 28 failures in setUp. Today (2026-10-21, chain head) the suite passes: 28 passed, 0 failed.","severity":"info","snippet":"        assertEq(IERC20Metadata(IMD).symbol(), \"IMD\");","title":"Fork suite setUp asserts IMD's symbol, which the IMD token owner can change; the contracts themselves do not depend on it"}],"hash":"41b00719a3fda268948870997c4f93a802fe90a04305da723b2087463911fd09","nodeId":"21b4b71e-bb83-4dff-9e58-9be5e95b1dc0","outcome":"completed","summary":"The review is complete and the findings file is written. The working tree is otherwise clean.\n\n**Outcome.** No critical, high or medium defect in the two contracts. Every state-changing entry point holds. The six findings kept are two low provenance and usability issues plus four documented trust assumptions, all reproduced against the code.\n\n**What I verified myself**\n\n- Build and the full local suite pass (60 tests, two invariant suites with fail-on-revert).\n- The fork suite against real mainnet IMD at today's chain head passes all 28 tests.\n- The manifest in the tree is schema-valid, orders the vault before the collection, and passes the backward reference correctly. Both runtimes are well within EIP-170 and EIP-3860 limits with no forbidden opcodes.\n- The aderyn reentrancy lead and the slither timestamp leads do not reproduce as defects. Mint settles payment and counters before the receiver callback under a reentrancy guard, and the timestamp window is the brief's design.\n\n**Findings kept, in order**\n\n1. Low. IMD sent directly to the collection contract is stranded forever. Four specialists reported this; merged into one. Reproduced with a scratch test.\n2. Low. The dependency record claims the vendored OpenZeppelin and forge-std files are unmodified, but 29 of them were reformatted. I downloaded both pinned archives, confirmed their hashes, and showed every difference is whitespace only.\n3. Info. The hardcoded publisher is an EIP-7702 delegated MetaMask smart account. Confirmed with a live code read.\n4. Info. Publisher self-mints are net zero in IMD and counted as revenue. Reproduced.\n5. Info. Identical content can be republished under a new ID after expiry. Reproduced.\n6. Info. The fork suite asserts the IMD symbol, which the token owner can change. Confirmed the owner and the rename selector.\n\n**Dropped.** The wrong-vault-argument hazard, because the manifest in the tree is correct. The fork-suite opt-in skip, because that is the right behavior for the offline verifier.\n\n**Remaining release blockers** are unchanged from the evidence file: source publication, mainnet factory deployment and Etherscan verification have not happened. The release status file states this plainly and separates fork results from real deployment.","treeHash":null,"usage":{"cachedInputTokens":860468,"inputTokens":354,"model":"claude-fable-5-1","outputTokens":20651,"runtime":"claude","turns":27,"wallClockMs":293721}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"2c968e88904ec22b","findings":[{"citation":"resolved","description":"The integration flow tells collectors to approve the collection address (not the vault), so a collector who confuses approve with transfer, or any wallet UI that pre-sends tokens, will push IMD straight to IMDDaily. IMDDaily has no function that can move an ERC20 balance it holds: mint only pulls msg.sender's allowance into the vault, and IMDDailyVault.withdraw only reads the vault's own balance. The publisher's sole payout path therefore never reaches those tokens and they are lost for everyone. README.md line 70 documents this as a known limitation, but the brief's constraint is only that no destination other than the publisher-owned vault may receive funds; a permissionless sweep that moves IMDDaily's IMD balance into the vault (without touching totalCollected, so it is treated as a donation) satisfies that constraint and removes the stranding path. Impact is limited to the sender's own mistake (self-inflicted loss), hence low; it is reported because it is the single value-stranding path in the system and the fix is small and in scope. Invariant violated: 'every IMD held by project contracts is withdrawable by the publisher'. Minimal fix: add `function sweepToVault() external nonReentrant { IERC20 t = IERC20(PAYMENT_TOKEN); uint256 b = t.balanceOf(address(this)); if (b == 0) revert ZeroAmount(); t.safeTransfer(address(vault), b); emit Swept(b); }` with no revenue accounting change.","line":15,"path":"src/IMDDaily.sol","reproduction":"State: IMDDailyVault and IMDDaily(vault) deployed, issue 1 published, alice holds 100 IMD. Calls: (1) alice: IMD.transfer(address(daily), 1e18). (2) publisher: vault.withdraw(1) -> reverts InsufficientFunds(0, 1) because the vault balance is 0. (3) alice: daily.mint(1, 1, alice, block.timestamp) succeeds; daily.totalCollected() == 1e17, IMD.balanceOf(address(daily)) is still 1e18 and no ABI function of IMDDaily (checked all 28 functions in abi/IMDDaily.json) can move it. Expected: the 1e18 IMD reaches the vault or is otherwise recoverable by the publisher. Actual: permanently locked in IMDDaily. Verified with a scratch Foundry test (test_imdSentToCollectionIsStranded) using an OpenZeppelin ERC20 etched at the IMD address.","severity":"low","snippet":"contract IMDDaily is ERC1155Supply, DailyAuthority, ReentrancyGuard {","title":"IMD transferred directly to the collection contract is permanently stranded; no in-spec sweep to the vault exists"}],"hash":"5070d048cacbc57d085e34ed1ad1c5bc83108c9db61db5d677ecf1283e22ce4e","nodeId":"15cc9e9d-dc5c-4eae-92b5-fd219b3776d8","outcome":"completed","summary":"The review is complete. The findings file is at the repository root and the working tree is otherwise unchanged.\n\n**Result: no critical, high or medium defects in the assigned economic area. One low finding.**\n\nWhat I checked, against the Economic Security, Invariant and Flow Gap guides:\n\n- **Value flows.** Mint pulls exactly `quantity * 0.1 IMD` from the caller into the vault with checked multiplication, verifies the exact vault credit and payer debit, and rolls back payment, counters and supply together on any failure. Withdrawal goes only to the hardcoded publisher, supports partial amounts, and rolls back its counter on failure.\n- **Invariants.** Collected revenue always equals total supply times price, and vault balance plus withdrawals always equals revenue plus donations. The existing invariant campaign and my own probes could not break either. Supply freezes at the closing timestamp, and no selector can reopen, extend, reprice or free-mint.\n- **Flow gaps.** Receiver callbacks run after payment settles and cannot re-enter mint or publish. A publisher smart wallet can withdraw inside its own receive hook, and a rejected mint undoes that withdrawal. A donation made mid-callback leaves counters honest. Copies cannot be sent to the collection, vault or token address.\n- **Token dependency.** I ran the fork suite myself against real mainnet IMD at the pinned block, and all 28 tests pass. The token is a LayerZero OFT with plain OpenZeppelin transfer semantics, hardcoded 18 decimals, and no fee, pause or blacklist. The residual trust is the token owner's peer configuration, which affects IMD's value rather than these contracts' accounting.\n\n**The one finding (low):** IMD transferred directly to the collection contract is stranded forever. Nothing in the collection's ABI can move it, and the vault only reads its own balance. It is self-inflicted and documented in the README, but the integration guide steers users to the collection address for approvals, which makes the approve-versus-transfer mistake plausible. A permissionless sweep from the collection to the vault, with no revenue accounting, would fix it within the brief's single-payout-destination rule.\n\nCoverage: all six listed entry points hold, plus five invariant and dependency rows, with the stranding invariant pointing at the finding. Nothing in my area was left unreached.","treeHash":null,"usage":{"cachedInputTokens":1129024,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":30759,"runtime":"claude","turns":42,"wallClockMs":448810}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"1c29c7c6e4cf57eb","findings":[{"citation":"resolved","description":"Collectors approve the collection address (not the vault) for IMD, so the collection is the address most likely to receive a mistaken direct IMD transfer. IMDDaily has no ERC20 rescue/forward path and the vault can only spend its own balance, so any IMD whose recipient is the collection is locked forever. It is not counted in totalCollected (correct), but it also never reaches the publisher, contradicting the brief's design that all IMD received is withdrawable by the publisher from a distinct vault. The vault path for donations works; only the collection-address path is a dead end. No mint-revenue math is affected.","line":15,"path":"src/IMDDaily.sol","reproduction":"Local mock IMD etched at 0xD34a...63B7. alice holds 10e18 IMD. alice calls IMD.transfer(address(daily), 1e18). Expected: funds reachable by the publisher (forwarded to vault or rescuable by PUBLISHER only, to PUBLISHER only). Actual: IMD.balanceOf(daily) == 1e18 permanently; IMDDaily exposes no function that moves ERC20; PUBLISHER calling vault.withdraw(1e18) reverts InsufficientFunds(0, 1e18). Verified with a scratch Foundry test (passes: balance stuck, withdraw reverts). Minimal fix: a publisher-only `sweepToVault()` on IMDDaily that transfers IMD.balanceOf(this) to the fixed vault without touching totalCollected.","severity":"low","snippet":"contract IMDDaily is ERC1155Supply, DailyAuthority, ReentrancyGuard {","title":"IMD sent directly to the IMDDaily collection contract is permanently unrecoverable"}],"hash":"6ebc52c6ef3803dbc7ed12e26256b789bd54b031cf44a2f0e09dc52ca4671ba3","nodeId":"fe74e90e-180c-41f9-88d9-81227fd0e534","outcome":"completed","summary":"I found no math defects in my area, and one low-severity custody issue outside it. The results are in `.imd-findings.json` at the repo root, with a coverage row for each of the six entry points (all `holds`) plus two invariant rows. The local suite passes (43 passed, 1 skipped); I ran the fork tests only through their saved output, not against the live chain.\n\n**What I checked (Math Precision, Boundary and Numerical Gap):**\n- **Price:** `PRICE = 1e17` is exactly 0.1 IMD at 18 decimals. The saved onchain evidence shows decimals is 18 (`0x12`), and `mint` re-checks it every time. There is no division, so nothing rounds or loses precision.\n- **Cost calculation:** `quantity * PRICE` uses Solidity's overflow-checked multiplication, so an oversized quantity reverts instead of wrapping. Zero quantity is rejected in both `mint` and `quote`.\n- **Mint window:** I tested the boundary in a temporary Foundry test. A mint at publication time + 86399 seconds succeeds and one at + 86400 reverts with `MintClosed`. A mint in the same block as publication is allowed, and the editorial date has no effect on eligibility.\n- **Deadline:** it is inclusive (a mint whose deadline equals the current time succeeds). It is checked separately from the window, so it can't extend it.\n- **Payment and withdrawal checks:**\n  - `mint` compares the vault's and the payer's IMD balances before and after the transfer.\n  - `withdraw` does the same for the vault and the publisher.\n  - Zero and over-balance withdrawals revert before any funds move.\n  - Partial withdrawal works.\n- **Counters:** vault balance + `totalWithdrawn` = `totalCollected` + donations to the vault. `totalWithdrawn` can exceed `totalCollected` once donations are withdrawn; the README documents this as intended, so I didn't report it.\n- **Supply:** an issue's supply can't grow after its window closes. Transfers don't change supply, and real IMD supply rules out overflow.\n- **Static-analysis leads:**\n  - Slither's two timestamp warnings are the required time window, not defects.\n  - Aderyn's \"reentrancy\" high is a false positive: its only external calls before state changes are reads to the fixed IMD token and the vault, and `mint` is `nonReentrant`.\n\n**Finding (low):** IMD sent directly to the `IMDDaily` collection contract is locked forever. Collectors approve the collection, not the vault, so that's the address a mistaken transfer is most likely to hit. The collection has no function that moves IMD, and the publisher's `vault.withdraw` can't reach it (it reverts with `InsufficientFunds(0, 1e18)`). My temporary test confirmed this. A suggested fix is a publisher-only function that forwards the collection's IMD balance to the vault without counting it in `totalCollected`. I didn't attach a proof test because the format asks for those only on critical and high findings.\n\nI deleted the temporary test afterwards; apart from `.imd-findings.json`, I changed no files.","treeHash":null,"usage":{"cachedInputTokens":614205,"inputTokens":24,"model":"claude-opus-5-5","outputTokens":10779,"runtime":"claude","turns":12,"wallClockMs":138237}},{"artifacts":[],"attempt":1,"bundleHash":"fb0debe3981a767097cf561c81d678751dc3a4b59340be658f802f56590cdacc","device":"98b4506bef931d13","findings":[],"hash":"8890803e92c401ae93cc97ba33a2151e441705a0bb52bad46b553739b4d77580","nodeId":"55490bd5-739f-4a31-884f-034cf5463db1","outcome":"completed","summary":"`launch.json` is written and is the only changed path in the tree.\n\n**What the manifest declares**\n\n- `IMDDailyVault` first, with an empty constructor argument list. The compiled ABI confirms it has no constructor parameters.\n- `IMDDaily` second, with the single address argument `$contract:IMDDailyVault`. The compiled ABI confirms one parameter, `address vault_`.\n- No owner argument appears because both contracts inherit a fixed authority. The publisher wallet from the brief and the existing IMD token are hardcoded constants, so neither the factory nor the launch wallet can hold any role.\n- The notes field explains the collection, the fixed publisher and payment token, the 0.1 IMD price, the 24-hour window, the vault custody rules, and the empty-chain-safe constructor. It is well under the 4000 character limit.\n\n**Checks run**\n\n- A schema check on the file passed: only the keys kind, contracts and notes, string arguments, unique identifiers under 32 characters, and a backward-only contract reference.\n- A clean offline build and the full test suite passed with the verifier's fuzz seed and an empty environment. The one skipped test is the mainnet fork suite, which skips itself by design when no fork is configured.\n- The repository's own deployment rehearsal already exercises this exact two-step CREATE2 order from a single factory call and passed.\n\n**Release status, unchanged by this task**\n\nThe contracts remain implemented and locally tested but not deployed. Source publication, attestation, review, factory deployment and Etherscan verification are later stages of the launch workflow, as the repository's release document already records.","treeHash":"9a784853059e7d0a84942d478722606dcf9bc309","usage":{"cachedInputTokens":301475,"inputTokens":194,"model":"claude-fable-5-1","outputTokens":4837,"runtime":"claude","turns":14,"wallClockMs":84452}},{"artifacts":[],"attempt":1,"bundleHash":"a45643df2280b889074605b73385f982e25bbb300e39b32a0fbf473d7dec0171","device":"a5c5e95a2ed07117","findings":[{"description":"Mint proceeds go to IMDDailyVault, and the vault lets the publisher withdraw donations too. But IMDDaily has no function that moves IMD it holds. A collector who sends IMD to the collection address by mistake (for example to the address they just approved) locks those tokens forever. They are correctly excluded from totalCollected, as the brief requires, but neither the publisher nor the sender can recover them. Possible fixes that keep the agreed design: a publisher-only sweep on IMDDaily that sends IMD only to the vault (never another destination, and not counted as revenue), or documenting in INTEGRATION.md that the collection address must never receive IMD directly.","line":15,"path":"src/IMDDaily.sol","reproduction":"Local mock (test/IMDDailyEdges.t.sol::test_imdSentToCollectionIsNotRevenueOrVaultBalance): bob calls IMD.transfer(address(daily), 3e17). Expected: the publisher can move it to the vault, or the deposit is refused. Actual: IMD.balanceOf(daily) == 3e17 for good. No selector on IMDDaily transfers ERC20, and the vault's withdraw only reads the vault's own balance. totalCollected stays correct (2e17 after a 2-copy mint).","severity":"low","title":"IMD transferred directly to the IMDDaily collection contract is permanently unrecoverable"},{"description":"IMDDailyForkTest skips itself when no fork is active. That is right for the offline verifier, but it means the default run never exercises real IMD. The suite was run during this task with `forge test --match-path test/IMDDailyFork.t.sol --fork-url https://ethereum-rpc.publicnode.com` at the then-current mainnet head: 28 passed, 0 failed. These are fork simulations only, not deployment evidence.","line":11,"path":"test/IMDDailyFork.t.sol","reproduction":"Run `forge test` without --fork-url: IMDDailyForkTest reports 1 skipped. Run it with a mainnet --fork-url: 28 pass.","severity":"info","title":"Real-IMD fork suite is opt-in and skipped in the default `forge test` run"}],"hash":"de8c5afd7843c94e5fed2eacf56e4549c5444b2e13b11b8a800dc34d9dd87fbe","nodeId":"ea0cac18-d6d5-446e-8786-5bd6e3421a95","outcome":"completed","summary":"I added two test files to the existing suite. `forge build` succeeds and `forge test` with the verifier's seed gives 60 passed, 0 failed, 1 skipped. The skip is the real-IMD fork suite, which only runs when you pass a fork URL.\n\n**New tests**\n- **`test/IMDDailyEdges.t.sol`** (16 tests, mostly failure paths):\n  - **Mint window:** at any publication time, minting works one second before close and is refused at close, a day later, and ten years later.\n  - **Caller deadline:** it counts up to and including the stated second, and it can never extend the 24-hour window.\n  - **Funds:** a buyer one wei short on either balance or allowance is refused, and exact funds succeed. The largest quantity that doesn't overflow fails for lack of funds, and one more fails on the overflow.\n  - **Withdrawals:** exactly the balance works, one wei more is refused, and a split withdrawal works.\n  - **Authority:** only the publisher can publish or withdraw. Any other address is refused, including whoever deployed the contracts and the transaction sender.\n  - **Other cases:** paying requires approving the collection (approving the vault isn't enough). Copies can't be sent to the vault, the collection or the zero address. No burn or free-mint function exists. Issues published in the same block get sequential IDs in their events, and a later issue never reopens an earlier one.\n- **`test/DailyModelInvariant.t.sol`**: an invariant suite that makes random sequences of publish, fund, mint, time-jump, transfer, donate and withdraw calls. Many calls are deliberately invalid: unknown IDs, zero quantity, a zero, rejecting or re-entering recipient, a past deadline, not enough funds, or a caller who isn't the publisher. For each call it predicts from the brief whether it should succeed and checks the contract agrees. A failed call must not move any funds.\n  - **Invariants checked after every call:** the vault holds exactly revenue plus donations minus withdrawals. Only the publisher ever receives IMD. Buyers lose exactly what they paid. Supply, publication times and closing times match the model.\n  - It ran 256 sequences of 64 calls. My first version almost never minted successfully, so the test would have passed while checking nothing. I adjusted it and confirmed that successful mints now happen in every campaign.\n\n**Fork run:** I ran the existing fork suite against Ethereum mainnet via `https://ethereum-rpc.publicnode.com`, and all 28 tests passed against the real IMD token. This was a local simulation only. Nothing was deployed or broadcast, and it is not deployment evidence.\n\n**Findings** (in `.imd-findings.json`)\n- **Low:** IMD sent straight to the collection contract, instead of the vault, is locked forever. It is correctly left out of revenue, but nobody can recover it. Possible fixes are a publisher-only sweep that sends only to the vault, or a clear warning in the integration guide. My tests check that this IMD isn't counted as revenue; they don't treat the lock as correct.\n- **Info:** the default `forge test` run never touches real IMD, because the fork suite skips itself offline.\n\nI found no defects in minting, payment, access control or the mint window. I haven't committed anything.","treeHash":"c005e47fd9454d368b01d2f936a5d506d939ffe6","usage":{"cachedInputTokens":2893442,"inputTokens":68,"model":"claude-opus-5-5","outputTokens":42255,"runtime":"claude","turns":35,"wallClockMs":714039}},{"artifacts":[],"attempt":1,"bundleHash":"0b4f79a67c13178aa2c26b6f9972a588e171b791c5b5651a84d1c47142f725a7","device":"c0e6ac7ffff8e2ca","findings":[],"hash":"f1313384c98108e81ed01d61bcc8d0d3d9a891d577ff85e3e151a462f96422d5","nodeId":"68658f28-6dec-4a4e-9aa8-ac267de0c2b1","outcome":"completed","summary":"Implemented the collection and vault, tests, vendored dependencies, ABIs, and integration documentation.\n\n- `forge build`, `forge test`, and `forge fmt --check` pass.\n- 43 local checks and 28 Ethereum-fork tests pass.\n- IMD’s 18 decimals were verified onchain.\n\n**Mainnet deployment, GitHub publication, source-commit pinning, independent review, and Etherscan verification remain pending network release steps.** No live issues or purchases were created.\n\nSee [README](README.md) and [release handoff](docs/RELEASE.md).","treeHash":"deba6003b00dac21bc46eac89d00b244abce8642","usage":{"cachedInputTokens":2388864,"inputTokens":119778,"model":"gpt-6-astra","outputTokens":49180,"runtime":"codex","turns":8,"wallClockMs":1583532}}],"verification":[{"checks":[{"durationMs":2830,"exitCode":0,"name":"build","output":"Compiling 55 files with Solc 0.8.26\nSolc 0.8.26 finished in 2.75s\nCompiler run successful!\n","passed":true},{"durationMs":2729,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/IMDDailyFork.t.sol:IMDDailyForkTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 511.09µs (0.00ns CPU time)\n\nRan 39 tests for test/IMDDaily.t.sol:IMDDailyTest\n[PASS] testFuzz_paymentArithmeticAndRepeatMints(uint256,uint256) (runs: 256, μ: 741972, ~: 742329)\nLogs:\n  Bound result 4756\n  Bound result 3919\n\n[PASS] testFuzz_quoteOverflow(uint256) (runs: 256, μ: 13023, ~: 13134)\nLogs:\n  Bound result 115792089237316194265650092635525953617560134578761485506757737351507489245366\n\n[PASS] testFuzz_windowIndependentOfEditorialDate(uint256,uint32) (runs: 256, μ: 586095, ~: 633150)\n[PASS] test_beforeStartIsRejected() (gas: 460584)\n[PASS] test_bubbledReceiverReentrancyRollsBackAll() (gas: 2167796)\n[PASS] test_donationsAndPartialWithdrawalHaveHonestCounters() (gas: 887904)\n[PASS] test_falseReturnPaymentRollsBackEvenAfterTokenMoved() (gas: 624381)\n[PASS] test_initialConfigurationAndZeroSupply() (gas: 184434)\n[PASS] test_insufficientBalanceAndAllowanceRollback() (gas: 751303)\n[PASS] test_invalidPublicationDoesNotConsumeAnID() (gas: 770206)\n[PASS] test_issuesHaveIndependentWindowsAndMetadata() (gas: 1305311)\n[PASS] test_mintEventIsIndexedAndAmountIsExact() (gas: 605270)\n[PASS] test_missingOrMismatchedVaultFailsAtUse() (gas: 1000651)\n[PASS] test_nativeETHRejectedByEveryEntryPoint() (gas: 596746)\n[PASS] test_noMutationUpgradeFreeMintOrReopenSelectors() (gas: 739816)\n[PASS] test_noReturnTokenIsSupportedForPaymentAndWithdrawal() (gas: 780136)\n[PASS] test_noTokenCodeFailsClosed() (gas: 466400)\n[PASS] test_nonexistentIDsRejectedAndAvailabilityFalse() (gas: 174016)\n[PASS] test_paymentFailureModesAreAtomic() (gas: 1245999)\n[PASS] test_paymentTokenCallbackCannotReenterMint() (gas: 857141)\n[PASS] test_publicationCommitsEveryFieldWithoutMinting() (gas: 570016)\n[PASS] test_publisherAlsoPaysFullPriceAndCannotMintExpiredIssues() (gas: 982997)\n[PASS] test_receiverCannotReenterMintAndObservesSettledState() (gas: 2161480)\n[PASS] test_receiverCannotWithdrawOrPublish() (gas: 2572370)\n[PASS] test_receiverMayTransferItsFullyPaidCopies() (gas: 1912170)\n[PASS] test_receiverRejectionRollsBackPaymentAllowanceSupplyAndCounters() (gas: 2154848)\n[PASS] test_rejectedMintAlsoRollsBackPublisherWithdrawalInCallback() (gas: 2107961)\n[PASS] test_repeatedMultiCopyMintsAndGift() (gas: 905222)\n[PASS] test_transfersAndBatchTransfersAfterExpiryPreserveSupply() (gas: 1417490)\n[PASS] test_unauthorizedPublicationAndWithdrawal() (gas: 691312)\n[PASS] test_vaultHasNoAlternativeRecipientOrAuthoritySetter() (gas: 166225)\n[PASS] test_windowStartsAtPublicationAndClosesExactly() (gas: 822795)\n[PASS] test_withdrawalFailureModesRollbackCountersAndBalances() (gas: 1401328)\n[PASS] test_withdrawalTokenCallbackCannotReenter() (gas: 868876)\n[PASS] test_wrongDecimalsFailBeforeTakingPayment() (gas: 520491)\n[PASS] test_wrongReceiverSelectorAndNonReceiverRevert() (gas: 2067658)\n[PASS] test_zeroAndExcessWithdrawalRevert() (gas: 74523)\n[PASS] test_zeroQuantityZeroRecipientOverflowAndDeadline() (gas: 741927)\n[PASS] test_zeroQuoteRejected() (gas: 8476)\nSuite result: ok. 39 passed; 0 failed; 0 skipped; finished in 22.67ms (66.01ms CPU time)\n\nRan 3 tests for test/Deployment.t.sol:DeploymentTest\n[PASS] test_constructorAcceptsStaticDependencyBeforeCodeExists() (gas: 17974)\n[PASS] test_constructorRejectsInvalidVaultAddresses() (gas: 3806)\n[PASS] test_factoryDeploymentOnEmptyChainNeedsNoExternalContractOrSetup() (gas: 17435464)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 25.65ms (25.97ms CPU time)\n\nRan 1 test for test/DailyInvariant.t.sol:DailyInvariantTest\n[PASS]\nDailyInvariantTest invariants:\n[PASS] invariant_conservationOfPaymentsDonationsAndWithdrawals\n[PASS] invariant_supplyOwnershipExpiryAndContentArePermanent\n DailyInvariantTest invariants (runs: 128, calls: 6144, reverts: 0)\n\n╭--------------+----------------+-------+---------+----------╮\n| Contract     | Selector       | Calls | Reverts | Discards |\n+============================================================+\n| DailyHandler | advance        | 838   | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| DailyHandler | buy            | 857   | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| DailyHandler | donate         | 908   | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| DailyHandler | publish        | 922   | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| DailyHandler | transferCopies | 869   | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| DailyHandler | tryExpiredMint | 866   | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| DailyHandler | withdraw       | 884   | 0       | 0        |\n╰--------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1\n  Bound result 6998\n  Bound result 1\n  Bound result 253\n  Bound result 1\n  Bound result 86399\n  Bound result 2\n  Bound result 2\n  Bound result 65280\n  Bound result 2\n  Bound result 4180\n  Bound result 2\n  Bound result 4014260849\n  Bound result 3\n  Bound result 8305\n  Bound result 2353\n  Bound result 7527\n  Bound result 2308\n  Bound result 254\n  Bound result 2\n  Bound result 2\n  Bound result 2\n  Bound result 4\n  Bound result 8256\n  Bound result 44428546790205402805\n  Bound result 4\n  Bound result 100000000000000000000\n  Bound result 4\n  Bound result 6\n  Bound result 243872796\n  Bound result 7\n  Bound result 7\n  Bound result 7373\n  Bound result 2\n  Bound result 4316\n  Bound result 1\n  Bound result 4161\n  Bound result 6\n  Bound result 79083\n  Bound result 8813181004765022129\n  Bound result 13\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.65s (2.64s CPU time)\n\nRan 4 test suites in 2.65s (2.69s CPU time): 43 tests passed, 0 failed, 1 skipped (44 total tests)\n","passed":true},{"durationMs":55,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"IMDDaily.createIssue((string,uint256,string,string,string,bytes32,bytes32,bytes32))\",\"IMDDaily.mint(uint256,uint256,address,uint256)\",\"IMDDaily.safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\",\"IMDDaily.safeTransferFrom(address,address,uint256,uint256,bytes)\",\"IMDDaily.setApprovalForAll(address,bool)\",\"IMDDailyVault.withdraw(uint256)\"],\"files\":{\".gitignore\":5,\"LICENSE\":21,\"README.md\":71,\"abi/IMD-payment.json\":224,\"abi/IMDDaily.json\":1054,\"abi/IMDDailyVault.json\":165,\"dependencies.json\":20,\"docs/INTEGRATION.md\":158,\"docs/RELEASE.md\":67,\"docs/SECURITY_REVIEW.md\":47,\"docs/metadata.schema.json\":39,\"evidence/build.json\":123,\"evidence/build.txt\":88,\"evidence/checks.json\":201,\"evidence/coverage.txt\":107,\"evidence/fork-tests.txt\":34,\"evidence/imd-mainnet.json\":18,\"evidence/local-tests.txt\":82,\"evidence/release-status.json\":26,\"foundry.toml\":23,\"launch.json\":16,\"remappings.txt\":3,\"scripts/export_artifacts.py\":77,\"src/DailyAuthority.sol\":23,\"src/IMDDaily.sol\":184,\"src/IMDDailyVault.sol\":46,\"test/DailyBehavior.sol\":590,\"test/DailyInvariant.t.sol\":164,\"test/Deployment.t.sol\":89,\"test/IMDDaily.t.sol\":161,\"test/IMDDailyFork.t.sol\":20,\"test/helpers/MockIMD.sol\":82,\"test/helpers/Receiver.sol\":78},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"8890803e92c401ae93cc97ba33a2151e441705a0bb52bad46b553739b4d77580","verifiedTreeHash":"9a784853059e7d0a84942d478722606dcf9bc309","verifierVersion":"0.1.0+560ab6a2"},{"checks":[{"durationMs":3767,"exitCode":0,"name":"build","output":"Compiling 57 files with Solc 0.8.26\nSolc 0.8.26 finished in 3.68s\nCompiler run successful!\n","passed":true},{"durationMs":6392,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/IMDDailyFork.t.sol:IMDDailyForkTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 505.20µs (0.00ns CPU time)\n\nRan 39 tests for test/IMDDaily.t.sol:IMDDailyTest\n[PASS] testFuzz_paymentArithmeticAndRepeatMints(uint256,uint256) (runs: 256, μ: 741992, ~: 742329)\nLogs:\n  Bound result 4756\n  Bound result 3919\n\n[PASS] testFuzz_quoteOverflow(uint256) (runs: 256, μ: 13024, ~: 13134)\nLogs:\n  Bound result 115792089237316194265650092635525953617560134578761485506771990009960062150459\n\n[PASS] testFuzz_windowIndependentOfEditorialDate(uint256,uint32) (runs: 256, μ: 587842, ~: 633162)\n[PASS] test_beforeStartIsRejected() (gas: 460584)\n[PASS] test_bubbledReceiverReentrancyRollsBackAll() (gas: 2167796)\n[PASS] test_donationsAndPartialWithdrawalHaveHonestCounters() (gas: 887904)\n[PASS] test_falseReturnPaymentRollsBackEvenAfterTokenMoved() (gas: 624381)\n[PASS] test_initialConfigurationAndZeroSupply() (gas: 184434)\n[PASS] test_insufficientBalanceAndAllowanceRollback() (gas: 751303)\n[PASS] test_invalidPublicationDoesNotConsumeAnID() (gas: 770206)\n[PASS] test_issuesHaveIndependentWindowsAndMetadata() (gas: 1305311)\n[PASS] test_mintEventIsIndexedAndAmountIsExact() (gas: 605270)\n[PASS] test_missingOrMismatchedVaultFailsAtUse() (gas: 1000651)\n[PASS] test_nativeETHRejectedByEveryEntryPoint() (gas: 596746)\n[PASS] test_noMutationUpgradeFreeMintOrReopenSelectors() (gas: 739816)\n[PASS] test_noReturnTokenIsSupportedForPaymentAndWithdrawal() (gas: 780136)\n[PASS] test_noTokenCodeFailsClosed() (gas: 466400)\n[PASS] test_nonexistentIDsRejectedAndAvailabilityFalse() (gas: 174016)\n[PASS] test_paymentFailureModesAreAtomic() (gas: 1245999)\n[PASS] test_paymentTokenCallbackCannotReenterMint() (gas: 857141)\n[PASS] test_publicationCommitsEveryFieldWithoutMinting() (gas: 570016)\n[PASS] test_publisherAlsoPaysFullPriceAndCannotMintExpiredIssues() (gas: 982997)\n[PASS] test_receiverCannotReenterMintAndObservesSettledState() (gas: 2161480)\n[PASS] test_receiverCannotWithdrawOrPublish() (gas: 2572370)\n[PASS] test_receiverMayTransferItsFullyPaidCopies() (gas: 1912170)\n[PASS] test_receiverRejectionRollsBackPaymentAllowanceSupplyAndCounters() (gas: 2154848)\n[PASS] test_rejectedMintAlsoRollsBackPublisherWithdrawalInCallback() (gas: 2107961)\n[PASS] test_repeatedMultiCopyMintsAndGift() (gas: 905222)\n[PASS] test_transfersAndBatchTransfersAfterExpiryPreserveSupply() (gas: 1417490)\n[PASS] test_unauthorizedPublicationAndWithdrawal() (gas: 691312)\n[PASS] test_vaultHasNoAlternativeRecipientOrAuthoritySetter() (gas: 166225)\n[PASS] test_windowStartsAtPublicationAndClosesExactly() (gas: 822795)\n[PASS] test_withdrawalFailureModesRollbackCountersAndBalances() (gas: 1401328)\n[PASS] test_withdrawalTokenCallbackCannotReenter() (gas: 868876)\n[PASS] test_wrongDecimalsFailBeforeTakingPayment() (gas: 520491)\n[PASS] test_wrongReceiverSelectorAndNonReceiverRevert() (gas: 2067658)\n[PASS] test_zeroAndExcessWithdrawalRevert() (gas: 74523)\n[PASS] test_zeroQuantityZeroRecipientOverflowAndDeadline() (gas: 741927)\n[PASS] test_zeroQuoteRejected() (gas: 8476)\nSuite result: ok. 39 passed; 0 failed; 0 skipped; finished in 76.29ms (157.84ms CPU time)\n\nRan 3 tests for test/Deployment.t.sol:DeploymentTest\n[PASS] test_constructorAcceptsStaticDependencyBeforeCodeExists() (gas: 17974)\n[PASS] test_constructorRejectsInvalidVaultAddresses() (gas: 3806)\n[PASS] test_factoryDeploymentOnEmptyChainNeedsNoExternalContractOrSetup() (gas: 17435464)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 76.30ms (56.84ms CPU time)\n\nRan 16 tests for test/IMDDailyEdges.t.sol:IMDDailyEdgesTest\n[PASS] testFuzz_callerDeadlineIsInclusiveAndCannotExtendWindow(uint256,uint256) (runs: 1000, μ: 688771, ~: 624658)\nLogs:\n  Bound result 243\n\n[PASS] testFuzz_exactFundsSucceedAndOneWeiShortFails(uint256,bool) (runs: 1000, μ: 983484, ~: 984926)\nLogs:\n  Bound result 12345\n\n[PASS] testFuzz_onlyPublisherMayPublishOrWithdraw(address) (runs: 500, μ: 829970, ~: 829970)\n[PASS] testFuzz_windowIsExactlyHalfOpenForAnyPublicationTime(uint256,uint256) (runs: 1000, μ: 779213, ~: 835667)\nLogs:\n  Bound result 3532652665370229097\n  Bound result 75828\n\n[PASS] test_copiesCannotBeParkedInVaultOrCollection() (gas: 1018848)\n[PASS] test_deadlineOneSecondBeforeNowRejectedAtNowAccepted() (gas: 773225)\n[PASS] test_factoryOrDeployerGetsNoAuthority() (gas: 824419)\n[PASS] test_holdersCannotBurnOrInflateAfterExpiry() (gas: 930923)\n[PASS] test_imdSentToCollectionIsNotRevenueOrVaultBalance() (gas: 988326)\n[PASS] test_largestNonOverflowingQuantityFailsOnFundsNotArithmetic() (gas: 685028)\n[PASS] test_lastSecondOpenAndClosingSecondShut() (gas: 838688)\n[PASS] test_laterPublicationNeverReopensOrExtendsEarlierIssue() (gas: 1492396)\n[PASS] test_paymentGoesToVaultNotCollectionAndApprovingVaultIsNotEnough() (gas: 866675)\n[PASS] test_publishedContentIsVerbatimIncludingUnicodeAndLongURLs() (gas: 510087)\n[PASS] test_sameBlockPublicationsAreSequentialAndShareOnlyTheirStartTime() (gas: 2129805)\n[PASS] test_withdrawBoundaryExactBalanceAndOneMore() (gas: 955127)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 76.36ms (305.48ms CPU time)\n\nRan 1 test for test/DailyInvariant.t.sol:DailyInvariantTest\n[PASS]\nDailyInvariantTest invariants:\n[PASS] invariant_conservationOfPaymentsDonationsAndWithdrawals\n[PASS] invariant_supplyOwnershipExpiryAndContentArePermanent\n DailyInvariantTest invariants (runs: 128, calls: 6144, reverts: 0)\n\n╭--------------+----------------+-------+---------+----------╮\n| Contract     | Selector       | Calls | Reverts | Discards |\n+============================================================+\n| DailyHandler | advance        | 838   | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| DailyHandler | buy            | 857   | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| DailyHandler | donate         | 908   | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| DailyHandler | publish        | 922   | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| DailyHandler | transferCopies | 869   | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| DailyHandler | tryExpiredMint | 866   | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| DailyHandler | withdraw       | 884   | 0       | 0        |\n╰--------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1\n  Bound result 6998\n  Bound result 1\n  Bound result 11266\n  Bound result 1\n  Bound result 17\n  Bound result 2\n  Bound result 2\n  Bound result 65280\n  Bound result 2\n  Bound result 4180\n  Bound result 2\n  Bound result 4014260849\n  Bound result 2\n  Bound result 8305\n  Bound result 2353\n  Bound result 7528\n  Bound result 2308\n  Bound result 315360000\n  Bound result 3\n  Bound result 2\n  Bound result 1549\n  Bound result 1\n  Bound result 2\n  Bound result 8540\n  Bound result 44428546790205402805\n  Bound result 4\n  Bound result 80\n  Bound result 4\n  Bound result 1\n  Bound result 710221914\n  Bound result 8\n  Bound result 4\n  Bound result 7548\n  Bound result 2\n  Bound result 4316\n  Bound result 5\n  Bound result 4162\n  Bound result 1\n  Bound result 80\n  Bound result 8813181004765022129\n  Bound result 20\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.51s (2.51s CPU time)\n\nRan 1 test for test/DailyModelInvariant.t.sol:DailyModelInvariantTest\n[PASS]\nDailyModelInvariantTest invariants:\n[PASS] invariant_copiesAreHeldOnlyByThoseWhoReceivedThem\n[PASS] invariant_issuesSupplyAndWindowsMatchModel\n[PASS] invariant_payersLoseExactlyWhatTheyPaid\n[PASS] invariant_vaultHoldsExactlyRevenuePlusDonationsMinusWithdrawals\n DailyModelInvariantTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭-------------------+-----------+-------+---------+----------╮\n| Contract          | Selector  | Calls | Reverts | Discards |\n+============================================================+\n| DailyModelHandler | donate    | 2025  | 0       | 0        |\n|-------------------+-----------+-------+---------+----------|\n| DailyModelHandler | fund      | 2078  | 0       | 0        |\n|-------------------+-----------+-------+---------+----------|\n| DailyModelHandler | mint      | 2004  | 0       | 0        |\n|-------------------+-----------+-------+---------+----------|\n| DailyModelHandler | mintBurst | 2022  | 0       | 0        |\n|-------------------+-----------+-------+---------+----------|\n| DailyModelHandler | publish   | 2096  | 0       | 0        |\n|-------------------+-----------+-------+---------+----------|\n| DailyModelHandler | transfer  | 2079  | 0       | 0        |\n|-------------------+-----------+-------+---------+----------|\n| DailyModelHandler | warp      | 2005  | 0       | 0        |\n|-------------------+-----------+-------+---------+----------|\n| DailyModelHandler | withdraw  | 2075  | 0       | 0        |\n╰-------------------+-----------+-------+---------+----------╯\n\nLogs:\n  Bound result 245\n  Bound result 20000\n  Bound result 1\n  Bound result 13\n  Bound result 19107\n  Bound result 21598\n  Bound result 0\n  Bound result 76\n  Bound result 96\n  Bound result 10\n  Bound result 0\n  Bound result 1\n  Bound result 1\n  Bound result 14161386188155214\n  Bound result 905026307631294388228\n  Bound result 2135\n  Bound result 100000000000000000\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 20000\n  Bound result 1345\n  Bound result 57\n  Bound result 13\n  Bound result 2\n  Bound result 70\n  Bound result 11107\n  Bound result 32\n  Bound result 8119\n  Bound result 11\n  Bound result 1\n  Bound result 891\n  Bound result 4890\n  Bound result 1\n  Bound result 84\n  Bound result 4131\n  Bound result 4\n  Bound result 15\n  Bound result 0\n  Bound result 5413\n  Bound result 12777\n  Bound result 2\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 127\n  Bound result 172800\n  Bound result 1850\n  Bound result 3\n  Bound result 14\n  Bound result 5\n  Bound result 0\n  Bound result 596\n  Bound result 1\n  Bound result 0\n  Bound result 7\n  Bound result 710221914\n  Bound result 1417\n  Bound result 1881\n  Bound result 6\n  Bound result 6928\n  Bound result 500000000000000000000\n  Bound result 15\n  Bound result 6993\n  Bound result 3\n  Bound result 0\n  Bound result 2078\n  Bound result 2563708027\n  Bound result 1582\n  Bound result 10238\n  Bound result 1693\n  Bound result 42\n  Bound result 18846\n  Bound result 22\n  Bound result 1257\n  Bound result 556\n  Bound result 11\n  Bound result 4899\n  Bound result 2\n  Bound result 242\n  Bound result 1\n  Bound result 12765\n  Bound result 60\n  Bound result 78\n  Bound result 259200\n  Bound result 551\n  Bound result 1\n  Bound result 44\n  Bound result 78\n  Bound result 50\n  Bound result 13428\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 6.30s (6.30s CPU time)\n\nRan 6 test suites in 6.30s (9.04s CPU time): 60 tests passed, 0 failed, 1 skipped (61 total tests)\n","passed":true},{"durationMs":53,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"IMDDaily.createIssue((string,uint256,string,string,string,bytes32,bytes32,bytes32))\",\"IMDDaily.mint(uint256,uint256,address,uint256)\",\"IMDDaily.safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\",\"IMDDaily.safeTransferFrom(address,address,uint256,uint256,bytes)\",\"IMDDaily.setApprovalForAll(address,bool)\",\"IMDDailyVault.withdraw(uint256)\"],\"files\":{\".gitignore\":5,\"LICENSE\":21,\"README.md\":71,\"abi/IMD-payment.json\":224,\"abi/IMDDaily.json\":1054,\"abi/IMDDailyVault.json\":165,\"dependencies.json\":20,\"docs/INTEGRATION.md\":158,\"docs/RELEASE.md\":67,\"docs/SECURITY_REVIEW.md\":47,\"docs/metadata.schema.json\":39,\"evidence/build.json\":123,\"evidence/build.txt\":88,\"evidence/checks.json\":201,\"evidence/coverage.txt\":107,\"evidence/fork-tests.txt\":34,\"evidence/imd-mainnet.json\":18,\"evidence/local-tests.txt\":82,\"evidence/release-status.json\":26,\"foundry.toml\":23,\"remappings.txt\":3,\"scripts/export_artifacts.py\":77,\"src/DailyAuthority.sol\":23,\"src/IMDDaily.sol\":184,\"src/IMDDailyVault.sol\":46,\"test/DailyBehavior.sol\":590,\"test/DailyInvariant.t.sol\":164,\"test/DailyModelInvariant.t.sol\":349,\"test/Deployment.t.sol\":89,\"test/IMDDaily.t.sol\":161,\"test/IMDDailyEdges.t.sol\":380,\"test/IMDDailyFork.t.sol\":20,\"test/helpers/MockIMD.sol\":82,\"test/helpers/Receiver.sol\":78},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"de8c5afd7843c94e5fed2eacf56e4549c5444b2e13b11b8a800dc34d9dd87fbe","verifiedTreeHash":"c005e47fd9454d368b01d2f936a5d506d939ffe6","verifierVersion":"0.1.0+560ab6a2"},{"checks":[{"durationMs":3280,"exitCode":0,"name":"build","output":"Compiling 55 files with Solc 0.8.26\nSolc 0.8.26 finished in 3.17s\nCompiler run successful!\n","passed":true},{"durationMs":2970,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/IMDDailyFork.t.sol:IMDDailyForkTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 459.12µs (0.00ns CPU time)\n\nRan 39 tests for test/IMDDaily.t.sol:IMDDailyTest\n[PASS] testFuzz_paymentArithmeticAndRepeatMints(uint256,uint256) (runs: 256, μ: 741972, ~: 742329)\nLogs:\n  Bound result 4756\n  Bound result 3919\n\n[PASS] testFuzz_quoteOverflow(uint256) (runs: 256, μ: 13023, ~: 13134)\nLogs:\n  Bound result 115792089237316194265650092635525953617560134578761485506757737351507489245366\n\n[PASS] testFuzz_windowIndependentOfEditorialDate(uint256,uint32) (runs: 256, μ: 586095, ~: 633150)\n[PASS] test_beforeStartIsRejected() (gas: 460584)\n[PASS] test_bubbledReceiverReentrancyRollsBackAll() (gas: 2167796)\n[PASS] test_donationsAndPartialWithdrawalHaveHonestCounters() (gas: 887904)\n[PASS] test_falseReturnPaymentRollsBackEvenAfterTokenMoved() (gas: 624381)\n[PASS] test_initialConfigurationAndZeroSupply() (gas: 184434)\n[PASS] test_insufficientBalanceAndAllowanceRollback() (gas: 751303)\n[PASS] test_invalidPublicationDoesNotConsumeAnID() (gas: 770206)\n[PASS] test_issuesHaveIndependentWindowsAndMetadata() (gas: 1305311)\n[PASS] test_mintEventIsIndexedAndAmountIsExact() (gas: 605270)\n[PASS] test_missingOrMismatchedVaultFailsAtUse() (gas: 1000651)\n[PASS] test_nativeETHRejectedByEveryEntryPoint() (gas: 596746)\n[PASS] test_noMutationUpgradeFreeMintOrReopenSelectors() (gas: 739816)\n[PASS] test_noReturnTokenIsSupportedForPaymentAndWithdrawal() (gas: 780136)\n[PASS] test_noTokenCodeFailsClosed() (gas: 466400)\n[PASS] test_nonexistentIDsRejectedAndAvailabilityFalse() (gas: 174016)\n[PASS] test_paymentFailureModesAreAtomic() (gas: 1245999)\n[PASS] test_paymentTokenCallbackCannotReenterMint() (gas: 857141)\n[PASS] test_publicationCommitsEveryFieldWithoutMinting() (gas: 570016)\n[PASS] test_publisherAlsoPaysFullPriceAndCannotMintExpiredIssues() (gas: 982997)\n[PASS] test_receiverCannotReenterMintAndObservesSettledState() (gas: 2161480)\n[PASS] test_receiverCannotWithdrawOrPublish() (gas: 2572370)\n[PASS] test_receiverMayTransferItsFullyPaidCopies() (gas: 1912170)\n[PASS] test_receiverRejectionRollsBackPaymentAllowanceSupplyAndCounters() (gas: 2154848)\n[PASS] test_rejectedMintAlsoRollsBackPublisherWithdrawalInCallback() (gas: 2107961)\n[PASS] test_repeatedMultiCopyMintsAndGift() (gas: 905222)\n[PASS] test_transfersAndBatchTransfersAfterExpiryPreserveSupply() (gas: 1417490)\n[PASS] test_unauthorizedPublicationAndWithdrawal() (gas: 691312)\n[PASS] test_vaultHasNoAlternativeRecipientOrAuthoritySetter() (gas: 166225)\n[PASS] test_windowStartsAtPublicationAndClosesExactly() (gas: 822795)\n[PASS] test_withdrawalFailureModesRollbackCountersAndBalances() (gas: 1401328)\n[PASS] test_withdrawalTokenCallbackCannotReenter() (gas: 868876)\n[PASS] test_wrongDecimalsFailBeforeTakingPayment() (gas: 520491)\n[PASS] test_wrongReceiverSelectorAndNonReceiverRevert() (gas: 2067658)\n[PASS] test_zeroAndExcessWithdrawalRevert() (gas: 74523)\n[PASS] test_zeroQuantityZeroRecipientOverflowAndDeadline() (gas: 741927)\n[PASS] test_zeroQuoteRejected() (gas: 8476)\nSuite result: ok. 39 passed; 0 failed; 0 skipped; finished in 21.63ms (56.24ms CPU time)\n\nRan 3 tests for test/Deployment.t.sol:DeploymentTest\n[PASS] test_constructorAcceptsStaticDependencyBeforeCodeExists() (gas: 17974)\n[PASS] test_constructorRejectsInvalidVaultAddresses() (gas: 3806)\n[PASS] test_factoryDeploymentOnEmptyChainNeedsNoExternalContractOrSetup() (gas: 17435464)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 26.22ms (26.16ms CPU time)\n\nRan 1 test for test/DailyInvariant.t.sol:DailyInvariantTest\n[PASS]\nDailyInvariantTest invariants:\n[PASS] invariant_conservationOfPaymentsDonationsAndWithdrawals\n[PASS] invariant_supplyOwnershipExpiryAndContentArePermanent\n DailyInvariantTest invariants (runs: 128, calls: 6144, reverts: 0)\n\n╭--------------+----------------+-------+---------+----------╮\n| Contract     | Selector       | Calls | Reverts | Discards |\n+============================================================+\n| DailyHandler | advance        | 838   | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| DailyHandler | buy            | 857   | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| DailyHandler | donate         | 908   | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| DailyHandler | publish        | 922   | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| DailyHandler | transferCopies | 869   | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| DailyHandler | tryExpiredMint | 866   | 0       | 0        |\n|--------------+----------------+-------+---------+----------|\n| DailyHandler | withdraw       | 884   | 0       | 0        |\n╰--------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1\n  Bound result 6998\n  Bound result 1\n  Bound result 253\n  Bound result 1\n  Bound result 86399\n  Bound result 2\n  Bound result 2\n  Bound result 65280\n  Bound result 2\n  Bound result 4180\n  Bound result 2\n  Bound result 4014260849\n  Bound result 3\n  Bound result 8305\n  Bound result 2353\n  Bound result 7527\n  Bound result 2308\n  Bound result 254\n  Bound result 2\n  Bound result 2\n  Bound result 2\n  Bound result 4\n  Bound result 8256\n  Bound result 44428546790205402805\n  Bound result 4\n  Bound result 100000000000000000000\n  Bound result 4\n  Bound result 6\n  Bound result 243872796\n  Bound result 7\n  Bound result 7\n  Bound result 7373\n  Bound result 2\n  Bound result 4316\n  Bound result 1\n  Bound result 4161\n  Bound result 6\n  Bound result 79083\n  Bound result 8813181004765022129\n  Bound result 13\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.86s (2.86s CPU time)\n\nRan 4 test suites in 2.87s (2.91s CPU time): 43 tests passed, 0 failed, 1 skipped (44 total tests)\n","passed":true},{"durationMs":53,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"IMDDaily.createIssue((string,uint256,string,string,string,bytes32,bytes32,bytes32))\",\"IMDDaily.mint(uint256,uint256,address,uint256)\",\"IMDDaily.safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\",\"IMDDaily.safeTransferFrom(address,address,uint256,uint256,bytes)\",\"IMDDaily.setApprovalForAll(address,bool)\",\"IMDDailyVault.withdraw(uint256)\"],\"files\":{\".gitignore\":5,\"LICENSE\":21,\"README.md\":71,\"abi/IMD-payment.json\":224,\"abi/IMDDaily.json\":1054,\"abi/IMDDailyVault.json\":165,\"dependencies.json\":20,\"docs/INTEGRATION.md\":158,\"docs/RELEASE.md\":67,\"docs/SECURITY_REVIEW.md\":47,\"docs/metadata.schema.json\":39,\"evidence/build.json\":123,\"evidence/build.txt\":88,\"evidence/checks.json\":201,\"evidence/coverage.txt\":107,\"evidence/fork-tests.txt\":34,\"evidence/imd-mainnet.json\":18,\"evidence/local-tests.txt\":82,\"evidence/release-status.json\":26,\"foundry.toml\":23,\"remappings.txt\":3,\"scripts/export_artifacts.py\":77,\"src/DailyAuthority.sol\":23,\"src/IMDDaily.sol\":184,\"src/IMDDailyVault.sol\":46,\"test/DailyBehavior.sol\":590,\"test/DailyInvariant.t.sol\":164,\"test/Deployment.t.sol\":89,\"test/IMDDaily.t.sol\":161,\"test/IMDDailyFork.t.sol\":20,\"test/helpers/MockIMD.sol\":82,\"test/helpers/Receiver.sol\":78},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":1992,"exitCode":0,"name":"slither","output":"[low/medium] timestamp at src/IMDDaily.sol:159: IMDDaily.isAvailable(uint256) (src/IMDDaily.sol#159-163) uses timestamp for comparisons\n[low/medium] timestamp at src/IMDDaily.sol:118: IMDDaily.mint(uint256,uint256,address,uint256) (src/IMDDaily.sol#118-143) uses timestamp for comparisons","passed":true},{"durationMs":509,"exitCode":0,"name":"aderyn","output":"[high] reentrancy-state-change at src/IMDDaily.sol:126: Reentrancy: State change after external call (6 places)\n[low] large-numeric-literal at src/IMDDaily.sol:20: Large Numeric Literal\n[low] unused-public-function at src/IMDDailyVault.sol:24: Public Function Not Used Internally","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"f1313384c98108e81ed01d61bcc8d0d3d9a891d577ff85e3e151a462f96422d5","verifiedTreeHash":"deba6003b00dac21bc46eac89d00b244abce8642","verifierVersion":"0.1.0+560ab6a2"}]}