{"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":"9aacd9d4-3dc5-4d67-a289-e4bb70208517","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"f7f68caa530a40dde9214b1d7c07940329bae71070f16cbf34a8f25b13014a4f","dependsOn":["audit_imported_code"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"2d7d84a1a9972f1497e5bc68a704cbf42294d08c62d2868f102ffe3b909b9b51","skillId":"adapt-contract-project","tools":[]},"key":"adapt_contract_project","kind":"code","role":"implement","skillHash":"2d7d84a1a9972f1497e5bc68a704cbf42294d08c62d2868f102ffe3b909b9b51","skillId":"adapt-contract-project","state":"accepted"},{"acceptedSubmissionHash":null,"dependsOn":["adapt_contract_project","write_foundry_tests","manifest"],"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":"waiting"},{"acceptedSubmissionHash":null,"dependsOn":["adapt_contract_project","write_foundry_tests","manifest"],"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":"waiting"},{"acceptedSubmissionHash":"c2bf843913d6ff6b2ed071b6465bf49faeed6f1588993cbf109920388768b6f2","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"9897597976b0e72440db7ca402d225aea20f3d37205ba53e7df2400ff80f29cc","skillId":"audit-imported-code","tools":[]},"key":"audit_imported_code","kind":"code","role":"review","skillHash":"9897597976b0e72440db7ca402d225aea20f3d37205ba53e7df2400ff80f29cc","skillId":"audit-imported-code","state":"accepted"},{"acceptedSubmissionHash":null,"dependsOn":["adapt_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"af3aa01159bbf354f621cafa5c0006f6169e0938a8b015be508b7377dbf165bc","skillId":"audit-judge","tools":[]},"key":"audit_judge","kind":"code","role":"review","skillHash":"af3aa01159bbf354f621cafa5c0006f6169e0938a8b015be508b7377dbf165bc","skillId":"audit-judge","state":"waiting"},{"acceptedSubmissionHash":null,"dependsOn":["adapt_contract_project","write_foundry_tests","manifest"],"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":"waiting"},{"acceptedSubmissionHash":null,"dependsOn":["adapt_contract_project","write_foundry_tests","manifest"],"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":"waiting"},{"acceptedSubmissionHash":null,"dependsOn":["audit_imported_code","adapt_contract_project","write_foundry_tests"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"failed"},{"acceptedSubmissionHash":"38a283b6a65714b5bfdad9cd31201c69b5856220f83f0926e9d859675fb0fc47","dependsOn":["adapt_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":"Launch hmm from this repository as it is: a custom_token launch on Ethereum mainnet, paired with IMD.\n\nToken: contract HmmToken (src/HmmToken.sol), name \"hmm\", symbol HMM, 18 decimals, constructorArgs [], totalSupply 1000000000000000000000000000 (1,000,000,000 HMM minted once to msg.sender, the factory). No owner, no mint or burn after construction, no fee or rule on transfer.\n\nApplication contracts, in this order:\n1. SwarmOracleAdapter (src/SwarmOracleAdapter.sol), constructorArgs [\"0xa43e6f75ee006411f79ac1c84120606c2330de82\", \"0x5598aa9146215bc13eb26f2c692ad1461fd32982\", \"5\", \"4\", \"0x0000000000000000000000000000000000000000\"]\n2. HmmMine (src/HmmMine.sol), constructorArgs [\"$token\", \"0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7\", \"0xa43e6f75ee006411f79ac1c84120606c2330de82\", \"0x6f7261636c652e72657175657374406f7261636c652d31000000000000000000\", \"0x876c2fb3eaa91d32ef03186853bb82433b949a71\", \"$contract:SwarmOracleAdapter\", \"0x0000000000000000000000000000000000000000\", \"0x39c593c1bc4d91e42d797456077586f6058ebf67\", \"500\", \"600\", \"15552000\", \"0\"]\n\nHmmMine's constructor calls bind() on the SwarmOracleAdapter deployed just before it (an earlier contract of this launch); it moves no tokens. The fourth HmmMine argument is bytes32(\"oracle.request@oracle-1\").\n\nEconomics, copied into launch.json exactly: poolBps 2500, initialMarketCapWei 10000000000000000000000 (10,000 IMD), remainderTo 0x876c2fb3eaa91d32ef03186853bb82433b949a71.\n\nThe remainder goes to the GenesisForwarder at 0x876c2fb3eaa91d32ef03186853bb82433b949a71, deployed earlier from src/GenesisForwarder.sol with registry 0x7c9d5ee697bff5ac4f10e2e54d3f40c44e48fe23 and mineName bytes32(\"HmmMine\"). After launch, anyone calls forward(launchNumber): it reads this launch from the registry, checks the HmmMine artifact mines this token and names this forwarder, moves the whole remainder into it and starts mining.\n\nWhat it does: HMM is mined by asking the IMD swarm. Anyone proposes a question in HmmMine (the mine writes the oracle.request JSON itself from validated fields) and backs it with IMD; once it holds the Intake price it is asked through the IMD Intake (requestWithFailure) with SwarmOracleAdapter as the callback target. Answers signed by the IMD oracle signer for the adapter (panel >= 5, quorum >= 4, agreed >= quorum and a majority) credit the current 10-minute round; backers share the round's emission pro-rata to IMD paid. Emission halves every 180 days and never exceeds the reserve; 5% of each round goes to the dev address. The steward argument is the zero address: nobody can change the adapter, the action id or any rule after launch; there are no owner powers at all.\n\nKeep contract logic, names, constructor arguments, fee rules and permissions exactly as they are; adapt the Foundry project only as much as the launch factory requires. The test suite (forge test) must stay green.","parentJobId":null,"planHash":"d725647cad88aadd592c5a2fef03fce9fb9e1ee3390ac6b912086ae658b8bfa7","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"9aacd9d4-3dc5-4d67-a289-e4bb70208517","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1551-launch-hmm-repository-custom-token"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"52584","feedbackHash":"d012ad170e615e87e665a4b408479d18290e749fee46e42e8dca7ff28cb68d1a","nodeKey":"adapt_contract_project","submissionHash":"f7f68caa530a40dde9214b1d7c07940329bae71070f16cbf34a8f25b13014a4f","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52604","feedbackHash":"185c67b2c12c63704619e998a0ab44164b7c5c1e06757a922dd3f61942907721","nodeKey":"audit_imported_code","submissionHash":"c2bf843913d6ff6b2ed071b6465bf49faeed6f1588993cbf109920388768b6f2","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51318","feedbackHash":"2f5640fdf88e49e718f8bea63858c6ed36439d3ddbafd70097a9e716fbb972ee","nodeKey":"write_foundry_tests","submissionHash":"38a283b6a65714b5bfdad9cd31201c69b5856220f83f0926e9d859675fb0fc47","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"d7c5e8ea0721ce3211a2a28dac8189e4e2e30a9e6546b67d2e276a9d643a59b8","state":"blocked","submissions":[{"artifacts":[],"attempt":1,"bundleHash":"ac6a45185d01372c197fe18447db025e0ee7046912395e70951b9c4108ad3cd8","device":"c7b1db4d25939bd5","findings":[{"description":"The pinned OracleAttestationConsumer checks both expiry and issuedAt <= block.timestamp + 5 minutes. SwarmOracleAdapter._check checks only expiresAt. A correctly signed attestation issued farther in the future is therefore accepted now, although the canonical verifier rejects it as not yet valid. This is a protocol conformance gap; exploitation requires a valid future-dated signature from the configured signer, not merely arbitrary attacker calldata. Keep the requested immutable signer and zero-steward launch configuration while enforcing the canonical validity window.","line":187,"path":"src/SwarmOracleAdapter.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {SwarmOracleAdapter} from \"src/SwarmOracleAdapter.sol\";\n\ncontract FutureAttestationProof is Test {\n    function test_rejectsAnAttestationOutsideTheProtocolIssuedAtTolerance() public {\n        vm.chainId(1);\n        vm.warp(1_800_000_000);\n        uint256 testSignerKey = 0xA11CE;\n        SwarmOracleAdapter adapter = new SwarmOracleAdapter(\n            makeAddr(\"intake\"), vm.addr(testSignerKey), 5, 4, address(this)\n        );\n        SwarmOracleAdapter.Attestation memory a;\n        a.requestId = keccak256(\"future oracle request\");\n        a.chainId = 1;\n        a.questionHash = keccak256(\"question\");\n        a.answerType = 0;\n        a.answer = abi.encode(true);\n        a.panelSize = 5;\n        a.quorum = 4;\n        a.agreed = 4;\n        a.issuedAt = uint64(block.timestamp + 301);\n        a.expiresAt = uint64(block.timestamp + 1 days);\n        (uint8 v, bytes32 r, bytes32 s) = vm.sign(testSignerKey, adapter.digest(a, 1, address(adapter)));\n        bytes memory signature = abi.encodePacked(r, s, v);\n\n        // OracleAttestationConsumer._verifyAttestation allows at most five minutes of clock drift.\n        assertTrue(adapter.check(a, signature) != bytes32(0), \"future attestation accepted beyond 300-second tolerance\");\n        vm.warp(block.timestamp + 1);\n        assertEq(adapter.check(a, signature), bytes32(0), \"the exact 300-second boundary is valid\");\n    }\n}","reproduction":"Run the supplied self-contained proof with forge test --match-path test/scratch/FutureAttestationProof.t.sol -vv. At chainId 1 and timestamp 1800000000, sign an otherwise valid 5/4/4 attestation for the actual adapter domain with issuedAt=1800000301 and expiresAt=1800086400. Expected: adapter.check returns a rejection until timestamp 1800000001 (the exact five-minute tolerance boundary). Actual: check returns bytes32(0) immediately. The proof was run against the unchanged source and failed with: future attestation accepted beyond 300-second tolerance.","severity":"low","title":"Adapter accepts attestations issued beyond the protocol clock-drift tolerance"},{"description":"The pinned oracle-consumer reference requires a deadline after which the requester can clear a pending request, because the Intake callback is attempted only once. HmmMine has a funding deadline and refund path only for Open questions. Once Asked, the only terminal transitions are credit and fail, both restricted to the recorded adapter, and there is no timeout endpoint. A completed but undelivered callback consequently leaves the question permanently shown as pending. This is a liveness/status defect, not a claim that spent IMD should be refunded or that an unanswered question should earn HMM.","line":382,"path":"src/HmmMine.sol","reproduction":"Reproduced locally with the existing real Intake implementation and a mine constructed with steward=address(0): Alice approves and proposes a valid default 5/4 question for 500000000000000000 IMD; record its Intake request id rid. The authorized writer calls intake.complete(rid, 0, keccak256(hex\"01\"), \"\", hex\"01\"). The malformed callback cannot decode: delivered=false, while intake.requests(rid).completed=true. Warp to question.deadline + 365 days. From Alice, mine.fail(rid, 2, bytes32(\"timeout\")) reverts NotAdapter (0xf521d159), and mine.refund(id) reverts NotRefundable (0x3742d1f6). There is no other expiry/close function. Actual question.status remains Asked (2), treasury has the spent 0.5 IMD, and assigned remains zero. Expected: after a bounded answer deadline the requester can explicitly close this stale question without receiving a refund or mining rewards. The ordinary Intake completion cannot be retried because it is already marked completed.","severity":"low","title":"Paid requests have no requester-accessible timeout after a lost callback"}],"hash":"38a283b6a65714b5bfdad9cd31201c69b5856220f83f0926e9d859675fb0fc47","nodeId":"a786dde9-5703-4511-b719-70284842fe46","outcome":"completed","summary":"Added failure-path, oracle conformance, fuzz, and invariant tests.\n\nOffline verification passed: `forge build` and `forge test` — 115 passed, 0 failed.\n\nReported two low-severity defects in [.imd-findings.json](/home/worker/.identitymd/work/9aacd9d4-3dc5-4d67-a289-e4bb70208517/a786dde9-5703-4511-b719-70284842fe46/.imd-findings.json): missing future-timestamp validation and missing pending-request timeout recovery. Includes a verified failing proof for the timestamp defect.","treeHash":"ac9261f7354106637c5fe250000d175390f1cd68","usage":{"cachedInputTokens":2537216,"inputTokens":119868,"model":"gpt-6-astra","outputTokens":30346,"runtime":"codex","turns":9,"wallClockMs":1128624}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"9e17b97b8ac7c97a","findings":[{"citation":"resolved","description":"The brief fixes HmmMine's seventh constructor argument (steward_) to 0x0000000000000000000000000000000000000000 so that nobody can change the adapter or action id after launch, and the contract explicitly allows it (only hmm_, imd_, intake_, forwarder_, adapter_ and dev_ are checked against zero at lines 217-220). The launch tooling disagrees: the custom-token-launch reference says of constructorArgs that 'native ETH in a Currency field is 0, and no other address may be zero', and the oracle-consumer skill says 'Never fill an address argument with the zero address, 0x...dEaD or any other stand-in: the verifier refuses them.' Contract logic is correct and the test suite covers the no-steward path (test/audit/StewardAdapter.t.sol:test_noSteward_rulesAreFixedForever); the defect is that the manifest the brief dictates cannot pass the verifier as written. There is no $-placeholder that yields 'no steward': $requester would install 0x876c...9a71 (the GenesisForwarder, a contract with no steward functions, which would make the role dead but still non-zero) and any EOA would create exactly the admin key the requester refuses. This needs an explicit decision (a verifier exemption for this argument, or a documented stand-in whose powers are provably unusable) before the manifest step, not a code change. I could not reach the verifier itself; the evidence is the two reference texts.","line":210,"path":"src/HmmMine.sol","reproduction":"Write launch.json contracts[1] = {\"contract\":\"HmmMine\",\"constructorArgs\":[\"$token\",\"0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7\",\"0xa43e6f75ee006411f79ac1c84120606c2330de82\",\"0x6f7261636c652e72657175657374406f7261636c652d31000000000000000000\",\"0x876c2fb3eaa91d32ef03186853bb82433b949a71\",\"$contract:SwarmOracleAdapter\",\"0x0000000000000000000000000000000000000000\",\"0x39c593c1bc4d91e42d797456077586f6058ebf67\",\"500\",\"600\",\"15552000\",\"0\"]} exactly as the brief lists. Expected: the manifest is accepted and HmmMine deploys with steward == address(0) (locally: new HmmMine(..., address(0), ...) succeeds and queueConfig reverts NotSteward for every caller). Actual per the launch references: entry index 6 is a zero address in a non-Currency field and the verifier refuses the manifest, so the launch cannot proceed with the arguments the brief requires.","severity":"medium","snippet":"        address steward_,","title":"HmmMine constructorArgs carry a zero address (steward) that the launch manifest verifier refuses"},{"citation":"resolved","description":"The adapter is deployed before the mine (contracts[0]) and learns the mine's address when HmmMine's constructor calls bind() (HmmMine.sol:239). That design requires mine_ == address(0) at deployment: a non-zero mine_ is stored as `mine` and HmmMine's bind() then reverts AlreadyBound(mine_) unless mine_ happens to equal the mine's own predicted address, which no manifest placeholder can express ($contract:HmmMine refers to a later contract and is not available to an earlier one). The same manifest rule as the previous finding ('no other address may be zero'; 'Never fill an address argument with the zero address ... the verifier refuses them') therefore blocks this argument too. Unlike the steward, there is no alternative value: any non-zero stand-in (the requester, 0xdEaD, the factory) makes HmmMine's constructor revert and the whole launch transaction fail. Options for the adapter agent: a verifier exemption for this field, or (if contract changes are permitted later) drop the mine_ parameter so the only path is bind(). bind() itself is safe at launch because the adapter and the mine deploy in one factory transaction, so no third party can claim the binding in between (verified on the mainnet fork: adapter.mine() == mine after launchCustom).","line":97,"path":"src/SwarmOracleAdapter.sol","reproduction":"Locally: vm.prank(factory); a = new SwarmOracleAdapter(intake, signer, 5, 4, X). With X = address(0): new HmmMine(..., address(a), ...) succeeds and a.mine() == address(mine). With any non-zero X that is not the mine's exact future address (e.g. X = 0x876c2fb3eaa91d32ef03186853bb82433b949a71, the $requester): new HmmMine(..., address(a), ...) reverts SwarmOracleAdapter.AlreadyBound(X), so the launch's second contract cannot deploy. Manifest: contracts[0].constructorArgs = [\"0xa43e6f75ee006411f79ac1c84120606c2330de82\",\"0x5598aa9146215bc13eb26f2c692ad1461fd32982\",\"5\",\"4\",\"0x0000000000000000000000000000000000000000\"] as the brief lists. Expected: accepted. Actual per the launch references: the zero address at index 4 is refused by the verifier.","severity":"medium","snippet":"        if (mine_ != address(0)) {","title":"SwarmOracleAdapter's fifth constructor argument (mine_) must be zero for the bind() handshake, which the manifest rule forbids"},{"citation":"resolved","description":"forward(n) is the forwarder's only function that moves tokens, and it always ends in HmmMine.start(), which reverts AlreadyStarted once genesis is set (HmmMine.sol:260). So after the one successful forward, any HMM that arrives at 0x876c2fb3eaa91d32ef03186853bb82433b949a71 (a mis-sent transfer, an airdrop, dust from a later copycat launch of the same token) can never leave: forward reverts and there is no sweep. The intended launch flow is unaffected because the factory delivers the whole remainder in the launch transaction before anyone can call forward, and the fork rehearsal confirms mine.reserve() == the remainder. The related, documented case is HMM sent to the mine itself after start(): it is held but never emitted (HmmMine.sol:257). Both are dead ends for user error rather than for the launch; reported so the site and docs can warn against sending HMM to either address.","line":62,"path":"src/GenesisForwarder.sol","reproduction":"After launch: forwarder.forward(n) succeeds, mine.started() == true. Then any holder calls hmm.transfer(0x876c2fb3eaa91d32ef03186853bb82433b949a71, 1 ether). forwarder.forward(n) now reverts HmmMine.AlreadyStarted() (the safeTransfer inside it is rolled back), and no other function of GenesisForwarder can move the 1 HMM. Expected: a path to move late arrivals into the mine or back out. Actual: the balance is irrecoverable.","severity":"low","snippet":"        IHmmMine(mine).start(); // reverts if this mine already started","title":"HMM that reaches the GenesisForwarder after forward() has run is stranded forever"},{"citation":"resolved","description":"_ask pays q.target (the price at proposal) and only guards against a rise (PriceRose at line 624). If the Intake owner lowers priceOf between proposal and completion, the mine forwards the old, higher amount; the Intake accepts any amount >= price and forwards it whole to payTo, so the backers' surplus goes to the swarm's treasury. This is the author's stated choice (test/HmmMine.t.sol:test_priceFall_paysTheQuotedTarget asserts payTo receives the full 0.5 IMD when the live price is 0.4) and round shares stay consistent with IMD actually paid, so it is not a defect; recorded so reviewers do not re-raise it.","line":620,"path":"src/HmmMine.sol","reproduction":"propose(spec, 0.3 ether) at price 0.5 IMD; Intake owner setPrice(action, imd, 0.4 ether); another backer back(id, 0.2 ether, body). The mine pays 0.5 IMD to the Intake although 0.4 would have been accepted. Expected (if the author wanted the live price): pay 0.4 and leave 0.1 refundable. Actual and intended: 0.5 paid, shares = 0.5.","severity":"info","snippet":"        uint256 price = q.target;","title":"A question pays its quoted target even when the Intake price has fallen (intended, tested)"},{"citation":"resolved","description":"The oracle-consumer reference requires the intake, action id, asset/price and signer to be constructor inputs AND owner-settable so an oracle-2 action, a moved price or a rotated signer never needs a redeploy. Here intake and imd are immutable, the adapter's signer is immutable and is checked by bare ECDSA (no ERC-1271 path, so a move to an OracleSignerRegistry contract would make every answer 'bad_signature'), and with steward == address(0) the action and adapter can never change. The brief asks for exactly this ('there are no owner powers at all') and docs/SECURITY.md lists the consequence as a known limitation: if IMD retires oracle-1 (setPrice to 0), moves Intake again or rotates the signer, mining stops and the unemitted part of the ~650M HMM reserve stays in the mine forever, since nothing can withdraw it. Verified on mainnet today: priceOf(action, IMD) == 0.5 IMD, callbackGas == 200000, the signer 0x5598...2982 has no code. Not a defect against the brief; recorded so the audit panel sees it is a deliberate trade, not an oversight.","line":110,"path":"src/HmmMine.sol","reproduction":"Intake owner calls setPrice(bytes32('oracle.request@oracle-1'), 0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7, 0). From then on HmmMine.propose reverts NotSold and every open question's completion reverts NotSold (then refunds after its deadline). queueConfig reverts NotSteward for every caller because steward == address(0). Expected under the oracle reference: an owner points the mine at the new action/intake. Actual (by design): no function can; the remaining reserve is never emitted.","severity":"info","snippet":"    IIntake public immutable intake;","title":"Intake, IMD, signer and (with steward zero) action and adapter are frozen for good; the oracle reference wants them owner-settable"},{"citation":"resolved","description":"Read completely: src/HmmToken.sol, src/HmmMine.sol, src/SwarmOracleAdapter.sol, src/GenesisForwarder.sol, src/interfaces/{IHmmMine,IIntake,ILaunchRegistry,IOracleAdapter}.sol, script/HmmLaunch.sol, the vendored Intake (test/external/Intake.sol), the test base, mocks and the fork rehearsal; the OZ v5 ERC20, SafeERC20, Math, Strings, ECDSA and ReentrancyGuardTransient bases are the library's. Checked against the Pashov list: every state-changing function's caller and effect (propose/back/refund/claim/payDev/credit/fail/start/forward/bind/onOracleResult/onOracleFailure/queueConfig/cancelConfig/applyConfig/setSteward), checks-effects-interactions order, uint128/uint32 casts, rounding direction (dev share ceil per round, floor in total; claims floor), the emission bound (sum of 64 halving eras < reserve), the EIP-712 struct/type string/domain against the protocol's canonical copy (identical, and real swarm signatures in test/fixtures verify), callback stipend, writer/outsider misdirection (an outsider's request naming the adapter cannot credit; failure args are bound to the request by the Intake), replay (used[a.requestId]), and the launch floor (plain OZ ERC20 token, constructors move no supply, HmmMine runtime 15,031 bytes, no DELEGATECALL/SELFDESTRUCT). forge test: 77 passed (unit, fuzz 2000 runs, invariants 256x80). FOUNDRY_PROFILE=fork against https://ethereum-rpc.publicnode.com at block 26182937: 4 passed, the whole launch through the real ProjectFactory, registry, pool, Intake and IMD. Verified on mainnet: the GenesisForwarder at 0x876c...9a71 has registry 0x7c9d...fe23 (== ProjectFactory.registry()) and mineName 'HmmMine'. Not reachable: the launch manifest verifier, admission and deployer services (apps/control-plane, apps/deployer) that decide the zero-address rule in the two medium findings; the real oracle writer's pairing of answers to requests, which the contracts trust by design (docs/SECURITY.md trust table). No loss-of-funds, accounting, reentrancy or access-control defect was found in the contract code; no proof tests are attached because no finding is high or critical.","line":32,"path":"src/HmmMine.sol","reproduction":"Not a defect. Commands run: forge build --sizes; forge test; FOUNDRY_PROFILE=fork MAINNET_RPC_URL=https://ethereum-rpc.publicnode.com forge test; cast call 0x876c2fb3eaa91d32ef03186853bb82433b949a71 'registry()(address)' / 'mineName()(bytes32)'; cast call 0xa43e6f75ee006411f79ac1c84120606c2330de82 'priceOf(bytes32,address)(uint256)' ... ; cast code 0x5598aa9146215bc13eb26f2c692ad1461fd32982.","severity":"info","snippet":"contract HmmMine is IHmmMine, ReentrancyGuardTransient {","title":"Coverage: every contract in src/ was read in full; service-side checks could not be reached"}],"hash":"c2bf843913d6ff6b2ed071b6465bf49faeed6f1588993cbf109920388768b6f2","nodeId":"448c5c51-5e83-42a2-844e-89cc616d7ea4","outcome":"completed","summary":"The review is complete. The findings file is written and no repository file was changed.\n\n**Verdict.** The contract code is sound. I found no loss-of-funds, accounting, reentrancy, access-control or arithmetic defect in HmmToken, HmmMine, SwarmOracleAdapter or GenesisForwarder, so no proof tests are attached. What blocks the launch sits in the manifest, not the Solidity.\n\n**Findings written to `.imd-findings.json`:**\n- **Medium:** HmmMine's steward argument is the zero address, which the launch references say the manifest verifier refuses. The contract allows it and the no-steward path is tested, but the manifest the brief dictates cannot pass as written.\n- **Medium:** SwarmOracleAdapter's fifth argument must be zero for the bind handshake with the later-deployed mine. Any non-zero stand-in makes HmmMine's constructor revert with AlreadyBound, confirmed by a scratch test. This one has no alternative value and needs a verifier decision.\n- **Low:** HMM sent to the GenesisForwarder after forward() has run is stranded forever, since forward always ends in start() which reverts once started. Confirmed by a scratch test. The launch flow itself is unaffected.\n- **Info:** a question pays its quoted target when the Intake price has fallen. This is intended and already tested by the author.\n- **Info:** intake, IMD, signer, action and adapter are frozen for good. The oracle reference wants them owner-settable, but the brief asks for no owner powers and the docs list the consequence.\n- **Info:** a coverage note listing what was read and what could not be reached.\n\n**What I verified.** All four source contracts, the interfaces, the launch library, the vendored Intake, the test harness and the fork rehearsal were read in full. The suite passes with 77 tests. The fork rehearsal passed against live mainnet through a public RPC: the real factory, registry, pool and Intake. On mainnet the forwarder at the remainderTo address holds the right registry and name, the Intake sells the action at 0.5 IMD with a 200k stipend, and the signer is an EOA. The EIP-712 struct and domain match the protocol's canonical copy, and `toleranceBps` is a documented body key.\n\n**Not reachable.** The manifest verifier, admission and deployer services that decide the zero-address rule, and the real oracle writer's pairing of answers to requests, which the contracts trust by design.","treeHash":null,"usage":{"cachedInputTokens":1368530,"inputTokens":386,"model":"claude-fable-5-1","outputTokens":34561,"runtime":"claude","turns":32,"wallClockMs":577195}},{"artifacts":[],"attempt":1,"bundleHash":"0d3103d07b4c2fd3df0c22115c370881647a8f447f39c5450beaa8e283054f27","device":"6f41bd9b44d3e708","findings":[],"hash":"f7f68caa530a40dde9214b1d7c07940329bae71070f16cbf34a8f25b13014a4f","nodeId":"d98a013d-6678-40b8-8be3-4b0fa82dd4d7","outcome":"completed","summary":"The project could already be launched as it arrived, so I changed no contracts. The deliverable is one new test file and ADAPTATION.md. `forge build` compiles, and `forge test` passes 86 tests: the 77 that were already there plus 9 new ones.\n\n**Why nothing in `src/` changed:** I checked each launch rule against the code and all were already met:\n- **Token:** `HmmToken` mints exactly 1,000,000,000 HMM once to the factory, and has no owner, mint, burn, fee or pause.\n- **Constructors:** the adapter takes 5 arguments and the mine 12, all of simple fixed-size types the factory can pass.\n- **Bytecode:** no contract needs libraries linked in after build, and none contains the forbidden opcodes (DELEGATECALL, CALLCODE, SELFDESTRUCT). All fit the contract size limit, with `HmmMine` the largest at 15,031 bytes.\n- **Settings:** `bytecode_hash = \"none\"` was already set.\n- **The one cross-contract call:** `HmmMine`'s constructor calls `bind()` on the adapter deployed just before it. The brief allows this explicitly.\n\n**What I added:**\n- **`test/LaunchReadiness.t.sol`:** deploys the token, then the adapter, then the mine the way the factory does, on an otherwise empty chain, with the brief's exact constructor arguments. It checks:\n  - the whole supply reaches the factory and no constructor moves any of it;\n  - the token's name, symbol and decimals, and every setting the constructors write;\n  - the adapter ends up bound to the mine;\n  - nobody, the factory included, has owner powers, and no common admin call can grow the supply;\n  - the forbidden opcodes are absent and every contract fits the size limit;\n  - the deploy order matters: the mine fails if the adapter isn't there first.\n- **`ADAPTATION.md`:** goes through each launch rule and how each audit finding was handled.\n\n**The audit findings:**\n- **Steward is the zero address (medium):** no code change. The requester chose zero deliberately to mean \"no steward\"; it isn't a placeholder for a missing value, and the brief fixes the constructor arguments.\n- **Adapter's `mine_` argument must be zero (medium):** reproduced, and a new test shows any other value makes the mine's constructor revert, so the launch would fail. The brief's zero is the only value that works.\n- **HMM sent to the GenesisForwarder after `forward()` is stuck there (low):** reproduced, and an existing test already shows it. I didn't fix it because the forwarder is already deployed on mainnet and can't be changed; editing its source would only make the repository disagree with it. The normal launch isn't affected.\n- **The three informational findings:** behaviour the brief asks for or the author intended, so no change.\n\n**Two things that could still block the launch:**\n- **Zero addresses in the manifest:** the audit says the manifest checks may refuse zero addresses in constructor arguments. Both medium findings depend on that, and nothing in this repository can settle it; it will be decided at the manifest step.\n- **Mainnet-fork tests:** I didn't run them, because they need an RPC endpoint and none of the code they exercise changed.\n\nI haven't committed anything.","treeHash":"36c13498701532b2eed9e73c4e5d5eea9eb6e271","usage":{"cachedInputTokens":911521,"inputTokens":26,"model":"claude-opus-5-5","outputTokens":13330,"runtime":"claude","turns":15,"wallClockMs":217611}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"4fa6ac0d62fd2e01","findings":[],"hash":"ff7ca489a7c2cac0822d29a9b712505fdc02837fbf3a9d4798fe0fe56ef7c112","nodeId":"11a288a2-733e-4356-b55a-da62039e7400","outcome":"failed","summary":"needs input: The launch_manifest checker rejects SwarmOracleAdapter constructorArgs[4] because it is the zero address, but the brief explicitly requires that exact value for HmmMine's constructor-time bind() handshake. LaunchReadinessTest.test_adapterMineArgumentMustBeZero passes and demonstrates that substituting the named forwarder makes HmmMine deployment revert. HmmMine constructorArgs[6] is also explicitly zero to disable steward powers and conflicts with the same blanket prohibition. Only launch.json may change; changing either required argument, introducing an address stand-in, or changing contract logic would violate the assignment. forge build succeeded and forge test passed all 115 tests. A checker policy decision is required, not a missing party address. — Will you authorize and arrange explicit checker exemptions for the intentional zero arguments SwarmOracleAdapter.mine_ (index 4) and HmmMine.steward_ (index 6), so this launch can keep its exact constructor arguments and manifest-only ","treeHash":null,"usage":{"cachedInputTokens":707200,"inputTokens":84078,"model":"gpt-6.1-sol","outputTokens":8155,"runtime":"codex","turns":7,"wallClockMs":357724}}],"verification":[{"checks":[{"durationMs":13703,"exitCode":0,"name":"build","output":"Compiling 82 files with Solc 0.8.26\nSolc 0.8.26 finished in 13.25s\nCompiler run successful with warnings:\nWarning (2018): Function state mutability can be restricted to view\n   --> test/utils/HmmTestBase.sol:199:5:\n    |\n199 |     function _delivered() internal returns (bool) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to view\n   --> test/HmmMine.t.sol:564:5:\n    |\n564 |     function test_halving_halvesTheRate() public {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to view\n   --> test/fork/Launch.fork.t.sol:246:5:\n    |\n246 |     function _delivered() internal returns (bool) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[missing-events-access-control]: `steward` is changed without an event but is used for access control\n    ╭▸ src/HmmMine.sol:428:9\n    │\n428 │         steward = next;\n    │         ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/SwarmOracleAdapter.sol:95:20\n   │\n95 │         minPanel = uint16(minPanel_);\n   │                    ━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint16' 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/GenesisForwarder.sol:54:68\n   │\n54 │             else if (a.role == ROLE_OTHER && a.name == mineName && mine == address(0)) mine = a.addr;\n   │                                                                    ━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n   ╭▸ src/GenesisForwarder.sol:53:41\n   │\n53 │             if (a.role == ROLE_TOKEN && token == address(0)) token = a.addr;\n   │                                         ━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/SwarmOracleAdapter.sol:96:21\n   │\n96 │         minQuorum = uint16(minQuorum_);\n   │                     ━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint16' 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[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/GenesisForwarder.sol:63:9\n   │\n63 │         emit Forwarded(launchNumber, token, mine, amount);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/SwarmOracleAdapter.sol:130:13\n    │\n130 │             emit Rejected(requestId, a.requestId, reason);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/SwarmOracleAdapter.sol:141:9\n    │\n141 │ ┏         emit Thought(\n142 │ ┃             requestId, a.requestId, a.chainId, a.answerType, answerHash, shown, a.panelSize, a.quorum, a.agreed\n143 │ ┃         );\n    │ ┗━━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/SwarmOracleAdapter.sol:123:47\n    │\n123 │         (, address target,, bool completed) = intake.requests(requestId);\n    │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/SwarmOracleAdapter.sol:160:9\n    │\n160 │         emit Unanswered(requestId, status, reason, agreed, answered);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[missing-zero-check]: address parameter is used in a state write or value transfer without a zero-address check\n    ╭▸ src/HmmMine.sol:210:9\n    │\n210 │         address steward_,\n    │         ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-zero-check\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HmmMine.sol:240:9\n    │\n240 │         emit StewardChanged(address(0), steward_);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HmmMine.sol:241:9\n    │\n241 │         emit ConfigApplied(adapter_, action_);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HmmMine.sol:292:9\n    │\n292 │         emit Proposed(id, msg.sender, price, q.deadline, body);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HmmMine.sol:597:9\n    │\n597 │         emit Backed(id, msg.sender, amount, raised);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HmmMine.sol:637:9\n    │\n637 │         emit Asked(id, requestId, a);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HmmMine.sol:288:22\n    │\n288 │         q.deadline = uint64(block.timestamp + FUNDING_WINDOW);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' 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/HmmMine.sol:290:20\n    │\n290 │         q.target = uint128(price);\n    │                    ━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' 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[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/HmmMine.sol:304:13\n    │\n304 │         if (block.timestamp > q.deadline) revert FundingClosed();\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/HmmMine.sol:314:40\n    │\n314 │         if (q.status != Status.Open || block.timestamp <= q.deadline) revert NotRefundable();\n    │                                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HmmMine.sol:318:21\n    │\n318 │         q.raised -= uint128(amount);\n    │                     ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' 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[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HmmMine.sol:332:13\n    │\n332 │             emit Claimed(id, msg.sender, amount);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HmmMine.sol:369:13\n    │\n369 │             emit RoundOpened(r, emitted, devShare);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HmmMine.sol:375:9\n    │\n375 │         emit Answered(id, requestId, r, shares);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HmmMine.sol:368:28\n    │\n368 │             round.reward = uint128(emitted - devShare);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' 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/HmmMine.sol:372:25\n    │\n372 │         round.shares += uint128(shares);\n    │                         ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' 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/HmmMine.sol:373:19\n    │\n373 │         q.round = uint32(r);\n    │                   ━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' 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[reentrancy-no-eth]: external call can be reentered before `pendingAdapter` is updated\n    ╭▸ src/HmmMine.sol:414:9\n    │\n414 │         IOracleAdapter(next).bind();\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/HmmMine.sol:412:13\n    │\n412 │         if (block.timestamp < eta) revert TooEarly(eta);\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/HmmMine.sol:422:9\n    │\n422 │         emit ConfigApplied(next, action);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[missing-zero-check]: address parameter is used in a state write or value transfer without a zero-address check\n    ╭▸ src/HmmMine.sol:426:25\n    │\n426 │     function setSteward(address next) external onlySteward {\n    │                         ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-zero-check\n\nwarning[encode-packed-collision]: `abi.encodePacked()` called with multiple dynamic type arguments; hash collisions possible\n    ╭▸ src/HmmMine.sol:441:29\n    │\n441 │           bytes memory head = abi.encodePacked(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n442 │ ┃             '{\"v\":1,\"question\":\"',\n443 │ ┃             spec.question,\n444 │ ┃             '\",\"chainId\":',\n    ‡ ┃\n451 │ ┃             spec.evidence == 0 ? _CHAIN : _PANEL\n452 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/encode-packed-collision\n\nwarning[encode-packed-collision]: `abi.encodePacked()` called with multiple dynamic type arguments; hash collisions possible\n    ╭▸ src/HmmMine.sol:453:29\n    │\n453 │           bytes memory tail = abi.encodePacked(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n454 │ ┃             '\",\"panelSize\":',\n455 │ ┃             Strings.toString(spec.panelSize),\n456 │ ┃             ',\"quorum\":',\n    ‡ ┃\n462 │ ┃             \"}\"\n463 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/encode-packed-collision\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/HmmMine.sol:477:13\n    │\n477 │         if (block.timestamp < roundEnd(r)) return 0;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/HmmMine.sol:496:56\n    │\n496 │         if (era < MAX_ERAS) total += rate * (elapsed - era * eraLength);\n    │                                                        ━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/HmmMine.sol:514:23\n    │\n514 │         if (g == 0 || block.timestamp < g) return 0;\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/HmmMine.sol:541:21\n    │\n541 │         uint256 t = block.timestamp < genesis ? genesis : block.timestamp;\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/HmmMine.sol:553:26\n    │\n553 │         return g != 0 && block.timestamp >= g;\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/HmmMine.sol:577:65\n    │\n577 │             if (c < 0x20 || c > 0x7e || c == 0x22 || c == 0x5c) revert BadQuestion();\n    │                                                                 ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HmmMine.sol:595:20\n    │\n595 │         q.raised = uint128(raised);\n    │                    ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' 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[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/Emission.t.sol:51:21\n   │\n51 │             vm.warp(block.timestamp + bound(uint256(gaps[i]), 1, 30 days));\n   │             ────────━━━━━━━━━━━━━━━─────────────────────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/utils/HmmTestBase.sol:154:29\n    │\n154 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Emission.t.sol:51:13\n    │\n 51 │             vm.warp(block.timestamp + bound(uint256(gaps[i]), 1, 30 days));\n    │             ────────────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/utils/HmmTestBase.sol:155:30\n    │\n155 │         a.expiresAt = uint64(block.timestamp + 1 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Emission.t.sol:51:13\n    │\n 51 │             vm.warp(block.timestamp + bound(uint256(gaps[i]), 1, 30 days));\n    │             ────────────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/HmmMine.t.sol:489:17\n    │\n489 │         vm.warp(block.timestamp + 3 hours + 5 minutes); // round 18\n    │         ────────━━━━━━━━━━━━━━━─────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/utils/HmmTestBase.sol:154:29\n    │\n154 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HmmMine.t.sol:552:9\n    │\n552 │         vm.warp(block.timestamp + 10 * ROUND);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/utils/HmmTestBase.sol:155:30\n    │\n155 │         a.expiresAt = uint64(block.timestamp + 1 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HmmMine.t.sol:552:9\n    │\n552 │         vm.warp(block.timestamp + 10 * ROUND);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/HmmMine.t.sol:552:17\n    │\n552 │         vm.warp(block.timestamp + 10 * ROUND);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/utils/HmmTestBase.sol:154:29\n    │\n154 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    ‡\n231 │         vm.warp(mine.roundEnd(_roundOf(id)));\n    │         ──────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/utils/HmmTestBase.sol:155:30\n    │\n155 │         a.expiresAt = uint64(block.timestamp + 1 days);\n    │                              ━━━━━━━━━━━━━━━\n    ‡\n231 │         vm.warp(mine.roundEnd(_roundOf(id)));\n    │         ──────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/HmmMine.t.sol:711:17\n    │\n711 │         vm.warp(block.timestamp + 40 * ERA + 7 days);\n    │         ────────━━━━━━━━━━━━━━━───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/HmmMine.t.sol:739:17\n    │\n739 │         vm.warp(block.timestamp + 40 * ERA + 7 days);\n    │         ────────━━━━━━━━━━━━━━━───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/HmmMine.t.sol:782:75\n    │\n782 │         vm.expectRevert(abi.encodeWithSelector(HmmMine.TooEarly.selector, block.timestamp + 3 days));\n    │                                                                           ━━━━━━━━━━━━━━━\n783 │         mine.applyConfig();\n784 │         vm.warp(block.timestamp + 3 days);\n    │         ───────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/HmmMine.t.sol:784:17\n    │\n784 │         vm.warp(block.timestamp + 3 days);\n    │         ────────━━━━━━━━━━━━━━━────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/HmmMine.t.sol:828:17\n    │\n828 │         vm.warp(block.timestamp + 25 minutes); // round 2\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/utils/HmmTestBase.sol:154:29\n    │\n154 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/MineFailureBoundaries.t.sol:152:9\n    │\n152 │         vm.warp(end);\n    │         ──────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/utils/HmmTestBase.sol:155:30\n    │\n155 │         a.expiresAt = uint64(block.timestamp + 1 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/MineFailureBoundaries.t.sol:152:9\n    │\n152 │         vm.warp(end);\n    │         ──────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/audit/StewardAdapter.t.sol:46:17\n   │\n46 │         vm.warp(block.timestamp + 3 days);\n   │         ────────━━━━━━━━━━━━━━━────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\n","passed":true},{"durationMs":16975,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 2 tests for test/audit/StewardAdapter.t.sol:AuditStewardAdapterTest\n[PASS] test_audit_stewardAdapter_capturesEmissionWithoutAnswers() (gas: 1561163)\nLogs:\n  HMM taken for 0.5 IMD, no oracle answer (whole tokens): 56616078\n\n[PASS] test_noSteward_rulesAreFixedForever() (gas: 104408)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 27.26ms (4.52ms CPU time)\n\nRan 1 test for test/audit/ForeignRequestFirst.t.sol:AuditForeignRequestFirstTest\n[PASS] test_audit_foreignRequestBeforeTheAsk_isRefused() (gas: 1344155)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 27.43ms (4.81ms CPU time)\n\nRan 1 test for test/audit/ConfigBoundary.t.sol:AuditConfigBoundaryTest\n[PASS] test_audit_questionProposedBeforeQueue_refusesTheNewConfig() (gas: 1125520)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 39.66ms (17.12ms CPU time)\n\nRan 9 tests for test/GenesisForwarder.t.sol:GenesisForwarderTest\n[PASS] test_constructor_validates() (gas: 3851)\n[PASS] test_copycatLaunch_cannotTouchTheRealReserve() (gas: 1516773)\n[PASS] test_crossWiredLaunch_isRefused() (gas: 1464974)\n[PASS] test_forward_movesTheWholeRemainderAndStarts() (gas: 767527)\n[PASS] test_forward_onlyOncePerMine() (gas: 252373)\n[PASS] test_forward_refusesALaunchWithoutAMine() (gas: 226480)\n[PASS] test_forward_refusesAMineOfAnotherForwarder() (gas: 88371)\n[PASS] test_forward_refusesAMineOfAnotherToken() (gas: 872809)\n[PASS] test_forward_refusesOtherLaunchKinds() (gas: 124957)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 44.01ms (24.32ms CPU time)\n\nRan 6 tests for test/OracleProtocolConformance.t.sol:OracleProtocolConformanceTest\n[PASS] test_acceptsAFreshSignatureFromTheVectorKey() (gas: 631127)\n[PASS] test_acceptsTheProtocolSignatureAsDelivered() (gas: 633768)\n[PASS] test_callbackSelectorIsCanonical() (gas: 418)\n[PASS] test_digestMatchesTheProtocol() (gas: 29684)\n[PASS] test_fixedSignatureExpiresOneSecondAfterTheBoundary() (gas: 36621)\n[PASS] test_fixedSignatureFailsUnderAnotherDomainChain() (gas: 21750)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 44.19ms (22.14ms CPU time)\n\nRan 11 tests for test/SwarmOracleAdapter.t.sol:SwarmOracleAdapterTest\n[PASS] testFuzz_realSignature_breaksOnAnyTamper(uint8,uint256) (runs: 2000, μ: 22868, ~: 22800)\n[PASS] test_bind_onceAndIdempotent() (gas: 125259)\n[PASS] test_check_reasons() (gas: 333794)\n[PASS] test_constructor_validates() (gas: 6239)\n[PASS] test_longAnswer_isCountedAndHashed() (gas: 2592519)\n[PASS] test_onlyTheIntakeCallsBack() (gas: 96585)\n[PASS] test_realSwarmSignatures_recoverTheOracleSigner() (gas: 76785)\n[PASS] test_selectors_matchTheSwarmsCallbackShape() (gas: 5907)\n[PASS] test_thoughtEvent_carriesTheAnswer() (gas: 660894)\n[PASS] test_unboundAdapterRefusesCallbacks() (gas: 78434)\n[PASS] test_unknownRequestIsRefused() (gas: 83194)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 878.16ms (878.45ms CPU time)\n\nRan 9 tests for test/LaunchReadiness.t.sol:LaunchReadinessTest\n[PASS] test_actionIsTheAsciiActionId() (gas: 295)\n[PASS] test_adapterMineArgumentMustBeZero() (gas: 2284159)\n[PASS] test_applicationConstructorsMoveNoSupply() (gas: 29251)\n[PASS] test_constructorsConfigureEverything() (gas: 112143)\n[PASS] test_mineNeedsTheAdapterDeployedFirst() (gas: 1095261)\n[PASS] test_noCallIncreasesSupply() (gas: 402680)\n[PASS] test_noOwnerPowersAfterLaunch() (gas: 192308)\n[PASS] test_runtimeHasNoForbiddenOpcodesAndFits() (gas: 14487412)\n[PASS] test_tokenMintsTheManifestSupplyToTheFactory() (gas: 46144)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 977.75ms (69.56ms CPU time)\n\nRan 45 tests for test/HmmMine.t.sol:HmmMineTest\n[PASS] test_answerInALaterEra_isWorthLess() (gas: 1418360)\n[PASS] test_answerThatDoesNotCount_isRecordedAsFailed() (gas: 565421)\n[PASS] test_answer_creditsTheRound_withRolloverSinceGenesis() (gas: 722582)\n[PASS] test_back_minimumUnlessCompletingTheRemainder() (gas: 596759)\n[PASS] test_back_refusedWhenClosedOrNotOpen() (gas: 723622)\n[PASS] test_bodyOf_isTheExactJsonTheSwarmChecked() (gas: 64766)\n[PASS] test_callback_fitsTheIntakeStipend() (gas: 719644)\nLogs:\n  callback gas (refused path): 46589\n\n[PASS] test_callback_gasMargin() (gas: 2547540)\nLogs:\n  minimum stipend for the costliest callback: 118437\n\n[PASS] test_claim_onlyAfterTheRoundEnds() (gas: 911830)\n[PASS] test_config_cancel_andRenounce() (gas: 241480)\n[PASS] test_config_queueApplyAfterDelay_newQuestionsOnly() (gas: 1451525)\n[PASS] test_config_refusesAnAdapterBoundToAnotherMine() (gas: 141176)\n[PASS] test_constructor_validates() (gas: 19384)\n[PASS] test_creditAndFail_onlyFromTheQuestionsAdapter() (gas: 503819)\n[PASS] test_devShare_isPaidToDev_byAnyone() (gas: 792433)\n[PASS] test_emptyRoundsRollIntoTheNextAnsweredRound() (gas: 1271544)\n[PASS] test_failure_closesTheQuestion_withoutCredit() (gas: 573114)\n[PASS] test_forgedAnswer_doesNotCount() (gas: 563656)\n[PASS] test_genesisDelay_blocksQuestionsUntilGenesis() (gas: 1239549)\n[PASS] test_halving_halvesTheRate() (gas: 153459)\n[PASS] test_oneAskPerTransaction() (gas: 1791891)\n[PASS] test_outsiderRequestNamingTheAdapter_cannotMine() (gas: 484743)\n[PASS] test_ownQuestion_completedByAContractIsFine() (gas: 890514)\n[PASS] test_pooledCompletion_mustComeFromAnAccountDirectly() (gas: 1197257)\n[PASS] test_pooledQuestion_isAskedWhenTheLastBackerCompletesIt() (gas: 906375)\n[PASS] test_priceFall_paysTheQuotedTarget() (gas: 609531)\n[PASS] test_priceRise_blocksTheAsk_andBackersRefund() (gas: 477101)\n[PASS] test_propose_capsAmountAtPrice() (gas: 412614)\n[PASS] test_propose_notSoldWhenPriceIsZero() (gas: 89875)\n[PASS] test_propose_rejectsDust() (gas: 53597)\n[PASS] test_refund_afterDeadlineOnly_andOnce() (gas: 598443)\n[PASS] test_refund_refusedOnceAsked() (gas: 453577)\n[PASS] test_refusal_closesTheQuestion() (gas: 516608)\n[PASS] test_sameOracleAnswer_countsOnce() (gas: 1107519)\n[PASS] test_sameRound_splitsByIMDPaid_andPooledBackersSplitByShare() (gas: 1493393)\n[PASS] test_soloAsk_paysTheSwarmAndRecordsTheRequest() (gas: 531574)\n[PASS] test_spec_rulesAndInjection() (gas: 576707)\n[PASS] test_start_needsReserve() (gas: 589418)\n[PASS] test_start_onlyForwarder() (gas: 29619)\n[PASS] test_start_onlyOnce() (gas: 34187)\n[PASS] test_start_setsReserveGenesisAndRate() (gas: 50267)\n[PASS] test_stats_andPot() (gas: 759737)\n[PASS] test_stats_beforeStart() (gas: 593294)\n[PASS] test_token_isPlainAndFixed() (gas: 36673)\n[PASS] test_writerCannotCreditAPendingRequestThroughAnotherCompletion() (gas: 937478)\nSuite result: ok. 45 passed; 0 failed; 0 skipped; finished in 1.04s (155.55ms CPU time)\n\nRan 12 tests for test/MineFailureBoundaries.t.sol:MineFailureBoundariesTest\n[PASS] testFuzz_priceBelowMinimumCanBeFundedExactly(uint256) (runs: 1000, μ: 895651, ~: 895897)\n[PASS] test_actionDelistedAtCompletionRollsBackAndAllowsRefund() (gas: 717530)\n[PASS] test_badSignatureFailureDoesNotConsumeTheOracleIdOrAllocateRewards() (gas: 1160969)\n[PASS] test_bodyMismatchRollsBackTheCompletersDepositAndCanBeRetried() (gas: 898445)\n[PASS] test_completionAtRoundBoundaryCreditsTheNewRound() (gas: 1300080)\n[PASS] test_duplicateAndUnknownIdsCannotIncreaseAClaim() (gas: 852031)\n[PASS] test_failedProposalDoesNotCreateAQuestionOrConsumeIMD() (gas: 251063)\n[PASS] test_failureArgumentSubstitutionIsRejectedByIntake() (gas: 992924)\n[PASS] test_fundingDeadlineIncludesTheLastSecondButRefundStartsAfterIt() (gas: 925831)\n[PASS] test_noAnswerCreditsWorkWithoutPayingInsideTheCallback() (gas: 814434)\n[PASS] test_outsiderFailureCannotCloseOrRefundTheMinesRequest() (gas: 926914)\n[PASS] test_settledQuestionCannotBeCreditedOrFailedAgain() (gas: 574333)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 1.04s (1.10s CPU time)\n\nRan 6 tests for test/HmmTokenProperties.t.sol:HmmTokenPropertiesTest\n[PASS] testFuzz_transferArrivesExactlyAndDoesNotChangeSupply(uint256) (runs: 1000, μ: 91976, ~: 92062)\n[PASS] test_allowanceRevocationBlocksFormerSpender() (gas: 117724)\n[PASS] test_failedTransferFromRollsBackAllowanceConsumption() (gas: 161089)\n[PASS] test_infiniteApprovalRemainsInfiniteAndSelfTransferOnlySpendsFiniteAllowance() (gas: 214481)\n[PASS] test_transferToZeroAndOverdrawRevertWithoutLosingBalance() (gas: 115878)\n[PASS] test_zeroTransfersNeedNeitherBalanceNorAllowance() (gas: 89875)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 1.04s (1.04s CPU time)\n\nRan 6 tests for test/Emission.t.sol:EmissionTest\n[PASS] testFuzz_answeredRounds_accountForEveryEmittedUnit(uint32[6]) (runs: 2000, μ: 3996733, ~: 4009976)\n[PASS] testFuzz_emittedAt_isMonotonic(uint64,uint64) (runs: 2000, μ: 35764, ~: 33852)\n[PASS] testFuzz_emittedAt_isTheIntegralOfTheRate(uint64) (runs: 2000, μ: 147898, ~: 43711)\n[PASS] testFuzz_emittedAt_neverExceedsTheReserve(uint256) (runs: 2000, μ: 25235, ~: 32256)\n[PASS] testFuzz_pooledClaims_neverExceedTheRound(uint96[5]) (runs: 2000, μ: 1867329, ~: 1791528)\n[PASS] test_firstEra_emitsHalfTheReserve_andTheTailIsDust() (gas: 46961)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 1.04s (3.71s CPU time)\n\nRan 2 tests for test/invariant/ForwarderInvariants.t.sol:ForwarderInvariantTest\n[PASS]\nForwarderInvariantTest invariants:\n[PASS] invariant_eachLaunchKeepsItsOwnSupply\n[PASS] invariant_forwardingStartsOnceAndDonationsDoNotRewriteTheSchedule\n ForwarderInvariantTest invariants (runs: 256, calls: 20480, reverts: 0)\n\n╭------------------+-------------------+-------+---------+----------╮\n| Contract         | Selector          | Calls | Reverts | Discards |\n+===================================================================+\n| ForwarderHandler | advance           | 3388  | 0       | 0        |\n|------------------+-------------------+-------+---------+----------|\n| ForwarderHandler | donate            | 3412  | 0       | 0        |\n|------------------+-------------------+-------+---------+----------|\n| ForwarderHandler | forward           | 3419  | 0       | 0        |\n|------------------+-------------------+-------+---------+----------|\n| ForwarderHandler | unauthorizedStart | 3458  | 0       | 0        |\n|------------------+-------------------+-------+---------+----------|\n| ForwarderHandler | unknownLaunch     | 3321  | 0       | 0        |\n|------------------+-------------------+-------+---------+----------|\n| ForwarderHandler | wrongLaunch       | 3482  | 0       | 0        |\n╰------------------+-------------------+-------+---------+----------╯\n\n[PASS] test_repeatedForwardRollsBackTheTokenTransferWhenStartReverts() (gas: 981231)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 5.86s (5.84s CPU time)\n\nRan 1 test for test/audit/AdversarialInvariants.t.sol:AuditAdversarialInvariantTest\n[PASS]\nAuditAdversarialInvariantTest invariants:\n[PASS] invariant_audit_hmmConservedAndSolvent\n[PASS] invariant_audit_imdConserved\n[PASS] invariant_audit_roundsConsistent\n AuditAdversarialInvariantTest invariants (runs: 256, calls: 20480, reverts: 0)\n\n╭--------------------+-----------+-------+---------+----------╮\n| Contract           | Selector  | Calls | Reverts | Discards |\n+=============================================================+\n| AdversarialHandler | back      | 2299  | 0       | 0        |\n|--------------------+-----------+-------+---------+----------|\n| AdversarialHandler | claim     | 2232  | 0       | 0        |\n|--------------------+-----------+-------+---------+----------|\n| AdversarialHandler | movePrice | 2339  | 0       | 0        |\n|--------------------+-----------+-------+---------+----------|\n| AdversarialHandler | payDev    | 2251  | 0       | 0        |\n|--------------------+-----------+-------+---------+----------|\n| AdversarialHandler | propose   | 2228  | 0       | 0        |\n|--------------------+-----------+-------+---------+----------|\n| AdversarialHandler | refund    | 2269  | 0       | 0        |\n|--------------------+-----------+-------+---------+----------|\n| AdversarialHandler | rotate    | 2301  | 0       | 0        |\n|--------------------+-----------+-------+---------+----------|\n| AdversarialHandler | settle    | 2294  | 0       | 0        |\n|--------------------+-----------+-------+---------+----------|\n| AdversarialHandler | warp      | 2267  | 0       | 0        |\n╰--------------------+-----------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 9.61s (9.58s CPU time)\n\nRan 1 test for test/HmmTokenProperties.t.sol:HmmTokenLedgerInvariantTest\n[PASS]\nHmmTokenLedgerInvariantTest invariants:\n[PASS] invariant_allowancesMatchIndependentLedger\n[PASS] invariant_fixedSupplyAndExactBalances\n HmmTokenLedgerInvariantTest invariants (runs: 256, calls: 20480, reverts: 0)\n\n╭-----------------------+--------------+-------+---------+----------╮\n| Contract              | Selector     | Calls | Reverts | Discards |\n+===================================================================+\n| HmmTokenLedgerHandler | approve      | 5135  | 0       | 0        |\n|-----------------------+--------------+-------+---------+----------|\n| HmmTokenLedgerHandler | revoke       | 5081  | 0       | 0        |\n|-----------------------+--------------+-------+---------+----------|\n| HmmTokenLedgerHandler | transfer     | 5136  | 0       | 0        |\n|-----------------------+--------------+-------+---------+----------|\n| HmmTokenLedgerHandler | transferFrom | 5128  | 0       | 0        |\n╰-----------------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 11.17s (11.15s CPU time)\n\nRan 2 tests for test/invariant/LaunchMineLiabilities.t.sol:LaunchMineLiabilityInvariantTest\n[PASS]\nLaunchMineLiabilityInvariantTest invariants:\n[PASS] invariant_allOpenBackingRemainsRefundableAndPaidIMDIsAccounted\n[PASS] invariant_allUnpaidRewardsAndDevShareAreSolvent\n[PASS] invariant_launchRulesAndGenesisStayFixed\n[PASS] invariant_tokenReceiptsMatchActualPayoutsIncludingDonations\n LaunchMineLiabilityInvariantTest invariants (runs: 256, calls: 20480, reverts: 0)\n\n╭------------------------+-----------------------+-------+---------+----------╮\n| Contract               | Selector              | Calls | Reverts | Discards |\n+=============================================================================+\n| LaunchLiabilityHandler | attackClosedQuestion  | 1774  | 0       | 0        |\n|------------------------+-----------------------+-------+---------+----------|\n| LaunchLiabilityHandler | attackPendingQuestion | 1768  | 0       | 0        |\n|------------------------+-----------------------+-------+---------+----------|\n| LaunchLiabilityHandler | attemptAdmin          | 1684  | 0       | 0        |\n|------------------------+-----------------------+-------+---------+----------|\n| LaunchLiabilityHandler | back                  | 1777  | 0       | 0        |\n|------------------------+-----------------------+-------+---------+----------|\n| LaunchLiabilityHandler | claim                 | 1754  | 0       | 0        |\n|------------------------+-----------------------+-------+---------+----------|\n| LaunchLiabilityHandler | claimWithDuplicates   | 1727  | 0       | 0        |\n|------------------------+-----------------------+-------+---------+----------|\n| LaunchLiabilityHandler | donate                | 1649  | 0       | 0        |\n|------------------------+-----------------------+-------+---------+----------|\n| LaunchLiabilityHandler | payDev                | 1680  | 0       | 0        |\n|------------------------+-----------------------+-------+---------+----------|\n| LaunchLiabilityHandler | propose               | 1654  | 0       | 0        |\n|------------------------+-----------------------+-------+---------+----------|\n| LaunchLiabilityHandler | refund                | 1700  | 0       | 0        |\n|------------------------+-----------------------+-------+---------+----------|\n| LaunchLiabilityHandler | settle                | 1669  | 0       | 0        |\n|------------------------+-----------------------+-------+---------+----------|\n| LaunchLiabilityHandler | warp                  | 1644  | 0       | 0        |\n╰------------------------+-----------------------+-------+---------+----------╯\n\n[PASS] test_handlerExercisesClaimsDonationsAndFailures() (gas: 2874258)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 11.93s (11.91s CPU time)\n\nRan 1 test for test/invariant/MineInvariants.t.sol:MineInvariantTest\n[PASS]\nMineInvariantTest invariants:\n[PASS] invariant_hmmIsConserved\n[PASS] invariant_imdIsConserved\n[PASS] invariant_questionsAreConsistent\n[PASS] invariant_roundSharesMatchAnsweredQuestions\n[PASS] invariant_solvency\n MineInvariantTest invariants (runs: 256, calls: 20480, reverts: 0)\n\n╭-------------+----------+-------+---------+----------╮\n| Contract    | Selector | Calls | Reverts | Discards |\n+=====================================================+\n| MineHandler | back     | 2977  | 0       | 0        |\n|-------------+----------+-------+---------+----------|\n| MineHandler | claim    | 2905  | 0       | 0        |\n|-------------+----------+-------+---------+----------|\n| MineHandler | payDev   | 2861  | 0       | 0        |\n|-------------+----------+-------+---------+----------|\n| MineHandler | propose  | 2873  | 0       | 0        |\n|-------------+----------+-------+---------+----------|\n| MineHandler | refund   | 2914  | 0       | 0        |\n|-------------+----------+-------+---------+----------|\n| MineHandler | settle   | 2945  | 0       | 0        |\n|-------------+----------+-------+---------+----------|\n| MineHandler | warp     | 3005  | 0       | 0        |\n╰-------------+----------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 16.70s (16.67s CPU time)\n\nRan 16 test suites in 16.71s (61.48s CPU time): 115 tests passed, 0 failed, 0 skipped (115 total tests)\n","passed":true},{"durationMs":197,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"GenesisForwarder.forward(uint64)\",\"HmmMine.applyConfig()\",\"HmmMine.back(uint256,uint256,bytes)\",\"HmmMine.cancelConfig()\",\"HmmMine.claim(uint256[])\",\"HmmMine.credit(bytes32)\",\"HmmMine.fail(bytes32,uint8,bytes32)\",\"HmmMine.payDev()\",\"HmmMine.propose((string,uint8,uint8,uint32,uint16,uint16,uint16,uint16),uint256)\",\"HmmMine.queueConfig(address,bytes32)\",\"HmmMine.refund(uint256)\",\"HmmMine.setSteward(address)\",\"HmmMine.start()\",\"HmmToken.approve(address,uint256)\",\"HmmToken.transfer(address,uint256)\",\"HmmToken.transferFrom(address,address,uint256)\",\"SwarmOracleAdapter.bind()\",\"SwarmOracleAdapter.onOracleFailure(bytes32,uint8,bytes32,uint16,uint16,bytes)\",\"SwarmOracleAdapter.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\"],\"files\":{\".github/workflows/test.yml\":20,\".gitignore\":18,\"ADAPTATION.md\":66,\"LICENSE\":21,\"README.md\":66,\"devnet/activity.mjs\":129,\"devnet/package-lock.json\":217,\"devnet/package.json\":12,\"devnet/preview-tunnel.sh\":21,\"devnet/preview.mjs\":127,\"devnet/start.sh\":44,\"devnet/stop.sh\":9,\"devnet/swarm.mjs\":222,\"docs/DESIGN.md\":71,\"docs/LAUNCH.md\":94,\"docs/SECURITY.md\":56,\"docs/TOKENOMICS.md\":52,\"foundry.toml\":52,\"launch/body.json\":36,\"launch/build-site-body.mjs\":22,\"launch/build.mjs\":103,\"launch/buy-imd.mjs\":65,\"launch/check.mjs\":21,\"launch/config.json\":12,\"launch/export-public.sh\":33,\"launch/export-site.sh\":40,\"launch/metrics.mjs\":70,\"launch/package-lock.json\":248,\"launch/package.json\":11,\"launch/pay.mjs\":205,\"launch/watch.mjs\":50,\"remappings.txt\":2,\"script/DeployForwarder.s.sol\":31,\"script/Devnet.s.sol\":87,\"script/HmmLaunch.sol\":144,\"script/IProjectFactory.sol\":64,\"src/GenesisForwarder.sol\":65,\"src/HmmMine.sol\":639,\"src/HmmToken.sol\":15,\"src/SwarmOracleAdapter.sol\":220,\"src/interfaces/IHmmMine.sol\":20,\"src/interfaces/IIntake.sol\":31,\"src/interfaces/ILaunchRegistry.sol\":27,\"src/interfaces/IOracleAdapter.sol\":15,\"test/Emission.t.sol\":119,\"test/GenesisForwarder.t.sol\":104,\"test/HmmMine.t.sol\":862,\"test/HmmTokenProperties.t.sol\":222,\"test/LaunchReadiness.t.sol\":185,\"test/MineFailureBoundaries.t.sol\":242,\"test/OracleProtocolConformance.t.sol\":123,\"test/SwarmOracleAdapter.t.sol\":190,\"test/audit/AdversarialInvariants.t.sol\":253,\"test/audit/ConfigBoundary.t.sol\":44,\"test/audit/ForeignRequestFirst.t.sol\":57,\"test/audit/StewardAdapter.t.sol\":112,\"test/external/Intake.sol\":325,\"test/fixtures/RealAttestations.sol\":137,\"test/fork/Launch.fork.t.sol\":262,\"test/invariant/ForwarderInvariants.t.sol\":194,\"test/invariant/LaunchMineLiabilities.t.sol\":233,\"test/invariant/MineInvariants.t.sol\":241,\"test/utils/HmmTestBase.sol\":233,\"test/utils/Mocks.sol\":45,\"web/.env.example\":22,\"web/.gitignore\":5,\"web/.npmrc\":1,\"web/README.md\":184,\"web/e2e/devnet.e2e.test.ts\":248,\"web/index.html\":24,\"web/lab/pond-lab.tsx\":267,\"web/lab/pond.html\":18,\"web/package-lock.json\":8959,\"web/package.json\":41,\"web/proxy/check-worker.js\":71,\"web/public/favicon.svg\":18,\"web/scripts/abi.mjs\":49,\"web/src/App.tsx\":113,\"web/src/abi/genesisForwarder.ts\":194,\"web/src/abi/hmmMine.ts\":1671,\"web/src/abi/hmmToken.ts\":329,\"web/src/abi/index.ts\":5,\"web/src/abi/swarmOracleAdapter.ts\":744,\"web/src/components/EmissionChart.tsx\":173,\"web/src/components/Footer.tsx\":46,\"web/src/components/FrogMascot.tsx\":142,\"web/src/components/Header.tsx\":109,\"web/src/components/LaunchBanner.tsx\":34,\"web/src/components/LiveNotifier.tsx\":40,\"web/src/components/MoonGlyph.tsx\":101,\"web/src/components/ScrollStory.tsx\":439,\"web/src/components/ShareCard.tsx\":236,\"web/src/components/Wallet.tsx\":225,\"web/src/components/icons.tsx\":70,\"web/src/components/question.tsx\":246,\"web/src/components/states.tsx\":63,\"web/src/components/toast.tsx\":97,\"web/src/components/ui.tsx\":416,\"web/src/config.ts\":209,\"web/src/data/app.tsx\":125,\"web/src/data/claim.ts\":19,\"web/src/data/clock.ts\":56,\"web/src/data/discovery.ts\":158,\"web/src/data/hooks.ts\":506,\"web/src/data/indexer.test.ts\":164,\"web/src/data/indexer.ts\":603,\"web/src/data/liveRound.test.ts\":45,\"web/src/data/mining.ts\":90,\"web/src/data/pondFeed.ts\":56,\"web/src/data/rpcErrors.ts\":10,\"web/src/data/token.ts\":33,\"web/src/data/tx.ts\":93,\"web/src/devnet/connectors.ts\":14,\"web/src/devnet/keys.ts\":13,\"web/src/devnet/localKey.ts\":123,\"web/src/devnet/ui.tsx\":144,\"web/src/env.d.ts\":4,\"web/src/lib/answer.test.ts\":51,\"web/src/lib/answer.ts\":97,\"web/src/lib/body.test.ts\":168,\"web/src/lib/body.ts\":321,\"web/src/lib/check.ts\":71,\"web/src/lib/emission.test.ts\":119,\"web/src/lib/emission.ts\":134,\"web/src/lib/errors.ts\":85,\"web/src/lib/format.test.ts\":88,\"web/src/lib/format.ts\":166,\"web/src/lib/reasons.test.ts\":34,\"web/src/lib/reasons.ts\":101,\"web/src/lib/spec.test.ts\":89,\"web/src/lib/spec.ts\":116,\"web/src/main.tsx\":49,\"web/src/pages/AskPage.tsx\":826,\"web/src/pages/FaqPage.tsx\":88,\"web/src/pages/HowPage.tsx\":293,\"web/src/pages/LedgerPage.tsx\":204,\"web/src/pages/MePage.tsx\":251,\"web/src/pages/MinersPage.tsx\":112,\"web/src/pages/MoonPage.tsx\":207,\"web/src/pages/NotFound.tsx\":9,\"web/src/pages/OpenPage.tsx\":97,\"web/src/pages/PondPage.tsx\":806,\"web/src/pages/QuestionPage.tsx\":277,\"web/src/pages/TokenPage.tsx\":222,\"web/src/pond/PondCanvas.tsx\":60,\"web/src/pond/camera.ts\":107,\"web/src/pond/crowd.ts\":629,\"web/src/pond/effects.ts\":889,\"web/src/pond/engine.ts\":1999,\"web/src/pond/fallback2d.ts\":159,\"web/src/pond/moon.ts\":222,\"web/src/pond/rng.ts\":100,\"web/src/pond/sim.ts\":278,\"web/src/pond/sprites.ts\":451,\"web/src/pond/types.ts\":130,\"web/src/pond/water-gl.ts\":480,\"web/src/sound/SoundToggle.tsx\":29,\"web/src/sound/engine.ts\":362,\"web/src/styles/app.css\":594,\"web/src/styles/global.css\":1171,\"web/src/styles/pages.css\":2073,\"web/src/theme.ts\":27,\"web/src/wagmi.ts\":32,\"web/tsconfig.json\":34,\"web/vite.config.ts\":166,\"web/vitest.e2e.config.ts\":14},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"38a283b6a65714b5bfdad9cd31201c69b5856220f83f0926e9d859675fb0fc47","verifiedTreeHash":"ac9261f7354106637c5fe250000d175390f1cd68","verifierVersion":"0.1.0+327e1e9f"},{"checks":[{"durationMs":5849,"exitCode":0,"name":"build","output":"Compiling 77 files with Solc 0.8.26\nSolc 0.8.26 finished in 5.68s\nCompiler run successful with warnings:\nWarning (2018): Function state mutability can be restricted to view\n   --> test/utils/HmmTestBase.sol:199:5:\n    |\n199 |     function _delivered() internal returns (bool) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to view\n   --> test/HmmMine.t.sol:564:5:\n    |\n564 |     function test_halving_halvesTheRate() public {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to view\n   --> test/fork/Launch.fork.t.sol:246:5:\n    |\n246 |     function _delivered() internal returns (bool) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[uninitialized-local]: local variable is read before being initialized\n   ╭▸ src/GenesisForwarder.sol:53:41\n   │\n53 │             if (a.role == ROLE_TOKEN && token == address(0)) token = a.addr;\n   │                                         ━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/SwarmOracleAdapter.sol:95:20\n   │\n95 │         minPanel = uint16(minPanel_);\n   │                    ━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint16' 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/SwarmOracleAdapter.sol:96:21\n   │\n96 │         minQuorum = uint16(minQuorum_);\n   │                     ━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint16' 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/GenesisForwarder.sol:54:68\n   │\n54 │             else if (a.role == ROLE_OTHER && a.name == mineName && mine == address(0)) mine = a.addr;\n   │                                                                    ━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/GenesisForwarder.sol:63:9\n   │\n63 │         emit Forwarded(launchNumber, token, mine, amount);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[missing-events-access-control]: `steward` is changed without an event but is used for access control\n    ╭▸ src/HmmMine.sol:428:9\n    │\n428 │         steward = next;\n    │         ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/SwarmOracleAdapter.sol:130:13\n    │\n130 │             emit Rejected(requestId, a.requestId, reason);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/SwarmOracleAdapter.sol:141:9\n    │\n141 │ ┏         emit Thought(\n142 │ ┃             requestId, a.requestId, a.chainId, a.answerType, answerHash, shown, a.panelSize, a.quorum, a.agreed\n143 │ ┃         );\n    │ ┗━━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/SwarmOracleAdapter.sol:123:47\n    │\n123 │         (, address target,, bool completed) = intake.requests(requestId);\n    │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/SwarmOracleAdapter.sol:160:9\n    │\n160 │         emit Unanswered(requestId, status, reason, agreed, answered);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[missing-zero-check]: address parameter is used in a state write or value transfer without a zero-address check\n    ╭▸ src/HmmMine.sol:210:9\n    │\n210 │         address steward_,\n    │         ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-zero-check\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HmmMine.sol:240:9\n    │\n240 │         emit StewardChanged(address(0), steward_);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HmmMine.sol:241:9\n    │\n241 │         emit ConfigApplied(adapter_, action_);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HmmMine.sol:292:9\n    │\n292 │         emit Proposed(id, msg.sender, price, q.deadline, body);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HmmMine.sol:597:9\n    │\n597 │         emit Backed(id, msg.sender, amount, raised);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HmmMine.sol:637:9\n    │\n637 │         emit Asked(id, requestId, a);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HmmMine.sol:288:22\n    │\n288 │         q.deadline = uint64(block.timestamp + FUNDING_WINDOW);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' 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/HmmMine.sol:290:20\n    │\n290 │         q.target = uint128(price);\n    │                    ━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' 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[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/HmmMine.sol:304:13\n    │\n304 │         if (block.timestamp > q.deadline) revert FundingClosed();\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/HmmMine.sol:314:40\n    │\n314 │         if (q.status != Status.Open || block.timestamp <= q.deadline) revert NotRefundable();\n    │                                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HmmMine.sol:318:21\n    │\n318 │         q.raised -= uint128(amount);\n    │                     ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' 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[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HmmMine.sol:332:13\n    │\n332 │             emit Claimed(id, msg.sender, amount);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HmmMine.sol:369:13\n    │\n369 │             emit RoundOpened(r, emitted, devShare);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HmmMine.sol:375:9\n    │\n375 │         emit Answered(id, requestId, r, shares);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HmmMine.sol:368:28\n    │\n368 │             round.reward = uint128(emitted - devShare);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' 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/HmmMine.sol:372:25\n    │\n372 │         round.shares += uint128(shares);\n    │                         ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' 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/HmmMine.sol:373:19\n    │\n373 │         q.round = uint32(r);\n    │                   ━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' 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[reentrancy-no-eth]: external call can be reentered before `pendingAdapter` is updated\n    ╭▸ src/HmmMine.sol:414:9\n    │\n414 │         IOracleAdapter(next).bind();\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/HmmMine.sol:412:13\n    │\n412 │         if (block.timestamp < eta) revert TooEarly(eta);\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/HmmMine.sol:422:9\n    │\n422 │         emit ConfigApplied(next, action);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[missing-zero-check]: address parameter is used in a state write or value transfer without a zero-address check\n    ╭▸ src/HmmMine.sol:426:25\n    │\n426 │     function setSteward(address next) external onlySteward {\n    │                         ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-zero-check\n\nwarning[encode-packed-collision]: `abi.encodePacked()` called with multiple dynamic type arguments; hash collisions possible\n    ╭▸ src/HmmMine.sol:441:29\n    │\n441 │           bytes memory head = abi.encodePacked(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n442 │ ┃             '{\"v\":1,\"question\":\"',\n443 │ ┃             spec.question,\n444 │ ┃             '\",\"chainId\":',\n    ‡ ┃\n451 │ ┃             spec.evidence == 0 ? _CHAIN : _PANEL\n452 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/encode-packed-collision\n\nwarning[encode-packed-collision]: `abi.encodePacked()` called with multiple dynamic type arguments; hash collisions possible\n    ╭▸ src/HmmMine.sol:453:29\n    │\n453 │           bytes memory tail = abi.encodePacked(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n454 │ ┃             '\",\"panelSize\":',\n455 │ ┃             Strings.toString(spec.panelSize),\n456 │ ┃             ',\"quorum\":',\n    ‡ ┃\n462 │ ┃             \"}\"\n463 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/encode-packed-collision\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/HmmMine.sol:477:13\n    │\n477 │         if (block.timestamp < roundEnd(r)) return 0;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/HmmMine.sol:496:56\n    │\n496 │         if (era < MAX_ERAS) total += rate * (elapsed - era * eraLength);\n    │                                                        ━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/HmmMine.sol:514:23\n    │\n514 │         if (g == 0 || block.timestamp < g) return 0;\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/HmmMine.sol:541:21\n    │\n541 │         uint256 t = block.timestamp < genesis ? genesis : block.timestamp;\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/HmmMine.sol:553:26\n    │\n553 │         return g != 0 && block.timestamp >= g;\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/HmmMine.sol:577:65\n    │\n577 │             if (c < 0x20 || c > 0x7e || c == 0x22 || c == 0x5c) revert BadQuestion();\n    │                                                                 ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HmmMine.sol:595:20\n    │\n595 │         q.raised = uint128(raised);\n    │                    ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' 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[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/Emission.t.sol:51:21\n   │\n51 │             vm.warp(block.timestamp + bound(uint256(gaps[i]), 1, 30 days));\n   │             ────────━━━━━━━━━━━━━━━─────────────────────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/utils/HmmTestBase.sol:154:29\n    │\n154 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Emission.t.sol:51:13\n    │\n 51 │             vm.warp(block.timestamp + bound(uint256(gaps[i]), 1, 30 days));\n    │             ────────────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/utils/HmmTestBase.sol:155:30\n    │\n155 │         a.expiresAt = uint64(block.timestamp + 1 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Emission.t.sol:51:13\n    │\n 51 │             vm.warp(block.timestamp + bound(uint256(gaps[i]), 1, 30 days));\n    │             ────────────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/HmmMine.t.sol:489:17\n    │\n489 │         vm.warp(block.timestamp + 3 hours + 5 minutes); // round 18\n    │         ────────━━━━━━━━━━━━━━━─────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/utils/HmmTestBase.sol:154:29\n    │\n154 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HmmMine.t.sol:552:9\n    │\n552 │         vm.warp(block.timestamp + 10 * ROUND);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/utils/HmmTestBase.sol:155:30\n    │\n155 │         a.expiresAt = uint64(block.timestamp + 1 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HmmMine.t.sol:552:9\n    │\n552 │         vm.warp(block.timestamp + 10 * ROUND);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/HmmMine.t.sol:552:17\n    │\n552 │         vm.warp(block.timestamp + 10 * ROUND);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/utils/HmmTestBase.sol:154:29\n    │\n154 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    ‡\n231 │         vm.warp(mine.roundEnd(_roundOf(id)));\n    │         ──────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/utils/HmmTestBase.sol:155:30\n    │\n155 │         a.expiresAt = uint64(block.timestamp + 1 days);\n    │                              ━━━━━━━━━━━━━━━\n    ‡\n231 │         vm.warp(mine.roundEnd(_roundOf(id)));\n    │         ──────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/HmmMine.t.sol:711:17\n    │\n711 │         vm.warp(block.timestamp + 40 * ERA + 7 days);\n    │         ────────━━━━━━━━━━━━━━━───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/HmmMine.t.sol:739:17\n    │\n739 │         vm.warp(block.timestamp + 40 * ERA + 7 days);\n    │         ────────━━━━━━━━━━━━━━━───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/HmmMine.t.sol:782:75\n    │\n782 │         vm.expectRevert(abi.encodeWithSelector(HmmMine.TooEarly.selector, block.timestamp + 3 days));\n    │                                                                           ━━━━━━━━━━━━━━━\n783 │         mine.applyConfig();\n784 │         vm.warp(block.timestamp + 3 days);\n    │         ───────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/HmmMine.t.sol:784:17\n    │\n784 │         vm.warp(block.timestamp + 3 days);\n    │         ────────━━━━━━━━━━━━━━━────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/HmmMine.t.sol:828:17\n    │\n828 │         vm.warp(block.timestamp + 25 minutes); // round 2\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/audit/StewardAdapter.t.sol:46:17\n   │\n46 │         vm.warp(block.timestamp + 3 days);\n   │         ────────━━━━━━━━━━━━━━━────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\n","passed":true},{"durationMs":12388,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/audit/ForeignRequestFirst.t.sol:AuditForeignRequestFirstTest\n[PASS] test_audit_foreignRequestBeforeTheAsk_isRefused() (gas: 1344155)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.13ms (524.12µs CPU time)\n\nRan 2 tests for test/audit/StewardAdapter.t.sol:AuditStewardAdapterTest\n[PASS] test_audit_stewardAdapter_capturesEmissionWithoutAnswers() (gas: 1561163)\nLogs:\n  HMM taken for 0.5 IMD, no oracle answer (whole tokens): 56616078\n\n[PASS] test_noSteward_rulesAreFixedForever() (gas: 104408)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 2.19ms (890.91µs CPU time)\n\nRan 1 test for test/audit/ConfigBoundary.t.sol:AuditConfigBoundaryTest\n[PASS] test_audit_questionProposedBeforeQueue_refusesTheNewConfig() (gas: 1125520)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.41ms (765.73µs CPU time)\n\nRan 11 tests for test/SwarmOracleAdapter.t.sol:SwarmOracleAdapterTest\n[PASS] testFuzz_realSignature_breaksOnAnyTamper(uint8,uint256) (runs: 2000, μ: 22867, ~: 22800)\n[PASS] test_bind_onceAndIdempotent() (gas: 125259)\n[PASS] test_check_reasons() (gas: 333794)\n[PASS] test_constructor_validates() (gas: 6239)\n[PASS] test_longAnswer_isCountedAndHashed() (gas: 2592519)\n[PASS] test_onlyTheIntakeCallsBack() (gas: 96585)\n[PASS] test_realSwarmSignatures_recoverTheOracleSigner() (gas: 76785)\n[PASS] test_selectors_matchTheSwarmsCallbackShape() (gas: 5907)\n[PASS] test_thoughtEvent_carriesTheAnswer() (gas: 660894)\n[PASS] test_unboundAdapterRefusesCallbacks() (gas: 78434)\n[PASS] test_unknownRequestIsRefused() (gas: 83194)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 515.01ms (524.99ms CPU time)\n\nRan 9 tests for test/GenesisForwarder.t.sol:GenesisForwarderTest\n[PASS] test_constructor_validates() (gas: 3851)\n[PASS] test_copycatLaunch_cannotTouchTheRealReserve() (gas: 1516773)\n[PASS] test_crossWiredLaunch_isRefused() (gas: 1464974)\n[PASS] test_forward_movesTheWholeRemainderAndStarts() (gas: 767527)\n[PASS] test_forward_onlyOncePerMine() (gas: 252373)\n[PASS] test_forward_refusesALaunchWithoutAMine() (gas: 226480)\n[PASS] test_forward_refusesAMineOfAnotherForwarder() (gas: 88371)\n[PASS] test_forward_refusesAMineOfAnotherToken() (gas: 872809)\n[PASS] test_forward_refusesOtherLaunchKinds() (gas: 124957)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 515.46ms (3.96ms CPU time)\n\nRan 45 tests for test/HmmMine.t.sol:HmmMineTest\n[PASS] test_answerInALaterEra_isWorthLess() (gas: 1418360)\n[PASS] test_answerThatDoesNotCount_isRecordedAsFailed() (gas: 565421)\n[PASS] test_answer_creditsTheRound_withRolloverSinceGenesis() (gas: 722582)\n[PASS] test_back_minimumUnlessCompletingTheRemainder() (gas: 596759)\n[PASS] test_back_refusedWhenClosedOrNotOpen() (gas: 723622)\n[PASS] test_bodyOf_isTheExactJsonTheSwarmChecked() (gas: 64766)\n[PASS] test_callback_fitsTheIntakeStipend() (gas: 719644)\nLogs:\n  callback gas (refused path): 46589\n\n[PASS] test_callback_gasMargin() (gas: 2547540)\nLogs:\n  minimum stipend for the costliest callback: 118437\n\n[PASS] test_claim_onlyAfterTheRoundEnds() (gas: 911830)\n[PASS] test_config_cancel_andRenounce() (gas: 241480)\n[PASS] test_config_queueApplyAfterDelay_newQuestionsOnly() (gas: 1451525)\n[PASS] test_config_refusesAnAdapterBoundToAnotherMine() (gas: 141176)\n[PASS] test_constructor_validates() (gas: 19384)\n[PASS] test_creditAndFail_onlyFromTheQuestionsAdapter() (gas: 503819)\n[PASS] test_devShare_isPaidToDev_byAnyone() (gas: 792433)\n[PASS] test_emptyRoundsRollIntoTheNextAnsweredRound() (gas: 1271544)\n[PASS] test_failure_closesTheQuestion_withoutCredit() (gas: 573114)\n[PASS] test_forgedAnswer_doesNotCount() (gas: 563656)\n[PASS] test_genesisDelay_blocksQuestionsUntilGenesis() (gas: 1239549)\n[PASS] test_halving_halvesTheRate() (gas: 153459)\n[PASS] test_oneAskPerTransaction() (gas: 1791891)\n[PASS] test_outsiderRequestNamingTheAdapter_cannotMine() (gas: 484743)\n[PASS] test_ownQuestion_completedByAContractIsFine() (gas: 890514)\n[PASS] test_pooledCompletion_mustComeFromAnAccountDirectly() (gas: 1197257)\n[PASS] test_pooledQuestion_isAskedWhenTheLastBackerCompletesIt() (gas: 906375)\n[PASS] test_priceFall_paysTheQuotedTarget() (gas: 609531)\n[PASS] test_priceRise_blocksTheAsk_andBackersRefund() (gas: 477101)\n[PASS] test_propose_capsAmountAtPrice() (gas: 412614)\n[PASS] test_propose_notSoldWhenPriceIsZero() (gas: 89875)\n[PASS] test_propose_rejectsDust() (gas: 53597)\n[PASS] test_refund_afterDeadlineOnly_andOnce() (gas: 598443)\n[PASS] test_refund_refusedOnceAsked() (gas: 453577)\n[PASS] test_refusal_closesTheQuestion() (gas: 516608)\n[PASS] test_sameOracleAnswer_countsOnce() (gas: 1107519)\n[PASS] test_sameRound_splitsByIMDPaid_andPooledBackersSplitByShare() (gas: 1493393)\n[PASS] test_soloAsk_paysTheSwarmAndRecordsTheRequest() (gas: 531574)\n[PASS] test_spec_rulesAndInjection() (gas: 576707)\n[PASS] test_start_needsReserve() (gas: 589418)\n[PASS] test_start_onlyForwarder() (gas: 29619)\n[PASS] test_start_onlyOnce() (gas: 34187)\n[PASS] test_start_setsReserveGenesisAndRate() (gas: 50267)\n[PASS] test_stats_andPot() (gas: 759737)\n[PASS] test_stats_beforeStart() (gas: 593294)\n[PASS] test_token_isPlainAndFixed() (gas: 36673)\n[PASS] test_writerCannotCreditAPendingRequestThroughAnotherCompletion() (gas: 937478)\nSuite result: ok. 45 passed; 0 failed; 0 skipped; finished in 515.58ms (30.43ms CPU time)\n\nRan 6 tests for test/Emission.t.sol:EmissionTest\n[PASS] testFuzz_answeredRounds_accountForEveryEmittedUnit(uint32[6]) (runs: 2000, μ: 3995615, ~: 4009976)\n[PASS] testFuzz_emittedAt_isMonotonic(uint64,uint64) (runs: 2000, μ: 35655, ~: 33649)\n[PASS] testFuzz_emittedAt_isTheIntegralOfTheRate(uint64) (runs: 2000, μ: 139407, ~: 43711)\n[PASS] testFuzz_emittedAt_neverExceedsTheReserve(uint256) (runs: 2000, μ: 25061, ~: 32256)\n[PASS] testFuzz_pooledClaims_neverExceedTheRound(uint96[5]) (runs: 2000, μ: 1860548, ~: 1791528)\n[PASS] test_firstEra_emitsHalfTheReserve_andTheTailIsDust() (gas: 46961)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 515.99ms (2.04s CPU time)\n\nRan 9 tests for test/LaunchReadiness.t.sol:LaunchReadinessTest\n[PASS] test_actionIsTheAsciiActionId() (gas: 295)\n[PASS] test_adapterMineArgumentMustBeZero() (gas: 2284159)\n[PASS] test_applicationConstructorsMoveNoSupply() (gas: 29251)\n[PASS] test_constructorsConfigureEverything() (gas: 112143)\n[PASS] test_mineNeedsTheAdapterDeployedFirst() (gas: 1095261)\n[PASS] test_noCallIncreasesSupply() (gas: 402680)\n[PASS] test_noOwnerPowersAfterLaunch() (gas: 192308)\n[PASS] test_runtimeHasNoForbiddenOpcodesAndFits() (gas: 14487412)\n[PASS] test_tokenMintsTheManifestSupplyToTheFactory() (gas: 46144)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 516.37ms (29.08ms CPU time)\n\nRan 1 test for test/audit/AdversarialInvariants.t.sol:AuditAdversarialInvariantTest\n[PASS]\nAuditAdversarialInvariantTest invariants:\n[PASS] invariant_audit_hmmConservedAndSolvent\n[PASS] invariant_audit_imdConserved\n[PASS] invariant_audit_roundsConsistent\n AuditAdversarialInvariantTest invariants (runs: 256, calls: 20480, reverts: 0)\n\n╭--------------------+-----------+-------+---------+----------╮\n| Contract           | Selector  | Calls | Reverts | Discards |\n+=============================================================+\n| AdversarialHandler | back      | 2325  | 0       | 0        |\n|--------------------+-----------+-------+---------+----------|\n| AdversarialHandler | claim     | 2269  | 0       | 0        |\n|--------------------+-----------+-------+---------+----------|\n| AdversarialHandler | movePrice | 2363  | 0       | 0        |\n|--------------------+-----------+-------+---------+----------|\n| AdversarialHandler | payDev    | 2266  | 0       | 0        |\n|--------------------+-----------+-------+---------+----------|\n| AdversarialHandler | propose   | 2255  | 0       | 0        |\n|--------------------+-----------+-------+---------+----------|\n| AdversarialHandler | refund    | 2307  | 0       | 0        |\n|--------------------+-----------+-------+---------+----------|\n| AdversarialHandler | rotate    | 2267  | 0       | 0        |\n|--------------------+-----------+-------+---------+----------|\n| AdversarialHandler | settle    | 2215  | 0       | 0        |\n|--------------------+-----------+-------+---------+----------|\n| AdversarialHandler | warp      | 2213  | 0       | 0        |\n╰--------------------+-----------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 6.12s (6.12s CPU time)\n\nRan 1 test for test/invariant/MineInvariants.t.sol:MineInvariantTest\n[PASS]\nMineInvariantTest invariants:\n[PASS] invariant_hmmIsConserved\n[PASS] invariant_imdIsConserved\n[PASS] invariant_questionsAreConsistent\n[PASS] invariant_roundSharesMatchAnsweredQuestions\n[PASS] invariant_solvency\n MineInvariantTest invariants (runs: 256, calls: 20480, reverts: 0)\n\n╭-------------+----------+-------+---------+----------╮\n| Contract    | Selector | Calls | Reverts | Discards |\n+=====================================================+\n| MineHandler | back     | 2910  | 0       | 0        |\n|-------------+----------+-------+---------+----------|\n| MineHandler | claim    | 2842  | 0       | 0        |\n|-------------+----------+-------+---------+----------|\n| MineHandler | payDev   | 2947  | 0       | 0        |\n|-------------+----------+-------+---------+----------|\n| MineHandler | propose  | 2899  | 0       | 0        |\n|-------------+----------+-------+---------+----------|\n| MineHandler | refund   | 3004  | 0       | 0        |\n|-------------+----------+-------+---------+----------|\n| MineHandler | settle   | 2989  | 0       | 0        |\n|-------------+----------+-------+---------+----------|\n| MineHandler | warp     | 2889  | 0       | 0        |\n╰-------------+----------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 12.24s (12.24s CPU time)\n\nRan 10 test suites in 12.25s (20.95s CPU time): 86 tests passed, 0 failed, 0 skipped (86 total tests)\n","passed":true},{"durationMs":124,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"GenesisForwarder.forward(uint64)\",\"HmmMine.applyConfig()\",\"HmmMine.back(uint256,uint256,bytes)\",\"HmmMine.cancelConfig()\",\"HmmMine.claim(uint256[])\",\"HmmMine.credit(bytes32)\",\"HmmMine.fail(bytes32,uint8,bytes32)\",\"HmmMine.payDev()\",\"HmmMine.propose((string,uint8,uint8,uint32,uint16,uint16,uint16,uint16),uint256)\",\"HmmMine.queueConfig(address,bytes32)\",\"HmmMine.refund(uint256)\",\"HmmMine.setSteward(address)\",\"HmmMine.start()\",\"HmmToken.approve(address,uint256)\",\"HmmToken.transfer(address,uint256)\",\"HmmToken.transferFrom(address,address,uint256)\",\"SwarmOracleAdapter.bind()\",\"SwarmOracleAdapter.onOracleFailure(bytes32,uint8,bytes32,uint16,uint16,bytes)\",\"SwarmOracleAdapter.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\"],\"files\":{\".github/workflows/test.yml\":20,\".gitignore\":18,\"ADAPTATION.md\":66,\"LICENSE\":21,\"README.md\":66,\"devnet/activity.mjs\":129,\"devnet/package-lock.json\":217,\"devnet/package.json\":12,\"devnet/preview-tunnel.sh\":21,\"devnet/preview.mjs\":127,\"devnet/start.sh\":44,\"devnet/stop.sh\":9,\"devnet/swarm.mjs\":222,\"docs/DESIGN.md\":71,\"docs/LAUNCH.md\":94,\"docs/SECURITY.md\":56,\"docs/TOKENOMICS.md\":52,\"foundry.toml\":52,\"launch/body.json\":36,\"launch/build-site-body.mjs\":22,\"launch/build.mjs\":103,\"launch/buy-imd.mjs\":65,\"launch/check.mjs\":21,\"launch/config.json\":12,\"launch/export-public.sh\":33,\"launch/export-site.sh\":40,\"launch/metrics.mjs\":70,\"launch/package-lock.json\":248,\"launch/package.json\":11,\"launch/pay.mjs\":205,\"launch/watch.mjs\":50,\"remappings.txt\":2,\"script/DeployForwarder.s.sol\":31,\"script/Devnet.s.sol\":87,\"script/HmmLaunch.sol\":144,\"script/IProjectFactory.sol\":64,\"src/GenesisForwarder.sol\":65,\"src/HmmMine.sol\":639,\"src/HmmToken.sol\":15,\"src/SwarmOracleAdapter.sol\":220,\"src/interfaces/IHmmMine.sol\":20,\"src/interfaces/IIntake.sol\":31,\"src/interfaces/ILaunchRegistry.sol\":27,\"src/interfaces/IOracleAdapter.sol\":15,\"test/Emission.t.sol\":119,\"test/GenesisForwarder.t.sol\":104,\"test/HmmMine.t.sol\":862,\"test/LaunchReadiness.t.sol\":185,\"test/SwarmOracleAdapter.t.sol\":190,\"test/audit/AdversarialInvariants.t.sol\":253,\"test/audit/ConfigBoundary.t.sol\":44,\"test/audit/ForeignRequestFirst.t.sol\":57,\"test/audit/StewardAdapter.t.sol\":112,\"test/external/Intake.sol\":325,\"test/fixtures/RealAttestations.sol\":137,\"test/fork/Launch.fork.t.sol\":262,\"test/invariant/MineInvariants.t.sol\":241,\"test/utils/HmmTestBase.sol\":233,\"test/utils/Mocks.sol\":45,\"web/.env.example\":22,\"web/.gitignore\":5,\"web/.npmrc\":1,\"web/README.md\":184,\"web/e2e/devnet.e2e.test.ts\":248,\"web/index.html\":24,\"web/lab/pond-lab.tsx\":267,\"web/lab/pond.html\":18,\"web/package-lock.json\":8959,\"web/package.json\":41,\"web/proxy/check-worker.js\":71,\"web/public/favicon.svg\":18,\"web/scripts/abi.mjs\":49,\"web/src/App.tsx\":113,\"web/src/abi/genesisForwarder.ts\":194,\"web/src/abi/hmmMine.ts\":1671,\"web/src/abi/hmmToken.ts\":329,\"web/src/abi/index.ts\":5,\"web/src/abi/swarmOracleAdapter.ts\":744,\"web/src/components/EmissionChart.tsx\":173,\"web/src/components/Footer.tsx\":46,\"web/src/components/FrogMascot.tsx\":142,\"web/src/components/Header.tsx\":109,\"web/src/components/LaunchBanner.tsx\":34,\"web/src/components/LiveNotifier.tsx\":40,\"web/src/components/MoonGlyph.tsx\":101,\"web/src/components/ScrollStory.tsx\":439,\"web/src/components/ShareCard.tsx\":236,\"web/src/components/Wallet.tsx\":225,\"web/src/components/icons.tsx\":70,\"web/src/components/question.tsx\":246,\"web/src/components/states.tsx\":63,\"web/src/components/toast.tsx\":97,\"web/src/components/ui.tsx\":416,\"web/src/config.ts\":209,\"web/src/data/app.tsx\":125,\"web/src/data/claim.ts\":19,\"web/src/data/clock.ts\":56,\"web/src/data/discovery.ts\":158,\"web/src/data/hooks.ts\":506,\"web/src/data/indexer.test.ts\":164,\"web/src/data/indexer.ts\":603,\"web/src/data/liveRound.test.ts\":45,\"web/src/data/mining.ts\":90,\"web/src/data/pondFeed.ts\":56,\"web/src/data/rpcErrors.ts\":10,\"web/src/data/token.ts\":33,\"web/src/data/tx.ts\":93,\"web/src/devnet/connectors.ts\":14,\"web/src/devnet/keys.ts\":13,\"web/src/devnet/localKey.ts\":123,\"web/src/devnet/ui.tsx\":144,\"web/src/env.d.ts\":4,\"web/src/lib/answer.test.ts\":51,\"web/src/lib/answer.ts\":97,\"web/src/lib/body.test.ts\":168,\"web/src/lib/body.ts\":321,\"web/src/lib/check.ts\":71,\"web/src/lib/emission.test.ts\":119,\"web/src/lib/emission.ts\":134,\"web/src/lib/errors.ts\":85,\"web/src/lib/format.test.ts\":88,\"web/src/lib/format.ts\":166,\"web/src/lib/reasons.test.ts\":34,\"web/src/lib/reasons.ts\":101,\"web/src/lib/spec.test.ts\":89,\"web/src/lib/spec.ts\":116,\"web/src/main.tsx\":49,\"web/src/pages/AskPage.tsx\":826,\"web/src/pages/FaqPage.tsx\":88,\"web/src/pages/HowPage.tsx\":293,\"web/src/pages/LedgerPage.tsx\":204,\"web/src/pages/MePage.tsx\":251,\"web/src/pages/MinersPage.tsx\":112,\"web/src/pages/MoonPage.tsx\":207,\"web/src/pages/NotFound.tsx\":9,\"web/src/pages/OpenPage.tsx\":97,\"web/src/pages/PondPage.tsx\":806,\"web/src/pages/QuestionPage.tsx\":277,\"web/src/pages/TokenPage.tsx\":222,\"web/src/pond/PondCanvas.tsx\":60,\"web/src/pond/camera.ts\":107,\"web/src/pond/crowd.ts\":629,\"web/src/pond/effects.ts\":889,\"web/src/pond/engine.ts\":1999,\"web/src/pond/fallback2d.ts\":159,\"web/src/pond/moon.ts\":222,\"web/src/pond/rng.ts\":100,\"web/src/pond/sim.ts\":278,\"web/src/pond/sprites.ts\":451,\"web/src/pond/types.ts\":130,\"web/src/pond/water-gl.ts\":480,\"web/src/sound/SoundToggle.tsx\":29,\"web/src/sound/engine.ts\":362,\"web/src/styles/app.css\":594,\"web/src/styles/global.css\":1171,\"web/src/styles/pages.css\":2073,\"web/src/theme.ts\":27,\"web/src/wagmi.ts\":32,\"web/tsconfig.json\":34,\"web/vite.config.ts\":166,\"web/vitest.e2e.config.ts\":14},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"f7f68caa530a40dde9214b1d7c07940329bae71070f16cbf34a8f25b13014a4f","verifiedTreeHash":"36c13498701532b2eed9e73c4e5d5eea9eb6e271","verifierVersion":"0.1.0+327e1e9f"}]}