{"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":"68f0feab-995f-4040-bf4f-bb429382962a","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"de444b10eb98f38a630f10e7df6c240f1c8cc0cac25ffe525b4fa79b23a2102d","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":"9f9878691d9e9b9e7af0abbb989601b9ce1111a15ac74b9f1f0a52dded237e29","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":"cf95b6e0dbbbff65f1337b8a7c04746c80f7f1df6baf17db33d26e96c8789b12","dependsOn":["build_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"3014f1ea5961918ca059453a484bf4c8bcbbfc2248dbe31d94ac7c5cdf8f50bd","skillId":"audit-judge","tools":[]},"key":"audit_judge","kind":"code","role":"review","skillHash":"3014f1ea5961918ca059453a484bf4c8bcbbfc2248dbe31d94ac7c5cdf8f50bd","skillId":"audit-judge","state":"accepted"},{"acceptedSubmissionHash":"764a5235cbdb2a5c6dfab2604e7c6b03bb29e1cd6633273ae7f6ee588cd90057","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":"21c29e9b1da1340c07248cb01d7676e6e808d05ac64ddab8633762988c24a444","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":"5fbe3a7ca02369d7b81eb73e326438edd2180f28e1c11092b78a661653d8a5fa","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"587567a5ef71546b5973ceaf6ef1dbbd590f49503b5ac9a6973ed86b89584857","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"587567a5ef71546b5973ceaf6ef1dbbd590f49503b5ac9a6973ed86b89584857","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":"27f7cb5983ff1e2a1c023db0cd406e026ab3c51ddeb591ccf54ae5bb1604247a","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"3c1a8da30d8e6e870827bfe77f2f42b0a5ffc51aff596101e30c7bf3c5c9359e","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","state":"accepted"}],"objective":"Pepeolithic: one ERC-721 contract that sells and gives away 737 pieces of a cave wall painted live by the IMD swarm, paid in ZTO that is sent to the dead address. Deploy on Ethereum mainnet (chain id 1). Nothing is upgradeable, pausable or ownable; the contract never holds funds.\n\nCONSTRUCTOR (static values, no external calls: the verifier deploys it in an empty EVM; ZTO has 18 decimals, a constant): zto 0xd782bdea4ef02a0bd391eb9089470c8080f0a68e ; dead 0x000000000000000000000000000000000000dEaD; admin 0x433c8a73bec1273561e4e2201649de12f20b7d58; adam 0x047F606fD5b2BaA5f5C6c4aB8958E45CB6B054B7; seatRoot 0xbe96ac9140fa07013148f2dd158576ae6cbe2b4a0ce4be64782b37acc9ad0e1b (Merkle root of keccak256(abi.encodePacked(address)) leaves, sorted pairs); startTime 1791810000 (Unix; Oct 12 2026, 9:00 AM New York time); caveLength 86400 and roundLength 3600 (seconds); firstPrice 1000000000000000000000000 and floorPrice 10000000000000000000000 (1,000,000 and 10,000 ZTO); labels: seven bytes32, one per cave, in cave order: pepeolithic-base-naij, -moss-naij, -water-naij, -ice-naij, -lava-naij, -crystal-naij, -roots-naij. It mints id 0 to adam and id 736 to admin.\n\nPIECES. Ids 0..736. Id 0 is Zero and id 736 is One. For 1..735: cave = (id-1)/105 + 1 (1..7), round = ((id-1) % 105)/5 + 1 (1..21), slot = (id-1) % 5 + 1 (1..5). Slots 1..4 are lines, slot 5 the gathering. Nothing else can ever be minted.\n\nDAYS. Cave c opens at startTime + (c-1) * caveLength and closes caveLength later, when the next cave opens (cave 7 at startTime + 7 * caveLength). Round r of cave c opens at caveOpen(c) + (r-1) * roundLength; its sale pieces cannot be bought before that. caveLength and roundLength are constructor arguments in seconds (mainnet: 1 day and 1 hour; the constructor requires 21 * roundLength <= caveLength). Day index d = c. caveOpen(c), caveClose(c) and roundOpen(c, r) are views.\n\nSALE PIECES. In every round, k(d) pieces are for sale, taken in this slot order: 5, 4, 3, 2, 1. k = 1,1,2,3,4,4,4 for caves 1..7, except cave 7 round 21 where k = 5. So caves sell 21,21,42,63,84,84,85 = 400 pieces. The other slots of each round are free pieces: 335 in all (315 in caves 1..6 and 20 in cave 7), every one of them for seats.\n\nPRICE. Every round has its own line: from roundOpen(c, r) the price falls from openingPrice(c, r) to floorPrice over one roundLength by HALVING, not in a straight line: K is the smallest integer with opening / 2^K <= floorPrice, the roundLength is split into K equal segments, at the end of segment k the price is opening / 2^k, linear inside a segment, never below floorPrice; after the line it waits at floorPrice until the cave closes. THE LADDER sets openings: cave 1 round 1 opens at firstPrice. Every later round looks at the round before it in week order (round r-1 of the same cave, or round 21 of the previous cave): if that round had a line sale (a buy above floorPrice) it opens at twice that round's last line-sale price, but never below half that round's opening; if it had none it opens at half that round's opening. Openings never go below 2 * floorPrice and have no cap. So the ladder moves at most 2x up or 2x down per round, and floor buys never move it. Implementation: per round store lastLineSale and lineSales; openingPrice(c, r) walks back over earlier rounds until one with a stored opening or a line sale, halving per quiet round, and a round's first buy stores its opening. firstPrice and floorPrice are CONSTRUCTOR ARGUMENTS (not code constants) in ZTO base units: firstPrice 1,000,000 ZTO = 1000000000000000000000000; floorPrice 10,000 ZTO = 10000000000000000000000. priceNow(c, r), openingPrice(c, r) and roundSold(c, r) are views; priceNow reverts if the cave is not open or the round has not opened. Rounds are independent: an older round's unsold pieces wait at the floor while a newer round opens at its own price.\n\nbuy(c, r): the buyer names the round; requires cave c open (opened and not yet closed), round r of cave c opened, and a sale piece of that round left; takes that round's next sale piece in slot order (5, 4, 3, 2, 1); charges price(c, r, now) by ZTO.transferFrom(msg.sender, dead, price), requiring the returned bool; mints to msg.sender with _mint, never _safeMint (no receiver callbacks anywhere); emits Bought(id, buyer, price). No per-wallet limit. The buyer approves ZTO first; the contract never holds it. TEETH: no buys after caveClose(c); sweep(c, max), callable by anyone after the close, mints up to max of its unsold sale pieces in id order to admin, Swept(id) each, and reverts while the cave is open or when none are left. So all 737 pieces are eventually minted.\n\nclaimSeat(proof): requires msg.sender in seatRoot and not claimed before; takes the next free piece of caves 1..7 in id order, skipping sale slots; mints to msg.sender; emits Claimed(id, wallet). Free, gas only. Available from startTime.\n\nreleaseUnclaimed(): callable by anyone after startTime + 8 * caveLength; after it, buyLeftover() takes the next still-unclaimed free piece of caves 1..7 in id order at floorPrice (same payment path as buy; no cave window; buyable until gone); emits Bought(id, buyer, price). claimSeat stops working once releaseUnclaimed has been called.\n\ntokenURI(id): before freeze, \"https://\" + label(c) + \".sites.imd.fun/\" + (\"gathering/\" if slot 5 else \"line-\" + slot + \"/\") + two-digit round + \".json\"; id 0 uses \"https://\" + label(1) + \".sites.imd.fun/zero.json\" and id 736 \"https://\" + label(7) + \".sites.imd.fun/one.json\". freeze(c, base) is admin only, once per cave: afterwards that cave's links use `base` (for example ipfs://<cid>/) in place of \"https://\" + label + \".sites.imd.fun/\". Labels hold up to 32 ASCII bytes, right-padded with zeros. contractURI() returns \"https://\" + label(1) + \".sites.imd.fun/collection.json\" (before freeze) or base(1) + \"collection.json\" (after cave 1 is frozen).\n\nRULES. supportsInterface for ERC-721, ERC-721Metadata and ERC-2981; name \"Pepeolithic\", symbol \"PEPEO\"; royaltyInfo(id, salePrice) returns (admin, salePrice / 100): a 1% creator fee to admin, fixed at deploy, no setter. No function may move ZTO anywhere but the dead address. Tests against a mock ZTO: the id arithmetic for every cave/round/slot, sale counts per cave (400), the halving line (segment ends at opening / 2^k, floor clamp), the ladder (2x last line sale; half after a quiet round; never below 2 * floor; floor buys ignored), buy before open reverts, claim with a bad proof reverts, double claim reverts, nothing mintable past 737, releaseUnclaimed timing, sweep only after close and only unsold sale pieces (never a seat piece, never twice), freeze once per cave, tokenURI strings for sample ids including 0 and 736, royaltyInfo (1% to admin), and events. README with the rules. BUILD: optimizer + via-IR (via_ir = true, optimizer_runs = 1) and deployed code under 9,000 bytes (the new gas schedule charges ~1,540 gas per byte and caps a transaction at 16,777,216 gas): custom errors only, no ReentrancyGuard (the coin call is the last thing buy does). Slither: string.concat, not encodePacked with 2+ dynamic args; multiply before dividing. REFERENCE: match swarm launch 928 src/Ochre.sol (commit b0923044) exactly; only name, symbol and constructor values differ.","parentJobId":null,"planHash":"cde8d9dfc8e9601e0746a5c133fae9f8c6c7ac3e2c5efbf3bf052c7858a4c80b","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"68f0feab-995f-4040-bf4f-bb429382962a","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1076-pepeolithic-one-erc-721-contract"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51021","feedbackHash":"898276ff3ccddd16a33018bfa1c0a8f0b7606d76a1463ab09289ad7d0440194e","nodeKey":"audit_economics","submissionHash":"de444b10eb98f38a630f10e7df6c240f1c8cc0cac25ffe525b4fa79b23a2102d","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52127","feedbackHash":"695248f71c765db2715696c0db71b5750ffdc859edb4ac9ffcddf5a79c9e6018","nodeKey":"audit_flow","submissionHash":"9f9878691d9e9b9e7af0abbb989601b9ce1111a15ac74b9f1f0a52dded237e29","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"50966","feedbackHash":"791612da40f6c92104bfb2160ee63c5caf6e4a57a064e32f949e9c4311d66435","nodeKey":"audit_judge","submissionHash":"cf95b6e0dbbbff65f1337b8a7c04746c80f7f1df6baf17db33d26e96c8789b12","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52250","feedbackHash":"8538f3b5f71788bad6ced40279c9208a1fc486f77af91c2cfc32f5b4b5dfb450","nodeKey":"audit_math","submissionHash":"764a5235cbdb2a5c6dfab2604e7c6b03bb29e1cd6633273ae7f6ee588cd90057","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51250","feedbackHash":"06dd121c0f01fe0ff90da96aae6bb1be5cac58bf4b6ca8dfaea78c2fa8d27e1d","nodeKey":"audit_permissions","submissionHash":"21c29e9b1da1340c07248cb01d7676e6e808d05ac64ddab8633762988c24a444","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51308","feedbackHash":"37beb71de4330048520ce770204a0b6b039f641e95243a061fce6f91e70502d6","nodeKey":"build_contract_project","submissionHash":"5fbe3a7ca02369d7b81eb73e326438edd2180f28e1c11092b78a661653d8a5fa","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51500","feedbackHash":"eeb947a3ad55582837fb0f7851fee45ec26070d6c6e4a03c979ae1df69b9ec67","nodeKey":"manifest","submissionHash":"27f7cb5983ff1e2a1c023db0cd406e026ab3c51ddeb591ccf54ae5bb1604247a","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51395","feedbackHash":"27101dd2a3071e884f943b3039a7374183ffe5d927813a73e5f2a71e821c20e8","nodeKey":"write_foundry_tests","submissionHash":"3c1a8da30d8e6e870827bfe77f2f42b0a5ffc51aff596101e30c7bf3c5c9359e","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"584dc51530c52948a3a308095398e572b319b8fb1fe33b61807778b2ef5ea33a","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"0cf632e317dfab7a","findings":[{"citation":"resolved","description":"Both safeTransferFrom overloads are routed through this override (OZ 5.0.2's 3-arg safeTransferFrom calls the virtual 4-arg one), which reverts whenever to.code.length != 0 and never calls onERC721Received. transferFrom to the same recipient succeeds, so the pair is asymmetric: the 'safe' variant is strictly more restrictive than the unsafe one while supportsInterface still advertises ERC-721 (0x80ac58cd), whose specification requires safeTransferFrom to succeed for a contract that returns the magic value. Concrete consequences on mainnet: (1) a holder cannot move a piece into a Gnosis Safe or any smart-contract wallet with a wallet UI that uses safeTransferFrom (most do); (2) marketplaces whose settlement uses safeTransferFrom (Blur ExecutionDelegate.transferERC721, many escrow/lending vaults) cannot deliver to a contract buyer, so fills revert; (3) since Pectra, an ordinary EOA that set an EIP-7702 delegation carries 23 bytes of code (0xef0100||addr) and is rejected too, so plain users can be hit. The README documents the restriction as intentional and the inherited test at test/Pepeolithic.t.sol:736 asserts it, and the brief requires matching Ochre.sol exactly, so changing it is a scope decision rather than a straight fix. Reported so the judge can decide; no funds are at risk (transferFrom remains available) and nothing is permanently stuck.","line":272,"path":"src/Pepeolithic.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {Pepeolithic} from \"src/Pepeolithic.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\n\ncontract Receiver is IERC721Receiver {\n    function onERC721Received(address, address, uint256, bytes calldata) external pure returns (bytes4) {\n        return IERC721Receiver.onERC721Received.selector;\n    }\n}\n\n/// @dev Fails on the current code: safeTransferFrom rejects every recipient with code, including\n/// an ERC-721 compliant receiver and an EIP-7702 delegated EOA. Passes once safeTransferFrom\n/// accepts recipients that return the onERC721Received magic value (standard behaviour).\ncontract SafeTransferScratch is Test {\n    address constant ADMIN = address(0xAD);\n    address constant ADAM = address(0xAA);\n    Pepeolithic wall;\n\n    function setUp() public {\n        wall = new Pepeolithic(\n            address(0xC0),\n            ADMIN,\n            ADAM,\n            bytes32(uint256(1)),\n            1791810000,\n            86400,\n            3600,\n            1e24,\n            1e22,\n            bytes32(\"a\"),\n            bytes32(\"b\"),\n            bytes32(\"c\"),\n            bytes32(\"d\"),\n            bytes32(\"e\"),\n            bytes32(\"f\"),\n            bytes32(\"g\")\n        );\n    }\n\n    // ERC-721: safeTransferFrom to a contract returning the magic value must succeed.\n    function test_safeTransferToCompliantReceiverSucceeds() public {\n        Receiver r = new Receiver();\n        vm.prank(ADMIN);\n        wall.safeTransferFrom(ADMIN, address(r), 736);\n        assertEq(wall.ownerOf(736), address(r));\n    }\n\n    // Same via the 4-arg overload; transferFrom to the same recipient already works (asymmetry).\n    function test_safeTransferWithDataToCompliantReceiverSucceeds() public {\n        Receiver r = new Receiver();\n        vm.prank(ADAM);\n        wall.transferFrom(ADAM, address(r), 0);\n        assertEq(wall.ownerOf(0), address(r), \"plain transferFrom accepts the contract\");\n        vm.prank(ADMIN);\n        wall.safeTransferFrom(ADMIN, address(r), 736, \"\");\n        assertEq(wall.ownerOf(736), address(r));\n    }\n}","reproduction":"Deploy with any valid constructor arguments. Deploy a contract R implementing onERC721Received returning its selector. As admin (owner of id 736): wall.safeTransferFrom(admin, address(R), 736) -> reverts ContractRecipient(); wall.safeTransferFrom(admin, address(R), 736, \"\") -> reverts ContractRecipient(); wall.transferFrom(admin, address(R), 736) -> succeeds. Expected per ERC-721: the first two succeed and R.onERC721Received is called. For the 7702 case: vm.etch(eoa, hex\"ef0100\" || 20-byte address) so eoa.code.length == 23, then safeTransferFrom(admin, eoa, 736) -> reverts ContractRecipient() although eoa is an externally owned account. Scratch test test/scratch/SafeTransfer.t.sol fails on the current tree with ContractRecipient() for both overloads.","severity":"low","snippet":"    function safeTransferFrom(address from, address to, uint256 id, bytes memory) public override {\n        if (to.code.length != 0) revert ContractRecipient();\n        transferFrom(from, to, id);\n    }","title":"safeTransferFrom rejects every recipient with code: ERC-721 receivers, Safe wallets and EIP-7702 delegated EOAs cannot receive via the safe path"}],"hash":"21c29e9b1da1340c07248cb01d7676e6e808d05ac64ddab8633762988c24a444","nodeId":"dfc9586e-bfe9-4c8f-969f-09b7d3990aac","outcome":"completed","summary":"The review is complete and `.imd-findings.json` holds the result. No tracked files were changed.\n\n**Outcome.** The permission model of Pepeolithic holds across the Access Control, Trust Gap and Asymmetry guides. I found one low-severity defect and no medium or higher issues.\n\n**What I verified**\n\n- **Roles.** The only privileged function is `freeze`, guarded by a fixed, non-zero admin set in the constructor. The factory caller receives nothing. Admin also receives swept pieces, id 736 and the 1% royalty, all fixed at deploy. These are trust assumptions, not bypasses.\n- **Public entry points.** `buy`, `claimSeat`, `releaseUnclaimed`, `buyLeftover` and `sweep` each have the time, quota or proof guard the brief specifies. Their mint sources are disjoint: sale slots via buy or sweep, free slots via the shared claim cursor, ids 0 and 736 only in the constructor.\n- **Asymmetry pairs.** The buy window and sweep window are exact complements at `caveClose`. The ladder derivation matches the brief, floor buys never move it, and a predecessor round's line always ends exactly when the next round opens, so a line sale in round r-1 cannot raise round r's opening while round r is open.\n- **Payment boundary.** ZTO at the configured mainnet address is a plain nine-selector ERC-20 with custom errors. A simulated `transfer` to the dead address returned `true`. The contract's only coin call is `transferFrom(msg.sender, dead, price)` with the bool required.\n- **Launch inputs.** The manifest arguments match the brief in order and value. Runtime is 8,285 bytes and the launch checker passes. The existing suite passes 55 of 55 tests.\n\n**The finding (low).** Both `safeTransferFrom` overloads reject any recipient with code and never call `onERC721Received`, while `transferFrom` to the same recipient succeeds. This breaks ERC-721 receiver semantics that `supportsInterface` still advertises. Concretely, pieces cannot be moved into a Safe through a safe-transfer wallet UI, marketplaces settling via `safeTransferFrom` cannot deliver to contract buyers, and since Pectra an EOA with an EIP-7702 delegation is rejected as well. The README documents this as intentional and the brief requires matching the reference exactly, so I flagged it as a scope decision for the judge. The attached proof test fails on the current tree with `ContractRecipient()`.\n\n**Coverage.** All eleven listed entry points have a row, plus four invariant rows. Nothing in my area was left unreached.","treeHash":null,"usage":{"cachedInputTokens":1126211,"inputTokens":418,"model":"claude-fable-5-1","outputTokens":28679,"runtime":"claude","turns":26,"wallClockMs":493384}},{"artifacts":[],"attempt":1,"bundleHash":"897fd84cf725e6c4598653396f54682306149a4dbcd878672b0759493417a223","device":"2e343a06f770172d","findings":[],"hash":"27f7cb5983ff1e2a1c023db0cd406e026ab3c51ddeb591ccf54ae5bb1604247a","nodeId":"5dc362d7-ebef-4e63-b8a8-9144532f608f","outcome":"completed","summary":"Updated only [launch.json](/home/seat/.identitymd/work/68f0feab-995f-4040-bf4f-bb429382962a/5dc362d7-ebef-4e63-b8a8-9144532f608f/launch.json), clarifying deployment notes and preserving the verified 16 constructor arguments.\n\nValidation passed: manifest schema, compiled ABI, `forge build`, and all 55 tests. Runtime: 8,285 bytes, below 9,000.","treeHash":"0d1d367de611feecb965faae39c87f7e7cb3198f","usage":{"cachedInputTokens":352256,"inputTokens":34099,"model":"gpt-6-astra","outputTokens":3396,"runtime":"codex","turns":4,"wallClockMs":137993}},{"artifacts":[],"attempt":1,"bundleHash":"3452bf86488ceda5a53f0376999c95faea867c0c26db44cae172a8d8ec3fa50c","device":"9a29c101a23c14cc","findings":[],"hash":"3c1a8da30d8e6e870827bfe77f2f42b0a5ffc51aff596101e30c7bf3c5c9359e","nodeId":"dbb5d87c-c4df-4169-98f1-b2b8254dd578","outcome":"completed","summary":"Added 14 adversarial tests, strengthened allowance and seat-allocation invariants, and updated test documentation. All changes are under `test/`.\n\n`forge build` and `forge test` pass: **69 tests, 0 failures**, including 256 invariant sequences.\n\nNo reproducible defects found in these checks.","treeHash":"88faf8cba7469afd6396bd52abc316912f34e33d","usage":{"cachedInputTokens":1993472,"inputTokens":115742,"model":"gpt-6-astra","outputTokens":17481,"runtime":"codex","turns":8,"wallClockMs":645180}},{"artifacts":[],"attempt":1,"bundleHash":"b063330afe44a071b614aa84b5fa96b5dbb1bbb414616de19c1b4551bf441361","device":"d47149da4d751a90","findings":[],"hash":"5fbe3a7ca02369d7b81eb73e326438edd2180f28e1c11092b78a661653d8a5fa","nodeId":"d573667e-6a97-427e-828e-5c100d465edc","outcome":"completed","summary":"Implemented Pepeolithic with vendored dependencies, mainnet manifest, tests, and documentation.\n\nPassed `forge build`, all **55 tests**, `forge fmt --check`, and offline launch checks. Runtime: **8,285 bytes**.\n\nPreserved the pinned reference’s `lastLineSale` representation without a separate `lineSales` counter; documented in README.\n\nDeployment is prepared; no transaction was broadcast.","treeHash":"d77a97d2b4fab71e0e3a20489d2e5d033816d4d2","usage":{"cachedInputTokens":1227776,"inputTokens":105254,"model":"gpt-6-astra","outputTokens":16562,"runtime":"codex","turns":6,"wallClockMs":565332}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"fc87c05048aca47d","findings":[{"citation":"resolved","description":"Boundary x precision seam in the ladder. The constructor (src/Pepeolithic.sol:88-93) validates roundLength_ <= max/21, caveLength_ <= (max - startTime_)/8 and floorPrice_ <= max/2 so that every later multiplication is overflow-free, but firstPrice_ has only a lower bound (firstPrice_ >= 2 * floorPrice_). A line sale at the opening of cave 1 round 1 stores lastLineSale = firstPrice. _opening() for every later round walks back to that stored round and computes 2 * previous.lastLineSale in checked arithmetic, which panics (0x11) when lastLineSale >= 2^255. Because no later round can ever store its own opening (every buy and priceNow first calls _opening, which panics), the walk from every one of the remaining 146 rounds reaches the same stored round and panics too: buy(), priceNow() and openingPrice() revert for the whole sale while claimSeat, sweep and buyLeftover still work. NOT REACHABLE with the mainnet constructor values in launch.json: firstPrice 1e24 ~ 2^79.7, and the ladder can at most double per round, so the largest value the expression can see over 147 rounds is 1e24 * 2^147 ~ 2^227 (verified by a 147-round all-doubling test in test/scratch/MathAudit.t.sol). Reported as information only so the judge sees this boundary was checked; the code is identical to the pinned Ochre.sol reference and the brief forbids changing it, so no fix is requested. If a fix were ever wanted it would be a constructor upper bound such as firstPrice_ > type(uint256).max >> 148 revert InvalidConfig().","line":285,"path":"src/Pepeolithic.sol","reproduction":"Deploy with firstPrice_ = 2^255 (0x8000...0), floorPrice_ = 1e22, all other mainnet arguments; the constructor accepts it. vm.warp(startTime); buy(1, 1) from a funded buyer succeeds at price 2^255 and stores lastLineSale(1,1) = 2^255. vm.warp(startTime + 3600). Expected per the ladder rule: round 2 opens at max(firstPrice/2, 2 * 2^255) which is uncapped per the brief, so buy(1, 2) should be possible. Actual: priceNow(1, 2), openingPrice(7, 21) and buy(1, 2) all revert with an arithmetic overflow panic, and every other round of every cave does too for the rest of the sale. Verified in test/scratch/EdgeAudit.t.sol::testHugeFirstPriceBricksLadder (passes, i.e. the reverts occur).","severity":"info","snippet":"                if (previous.lastLineSale != 0) next = Math.max(next, 2 * previous.lastLineSale);","title":"Constructor bounds every other overflow input but not firstPrice; firstPrice >= 2^255 lets one line sale brick every later round via 2 * lastLineSale overflow"}],"hash":"764a5235cbdb2a5c6dfab2604e7c6b03bb29e1cd6633273ae7f6ee588cd90057","nodeId":"9ea98fac-71d4-49c5-9e0b-9468fac41bff","outcome":"completed","summary":"The review is complete. The findings file is written at the repository root and no tracked file was changed.\n\n**Outcome.** The math in `src/Pepeolithic.sol` holds under the Math Precision, Boundary and Numerical Gap checklists. I found no defect reachable with the launch.json constructor values. One information-only boundary note is recorded.\n\n**What I verified, with concrete numbers**\n\n- **Halving line.** Compared `priceNow(1,1)` against an independent rational reference for every second of the hour at mainnet values (K is 7 segments). Segment ends land at opening divided by 2^k, the floor clamp holds, interpolation rounds up by under 1 wei, and the line is monotone across segment joins. The extreme K of 255 (opening 2^255, floor 1) runs without revert since shifts never reach 256.\n- **Ladder.** Doubling of the last line sale, halving over quiet rounds, the 2x floor minimum, floor buys being ignored, and the half-of-previous-opening bound all match the brief. I proved the stored-opening walk equals the per-round rule under integer division, and that a late floor buy in an old round cannot change later stored openings. A 147-round all-doubling run stays below 2^227, so no overflow at mainnet prices. Worst case walk after 146 quiet rounds costs about 499k gas for a buy.\n- **Boundaries.** Buy and sweep windows are exact complements at caveClose. Id arithmetic gives 400 sale pieces and 335 free pieces ending at id 726. Sweep never touches seat pieces, never mints twice, and cave 7 stops at 735.\n- **External boundary.** The real ZTO at the brief's address on mainnet is an 18-decimal OpenZeppelin-style ERC-20 that returns `true` from `transferFrom`, so the boolean check in `_pay` is compatible.\n- **Reference match.** The pinned Ochre.sol fetched from GitHub matches the SHA-256 in DEPENDENCIES.md, and after reversing the rename the only diff is the symbol string. Runtime size is 8,285 bytes.\n\n**The one recorded item (info).** The constructor bounds roundLength, caveLength, startTime and floorPrice against overflow but not firstPrice. With firstPrice of 2^255, a single opening buy makes `2 * lastLineSale` panic in `_opening`, bricking buy, priceNow and openingPrice for every later round. This is unreachable with the mainnet value of 1e24 and the code must match the reference, so no fix is requested.\n\n**Coverage.** All 11 verifier entry points have a row, all marked `holds`, plus six invariant rows, one pointing at the info finding. Scratch tests live only under `test/scratch/`, which is gitignored.","treeHash":null,"usage":{"cachedInputTokens":1164795,"inputTokens":450,"model":"claude-fable-5-1","outputTokens":37072,"runtime":"claude","turns":31,"wallClockMs":505863}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"fd5402086dce252e","findings":[{"citation":"resolved","description":"Both safeTransferFrom overloads (the 3-arg OZ version routes into this 4-arg override) revert with ContractRecipient() for any `to` whose code length is non-zero. That covers (a) contracts that correctly implement IERC721Receiver (Safe multisigs, vaults, escrow and marketplace custody contracts), and (b) on mainnet post-Pectra, ordinary EOAs that have an EIP-7702 delegation (23 bytes of code `0xef0100||address`). EIP-721 requires safeTransferFrom to succeed when the receiver returns the onERC721Received magic value; this contract returns true for supportsInterface(0x80ac58cd) but cannot satisfy that path. Holders who try to move a piece into a smart wallet or a delegated EOA through any integration that uses safeTransferFrom (most wallets' default 'send NFT' flow, several marketplaces and bridges) get a revert; only raw transferFrom works. This is the documented consequence of the brief's 'no receiver callbacks anywhere' and the exact-reference constraint, so it is reported at low severity as a deviation from the ERC-721 guarantee the contract advertises, for the requester to accept knowingly. A non-callback alternative that keeps the brief's intent is not available without changing the reference; the practical mitigation is to document for holders that transferFrom must be used for contract and delegated-EOA recipients.","line":272,"path":"src/Pepeolithic.sol","reproduction":"State: Alice owns id 5 (buy(1,1) at START). 1) vm.etch(delegated, abi.encodePacked(hex\"ef0100\", address(0x1234))) so delegated.code.length == 23 (an EIP-7702 EOA). vm.prank(ALICE); wall.safeTransferFrom(ALICE, delegated, 5) -> reverts ContractRecipient(). Expected per ERC-721: for an EOA-style recipient the transfer completes. 2) GoodReceiver good = new GoodReceiver() returning IERC721Receiver.onERC721Received.selector; vm.prank(ALICE); wall.safeTransferFrom(ALICE, address(good), 5) -> reverts ContractRecipient(). Expected per ERC-721: transfer completes because the receiver returns the magic value. 3) wall.transferFrom(ALICE, address(good), 5) succeeds, showing only the safe path is blocked. Verified with test/scratch/Explore.t.sol::testSafeTransferToDelegatedEoaAndCompliantReceiver on the current tree.","severity":"low","snippet":"        if (to.code.length != 0) revert ContractRecipient();","title":"safeTransferFrom rejects every code-bearing recipient, including ERC-721-compliant receivers and EIP-7702 delegated EOAs, while supportsInterface advertises ERC-721"},{"citation":"resolved","description":"The constructor validates schedule arithmetic but not that startTime_ > block.timestamp. The mainnet startTime 1791810000 is four days after this review and the remaining pipeline (attestation, admission, deployment) runs after it. If the factory transaction executes after startTime, every round whose line already elapsed is immediately purchasable at floorPrice (10,000 ZTO) and the ladder for the following rounds has already halved through the missed rounds, so the 1,000,000 ZTO first-round opening is never charged. Nothing is lost by buyers, and ZTO still goes to the dead address, but the sale design (the opening ladder) is defeated without any signal on-chain. The reference-match constraint forbids adding a constructor check; the mitigation is operational: the deployer must confirm the transaction is mined before 1791810000 or the requester must re-issue the brief with a later startTime.","line":98,"path":"src/Pepeolithic.sol","reproduction":"vm.warp(1791810000 + 2 hours + 1); deploy Pepeolithic with the mainnet arguments (startTime 1791810000, caveLength 86400, roundLength 3600, firstPrice 1e24, floorPrice 1e22). Immediately: priceNow(1,1) == 1e22 and priceNow(1,2) == 1e22 (both lines elapsed); buy(1,1) succeeds, mints id 5 and charges 1e22 ZTO to dead; openingPrice(1,3) == 2.5e23 (firstPrice halved twice through the missed rounds). Expected under the brief: round 1 opens at 1,000,000 ZTO when the sale starts. Verified with test/scratch/LateDeploy.t.sol::testDeployAfterStartTimeSellsElapsedRoundsAtFloor on the current tree.","severity":"info","snippet":"        startTime = startTime_;","title":"No guard that startTime is in the future at deployment: a deployment landing after Oct 12 2026 13:00 UTC silently sells already-elapsed rounds at the floor"}],"hash":"9f9878691d9e9b9e7af0abbb989601b9ce1111a15ac74b9f1f0a52dded237e29","nodeId":"a4312c5f-af4e-46c4-9621-306bb63e4c36","outcome":"completed","summary":"The findings file is in place at the repository root (it is excluded from git by the harness's own rule, as expected) and no tracked file was changed. Review complete.\n\n## Outcome\n\nThe contract holds up under the Execution Trace, Periphery and First Principles passes. I found no critical, high or medium defect. Two low/info items are recorded in `.imd-findings.json`, each with a reproduction I ran on the current tree.\n\n**What I verified**\n\n- **Source fidelity.** The local contract is byte-identical to the reference Ochre.sol at commit b0923044 after the permitted renames. The vendored OpenZeppelin files equal upstream v5.0.2 modulo formatting. The launch checker passes at 8,285 runtime bytes.\n- **Live ZTO (the only external call).** On a mainnet fork, the token is a 1,287-byte minimal ERC-20 with no owner or pause functions. A real `buy` moved 1,000,000 ZTO to the dead address and `transferFrom` returned true. Overdraws revert with a custom error.\n- **Ladder and halving line.** Hand-checked the README knots (650,000 at 360 s, 93,750 at 1,800 s, floor at 3,456 s). Fuzzed that a round's quoted opening cannot change between the moment it opens and its first buy, because a predecessor's line always ends exactly when the next round opens. Floor buys never move it.\n- **Issuance paths.** Traced buy, claimSeat, buyLeftover and sweep for id collisions, cursor handling, the close boundary, and payment-revert rollback. All behave as the brief states.\n\n**Findings**\n\n1. **Low.** `safeTransferFrom` reverts for every recipient with code, which includes ERC-721-compliant receivers such as Safe wallets and EIP-7702 delegated EOAs on mainnet, while `supportsInterface` advertises ERC-721. This follows from the brief's \"no callbacks anywhere\" rule, so it is reported for the requester to accept knowingly.\n2. **Info.** The constructor does not require `startTime` to be in the future. If the factory transaction lands after Oct 12 2026 13:00 UTC, elapsed rounds sell at the floor and the ladder has already halved through them. Mitigation is operational.\n\n**Coverage.** All 11 listed entry points have a row (9 hold, 2 carry finding 1), plus five invariant and periphery rows. Nothing was left unreached.","treeHash":null,"usage":{"cachedInputTokens":1994538,"inputTokens":610,"model":"claude-fable-5-1","outputTokens":45603,"runtime":"claude","turns":33,"wallClockMs":820512}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"759c614fdc84ff66","findings":[{"citation":"resolved","description":"Merged from audit_economics, audit_permissions and audit_flow (same root cause, same line). OZ 5.0.2's 3-arg safeTransferFrom calls the virtual 4-arg overload, which this contract overrides to revert on any code-bearing `to` instead of calling onERC721Received. This deviates from the ERC-721 safe-transfer rule that the advertised interface implies: Safe multisigs, escrow/marketplace custody contracts and post-Pectra EOAs with a 7702 delegation (23 bytes of code) cannot receive through the safe path; transferFrom to the same recipients works. Recalibrated to info, not a defect to fix: the brief requires 'no receiver callbacks anywhere' and an exact match of Ochre.sol (b0923044), and any ERC-721-compliant safeTransferFrom must make that callback. Reverting is the conservative reading (a contract never receives a piece through an unchecked 'safe' call), and the README documents it. No funds are at risk and nothing gets stuck. Record it as a holder-facing trust assumption: send pieces to contract wallets with transferFrom. Change it only if the requester relaxes the no-callback rule.","line":272,"path":"src/Pepeolithic.sol","reproduction":"Deploy with the mainnet constructor values (coin can be any address). Deploy R whose onERC721Received returns IERC721Receiver.onERC721Received.selector. vm.prank(admin); safeTransferFrom(admin, address(R), 736) -> reverts ContractRecipient(); safeTransferFrom(admin, address(R), 736, \"\") -> reverts ContractRecipient(). vm.prank(adam); transferFrom(adam, address(R), 0) succeeds and ownerOf(0) == R. Under plain ERC-721 the expected result is that both safe calls succeed. Confirmed by running the specialist proof .imd/reads/proofs/Proof_7ffaa7975b3a.t.sol: both tests fail with ContractRecipient().","severity":"info","snippet":"        if (to.code.length != 0) revert ContractRecipient();","title":"safeTransferFrom (both overloads) reverts for every recipient with code, including compliant IERC721Receiver contracts and EIP-7702 delegated EOAs, while supportsInterface(0x80ac58cd) returns true"},{"citation":"resolved","description":"From audit_flow; reproduced. Constructor validation (lines 88-93) checks schedule arithmetic but not startTime_ > block.timestamp. If the factory transaction lands after 1791810000, every round whose hour has passed is buyable straight away at floorPrice, and later openings have already halved through the quiet rounds. The ladder's first-round price is never charged. Payment still goes only to dead, and no buyer or admin funds are lost. This is an operational deployment-timing risk, not a code change request. The exact-reference requirement rules out adding a constructor check, and the verifier's empty EVM deploy would pass either way. The deployer must make sure the transaction is mined before startTime (four days after this review), or the requester must re-issue the start time.","line":98,"path":"src/Pepeolithic.sol","reproduction":"vm.warp(1791810000 + 2 hours + 1); deploy Pepeolithic(mockCoin, admin, adam, root, 1791810000, 86400, 3600, 1e24, 1e22, labels...). Deployment succeeds. priceNow(1,1) == 1e22 and priceNow(1,2) == 1e22, where the brief's schedule expects round 1 to open at 1e24. openingPrice(1,3) == 2.5e23. Verified with a scratch Foundry test; all three assertions pass on the current tree.","severity":"info","snippet":"        startTime = startTime_;","title":"Constructor does not require startTime in the future; a mainnet deployment mined after 2026-10-12 13:00 UTC sells elapsed rounds at the floor and skips the 1,000,000 ZTO opening"}],"hash":"cf95b6e0dbbbff65f1337b8a7c04746c80f7f1df6baf17db33d26e96c8789b12","nodeId":"dfba399d-a21e-4eab-ba72-8f3cfeb624ea","outcome":"completed","summary":"I found no blocking defects in `src/Pepeolithic.sol`. I wrote `.imd-findings.json` with two info-level findings and a coverage row for all 11 entry points (9 hold, the 2 `safeTransferFrom` overloads point to finding 1), plus 3 invariants I checked. No tracked files changed, and I deleted my scratch tests.\n\n**What I checked myself**\n- **Build and tests:** all 69 existing tests pass. Deployed code is 8,285 bytes, under the 9,000 limit.\n- **Real ZTO:** on a mainnet fork, `buy(1,1)` against the live ZTO contract charged 1,000,000 ZTO to the dead address and minted id 5. ZTO's `transferFrom` returns a bool, as the contract requires.\n- **Manifest:** the seven labels in `launch.json` decode correctly, the argument order matches the constructor, and `startTime` is 13:00 UTC, which is 9:00 in New York.\n- **Logic traced:** id arithmetic, sale counts (400 sale, 335 seat, 737 total), the halving price line, the ladder walk-back, seat claims and their proof hashing, leftovers, sweeping, freezing, metadata links and royalties all behave as the brief says. ZTO only ever goes to the dead address.\n- **Protected test:** it could not run here because it needs the verifier's `IMD_PROJECT_FACTORY` setting, which only the verifier has.\n\n**Specialist findings**\n1. **`safeTransferFrom` rejects any recipient with code** (`src/Pepeolithic.sol:272`). Three specialists reported this; I merged it into one finding and confirmed it with the attached proof. I lowered it from low to info. The brief says \"no receiver callbacks anywhere\" and requires an exact copy of the reference contract, and any fully standard `safeTransferFrom` has to make that callback. Reverting is the cautious choice, the README documents it, and `transferFrom` still works for contract wallets. It is a point to tell holders about, not a fix to make.\n2. **A late deployment skips the opening price** (`src/Pepeolithic.sol:98`). Confirmed: if the deployment lands after Oct 12 13:00 UTC, rounds that have already elapsed sell at the 10,000 ZTO floor, and later rounds open at already-halved prices. This is a timing risk for the deployer, four days out, not a code change.\n3. **Dropped: the `firstPrice` overflow** from the math specialist. It only happens if `firstPrice` is at least 2^255. With the fixed 1,000,000 ZTO value, the largest number the ladder can reach is about 2^227, so it can't happen in this launch.\n\nThe static-analysis warnings were all false positives (Solidity zero-initialises local variables) or intended design (timestamp checks, the unchecked-return flag even though the ZTO return value is checked, and `_mint` instead of `_safeMint`, which the brief requires).","treeHash":null,"usage":{"cachedInputTokens":920612,"inputTokens":30,"model":"claude-opus-5-5","outputTokens":20720,"runtime":"claude","turns":15,"wallClockMs":383670}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"72ae9b5bbd1a54b6","findings":[{"citation":"resolved","description":"Flow gap (periphery x first principles). The override rejects any `to` with code instead of performing the ERC-721 receiver check. OpenZeppelin v5's three-argument safeTransferFrom routes through this four-argument overload, so both overloads revert with ContractRecipient for every contract recipient, even one that implements IERC721Receiver and returns the magic value. The contract still reports ERC-721 support through supportsInterface(0x80ac58cd), so integrators that follow the standard (marketplaces and escrow or vault contracts that call safeTransferFrom, and multisig wallets such as a Safe whose fallback handler implements onERC721Received) will see transfers fail at execution time. A secondary sale to a contract-wallet buyer through any venue that uses safeTransferFrom reverts; a listing paid through such a venue cannot settle. The README documents this as an intentional reading of the brief's 'no receiver callbacks anywhere', which in the brief is attached to minting (_mint, never _safeMint). The brief also requires ERC-721 support via supportsInterface. If the restriction is kept it should be stated as a trust assumption for holders; the minimal fix that keeps the no-callback intent on mints is to remove the override and let the inherited safeTransferFrom perform the standard receiver check (it only runs on explicit holder-initiated transfers, never in buy, claimSeat, sweep or buyLeftover).","line":271,"path":"src/Pepeolithic.sol","reproduction":"Deploy with any valid constructor arguments. Warp to startTime, buyer (EOA) calls buy(1,1) and receives id 5. Deploy a receiver contract V whose onERC721Received returns IERC721Receiver.onERC721Received.selector. Buyer calls safeTransferFrom(buyer, address(V), 5) or safeTransferFrom(buyer, address(V), 5, \"\"). Expected under ERC-721 (and under supportsInterface(0x80ac58cd) == true): transfer succeeds and ownerOf(5) == address(V). Actual: both calls revert with ContractRecipient(); only transferFrom(buyer, address(V), 5) succeeds. Verified with a Foundry test under test/scratch (Vault is a minimal IERC721Receiver; both overloads expectRevert(Pepeolithic.ContractRecipient.selector); transferFrom then succeeds).","severity":"low","snippet":"    function safeTransferFrom(address from, address to, uint256 id, bytes memory) public override {\n        if (to.code.length != 0) revert ContractRecipient();","title":"safeTransferFrom reverts for every contract recipient, including ERC-721-compliant receivers, while supportsInterface(0x80ac58cd) claims full ERC-721"}],"hash":"de444b10eb98f38a630f10e7df6c240f1c8cc0cac25ffe525b4fa79b23a2102d","nodeId":"c2e1d2fa-9068-4e6d-808f-d21e79cf752f","outcome":"completed","summary":"The review is complete. The findings file is in place at the repository root, and no tracked files were changed. Build artifacts and my scratch tests are gone or ignored.\n\n**Result: one low-severity finding, no economic or invariant defects.**\n\nThe contract under review is `src/Pepeolithic.sol`. I checked it against the Economic Security, Invariant and Flow Gap guides and could not break the pricing, ladder, supply, or payment invariants.\n\nWhat I verified, beyond reading:\n\n- **Ladder and halving line.** A scratch differential fuzz (64 runs, all 147 rounds, random line buys, floor-tail buys and late floor buys of older rounds) matched the contract's lazy walk-back opening against an eager per-round model in every case. Price is monotone within a round, equals opening shifted by k at each segment end, and clamps at floor.\n- **Payment path.** The live ZTO contract on mainnet is a small plain ERC20 with custom errors. It returns true on `transferFrom` to the dead address and reverts on allowance shortfall, so the required-bool payment path behaves as the brief assumes.\n- **Supply and disjointness.** Sale pieces total 400, free pieces 335, all mints go through one helper, and sweep, claim and leftover paths cannot touch each other's ids or mint twice.\n- **Project suite.** All 55 existing tests pass. Deployed size is 8,285 bytes.\n- **Fixed roles.** Admin and Adam are active externally owned accounts on mainnet, so freeze and the constructor mint are reachable.\n\nThe one finding is a flow gap: both `safeTransferFrom` overloads revert for any contract recipient, even one implementing the ERC-721 receiver interface, while the contract advertises ERC-721 support. The README documents this as deliberate, so I reported it at low severity with a reproduction and left the severity call to the judge.\n\nCoverage has a row for all 11 listed entry points plus four invariants. Nothing was left unreached.","treeHash":null,"usage":{"cachedInputTokens":2418932,"inputTokens":706,"model":"claude-fable-5-1","outputTokens":36773,"runtime":"claude","turns":23,"wallClockMs":717763}}],"verification":[{"checks":[{"durationMs":14585,"exitCode":0,"name":"build","output":"Compiling 37 files with Solc 0.8.26\nSolc 0.8.26 finished in 14.46s\nCompiler run successful!\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/Pepeolithic.sol:339:34\n    │\n339 │         if (label == bytes32(0)) revert InvalidConfig();\n    │                                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/Pepeolithic.sol:344:50\n    │\n344 │             else if (padding || character > 127) revert InvalidConfig();\n    │                                                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Pepeolithic.sol:164:13\n    │\n164 │         if (block.timestamp < opens || block.timestamp >= caveClose(c)) revert NotOpen();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Pepeolithic.sol:164:40\n    │\n164 │         if (block.timestamp < opens || block.timestamp >= caveClose(c)) revert NotOpen();\n    │                                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Pepeolithic.sol:171:13\n    │\n171 │         if (block.timestamp < opens || block.timestamp >= caveClose(c)) revert NotOpen();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Pepeolithic.sol:171:40\n    │\n171 │         if (block.timestamp < opens || block.timestamp >= caveClose(c)) revert NotOpen();\n    │                                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/Pepeolithic.sol:181:9\n    │\n181 │         emit Bought(id, msg.sender, price);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Pepeolithic.sol:186:13\n    │\n186 │         if (block.timestamp < startTime) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Pepeolithic.sol:202:13\n    │\n202 │         if (block.timestamp < startTime + 8 * caveLength) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Pepeolithic.sol:218:13\n    │\n218 │         if (block.timestamp < caveClose(c)) revert NotClosed();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/Pepeolithic.sol:129:23\n    │\n129 │         if (id > 736) revert InvalidPiece();\n    │                       ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/Pepeolithic.sol:349:30\n    │\n349 │         if (c == 0 || c > 7) revert InvalidCave();\n    │                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/Pepeolithic.sol:354:31\n    │\n354 │         if (r == 0 || r > 21) revert InvalidRound();\n    │                               ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Pepeolithic.sol:240:61\n    │\n240 │         if (value.length == 0 || value[value.length - 1] != bytes1(\"/\")) revert InvalidBase();\n    │                                                             ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'bytes1' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Pepeolithic.sol:253:87\n    │\n253 │             slot == 5 ? \"gathering/\" : string.concat(\"line-\", string(abi.encodePacked(uint8(48 + slot))), \"/\");\n    │                                                                                       ━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Pepeolithic.sol:254:66\n    │\n254 │         return string.concat(base, path, string(abi.encodePacked(uint8(48 + r / 10), uint8(48 + r % 10))), \".json\");\n    │                                                                  ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Pepeolithic.sol:254:86\n    │\n254 │         return string.concat(base, path, string(abi.encodePacked(uint8(48 + r / 10), uint8(48 + r % 10))), \".json\");\n    │                                                                                      ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Pepeolithic.sol:286:57\n    │\n286 │                 return Math.max(2 * floorPrice, next >> quiet);\n    │                                                         ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Pepeolithic.sol:300:15\n    │\n300 │             ++segments;\n    │               ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-oz-erc721-mint]: `ERC721._mint` does not check that the recipient can receive the token; use `_safeMint`\n    ╭▸ src/Pepeolithic.sol:323:9\n    │\n323 │         _mint(to, id);\n    │         ━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-oz-erc721-mint\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Pepeolithic.sol:330:16\n    │\n330 │         while (length < 32 && label[length] != 0) ++length;\n    │                ━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Pepeolithic.sol:344:22\n    │\n344 │             else if (padding || character > 127) revert InvalidConfig();\n    │                      ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\n","passed":true},{"durationMs":18293,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 30 tests for test/Pepeolithic.t.sol:PepeolithicTest\n[PASS] testAll335SeatsInIdOrderAndMerkleExhaustion() (gas: 49642027)\n[PASS] testAll737EventuallyMintedExactlyOnce() (gas: 57915696)\n[PASS] testBuyAndQuoteTimeBoundaries() (gas: 691279)\n[PASS] testBuyEventAndDirectBurnPayment() (gas: 320903)\n[PASS] testClaimProofStartAndDuplicate() (gas: 315080)\n[PASS] testCoinReentrySeesCompletedSaleAndCannotDuplicatePiece() (gas: 751690)\n[PASS] testConstructorWithoutCoinCodeAndFixedDeployment() (gas: 174212)\n[PASS] testERC721TransfersApprovalsAndNoReceiverCallbacks() (gas: 811912)\n[PASS] testEveryPieceAndSaleCount() (gas: 9470948)\n[PASS] testEverySaleSlotBoughtInOrderAndAllSalesExhausted() (gas: 63856939)\n[PASS] testFalseAndRevertingCoinRollbackEntireBuy() (gas: 1275690)\n[PASS] testFreezeOnlyAdminOnceAndValidBase() (gas: 233830)\n[PASS] testFuzzHalvingPriceIsBoundedAndMonotone(uint256) (runs: 256, μ: 51793, ~: 51660)\nLogs:\n  Bound result 167\n\n[PASS] testHalvingSegmentEndsAndInterior() (gas: 188844)\n[PASS] testInterfacesRoyaltyAndNonexistentURI() (gas: 83965)\n[PASS] testInvalidConfiguration() (gas: 5576)\n[PASS] testLadderAcrossCavesAndUnboughtRoundNotSnapshot() (gas: 635856)\n[PASS] testLadderDoublesLastLineSaleAndHalvesQuietRounds() (gas: 903635)\n[PASS] testLadderFloorBuysIgnoredAndStoredOpeningStable() (gas: 1013662)\n[PASS] testLastLineSaleReplacesEarlierSaleAndHalfOpeningMinimum() (gas: 1170907)\n[PASS] testLeftoverFailureRollsBackCursorAndReentryUsesNextPiece() (gas: 808452)\n[PASS] testMintToContractWithoutReceiver() (gas: 518998)\n[PASS] testMissingBoolOrMissingAllowanceRejectsBuy() (gas: 428452)\n[PASS] testQuietFirstBuyAtFloorDoesNotRaiseNextOpening() (gas: 271073)\n[PASS] testRehearsalFractionalSegments() (gas: 94065)\n[PASS] testReleaseTimingPermissionlessAndClaimStopsOnlyOnRelease() (gas: 543102)\n[PASS] testRuntimePassesProtectedOpcodeScanAndSizeLimit() (gas: 3630547)\n[PASS] testSweepBoundariesPartialBatchesAndEvents() (gas: 1936589)\n[PASS] testURIsIncludingEndpointsRoundsSlotsAndFrozenCaves() (gas: 12549467)\n[PASS] testWindowsAndInvalidIndices() (gas: 2286269)\nSuite result: ok. 30 passed; 0 failed; 0 skipped; finished in 70.16ms (186.63ms CPU time)\n\nRan 10 tests for test/PepeolithicMainnet.t.sol:PepeolithicMainnetTest\n[PASS] testMainnetAll400SalesAnd335LeftoversFinishExactly737() (gas: 93244812)\n[PASS] testMainnetConstructorEmptyEVMAndExactValues() (gas: 234418)\n[PASS] testMainnetEveryScheduleBoundary() (gas: 35397543)\n[PASS] testMainnetHalvingFractionalKnotsAndFloorClamp() (gas: 256694)\n[PASS] testMainnetHighest147RoundLadderFitsUint256() (gas: 36903089)\n[PASS] testMainnetLaterSaleReplacesLastPriceAndHalfOpeningBound() (gas: 1355470)\n[PASS] testMainnetMetadataAllCavesAndPermanentFreeze() (gas: 66952757)\n[PASS] testMainnetPaymentRollbackAndEvents() (gas: 831014)\n[PASS] testMainnetQuietLadderAndFloorBuyIgnored() (gas: 637489)\n[PASS] testMainnetSortedProofClaimAndRelease() (gas: 301949)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 72.77ms (160.54ms CPU time)\n\nRan 13 tests for test/PepeolithicProperties.t.sol:PepeolithicPropertiesTest\n[PASS] testConstructorRejectsZeroAddressesAndOverflowingSchedule() (gas: 6474)\n[PASS] testEveryMintPathWorksWithAReceiverThatRejectsCallbacks() (gas: 1458194)\n[PASS] testFullWidthInterpolationDoesNotOverflow() (gas: 118389)\n[PASS] testFuzzEveryCaveRoundBoundary(uint8,uint8) (runs: 1000, μ: 505203, ~: 479782)\nLogs:\n  Bound result 7\n  Bound result 12\n\n[PASS] testFuzzFractionalCurveBoundsAndPayment(uint96,uint96,uint32,uint32) (runs: 1000, μ: 476039, ~: 472893)\nLogs:\n  Bound result 7\n  Bound result 14\n  Bound result 23293\n  Bound result 14\n\n[PASS] testFuzzHalvingKnotsAcrossConstructorPrices(uint96,uint8,uint32) (runs: 1000, μ: 336949, ~: 251555)\nLogs:\n  Bound result 1247041304235049\n  Bound result 1\n  Bound result 5493\n\n[PASS] testFuzzRoyaltyRoundingIdentity(uint256,uint256) (runs: 1000, μ: 12256, ~: 12256)\n[PASS] testInsufficientBalanceAndLeftoverAllowancePreserveInventory() (gas: 747747)\n[PASS] testLabelsRejectMalformedPaddingAndAcceptAll32Bytes() (gas: 6753)\n[PASS] testMaximumRehearsalLadderRemainsLiveThroughAll147Rounds() (gas: 34980862)\n[PASS] testMerkleProofCannotBeReusedByAnotherWalletOrAltered() (gas: 245132)\n[PASS] testNativeCurrencyIsRejectedByAllIssuancePaths() (gas: 183191)\n[PASS] testOneWeiFloorOddOpeningAndSubsecondSegments() (gas: 208289)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 82.99ms (229.30ms CPU time)\n\nRan 2 tests for test/PepeolithicInvariant.t.sol:PepeolithicInvariantTest\n[PASS] invariant_supplyPaymentAndPermanentTransitions() (runs: 256, calls: 32768, reverts: 0)\n\n╭-----------------------------+-------------+-------+---------+----------╮\n| Contract                    | Selector    | Calls | Reverts | Discards |\n+========================================================================+\n| PepeolithicLifecycleHandler | advanceTime | 4104  | 0       | 0        |\n|-----------------------------+-------------+-------+---------+----------|\n| PepeolithicLifecycleHandler | buy         | 4107  | 0       | 0        |\n|-----------------------------+-------------+-------+---------+----------|\n| PepeolithicLifecycleHandler | buyLeftover | 4063  | 0       | 0        |\n|-----------------------------+-------------+-------+---------+----------|\n| PepeolithicLifecycleHandler | claim       | 4118  | 0       | 0        |\n|-----------------------------+-------------+-------+---------+----------|\n| PepeolithicLifecycleHandler | freeze      | 4119  | 0       | 0        |\n|-----------------------------+-------------+-------+---------+----------|\n| PepeolithicLifecycleHandler | release     | 4126  | 0       | 0        |\n|-----------------------------+-------------+-------+---------+----------|\n| PepeolithicLifecycleHandler | sweep       | 4010  | 0       | 0        |\n|-----------------------------+-------------+-------+---------+----------|\n| PepeolithicLifecycleHandler | transfer    | 4121  | 0       | 0        |\n╰-----------------------------+-------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1334\n  Bound result 1\n  Bound result 16\n  Bound result 4\n  Bound result 1\n  Bound result 3\n  Bound result 18\n  Bound result 9\n  Bound result 2\n  Bound result 0\n  Bound result 3\n  Bound result 5288\n  Bound result 2748\n  Bound result 2880\n  Bound result 5\n  Bound result 6\n  Bound result 4\n  Bound result 2\n  Bound result 1756\n  Bound result 4\n  Bound result 3\n  Bound result 3\n  Bound result 1\n  Bound result 1\n  Bound result 3\n  Bound result 7\n  Bound result 6193\n  Bound result 277\n  Bound result 5\n  Bound result 5\n  Bound result 11\n  Bound result 16\n  Bound result 1\n  Bound result 15\n  Bound result 3\n  Bound result 3\n  Bound result 69\n  Bound result 2\n  Bound result 20\n  Bound result 9\n  Bound result 7\n  Bound result 4084\n  Bound result 3\n  Bound result 60\n  Bound result 1\n  Bound result 73\n  Bound result 5057\n  Bound result 7\n  Bound result 42\n  Bound result 2773\n  Bound result 1\n  Bound result 6\n  Bound result 10\n  Bound result 2\n  Bound result 1\n  Bound result 7\n  Bound result 3783\n  Bound result 160\n  Bound result 2\n  Bound result 4\n  Bound result 5\n  Bound result 3600\n  Bound result 214\n  Bound result 3\n  Bound result 1\n  Bound result 17\n  Bound result 967\n  Bound result 7\n  Bound result 7\n  Bound result 6\n  Bound result 6\n  Bound result 3\n  Bound result 7\n  Bound result 20\n  Bound result 5\n  Bound result 69\n  Bound result 5\n  Bound result 68\n  Bound result 1\n  Bound result 3\n  Bound result 3276\n  Bound result 6\n  Bound result 70\n  Bound result 1\n  Bound result 2\n  Bound result 3\n  Bound result 4\n  Bound result 5\n  Bound result 6\n  Bound result 7\n  Bound result 1\n  Bound result 2\n  Bound result 3\n  Bound result 4\n  Bound result 5\n  Bound result 6\n  Bound result 7\n\n[PASS] testHandlerExercisesEveryTransition() (gas: 74748874)\nLogs:\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 3600\n  Bound result 1\n  Bound result 0\n  Bound result 1\n  Bound result 1\n  Bound result 7200\n  Bound result 7200\n  Bound result 7200\n  Bound result 3600\n  Bound result 1\n  Bound result 2\n  Bound result 3\n  Bound result 4\n  Bound result 5\n  Bound result 6\n  Bound result 7\n  Bound result 1\n  Bound result 2\n  Bound result 3\n  Bound result 4\n  Bound result 5\n  Bound result 6\n  Bound result 7\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 18.21s (18.28s CPU time)\n\nRan 4 test suites in 18.22s (18.44s CPU time): 55 tests passed, 0 failed, 0 skipped (55 total tests)\n","passed":true},{"durationMs":47,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Pepeolithic.approve(address,uint256)\",\"Pepeolithic.buy(uint256,uint256)\",\"Pepeolithic.buyLeftover()\",\"Pepeolithic.claimSeat(bytes32[])\",\"Pepeolithic.freeze(uint256,string)\",\"Pepeolithic.releaseUnclaimed()\",\"Pepeolithic.safeTransferFrom(address,address,uint256)\",\"Pepeolithic.safeTransferFrom(address,address,uint256,bytes)\",\"Pepeolithic.setApprovalForAll(address,bool)\",\"Pepeolithic.sweep(uint256,uint256)\",\"Pepeolithic.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"DEPENDENCIES.md\":24,\"README.md\":123,\"foundry.toml\":18,\"launch.json\":27,\"remappings.txt\":2,\"script/check_launch.py\":50,\"src/Pepeolithic.sol\":357,\"test/Pepeolithic.t.sol\":765,\"test/PepeolithicInvariant.t.sol\":351,\"test/PepeolithicMainnet.t.sol\":297,\"test/PepeolithicProperties.t.sol\":298,\"test/README.md\":50,\"test/support/MainnetSetup.sol\":67,\"test/support/PepeolithicSetup.sol\":123},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"27f7cb5983ff1e2a1c023db0cd406e026ab3c51ddeb591ccf54ae5bb1604247a","verifiedTreeHash":"0d1d367de611feecb965faae39c87f7e7cb3198f","verifierVersion":"0.1.0+ad90ce4c"},{"checks":[{"durationMs":19281,"exitCode":0,"name":"build","output":"Compiling 39 files with Solc 0.8.26\nSolc 0.8.26 finished in 19.14s\nCompiler run successful!\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/Pepeolithic.sol:339:34\n    │\n339 │         if (label == bytes32(0)) revert InvalidConfig();\n    │                                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/Pepeolithic.sol:344:50\n    │\n344 │             else if (padding || character > 127) revert InvalidConfig();\n    │                                                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Pepeolithic.sol:164:13\n    │\n164 │         if (block.timestamp < opens || block.timestamp >= caveClose(c)) revert NotOpen();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Pepeolithic.sol:164:40\n    │\n164 │         if (block.timestamp < opens || block.timestamp >= caveClose(c)) revert NotOpen();\n    │                                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Pepeolithic.sol:171:13\n    │\n171 │         if (block.timestamp < opens || block.timestamp >= caveClose(c)) revert NotOpen();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Pepeolithic.sol:171:40\n    │\n171 │         if (block.timestamp < opens || block.timestamp >= caveClose(c)) revert NotOpen();\n    │                                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/Pepeolithic.sol:181:9\n    │\n181 │         emit Bought(id, msg.sender, price);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Pepeolithic.sol:186:13\n    │\n186 │         if (block.timestamp < startTime) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Pepeolithic.sol:202:13\n    │\n202 │         if (block.timestamp < startTime + 8 * caveLength) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Pepeolithic.sol:218:13\n    │\n218 │         if (block.timestamp < caveClose(c)) revert NotClosed();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/Pepeolithic.sol:129:23\n    │\n129 │         if (id > 736) revert InvalidPiece();\n    │                       ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/Pepeolithic.sol:349:30\n    │\n349 │         if (c == 0 || c > 7) revert InvalidCave();\n    │                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/Pepeolithic.sol:354:31\n    │\n354 │         if (r == 0 || r > 21) revert InvalidRound();\n    │                               ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Pepeolithic.sol:240:61\n    │\n240 │         if (value.length == 0 || value[value.length - 1] != bytes1(\"/\")) revert InvalidBase();\n    │                                                             ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'bytes1' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Pepeolithic.sol:253:87\n    │\n253 │             slot == 5 ? \"gathering/\" : string.concat(\"line-\", string(abi.encodePacked(uint8(48 + slot))), \"/\");\n    │                                                                                       ━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Pepeolithic.sol:254:66\n    │\n254 │         return string.concat(base, path, string(abi.encodePacked(uint8(48 + r / 10), uint8(48 + r % 10))), \".json\");\n    │                                                                  ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Pepeolithic.sol:254:86\n    │\n254 │         return string.concat(base, path, string(abi.encodePacked(uint8(48 + r / 10), uint8(48 + r % 10))), \".json\");\n    │                                                                                      ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Pepeolithic.sol:286:57\n    │\n286 │                 return Math.max(2 * floorPrice, next >> quiet);\n    │                                                         ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Pepeolithic.sol:300:15\n    │\n300 │             ++segments;\n    │               ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-oz-erc721-mint]: `ERC721._mint` does not check that the recipient can receive the token; use `_safeMint`\n    ╭▸ src/Pepeolithic.sol:323:9\n    │\n323 │         _mint(to, id);\n    │         ━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-oz-erc721-mint\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Pepeolithic.sol:330:16\n    │\n330 │         while (length < 32 && label[length] != 0) ++length;\n    │                ━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Pepeolithic.sol:344:22\n    │\n344 │             else if (padding || character > 127) revert InvalidConfig();\n    │                      ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\n","passed":true},{"durationMs":19721,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 8 tests for test/PepeolithicCallbacks.t.sol:PepeolithicCallbacksTest\n[PASS] testCaughtNestedFalseDoesNotConsumeSaleOrPayment() (gas: 938366)\n[PASS] testCaughtNestedRevertDoesNotConsumeSaleOrPayment() (gas: 937858)\n[PASS] testNestedBuyCannotReuseTheFinalSaleSlot() (gas: 505053)\n[PASS] testNestedLeftoverCannotExceedFreeInventory() (gas: 50525838)\n[PASS] testOuterFailureRollsBackNestedSeatClaim() (gas: 1208537)\n[PASS] testOuterFalseRollsBackBothLeftoversAndSharedCursor() (gas: 982046)\n[PASS] testOuterFalseRollsBackSuccessfulNestedSale() (gas: 1536892)\n[PASS] testOuterRevertRollsBackSuccessfulNestedSale() (gas: 1536456)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 71.49ms (34.47ms CPU time)\n\nRan 10 tests for test/PepeolithicMainnet.t.sol:PepeolithicMainnetTest\n[PASS] testMainnetAll400SalesAnd335LeftoversFinishExactly737() (gas: 93244812)\n[PASS] testMainnetConstructorEmptyEVMAndExactValues() (gas: 234418)\n[PASS] testMainnetEveryScheduleBoundary() (gas: 35397543)\n[PASS] testMainnetHalvingFractionalKnotsAndFloorClamp() (gas: 256694)\n[PASS] testMainnetHighest147RoundLadderFitsUint256() (gas: 36903089)\n[PASS] testMainnetLaterSaleReplacesLastPriceAndHalfOpeningBound() (gas: 1355470)\n[PASS] testMainnetMetadataAllCavesAndPermanentFreeze() (gas: 66952757)\n[PASS] testMainnetPaymentRollbackAndEvents() (gas: 831014)\n[PASS] testMainnetQuietLadderAndFloorBuyIgnored() (gas: 637489)\n[PASS] testMainnetSortedProofClaimAndRelease() (gas: 301949)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 71.54ms (131.39ms CPU time)\n\nRan 30 tests for test/Pepeolithic.t.sol:PepeolithicTest\n[PASS] testAll335SeatsInIdOrderAndMerkleExhaustion() (gas: 49642027)\n[PASS] testAll737EventuallyMintedExactlyOnce() (gas: 57915696)\n[PASS] testBuyAndQuoteTimeBoundaries() (gas: 691279)\n[PASS] testBuyEventAndDirectBurnPayment() (gas: 320903)\n[PASS] testClaimProofStartAndDuplicate() (gas: 315080)\n[PASS] testCoinReentrySeesCompletedSaleAndCannotDuplicatePiece() (gas: 751690)\n[PASS] testConstructorWithoutCoinCodeAndFixedDeployment() (gas: 174212)\n[PASS] testERC721TransfersApprovalsAndNoReceiverCallbacks() (gas: 811912)\n[PASS] testEveryPieceAndSaleCount() (gas: 9470948)\n[PASS] testEverySaleSlotBoughtInOrderAndAllSalesExhausted() (gas: 63856939)\n[PASS] testFalseAndRevertingCoinRollbackEntireBuy() (gas: 1275690)\n[PASS] testFreezeOnlyAdminOnceAndValidBase() (gas: 233830)\n[PASS] testFuzzHalvingPriceIsBoundedAndMonotone(uint256) (runs: 256, μ: 51763, ~: 51660)\nLogs:\n  Bound result 991\n\n[PASS] testHalvingSegmentEndsAndInterior() (gas: 188844)\n[PASS] testInterfacesRoyaltyAndNonexistentURI() (gas: 83965)\n[PASS] testInvalidConfiguration() (gas: 5576)\n[PASS] testLadderAcrossCavesAndUnboughtRoundNotSnapshot() (gas: 635856)\n[PASS] testLadderDoublesLastLineSaleAndHalvesQuietRounds() (gas: 903635)\n[PASS] testLadderFloorBuysIgnoredAndStoredOpeningStable() (gas: 1013662)\n[PASS] testLastLineSaleReplacesEarlierSaleAndHalfOpeningMinimum() (gas: 1170907)\n[PASS] testLeftoverFailureRollsBackCursorAndReentryUsesNextPiece() (gas: 808452)\n[PASS] testMintToContractWithoutReceiver() (gas: 518998)\n[PASS] testMissingBoolOrMissingAllowanceRejectsBuy() (gas: 428452)\n[PASS] testQuietFirstBuyAtFloorDoesNotRaiseNextOpening() (gas: 271073)\n[PASS] testRehearsalFractionalSegments() (gas: 94065)\n[PASS] testReleaseTimingPermissionlessAndClaimStopsOnlyOnRelease() (gas: 543102)\n[PASS] testRuntimePassesProtectedOpcodeScanAndSizeLimit() (gas: 3630547)\n[PASS] testSweepBoundariesPartialBatchesAndEvents() (gas: 1936589)\n[PASS] testURIsIncludingEndpointsRoundsSlotsAndFrozenCaves() (gas: 12549467)\n[PASS] testWindowsAndInvalidIndices() (gas: 2286269)\nSuite result: ok. 30 passed; 0 failed; 0 skipped; finished in 71.60ms (170.69ms CPU time)\n\nRan 13 tests for test/PepeolithicProperties.t.sol:PepeolithicPropertiesTest\n[PASS] testConstructorRejectsZeroAddressesAndOverflowingSchedule() (gas: 6474)\n[PASS] testEveryMintPathWorksWithAReceiverThatRejectsCallbacks() (gas: 1458194)\n[PASS] testFullWidthInterpolationDoesNotOverflow() (gas: 118389)\n[PASS] testFuzzEveryCaveRoundBoundary(uint8,uint8) (runs: 1000, μ: 507166, ~: 488293)\nLogs:\n  Bound result 1\n  Bound result 2\n\n[PASS] testFuzzFractionalCurveBoundsAndPayment(uint96,uint96,uint32,uint32) (runs: 1000, μ: 476292, ~: 473310)\nLogs:\n  Bound result 75\n  Bound result 72591704069164130608105147903\n  Bound result 3\n  Bound result 0\n\n[PASS] testFuzzHalvingKnotsAcrossConstructorPrices(uint96,uint8,uint32) (runs: 1000, μ: 351157, ~: 274028)\nLogs:\n  Bound result 3954\n  Bound result 7\n  Bound result 203\n\n[PASS] testFuzzRoyaltyRoundingIdentity(uint256,uint256) (runs: 1000, μ: 12256, ~: 12256)\n[PASS] testInsufficientBalanceAndLeftoverAllowancePreserveInventory() (gas: 747747)\n[PASS] testLabelsRejectMalformedPaddingAndAcceptAll32Bytes() (gas: 6753)\n[PASS] testMaximumRehearsalLadderRemainsLiveThroughAll147Rounds() (gas: 34980862)\n[PASS] testMerkleProofCannotBeReusedByAnotherWalletOrAltered() (gas: 245132)\n[PASS] testNativeCurrencyIsRejectedByAllIssuancePaths() (gas: 183191)\n[PASS] testOneWeiFloorOddOpeningAndSubsecondSegments() (gas: 208289)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 75.96ms (292.03ms CPU time)\n\nRan 6 tests for test/PepeolithicAdversarial.t.sol:PepeolithicAdversarialTest\n[PASS] testDistinctCavesCanFreezeBeforeMintWithoutChangingOtherBases() (gas: 1895390)\n[PASS] testFuzzFullWeekLadderAgainstForwardModel(uint256) (runs: 128, μ: 46517335, ~: 46579134)\n[PASS] testFuzzInvalidCaveRejectedAcrossValidatedAPI(uint256) (runs: 1000, μ: 159045, ~: 157125)\nLogs:\n  Bound result 98010382573748185939421683690328615869828486734818635751\n\n[PASS] testFuzzInvalidRoundRejectedAcrossValidatedAPI(uint256,uint8) (runs: 1000, μ: 96064, ~: 94410)\nLogs:\n  Bound result 2\n\n[PASS] testMaximumIndicesRevertWithCustomErrorsRatherThanArithmeticPanics() (gas: 274244)\nLogs:\n  Bound result 115792089237316195423570985008687907853269984665640564039457584007913129639935\n  Bound result 7\n  Bound result 115792089237316195423570985008687907853269984665640564039457584007913129639935\n\n[PASS] testTransferredTokensDoNotTransferClaimsOrAdminAuthority() (gas: 496496)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 1.10s (2.27s CPU time)\n\nRan 2 tests for test/PepeolithicInvariant.t.sol:PepeolithicInvariantTest\n[PASS] invariant_supplyPaymentAndPermanentTransitions() (runs: 256, calls: 32768, reverts: 0)\n\n╭-----------------------------+-------------+-------+---------+----------╮\n| Contract                    | Selector    | Calls | Reverts | Discards |\n+========================================================================+\n| PepeolithicLifecycleHandler | advanceTime | 4084  | 0       | 0        |\n|-----------------------------+-------------+-------+---------+----------|\n| PepeolithicLifecycleHandler | buy         | 4163  | 0       | 0        |\n|-----------------------------+-------------+-------+---------+----------|\n| PepeolithicLifecycleHandler | buyLeftover | 4151  | 0       | 0        |\n|-----------------------------+-------------+-------+---------+----------|\n| PepeolithicLifecycleHandler | claim       | 4073  | 0       | 0        |\n|-----------------------------+-------------+-------+---------+----------|\n| PepeolithicLifecycleHandler | freeze      | 3994  | 0       | 0        |\n|-----------------------------+-------------+-------+---------+----------|\n| PepeolithicLifecycleHandler | release     | 4100  | 0       | 0        |\n|-----------------------------+-------------+-------+---------+----------|\n| PepeolithicLifecycleHandler | sweep       | 4145  | 0       | 0        |\n|-----------------------------+-------------+-------+---------+----------|\n| PepeolithicLifecycleHandler | transfer    | 4058  | 0       | 0        |\n╰-----------------------------+-------------+-------+---------+----------╯\n\nLogs:\n  Bound result 2\n  Bound result 20\n  Bound result 6\n  Bound result 9\n  Bound result 1\n  Bound result 75\n  Bound result 3\n  Bound result 2\n  Bound result 0\n  Bound result 1\n  Bound result 2\n  Bound result 5\n  Bound result 18\n  Bound result 5\n  Bound result 14\n  Bound result 3\n  Bound result 20\n  Bound result 1\n  Bound result 65\n  Bound result 6\n  Bound result 45\n  Bound result 5\n  Bound result 3\n  Bound result 4\n  Bound result 96\n  Bound result 6\n  Bound result 1\n  Bound result 4\n  Bound result 18\n  Bound result 90\n  Bound result 6\n  Bound result 22\n  Bound result 1\n  Bound result 75\n  Bound result 5\n  Bound result 6\n  Bound result 4\n  Bound result 100\n  Bound result 5\n  Bound result 16\n  Bound result 2\n  Bound result 1\n  Bound result 3\n  Bound result 7\n  Bound result 77\n  Bound result 7176\n  Bound result 3\n  Bound result 3\n  Bound result 53\n  Bound result 2\n  Bound result 6\n  Bound result 87\n  Bound result 2\n  Bound result 97\n  Bound result 6\n  Bound result 7\n  Bound result 28\n  Bound result 4\n  Bound result 5\n  Bound result 1\n  Bound result 7\n  Bound result 21\n  Bound result 4\n  Bound result 1\n  Bound result 5\n  Bound result 94\n  Bound result 7\n  Bound result 11\n  Bound result 5628\n  Bound result 7\n  Bound result 39\n  Bound result 4\n  Bound result 60\n  Bound result 3\n  Bound result 4\n  Bound result 15\n  Bound result 4\n  Bound result 7\n  Bound result 3\n  Bound result 74\n  Bound result 5\n  Bound result 60\n  Bound result 5\n  Bound result 2\n  Bound result 1\n  Bound result 3\n  Bound result 11\n  Bound result 8\n  Bound result 99\n  Bound result 6232\n  Bound result 2\n  Bound result 5\n  Bound result 55\n  Bound result 3\n  Bound result 5\n  Bound result 23\n  Bound result 4\n  Bound result 87\n  Bound result 7\n  Bound result 15\n  Bound result 6\n  Bound result 7\n  Bound result 13\n  Bound result 2\n  Bound result 39\n  Bound result 1\n  Bound result 2\n  Bound result 3\n  Bound result 4\n  Bound result 5\n  Bound result 6\n  Bound result 7\n  Bound result 1\n  Bound result 2\n  Bound result 3\n  Bound result 4\n  Bound result 5\n  Bound result 6\n  Bound result 7\n\n[PASS] testHandlerExercisesEveryTransition() (gas: 74906709)\nLogs:\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 3600\n  Bound result 1\n  Bound result 0\n  Bound result 1\n  Bound result 1\n  Bound result 7200\n  Bound result 7200\n  Bound result 7200\n  Bound result 3600\n  Bound result 1\n  Bound result 2\n  Bound result 3\n  Bound result 4\n  Bound result 5\n  Bound result 6\n  Bound result 7\n  Bound result 1\n  Bound result 2\n  Bound result 3\n  Bound result 4\n  Bound result 5\n  Bound result 6\n  Bound result 7\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 19.63s (19.67s CPU time)\n\nRan 6 test suites in 19.63s (21.02s CPU time): 69 tests passed, 0 failed, 0 skipped (69 total tests)\n","passed":true},{"durationMs":49,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Pepeolithic.approve(address,uint256)\",\"Pepeolithic.buy(uint256,uint256)\",\"Pepeolithic.buyLeftover()\",\"Pepeolithic.claimSeat(bytes32[])\",\"Pepeolithic.freeze(uint256,string)\",\"Pepeolithic.releaseUnclaimed()\",\"Pepeolithic.safeTransferFrom(address,address,uint256)\",\"Pepeolithic.safeTransferFrom(address,address,uint256,bytes)\",\"Pepeolithic.setApprovalForAll(address,bool)\",\"Pepeolithic.sweep(uint256,uint256)\",\"Pepeolithic.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"DEPENDENCIES.md\":24,\"README.md\":123,\"foundry.toml\":18,\"launch.json\":27,\"remappings.txt\":2,\"script/check_launch.py\":50,\"src/Pepeolithic.sol\":357,\"test/Pepeolithic.t.sol\":765,\"test/PepeolithicAdversarial.t.sol\":213,\"test/PepeolithicCallbacks.t.sol\":291,\"test/PepeolithicInvariant.t.sol\":357,\"test/PepeolithicMainnet.t.sol\":297,\"test/PepeolithicProperties.t.sol\":298,\"test/README.md\":79,\"test/support/MainnetSetup.sol\":67,\"test/support/PepeolithicSetup.sol\":123},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"3c1a8da30d8e6e870827bfe77f2f42b0a5ffc51aff596101e30c7bf3c5c9359e","verifiedTreeHash":"88faf8cba7469afd6396bd52abc316912f34e33d","verifierVersion":"0.1.0+ad90ce4c"},{"checks":[{"durationMs":15988,"exitCode":0,"name":"build","output":"Compiling 37 files with Solc 0.8.26\nSolc 0.8.26 finished in 15.86s\nCompiler run successful!\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/Pepeolithic.sol:339:34\n    │\n339 │         if (label == bytes32(0)) revert InvalidConfig();\n    │                                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/Pepeolithic.sol:344:50\n    │\n344 │             else if (padding || character > 127) revert InvalidConfig();\n    │                                                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Pepeolithic.sol:164:13\n    │\n164 │         if (block.timestamp < opens || block.timestamp >= caveClose(c)) revert NotOpen();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Pepeolithic.sol:164:40\n    │\n164 │         if (block.timestamp < opens || block.timestamp >= caveClose(c)) revert NotOpen();\n    │                                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Pepeolithic.sol:171:13\n    │\n171 │         if (block.timestamp < opens || block.timestamp >= caveClose(c)) revert NotOpen();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Pepeolithic.sol:171:40\n    │\n171 │         if (block.timestamp < opens || block.timestamp >= caveClose(c)) revert NotOpen();\n    │                                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/Pepeolithic.sol:181:9\n    │\n181 │         emit Bought(id, msg.sender, price);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Pepeolithic.sol:186:13\n    │\n186 │         if (block.timestamp < startTime) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Pepeolithic.sol:202:13\n    │\n202 │         if (block.timestamp < startTime + 8 * caveLength) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Pepeolithic.sol:218:13\n    │\n218 │         if (block.timestamp < caveClose(c)) revert NotClosed();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/Pepeolithic.sol:129:23\n    │\n129 │         if (id > 736) revert InvalidPiece();\n    │                       ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/Pepeolithic.sol:349:30\n    │\n349 │         if (c == 0 || c > 7) revert InvalidCave();\n    │                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/Pepeolithic.sol:354:31\n    │\n354 │         if (r == 0 || r > 21) revert InvalidRound();\n    │                               ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Pepeolithic.sol:240:61\n    │\n240 │         if (value.length == 0 || value[value.length - 1] != bytes1(\"/\")) revert InvalidBase();\n    │                                                             ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'bytes1' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Pepeolithic.sol:253:87\n    │\n253 │             slot == 5 ? \"gathering/\" : string.concat(\"line-\", string(abi.encodePacked(uint8(48 + slot))), \"/\");\n    │                                                                                       ━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Pepeolithic.sol:254:66\n    │\n254 │         return string.concat(base, path, string(abi.encodePacked(uint8(48 + r / 10), uint8(48 + r % 10))), \".json\");\n    │                                                                  ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Pepeolithic.sol:254:86\n    │\n254 │         return string.concat(base, path, string(abi.encodePacked(uint8(48 + r / 10), uint8(48 + r % 10))), \".json\");\n    │                                                                                      ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Pepeolithic.sol:286:57\n    │\n286 │                 return Math.max(2 * floorPrice, next >> quiet);\n    │                                                         ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Pepeolithic.sol:300:15\n    │\n300 │             ++segments;\n    │               ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-oz-erc721-mint]: `ERC721._mint` does not check that the recipient can receive the token; use `_safeMint`\n    ╭▸ src/Pepeolithic.sol:323:9\n    │\n323 │         _mint(to, id);\n    │         ━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-oz-erc721-mint\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Pepeolithic.sol:330:16\n    │\n330 │         while (length < 32 && label[length] != 0) ++length;\n    │                ━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Pepeolithic.sol:344:22\n    │\n344 │             else if (padding || character > 127) revert InvalidConfig();\n    │                      ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\n","passed":true},{"durationMs":19227,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 13 tests for test/PepeolithicProperties.t.sol:PepeolithicPropertiesTest\n[PASS] testConstructorRejectsZeroAddressesAndOverflowingSchedule() (gas: 6474)\n[PASS] testEveryMintPathWorksWithAReceiverThatRejectsCallbacks() (gas: 1458194)\n[PASS] testFullWidthInterpolationDoesNotOverflow() (gas: 118389)\n[PASS] testFuzzEveryCaveRoundBoundary(uint8,uint8) (runs: 1000, μ: 501269, ~: 477371)\nLogs:\n  Bound result 5\n  Bound result 3\n\n[PASS] testFuzzFractionalCurveBoundsAndPayment(uint96,uint96,uint32,uint32) (runs: 1000, μ: 476574, ~: 473813)\nLogs:\n  Bound result 4318095\n  Bound result 2210014051347136788\n  Bound result 99\n  Bound result 82\n\n[PASS] testFuzzHalvingKnotsAcrossConstructorPrices(uint96,uint8,uint32) (runs: 1000, μ: 353596, ~: 274466)\nLogs:\n  Bound result 7\n  Bound result 1\n  Bound result 28\n\n[PASS] testFuzzRoyaltyRoundingIdentity(uint256,uint256) (runs: 1000, μ: 12256, ~: 12256)\n[PASS] testInsufficientBalanceAndLeftoverAllowancePreserveInventory() (gas: 747747)\n[PASS] testLabelsRejectMalformedPaddingAndAcceptAll32Bytes() (gas: 6753)\n[PASS] testMaximumRehearsalLadderRemainsLiveThroughAll147Rounds() (gas: 34980862)\n[PASS] testMerkleProofCannotBeReusedByAnotherWalletOrAltered() (gas: 245132)\n[PASS] testNativeCurrencyIsRejectedByAllIssuancePaths() (gas: 183191)\n[PASS] testOneWeiFloorOddOpeningAndSubsecondSegments() (gas: 208289)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 75.69ms (231.18ms CPU time)\n\nRan 30 tests for test/Pepeolithic.t.sol:PepeolithicTest\n[PASS] testAll335SeatsInIdOrderAndMerkleExhaustion() (gas: 49642027)\n[PASS] testAll737EventuallyMintedExactlyOnce() (gas: 57915696)\n[PASS] testBuyAndQuoteTimeBoundaries() (gas: 691279)\n[PASS] testBuyEventAndDirectBurnPayment() (gas: 320903)\n[PASS] testClaimProofStartAndDuplicate() (gas: 315080)\n[PASS] testCoinReentrySeesCompletedSaleAndCannotDuplicatePiece() (gas: 751690)\n[PASS] testConstructorWithoutCoinCodeAndFixedDeployment() (gas: 174212)\n[PASS] testERC721TransfersApprovalsAndNoReceiverCallbacks() (gas: 811912)\n[PASS] testEveryPieceAndSaleCount() (gas: 9470948)\n[PASS] testEverySaleSlotBoughtInOrderAndAllSalesExhausted() (gas: 63856939)\n[PASS] testFalseAndRevertingCoinRollbackEntireBuy() (gas: 1275690)\n[PASS] testFreezeOnlyAdminOnceAndValidBase() (gas: 233830)\n[PASS] testFuzzHalvingPriceIsBoundedAndMonotone(uint256) (runs: 256, μ: 51777, ~: 51660)\nLogs:\n  Bound result 829\n\n[PASS] testHalvingSegmentEndsAndInterior() (gas: 188844)\n[PASS] testInterfacesRoyaltyAndNonexistentURI() (gas: 83965)\n[PASS] testInvalidConfiguration() (gas: 5576)\n[PASS] testLadderAcrossCavesAndUnboughtRoundNotSnapshot() (gas: 635856)\n[PASS] testLadderDoublesLastLineSaleAndHalvesQuietRounds() (gas: 903635)\n[PASS] testLadderFloorBuysIgnoredAndStoredOpeningStable() (gas: 1013662)\n[PASS] testLastLineSaleReplacesEarlierSaleAndHalfOpeningMinimum() (gas: 1170907)\n[PASS] testLeftoverFailureRollsBackCursorAndReentryUsesNextPiece() (gas: 808452)\n[PASS] testMintToContractWithoutReceiver() (gas: 518998)\n[PASS] testMissingBoolOrMissingAllowanceRejectsBuy() (gas: 428452)\n[PASS] testQuietFirstBuyAtFloorDoesNotRaiseNextOpening() (gas: 271073)\n[PASS] testRehearsalFractionalSegments() (gas: 94065)\n[PASS] testReleaseTimingPermissionlessAndClaimStopsOnlyOnRelease() (gas: 543102)\n[PASS] testRuntimePassesProtectedOpcodeScanAndSizeLimit() (gas: 3630547)\n[PASS] testSweepBoundariesPartialBatchesAndEvents() (gas: 1936589)\n[PASS] testURIsIncludingEndpointsRoundsSlotsAndFrozenCaves() (gas: 12549467)\n[PASS] testWindowsAndInvalidIndices() (gas: 2286269)\nSuite result: ok. 30 passed; 0 failed; 0 skipped; finished in 76.33ms (135.54ms CPU time)\n\nRan 10 tests for test/PepeolithicMainnet.t.sol:PepeolithicMainnetTest\n[PASS] testMainnetAll400SalesAnd335LeftoversFinishExactly737() (gas: 93244812)\n[PASS] testMainnetConstructorEmptyEVMAndExactValues() (gas: 234418)\n[PASS] testMainnetEveryScheduleBoundary() (gas: 35397543)\n[PASS] testMainnetHalvingFractionalKnotsAndFloorClamp() (gas: 256694)\n[PASS] testMainnetHighest147RoundLadderFitsUint256() (gas: 36903089)\n[PASS] testMainnetLaterSaleReplacesLastPriceAndHalfOpeningBound() (gas: 1355470)\n[PASS] testMainnetMetadataAllCavesAndPermanentFreeze() (gas: 66952757)\n[PASS] testMainnetPaymentRollbackAndEvents() (gas: 831014)\n[PASS] testMainnetQuietLadderAndFloorBuyIgnored() (gas: 637489)\n[PASS] testMainnetSortedProofClaimAndRelease() (gas: 301949)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 76.33ms (132.24ms CPU time)\n\nRan 2 tests for test/PepeolithicInvariant.t.sol:PepeolithicInvariantTest\n[PASS] invariant_supplyPaymentAndPermanentTransitions() (runs: 256, calls: 32768, reverts: 0)\n\n╭-----------------------------+-------------+-------+---------+----------╮\n| Contract                    | Selector    | Calls | Reverts | Discards |\n+========================================================================+\n| PepeolithicLifecycleHandler | advanceTime | 4117  | 0       | 0        |\n|-----------------------------+-------------+-------+---------+----------|\n| PepeolithicLifecycleHandler | buy         | 4116  | 0       | 0        |\n|-----------------------------+-------------+-------+---------+----------|\n| PepeolithicLifecycleHandler | buyLeftover | 4031  | 0       | 0        |\n|-----------------------------+-------------+-------+---------+----------|\n| PepeolithicLifecycleHandler | claim       | 4060  | 0       | 0        |\n|-----------------------------+-------------+-------+---------+----------|\n| PepeolithicLifecycleHandler | freeze      | 4101  | 0       | 0        |\n|-----------------------------+-------------+-------+---------+----------|\n| PepeolithicLifecycleHandler | release     | 4085  | 0       | 0        |\n|-----------------------------+-------------+-------+---------+----------|\n| PepeolithicLifecycleHandler | sweep       | 4133  | 0       | 0        |\n|-----------------------------+-------------+-------+---------+----------|\n| PepeolithicLifecycleHandler | transfer    | 4125  | 0       | 0        |\n╰-----------------------------+-------------+-------+---------+----------╯\n\nLogs:\n  Bound result 6\n  Bound result 62\n  Bound result 6\n  Bound result 80\n  Bound result 4\n  Bound result 3\n  Bound result 12\n  Bound result 5\n  Bound result 21\n  Bound result 731\n  Bound result 3\n  Bound result 18\n  Bound result 4\n  Bound result 2446\n  Bound result 4\n  Bound result 3419\n  Bound result 3\n  Bound result 1\n  Bound result 1\n  Bound result 2\n  Bound result 1\n  Bound result 52\n  Bound result 5\n  Bound result 48\n  Bound result 645\n  Bound result 6\n  Bound result 49\n  Bound result 4\n  Bound result 16\n  Bound result 5\n  Bound result 19\n  Bound result 2\n  Bound result 4\n  Bound result 103\n  Bound result 360\n  Bound result 21\n  Bound result 3116\n  Bound result 2\n  Bound result 9\n  Bound result 9\n  Bound result 7\n  Bound result 44\n  Bound result 2\n  Bound result 6\n  Bound result 4\n  Bound result 25\n  Bound result 3\n  Bound result 109\n  Bound result 1799\n  Bound result 3\n  Bound result 244\n  Bound result 3\n  Bound result 5\n  Bound result 5\n  Bound result 4\n  Bound result 16\n  Bound result 1\n  Bound result 48\n  Bound result 5\n  Bound result 1\n  Bound result 8\n  Bound result 7\n  Bound result 4\n  Bound result 6\n  Bound result 7\n  Bound result 3\n  Bound result 4\n  Bound result 4\n  Bound result 4\n  Bound result 4\n  Bound result 4\n  Bound result 6\n  Bound result 62\n  Bound result 5\n  Bound result 9\n  Bound result 2341\n  Bound result 2\n  Bound result 6\n  Bound result 7\n  Bound result 24\n  Bound result 1\n  Bound result 4\n  Bound result 21\n  Bound result 1\n  Bound result 59\n  Bound result 4\n  Bound result 21\n  Bound result 5\n  Bound result 20\n  Bound result 5\n  Bound result 6713\n  Bound result 6\n  Bound result 2\n  Bound result 3719\n  Bound result 6157\n  Bound result 2\n  Bound result 1\n  Bound result 2\n  Bound result 3\n  Bound result 4\n  Bound result 5\n  Bound result 6\n  Bound result 7\n  Bound result 1\n  Bound result 2\n  Bound result 3\n  Bound result 4\n  Bound result 5\n  Bound result 6\n  Bound result 7\n\n[PASS] testHandlerExercisesEveryTransition() (gas: 74748874)\nLogs:\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 3600\n  Bound result 1\n  Bound result 0\n  Bound result 1\n  Bound result 1\n  Bound result 7200\n  Bound result 7200\n  Bound result 7200\n  Bound result 3600\n  Bound result 1\n  Bound result 2\n  Bound result 3\n  Bound result 4\n  Bound result 5\n  Bound result 6\n  Bound result 7\n  Bound result 1\n  Bound result 2\n  Bound result 3\n  Bound result 4\n  Bound result 5\n  Bound result 6\n  Bound result 7\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 19.15s (19.21s CPU time)\n\nRan 4 test suites in 19.15s (19.37s CPU time): 55 tests passed, 0 failed, 0 skipped (55 total tests)\n","passed":true},{"durationMs":45,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Pepeolithic.approve(address,uint256)\",\"Pepeolithic.buy(uint256,uint256)\",\"Pepeolithic.buyLeftover()\",\"Pepeolithic.claimSeat(bytes32[])\",\"Pepeolithic.freeze(uint256,string)\",\"Pepeolithic.releaseUnclaimed()\",\"Pepeolithic.safeTransferFrom(address,address,uint256)\",\"Pepeolithic.safeTransferFrom(address,address,uint256,bytes)\",\"Pepeolithic.setApprovalForAll(address,bool)\",\"Pepeolithic.sweep(uint256,uint256)\",\"Pepeolithic.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"DEPENDENCIES.md\":24,\"README.md\":123,\"foundry.toml\":18,\"launch.json\":27,\"remappings.txt\":2,\"script/check_launch.py\":50,\"src/Pepeolithic.sol\":357,\"test/Pepeolithic.t.sol\":765,\"test/PepeolithicInvariant.t.sol\":351,\"test/PepeolithicMainnet.t.sol\":297,\"test/PepeolithicProperties.t.sol\":298,\"test/README.md\":50,\"test/support/MainnetSetup.sol\":67,\"test/support/PepeolithicSetup.sol\":123},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":1799,"exitCode":0,"name":"slither","output":"[medium/medium] uninitialized-local at src/Pepeolithic.sol:296: Pepeolithic._price(uint256,uint256).segments (src/Pepeolithic.sol#296) is a local variable never initialized\n[medium/medium] uninitialized-local at src/Pepeolithic.sol:340: Pepeolithic._checkLabel(bytes32).padding (src/Pepeolithic.sol#340) is a local variable never initialized\n[low/medium] timestamp at src/Pepeolithic.sol:217: Pepeolithic.sweep(uint256,uint256) (src/Pepeolithic.sol#217-233) uses timestamp for comparisons\n[low/medium] timestamp at src/Pepeolithic.sol:294: Pepeolithic._price(uint256,uint256) (src/Pepeolithic.sol#294-308) uses timestamp for comparisons\n[low/medium] timestamp at src/Pepeolithic.sol:185: Pepeolithic.claimSeat(bytes32[]) (src/Pepeolithic.sol#185-199) uses timestamp for comparisons\n[low/medium] timestamp at src/Pepeolithic.sol:168: Pepeolithic.buy(uint256,uint256) (src/Pepeolithic.sol#168-183) uses timestamp for comparisons\n[low/medium] timestamp at src/Pepeolithic.sol:162: Pepeolithic.priceNow(uint256,uint256) (src/Pepeolithic.sol#162-166) uses timestamp for comparisons\n[low/medium] timestamp at src/Pepeolithic.sol:201: Pepeolithic.releaseUnclaimed() (src/Pepeolithic.sol#201-206) uses timestamp for comparisons","passed":true},{"durationMs":360,"exitCode":0,"name":"aderyn","output":"[low] costly-loop at src/Pepeolithic.sol:223: Costly operations inside loop\n[low] literal-instead-of-constant at src/Pepeolithic.sol:90: Literal Instead of Constant (37 places)\n[low] require-revert-in-loop at src/Pepeolithic.sol:223: Loop Contains `require`/`revert` (2 places)\n[low] state-variable-could-be-immutable at src/Pepeolithic.sol:42: State Variable Could Be Immutable (9 places)\n[low] unchecked-return at src/Pepeolithic.sol:123: Unchecked Return (3 places)\n[low] uninitialized-local-variable at src/Pepeolithic.sol:190: Uninitialized Local Variable (5 places)\n[low] unsafe-oz-erc721-mint at src/Pepeolithic.sol:323: Unsafe `ERC721::_mint()`\n[low] unused-public-function at src/Pepeolithic.sol:158: Public Function Not Used Internally (2 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"5fbe3a7ca02369d7b81eb73e326438edd2180f28e1c11092b78a661653d8a5fa","verifiedTreeHash":"d77a97d2b4fab71e0e3a20489d2e5d033816d4d2","verifierVersion":"0.1.0+ad90ce4c"}]}