{"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":"1dab3513-76f3-4a54-a326-db5036c0b8a0","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"ae97d6ad22f7e64636923b60b44a4dbc332cbbd9d834e9f073eaa6aaa02c0ea2","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":"c8ffedbb338f4f7d933ddbc0f78510ab2310c45035fbabc33e1740ca2f7dd140","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_economics","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"2eb15be20d76860fb097d092988cc24d49638e32cb5f8271418a39db420d9fdf","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_flow","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"76fdbd2f93cd3c2e1d39a4c7ae25ce86288fde329e91a9e76d48c6597a884c73","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":"4135c044dc101c0fefd2a1930c63cd0edc50b70661c38e9f426e6e1a0a0dae96","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":"accepted"},{"acceptedSubmissionHash":"5d338d723e52f6fd291713f4f54913c7722887577fb6aa77bd7d0cf8b693c838","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_math","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"faaa5f6fb91a77585328d8964372b89cb7fe6dc392c04712487f6c6c57bc2044","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_permissions","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"67bbd6d3dadf1e4cc5964c811decbcebf1948b1fe8212d3a1d3f3d3d708fb702","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"cad7286f97c623aeea5dc062faa6b79e49847fba831b88f562628738463e8b2b","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":"Start from this repository's audited Verdict contracts (src/VerdictBurnVault.sol, src/VerdictOracle.sol, src/VerdictMarkets.sol and their tests, deployed on Sepolia as launch 1277). Add settler rewards to VerdictMarkets and point VerdictOracle at IMD's Intake version 2; change nothing else in behaviour. Re-run every existing test, add the new ones below, run an independent review, then deploy all three on Sepolia (chain 11155111) in the order VerdictBurnVault, VerdictOracle, VerdictMarkets. Leave web/ and dist/ untouched; a later job updates the site.\n\nWhy: anyone who moves a market forward is paid a small reward from that market's own bounty, so settlement never depends on one operator's bot.\n\nSettler rewards in VerdictMarkets:\n- New immutable constructor parameter maxSettlerReward, appended after maxPoolPerMarket.\n- Params gains settlerReward (uint256, appended after bounty). createMarket reverts when settlerReward > maxSettlerReward, and requires the requested and the received bounty to be at least 2 x the oracle price + 5 x settlerReward.\n- Rewarded actions, paid to msg.sender: each successful resolve, each accepted propose (first proposal and the escalation replacement), finalize, and voidMarket. escalate is never rewarded.\n- A reward is paid from the market's remaining bounty after all state changes of that call. While the market can still ask the oracle, a reward never leaves the remaining bounty below the current oracle price x (2 - asks used); if it would, the call still succeeds and the reward is the largest amount that keeps that reserve (possibly zero). In finalize and voidMarket the reserve is zero; the reward is paid first and the rest of the bounty then returns to the creator as today.\n- settlerReward of zero must work exactly like the current contract.\n- Event SettlerRewarded(uint256 indexed id, address indexed settler, uint8 action, uint256 amount) with action 0 resolve, 1 propose, 2 finalize, 3 void. Market (and getMarket) also exposes settlerReward and rewardsPaid.\n- Invariant, per market: payouts + refunds + fees + oracle spend + settler rewards + returned bounty == deposits, with no dust left.\n\nVerdictOracle: no code change. Its intake is IMD's Intake v2 0xa43e6f75ee006411f79ac1c84120606c2330de82 on Sepolia, whose request(bytes32 action, bytes body, (address target, bytes4 selector) callback, address asset, uint256 amount) is the same as version 1 and calls the callback from the Intake itself. Do not use requestWithFailure.\n\nNew tests: each rewarded action pays the caller once and emits SettlerRewarded; escalate pays no reward; the reserve rule when the oracle price rises after creation; the bounty minimum with a reward; maxSettlerReward bound; reward zero matches the previous behaviour; rewards never touch bettor deposits or fees; the full lifecycle invariant with rewards; existing tests updated only for the new constructor parameter and Params field.\n\nSepolia only. GitHub publication is approved. Contracts only: no token, no pool, no proxy. Constructor arguments: VerdictBurnVault(); VerdictOracle(0xa43e6f75ee006411f79ac1c84120606c2330de82, 0x44a1cd38474fb1748400e7deb5f8d786cce3f89a, 0x5598aa9146215bc13eb26f2c692ad1461fd32982, 0x6f7261636c652e72657175657374406f7261636c652d31000000000000000000, 500000000000000000, $owner, 0); VerdictMarkets($contract:VerdictOracle, 0x44a1cd38474fb1748400e7deb5f8d786cce3f89a, $owner, $contract:VerdictBurnVault, $owner, 100, 50, 50, 500000000000000000000, 250000000000000000). The owner is 0x397dacb1ee8e9a8ce5196988958f56bde0a0a312. Solidity 0.8.26, OpenZeppelin v5 as vendored.","parentJobId":null,"planHash":"435e22a1b600abd7375075a3aded3b47c8e2e59216647d0720187d32cdf94ff2","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"1dab3513-76f3-4a54-a326-db5036c0b8a0","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1296-start-repository-s-audited-verdict"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51005","feedbackHash":"773b444c57eee9354c377db4d7d8eda78c678ff37cc9070cc2f5a237abfa702e","nodeKey":"adapt_contract_project","submissionHash":"ae97d6ad22f7e64636923b60b44a4dbc332cbbd9d834e9f073eaa6aaa02c0ea2","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52176","feedbackHash":"a05decd97794462f1f483b5c258ea4e0099ce8d18c4d82e4d9f7039d239244f6","nodeKey":"audit_economics","submissionHash":"c8ffedbb338f4f7d933ddbc0f78510ab2310c45035fbabc33e1740ca2f7dd140","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51084","feedbackHash":"70a4edc6302e6a8da87a42731c8701f5be28314f2335a4d319abeebef4c8ce14","nodeKey":"audit_flow","submissionHash":"2eb15be20d76860fb097d092988cc24d49638e32cb5f8271418a39db420d9fdf","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51145","feedbackHash":"fb2ac3d3b291f7a36d87451e20fba92d07264d681082bd2d74594695173dfa57","nodeKey":"audit_imported_code","submissionHash":"76fdbd2f93cd3c2e1d39a4c7ae25ce86288fde329e91a9e76d48c6597a884c73","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51476","feedbackHash":"ab8a64c80d70b7282180481d90da5597fe167d78c30fb592ba937fc6ff06c346","nodeKey":"audit_judge","submissionHash":"4135c044dc101c0fefd2a1930c63cd0edc50b70661c38e9f426e6e1a0a0dae96","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52160","feedbackHash":"0ba2cbaa71031d7cd342f70800315914627fa8373d9971c16cb2552cfdad93fb","nodeKey":"audit_math","submissionHash":"5d338d723e52f6fd291713f4f54913c7722887577fb6aa77bd7d0cf8b693c838","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52130","feedbackHash":"a0701e13880429cdbe0f118fad88a0a1357720722523c1cae1cf178f277bab99","nodeKey":"audit_permissions","submissionHash":"faaa5f6fb91a77585328d8964372b89cb7fe6dc392c04712487f6c6c57bc2044","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"50956","feedbackHash":"095b2ecf52c2c18e74214d13c0a77246ad9f6e4eba56d63138fbf710cd7e398a","nodeKey":"manifest","submissionHash":"67bbd6d3dadf1e4cc5964c811decbcebf1948b1fe8212d3a1d3f3d3d708fb702","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51007","feedbackHash":"7931165383e30fd0c1c012b9e0a00b0841250251d705686d826e6f01e547fbb9","nodeKey":"write_foundry_tests","submissionHash":"cad7286f97c623aeea5dc062faa6b79e49847fba831b88f562628738463e8b2b","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"568445a8692f4a5a71e9658f4e9d6547a95724a57c51c6a5a47b317600930206","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"7c0191a32541eb74","findings":[{"citation":"resolved","description":"The brief ties the reserve to the market's ability to keep asking: 'While the market can still ask the oracle, a reward never leaves the remaining bounty below the current oracle price x (2 - asks used)'. _recordSettlerReward approximates 'can still ask' by `m.asks < 2` only. Two reachable states have asks == 1 but no further ask is possible: (a) `propose` (action 1) on a market created with an empty escalationBody, where `escalate` always reverts EscalationUnavailable and `resolve` reverts WrongState once Provisional; (b) `propose` or `resolve` at a time when `block.timestamp + 24 hours >= answerUntil` for the retry, or `block.timestamp >= answerUntil` for the escalation, so `_askWindow` rejects every later ask. In those states the code still subtracts the full current oracle price before computing the reward, so when the price has risen since creation the settler's reward is clipped (possibly to zero) although nothing is left for that reserve to fund; the clipped amount is later returned to the creator by finalize/voidMarket. No funds are lost and the invariant holds; the deviation is only against the brief's reserve clause and only after an owner-driven price rise. Reported low. If the author prefers the conservative reading (reserve whenever asks < 2), the brief wording should say so; otherwise the condition should also require that an ask is still possible, e.g. for action 1: `m.escalationBodyHash != bytes32(0) && block.timestamp < m.params.answerUntil`, and for action 0: `block.timestamp + 24 hours < m.params.answerUntil`.","line":467,"path":"src/VerdictMarkets.sol","reproduction":"TestBase setup (price 0.5 IMD, maxSettlerReward 0.25). creator calls createMarket(p, body, \"\" /* no escalation body */, uri, 1) with p.settlerReward = 0.1 IMD and p.bounty = 1.5 IMD (= 2*0.5 + 5*0.1). Warp to answerFrom; any address calls resolve(id, body): oracleSpend 0.5, reward 0.1 paid, bountyRemaining 0.9. Deliver the signed attestation to VerdictOracle. Oracle owner proposeConfig/acceptConfig with price = 0.9 IMD (configDelay is 0 in the Sepolia constructor). proposer calls propose(id, a). Expected per brief: the market is now Provisional with escalationBodyHash == 0, so no ask is possible, the reserve clause does not apply, and the proposer receives min(0.1, 0.9) = 0.1 IMD. Actual: reserve = oracle.price() = 0.9, bountyRemaining (0.9) is not > reserve, amount = 0, SettlerRewarded(id, proposer, 1, 0) is emitted, proposer's balance change is 0, bountyRemaining stays 0.9; escalate(id, ...) reverts EscalationUnavailable confirming no ask remains; after disputeEnds voidMarket pays the voider 0.1 and returns 0.8 to the creator. The scratch test test/scratch/Probe.t.sol::test_noEscalationBodyStillReservesPrice reproduces these exact numbers (proposer reward 0, remaining 0.9e18).","severity":"low","snippet":"        if (action < 2 && m.asks < 2) reserve = oracle.price();","title":"Reward reserve is held even when the market can no longer ask the oracle (no escalation body, or ask window closed), so a settler is underpaid after a price rise"}],"hash":"2eb15be20d76860fb097d092988cc24d49638e32cb5f8271418a39db420d9fdf","nodeId":"6d2756b4-41ba-4e0a-999b-2e997a86f5a7","outcome":"completed","summary":"Review complete. The findings file is written and validated, with the one substantiated finding and a full coverage record for all 22 entry points plus three invariants.\n\n**Outcome**\n\nThe settler-reward adaptation holds up under the Execution Trace, Periphery and First Principles checks. The full existing suite passes (147 tests, 20 suites), the contracts build under the pinned configuration with VerdictMarkets at 16,825 bytes of runtime, and the probes I wrote under `test/scratch/` confirmed every trace.\n\n**One finding, low severity**, in `src/VerdictMarkets.sol:467`. The reward reserve is keyed only on `asks < 2`, so it is still held when the market can no longer ask at all: a market created with no escalation body, or one whose ask window has closed. After an owner-driven price rise, a proposer in that state is paid less than the brief's reserve clause allows (zero in the reproduced case) and the difference goes back to the creator at finalize or void. No funds are lost and the conservation invariant holds, so I rated it low and noted that the conservative reading is defensible if the brief is clarified.\n\n**What traced clean**\n\n- Reward amounts are bounded by the market's own remaining bounty, never by the pool, so bettor deposits and fees are unreachable.\n- Reserve is price times one when one ask remains and zero after two asks or at any terminal call, matching the brief's formula on every reachable path.\n- Bounty minimum arithmetic is overflow-free and exactly equivalent to twice price plus five rewards.\n- Rewards are recorded before any transfer, settlers are paid before the creator in finalize and void, and escalate never rewards.\n- A zero settlerReward skips the price read, event and transfer, so legacy behaviour and event order are unchanged.\n- VerdictOracle is unchanged, pins the intake and signer per request, and its callback selector and struct match the protocol vector, so pointing at Intake v2 only changes the constructor address.\n\n**Static-analysis leads** (reentrancy, uninitialized locals, strict equality, timestamps) were each checked and none reproduced as a defect; the guards and exact-balance checks interrupt every path.\n\n**Not reached**: nothing in the assigned area. I did not evaluate the web or dist directories, which the brief excludes, nor the off-chain Intake v2 contract itself beyond the interface the brief and reference describe.","treeHash":null,"usage":{"cachedInputTokens":1905536,"inputTokens":706,"model":"claude-fable-5-1","outputTokens":29048,"runtime":"claude","turns":23,"wallClockMs":780911}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"e9049e5b12ba53ba","findings":[{"citation":"resolved","description":"Merged from audit_permissions, audit_flow and audit_economics, which all report the same root cause. The brief limits the reserve to the time 'while the market can still ask the oracle'. _recordSettlerReward checks only `m.asks < 2`. With asks == 1, three states can no longer ask: (a) an accepted first propose on a market created with an empty escalationBody (escalate reverts EscalationUnavailable at line 309, and resolve reverts WrongState because the market is Provisional); (b) a first propose accepted at or after answerUntil (escalate's _askWindow reverts); (c) a resolve whose 24h retry would land at or after answerUntil, on a market with no escalation body. In each state, once the current oracle price has risen so that bountyRemaining - price < settlerReward, the settler's reward is clipped, possibly to zero. The withheld amount then goes to the creator in finalize/voidMarket. No bettor funds are touched and the conservation invariant still holds. Value moves from settler to creator, against the brief's reserve clause. Minimal fix: for action 1, reserve only if `!m.escalated && m.escalationBodyHash != 0 && block.timestamp < m.params.answerUntil`. For action 0, also require that a retry (`block.timestamp + 24 hours < answerUntil`) or an escalation is still reachable.","line":467,"path":"src/VerdictMarkets.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {VerdictOracle} from \"src/VerdictOracle.sol\";\nimport {VerdictMarkets} from \"src/VerdictMarkets.sol\";\nimport {VerdictBurnVault} from \"src/VerdictBurnVault.sol\";\nimport {OracleAttestation} from \"src/OracleAttestation.sol\";\nimport {IIntake} from \"src/interfaces/IIntake.sol\";\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ncontract ScratchIMD is ERC20 {\n    constructor() ERC20(\"Test IMD\", \"IMD\") {}\n\n    function mint(address to, uint256 amount) external {\n        _mint(to, amount);\n    }\n}\n\ncontract ScratchIntake is IIntake {\n    uint256 public nonce;\n    mapping(bytes32 => Callback) public callbacks;\n\n    function request(bytes32, bytes calldata, Callback calldata callback, address asset, uint256 amount)\n        external\n        payable\n        returns (bytes32 id)\n    {\n        IERC20(asset).transferFrom(msg.sender, address(this), amount);\n        id = keccak256(abi.encode(address(this), ++nonce));\n        callbacks[id] = callback;\n    }\n\n    function deliver(bytes32 id, OracleAttestation.Attestation calldata a, bytes calldata signature) external {\n        Callback memory cb = callbacks[id];\n        (bool ok,) = cb.target.call{gas: 200_000}(abi.encodeWithSelector(cb.selector, id, a, signature));\n        require(ok, \"callback failed\");\n    }\n}\n\n/// @dev Reserve rule: \"while the market can still ask the oracle, a reward never leaves the remaining\n/// bounty below the current oracle price x (2 - asks used)\". With no escalation body the market can\n/// never ask again once its first proposal is accepted, yet the proposal reward is still clipped by a\n/// full oracle price. The withheld part is later returned to the creator, not paid to the proposer.\ncontract ReserveWithoutAskTest is Test {\n    uint256 internal constant SIGNER_KEY = 0x123456;\n    uint256 internal constant PRICE = 0.5 ether;\n    uint256 internal constant REWARD = 0.1 ether;\n    bytes32 internal constant ACTION = bytes32(\"oracle.request@oracle-1\");\n    address internal creator = makeAddr(\"creator\");\n    address internal resolver = makeAddr(\"resolver\");\n    address internal proposer = makeAddr(\"proposer\");\n    address internal treasury = makeAddr(\"treasury\");\n    ScratchIMD internal token;\n    ScratchIntake internal intake;\n    VerdictOracle internal oracle;\n    VerdictMarkets internal markets;\n    bytes internal body = '{\"v\":1,\"question\":\"primary\"}';\n\n    function setUp() public {\n        vm.warp(1_800_000_000);\n        vm.chainId(11155111);\n        token = new ScratchIMD();\n        intake = new ScratchIntake();\n        oracle =\n            new VerdictOracle(address(intake), address(token), vm.addr(SIGNER_KEY), ACTION, PRICE, address(this), 0);\n        VerdictBurnVault burn = new VerdictBurnVault();\n        markets = new VerdictMarkets(\n            address(oracle), address(token), treasury, address(burn), address(this), 100, 50, 50, 500 ether, 0.25 ether\n        );\n        markets.setCreatorAllowed(creator, true);\n        token.mint(creator, 100 ether);\n        vm.prank(creator);\n        token.approve(address(markets), type(uint256).max);\n    }\n\n    function setPrice(uint256 price) internal {\n        oracle.proposeConfig(VerdictOracle.Config(address(intake), address(token), vm.addr(SIGNER_KEY), ACTION, price));\n        oracle.acceptConfig();\n    }\n\n    function test_proposalRewardIsClippedAlthoughNoAskRemains() public {\n        VerdictMarkets.Params memory p;\n        p.questionHash = keccak256(\"q\");\n        p.answerType = 0;\n        p.dataChainId = 1;\n        p.fromBlock = 100;\n        p.toBlock = 200;\n        p.minPanelSize = 5;\n        p.minAgreed = 4;\n        p.closeAt = uint64(block.timestamp + 1 hours);\n        p.answerFrom = p.closeAt;\n        p.answerUntil = p.answerFrom + 4 days;\n        p.disputeWindow = 1 days;\n        p.voidAfter = p.answerUntil + 1 hours;\n        p.bounty = 2 * PRICE + 5 * REWARD; // 1.5 IMD, the exact minimum\n        p.settlerReward = REWARD;\n        vm.prank(creator);\n        // No escalation body: this market can never ask the oracle a second time after a proposal.\n        uint256 id = markets.createMarket(p, body, \"\", \"ipfs://m\", 0);\n\n        vm.warp(p.answerFrom);\n        vm.prank(resolver);\n        bytes32 rid = markets.resolve(id, body);\n        assertEq(token.balanceOf(resolver), REWARD);\n        assertEq(markets.getMarket(id).bountyRemaining, 0.9 ether);\n\n        OracleAttestation.Attestation memory a;\n        a.requestId = keccak256(\"req\");\n        a.chainId = 1;\n        a.questionHash = p.questionHash;\n        a.answerType = 0;\n        a.answer = abi.encode(true);\n        a.fromBlock = 100;\n        a.toBlock = 200;\n        a.blockHash = keccak256(\"b\");\n        a.panelJobId = keccak256(\"j\");\n        a.panelSize = 5;\n        a.quorum = 4;\n        a.agreed = 5;\n        a.issuedAt = uint64(block.timestamp);\n        a.expiresAt = uint64(block.timestamp + 7 days);\n        (uint8 v, bytes32 r, bytes32 s) = vm.sign(SIGNER_KEY, oracle.attestationDigest(a));\n        intake.deliver(rid, a, abi.encodePacked(r, s, v));\n\n        // The oracle price rises after the ask. No further ask is possible for this market.\n        setPrice(0.85 ether);\n        vm.prank(proposer);\n        markets.propose(id, a);\n        VerdictMarkets.Market memory m = markets.getMarket(id);\n        assertEq(uint8(m.status), uint8(VerdictMarkets.Status.Provisional));\n        assertEq(m.escalationBodyHash, bytes32(0));\n        vm.expectRevert(VerdictMarkets.EscalationUnavailable.selector);\n        markets.escalate(id, body);\n\n        // Expected by the brief's wording: the market cannot ask again, so the full reward is paid.\n        assertEq(token.balanceOf(proposer), REWARD, \"proposer reward clipped although no ask remains\");\n    }\n}","reproduction":"Reproduced by running the attached proof (the specialist's, fails on this tree). Setup: oracle price 0.5e18, configDelay 0, maxSettlerReward 0.25e18. createMarket with settlerReward 0.1e18, bounty 1.5e18 (the exact minimum, 2*0.5 + 5*0.1) and escalationBody = \"\". At answerFrom, resolver calls resolve: reward 0.1e18, bountyRemaining 0.9e18. A valid 5-seat attestation is delivered. The oracle owner sets the price to 0.85e18 via proposeConfig + acceptConfig. Proposer calls propose(id,a). The market is now Provisional with escalationBodyHash 0, and escalate reverts EscalationUnavailable. Expected: proposer receives 0.1e18. Actual: 0.05e18 (forge: 'proposer reward clipped although no ask remains: 50000000000000000 != 100000000000000000'). The other 0.05e18 is returned to the creator at finalize.","severity":"low","snippet":"        if (action < 2 && m.asks < 2) reserve = oracle.price();","title":"Settler reward still reserves a full oracle price when the market can no longer ask (no escalation body / ask window closed), underpaying the settler after a price rise"}],"hash":"4135c044dc101c0fefd2a1930c63cd0edc50b70661c38e9f426e6e1a0a0dae96","nodeId":"317ecfcb-c13b-466a-87d2-2216c580ee12","outcome":"completed","summary":"The review found one defect worth keeping, rated low. I wrote it with a coverage record to `.imd-findings.json`, and no repository files were changed.\n\n**Kept finding (low): settlers are underpaid when the market can no longer ask the oracle.** Three of the specialists (permissions, flow, economics) reported this, so it is one merged finding.\n- **Where:** `src/VerdictMarkets.sol:467`, `if (action < 2 && m.asks < 2) reserve = oracle.price();`\n- **Rule broken:** the brief says the reserve applies only \"while the market can still ask the oracle\". The code checks only that fewer than two asks have been used.\n- **When it bites:** after a first proposal on a market with no escalation body, after a proposal at or after `answerUntil`, or after a late resolve that leaves no room for a retry. In those states no further ask is possible, but the full current oracle price is still held back.\n- **Effect:** if the oracle price has risen, the settler's reward is cut, possibly to zero. The withheld amount goes back to the creator at finalize or void. Bettor funds are never touched, and the deposits-equal-outflows invariant still holds.\n- **Reproduction:** I ran the economics specialist's proof test and it fails on this code with `50000000000000000 != 100000000000000000`. With price 0.5, reward 0.1 and bounty 1.5, the price is raised to 0.85 after resolve. The proposer then gets 0.05 instead of 0.1, and `escalate` reverts `EscalationUnavailable`. The test is attached to the finding.\n\n**Dropped:**\n- **Late resolve is rewarded (math):** a resolve in the last seconds of the answer window buys an answer that can never be accepted, and still earns a reward. It does reproduce, but the brief says to reward every successful resolve, so the code does what was asked. Changing it would change the agreed design.\n- **Escalate then propose earns a reward (economics):** escalation itself pays nothing, and the replacement proposal is rewarded exactly as the brief specifies. The cost to creators is limited to what they funded, and a reward of zero opts out.\n- **Oracle owner with zero config delay can decide markets (permissions):** this predates the change. The brief requires the zero delay and no change to VerdictOracle, so it is a trust assumption, not a defect in this change.\n- **Static-analysis leads:** the reentrancy warnings in `request` and `_ask` are blocked by `nonReentrant` plus exact balance checks. The \"uninitialized\" locals are meant to start at zero, and the strict equality in `_pull` is safe.\n\n**Other checks:**\n- Compared with the audited version, the code diff only adds the reward feature.\n- The bounty check is exactly \"at least 2 × price + 5 × reward\" and cannot overflow.\n- A reward of zero returns early and keeps the old behaviour.\n- The full test suite passes (156/156).\n- All three contracts are under the size limits; VerdictMarkets is 16.8 KB deployed.\n- The coverage record answers all 22 entry points plus the invariant: 20 hold, and `resolve` and `propose` are linked to the finding.\n\n`launch.json` writes the owner as `$owner` rather than the static address the brief names. I left this out of the findings because the brief's own constructor arguments use `$owner`.","treeHash":null,"usage":{"cachedInputTokens":444581,"inputTokens":14,"model":"claude-opus-5-5","outputTokens":8266,"runtime":"claude","turns":8,"wallClockMs":386955}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"cd8076510aad8b8e","findings":[{"citation":"resolved","description":"resolve() only requires block.timestamp < answerUntil (_askWindow, line 438) and rewards every successful ask. propose() later rejects any primary attestation with a.issuedAt > p.answerUntil (line 348). The oracle answers minutes after the request, so a resolve() placed in the last seconds (realistically the last minutes) of the answer window buys an answer that is guaranteed to fail the issuedAt bound. The caller is still paid settlerReward from the creator's bounty and the oracle price is spent, although nothing can move the market forward from that ask; the only remaining path is voidMarket, which pays a second reward. Before this adaptation the same late ask was possible but cost the caller gas for nothing; with rewards it is net positive for the caller (reward minus gas) and the creator loses price + reward relative to a plain void. Severity is low: the loss per market is bounded to one oracle price plus one reward, it only applies to markets nobody resolved earlier, and the brief's reward-on-every-successful-resolve rule is what the code implements. A minimal fix that keeps the agreed design would be to compute the reserve/reward only when the ask still has a realistic chance to be answered (e.g. require answerUntil - block.timestamp >= some margin for a rewarded resolve, or pay the resolve reward lazily when the answer is proposed). Both change behaviour slightly, so the author must decide.","line":301,"path":"src/VerdictMarkets.sol","reproduction":"Deployed parameters (price 0.5 IMD, maxSettlerReward 0.25). createMarket with settlerReward = 0.1 IMD, bounty = 2*0.5 + 5*0.1 = 1.5 IMD, answerFrom = closeAt, answerUntil = answerFrom + 4 days, voidAfter = answerUntil + 1 hour. Warp to answerUntil - 1 second; griefer calls resolve(id, body). Expected: no reward for an ask that cannot be answered in time. Actual: succeeds, oracle spend 0.5, SettlerRewarded(id, griefer, 0, 0.1e18), griefer balance +0.1 IMD, bountyRemaining 0.9. Oracle delivers the attestation at answerUntil + 5 minutes with issuedAt = that timestamp; propose(id, a) reverts InvalidAttestation (issuedAt > answerUntil). Warp to voidAfter; griefer calls voidMarket(id): paid another 0.1 IMD; creator receives 0.8 IMD of the 1.5 IMD bounty (loses 0.5 price + 0.2 rewards) whereas without the late ask a void would have returned 1.4 IMD. Reproduced with test/scratch/Probe.t.sol::test_lateResolveRewardedButAnswerUnacceptable (passes on the current code, i.e. the behaviour occurs).","severity":"low","snippet":"        _pay(msg.sender, _recordSettlerReward(id, m, 0));","title":"resolve() pays the settler reward for an ask placed so late in the answer window that its answer can never be accepted (boundary x invariant: reward paid without the market moving forward)"}],"hash":"5d338d723e52f6fd291713f4f54913c7722887577fb6aa77bd7d0cf8b693c838","nodeId":"5b72ab8e-2af6-4392-b16e-d549e9008439","outcome":"completed","summary":"The findings file is valid, the cited line matches the tree, the scratch tests are removed, and the working tree is clean apart from the findings file.\n\n**Outcome.** The settler-reward arithmetic in VerdictMarkets is sound. One low-severity defect was substantiated, and every entry point received a coverage row (23 entry points plus three invariants, 25 rows).\n\n**What I checked in my area (Math Precision, Boundary, Numerical Gap):**\n- The bounty minimum check is exactly `bounty >= 2*price + 5*reward` with no overflow or underflow path. The short-circuit order guarantees that `2*cost` fits and the subtraction cannot wrap.\n- The reserve rule pays `min(reward, remaining - price)` only when remaining exceeds the current price, and uses a zero reserve after the second ask and on terminal calls. A 512-run fuzz over post-resolve price changes confirmed an unchanged price always leaves the escalation affordable.\n- Fee rounding is down on three `mulDiv` calls, and the last winner takes the exact remainder, so payouts plus fees equal the pool with no dust. A 1-wei winner can round to zero, which the existing tests already document.\n- Time boundaries at `closeAt`, `answerUntil`, `voidAfter` and `disputeEnds` are mutually exclusive between competing actions. No comparator is off by one.\n- VerdictOracle enforces exact payment in both directions, bounded body and answer sizes, and a non-overflowing issuedAt tolerance. The deployed zero config delay is a documented owner trust assumption, not a defect.\n- The full suite passed locally, 147 tests across 20 suites.\n\n**The one finding (low).** A `resolve` placed in the last seconds of the answer window is rewarded although its answer must arrive after `answerUntil` and will be rejected by `propose`. The griefer nets the reward and the creator loses one oracle price plus two rewards compared with a plain void. The loss is bounded per market and only applies to markets nobody resolved earlier, so I rated it low and left it without a proof file. A fix would change behaviour slightly, so the author must decide.\n\n**Not reached.** Nothing in the assigned entry-point list was left unverified. I did not re-derive the EIP-712 conformance vector or the launch manifest, which belong to other specialists.","treeHash":null,"usage":{"cachedInputTokens":920625,"inputTokens":258,"model":"claude-fable-5-1","outputTokens":34449,"runtime":"claude","turns":25,"wallClockMs":760720}},{"artifacts":[],"attempt":1,"bundleHash":"40aa50b847015011d1052bc24535b7d52729452c9b3a36110b7d23aa6422d22c","device":"bb0a3bf63233e5e5","findings":[],"hash":"67bbd6d3dadf1e4cc5964c811decbcebf1948b1fe8212d3a1d3f3d3d708fb702","nodeId":"38971061-b5b1-466a-8c10-8f7257aa12b6","outcome":"completed","summary":"Created [launch.json](/home/imd-worker/.identitymd/work/1dab3513-76f3-4a54-a326-db5036c0b8a0/38971061-b5b1-466a-8c10-8f7257aa12b6/launch.json) with the approved contract order, Intake v2 address, `$owner` references, and reward cap.\n\nSchema and compiled constructor ABI checks passed. `forge build` succeeded; all 147 tests passed offline.\n\nOnly `launch.json` is changed for submission.","treeHash":"603eabe8f662682c994d7895a37955a5f8e0e82b","usage":{"cachedInputTokens":639744,"inputTokens":57381,"model":"gpt-6-astra","outputTokens":5388,"runtime":"codex","turns":5,"wallClockMs":245734}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"3b9f88f55251764d","findings":[{"citation":"resolved","description":"The brief for this adaptation points VerdictOracle at IMD Intake v2 (0xa43e6f75ee006411f79ac1c84120606c2330de82) and appends a tenth VerdictMarkets constructor argument maxSettlerReward = 250000000000000000. The tree still carries launch.json with the v1 Intake 0x1397434cd35e8a9c8ac312a61d3a285eb31dea56 and nine VerdictMarkets constructorArgs, script/SepoliaParameters.sol line 9 with INTAKE = v1 and marketsConstructorArgs encoding nine values, docs/DEPLOYMENT.md line 26 stating 'The supplied v1 Intake is deliberate', and test/Deployment.t.sol asserting oracle.intake() == SepoliaParameters.INTAKE. None of this is a runtime defect in the contracts, and the contracts themselves take the intake as a constructor input with no hardcoded address, so VerdictOracle needs no code change. But a launch.json present in the tree is checked as a manifest: once maxSettlerReward is added, a nine-entry constructorArgs list no longer matches the ten-parameter constructor and the whole submission is rejected, and a manifest that still names v1 would deploy against the wrong intake. The adapter must update launch.json (or remove it so the manifest step regenerates it), SepoliaParameters.sol, Deployment.t.sol and DEPLOYMENT.md together.","line":11,"path":"launch.json","reproduction":"State: tree as committed at 94cc85c. Input: compare launch.json contracts[1].constructorArgs[0] (0x1397434c...) with the brief's VerdictOracle argument 0xa43e6f75...; compare contracts[2].constructorArgs length (9) with the brief's VerdictMarkets argument list (10, ending 250000000000000000). Expected after adaptation: VerdictOracle arg 0 == 0xa43e6f75ee006411f79ac1c84120606c2330de82 and VerdictMarkets constructorArgs has 10 entries. Actual: v1 address and 9 entries; test/Deployment.t.sol line 46 pins SepoliaParameters.INTAKE (v1) and would fail if only the manifest were changed.","severity":"low","snippet":"        \"0x1397434cd35e8a9c8ac312a61d3a285eb31dea56\",","title":"Launch artifacts still describe the pre-adaptation deployment: Intake v1 address and a 9-argument VerdictMarkets constructor"},{"citation":"resolved","description":"escalate has no caller restriction, no stake requirement and no cost to msg.sender. It charges the current oracle price to the market's bountyRemaining and raises disputeEnds to at least block.timestamp + 24 hours (line 306). A griefer who has no position in the market can therefore, once per market, burn one oracle price of the creator's bounty and delay finalize for every bettor by almost a full day, paying only gas. Because escalation is bounded to one per market and the amount is one oracle price, the impact is bounded and non-compounding, which is why this is low rather than medium. It matters more for the adaptation the brief describes: the bounty remaining after escalation is also what funds settler rewards and what returns to the creator, so a free escalation also removes 0.5 IMD from the reward budget. The permissionless design is intentional (README: 'anyone may call escalate'), so this is reported as a griefing vector to decide on, not a permission bypass. A minimal mitigation that preserves the design is to require the escalator to hold stake in the market, or to let the escalator pay the escalation ask themselves instead of the bounty.","line":296,"path":"src/VerdictMarkets.sol","reproduction":"Setup (TestBase): oracle price 0.5 IMD, market created with bounty 1 IMD, alice bets 100 IMD on outcome 1, bob bets 100 IMD on outcome 0, a primary answer 'true' is delivered and proposed at time T with disputeWindow 1 day, so disputeEnds = T + 1 day. At disputeEnds - 1 an address 'griefer' that holds no stake and spends no tokens calls escalate(id, escalationBody). Expected (for a safe design): either reverts for a non-participant or the escalator pays. Actual: call succeeds, griefer's token balance is unchanged, bountyRemaining drops from 0.5 IMD to 0 (the creator's bounty paid the ask), disputeEnds moves from T + 1 day to T + 1 day + 24 hours - 1 second, finalize(id) at the original disputeEnds reverts OutsideWindow, and after settlement returnedBounty is 0. Verified in test/scratch/Probe.t.sol test_strangerEscalatesAtNoCostBurnsBountyAndDelays (passes on current code, demonstrating the behaviour).","severity":"low","snippet":"    function escalate(uint256 id, bytes calldata body) external nonReentrant returns (bytes32 requestId) {","title":"escalate is free for the caller: any address with no stake can spend 0.5 IMD of the creator's bounty and push settlement back by up to 24 hours"},{"citation":"resolved","description":"_validateParams only orders closeAt <= answerFrom < answerUntil < voidAfter. The request bodies are opaque bytes; a body that the Intake refuses (bad JSON, a 'consumer' naming another contract, a 'deliver' block) spends the bounty and never produces a callback, so the market can only end by voidMarket at voidAfter. With voidAfter = type(uint64).max every bettor's deposit stays in the contract with no path out, forever in practice. The README documents 'No maximum lifetime', bettors can read voidAfter and both bodies in MarketCreated before betting, and creators are allowlisted by the guardian at launch, so this is a documented trust assumption rather than a defect; it is recorded here so the adapter and the final panel can decide whether a lifetime cap (for example voidAfter - answerUntil <= 30 days) belongs in the adaptation. Not an issue for the settler-reward change itself.","line":471,"path":"src/VerdictMarkets.sol","reproduction":"Input: Params from TestBase with p.voidAfter = type(uint64).max; createMarket succeeds; alice bets 10 IMD on outcome 1; no usable answer is ever delivered. At answerUntil + 365 days: voidMarket(id) reverts OutsideWindow and alice's claim(id) reverts WrongState. Expected: a bounded lifetime after which deposits are refundable. Actual: deposits remain locked until the year 584 billion. Verified in test/scratch/Probe.t.sol test_creatorCanSetVoidAfterFarInFuture.","severity":"info","snippet":"                || p.answerFrom >= p.answerUntil || p.answerUntil >= p.voidAfter || p.disputeWindow < 1 hours","title":"voidAfter has no upper bound: a creator can publish a market whose refund date is arbitrarily far away while the oracle body is unverifiable on chain"},{"citation":"resolved","description":"The launch rules forbid pausing, freezing, blacklisting or seizing holder balances. VerdictMarkets has a guardian pause and a creator allowlist. Both gate entry only: pause() blocks createMarket and bet through the entryOpen modifier; setCreatorAllowed gates createMarket. resolve, escalate, propose, finalize, voidMarket and claim carry no entryOpen modifier, so no deposit, payout or refund can be frozen, and no balance can be seized or moved by the guardian. The brief says to change nothing else in behaviour and this design was accepted for launch 1277, so this is not reported as a defect to remove; it is recorded so the adapter and the final review confirm the policy reading explicitly rather than by omission. The oracle owner's zero-delay proposeConfig/acceptConfig (src/VerdictOracle.sol line 159) is the other privileged power: it can rotate intake and signer in one block and so author answers to future asks, including for markets that already hold bets; requests already paid keep their pinned intake and signer. Both powers are documented in README and DEPLOYMENT.md.","line":189,"path":"src/VerdictMarkets.sol","reproduction":"State: guardian = 0x397dacb1ee8e9a8ce5196988958f56bde0a0a312 calls pause(). Then: bet(id, 1, 1 ether, 0) reverts EntryPaused and createMarket reverts EntryPaused; finalize(id) and claim(id) on a market past its dispute window succeed and move tokens (test/VerdictLifecycleInvariant.t.sol exercises claims while paused). Expected and actual agree: funds are never frozen by the guardian.","severity":"info","snippet":"    function pause() external onlyGuardian {","title":"Guardian pause and creator allowlist: entry-only controls, recorded for the launch policy on pausing"},{"citation":"resolved","description":"Not a defect in the current code; a map for the change the brief asks for. _releaseBounty sets returnedBounty = bountyRemaining and zeroes bountyRemaining, and finalize then pays creatorFee + bounty to the creator in one transfer (line 368). The brief's invariant payouts + refunds + fees + oracle spend + settler rewards + returned bounty == deposits only holds if the reward is subtracted from bountyRemaining and added to rewardsPaid before _releaseBounty runs, and if the reserve rule (bountyRemaining must stay >= oracle price x (2 - asks) while asks < 2 for resolve and propose) reads oracle.price() at reward time, not the creation-time price. Also note escalate (line 296) must stay unrewarded, and that a free escalation (finding 2) already reduces the bounty that rewards draw from.","line":448,"path":"src/VerdictMarkets.sol","reproduction":"Illustrative for the adapted code: market with bounty 1.5 IMD, oracle price 0.5 IMD, settlerReward 0.1 IMD, one ask made (bountyRemaining 1.0). If finalize calls _releaseBounty first and then pays the reward, returnedBounty records 1.0 while the creator receives 0.9 and the settler 0.1, so the recorded sum exceeds deposits by 0.1 IMD and the brief's invariant fails. Expected: bountyRemaining 0.9 enters _releaseBounty, returnedBounty 0.9, rewardsPaid 0.1.","severity":"info","snippet":"    function _releaseBounty(uint256 id, Market storage m) private returns (uint256 bounty) {","title":"Adapter note for settler rewards: finalize and voidMarket release the whole remaining bounty in _releaseBounty, so the reward must be taken before it"}],"hash":"76fdbd2f93cd3c2e1d39a4c7ae25ce86288fde329e91a9e76d48c6597a884c73","nodeId":"01ee1c0f-eb5b-4543-aa5a-c416cd805efc","outcome":"completed","summary":"Review complete. The findings file is valid JSON with five entries, every snippet matches its line exactly, and `git status` shows no new tracked files; only the ignored `.imd-findings.json`, build caches and `test/scratch/` exist.\n\n**Outcome: no critical, high or medium defect found.** The three contracts as they arrived are sound for the brief's purpose. Two low findings and three info notes are in `.imd-findings.json`.\n\n**Scope read in full:** `src/VerdictMarkets.sol`, `src/VerdictOracle.sol`, `src/VerdictBurnVault.sol`, `src/OracleAttestation.sol`, both interfaces, both mocks, the test base, the market, regression and deployment suites, `launch.json`, `script/SepoliaParameters.sol`, the docs, and the vendored OpenZeppelin SignatureChecker. Nothing in scope was unreachable. I skimmed rather than fully read the lifecycle invariant, atomicity, settlement-property and adversarial oracle suites. The existing suite passed in full before I started.\n\nFindings, ranked:\n\n- **Low, launch.json line 11.** The manifest, `script/SepoliaParameters.sol`, `docs/DEPLOYMENT.md` and `test/Deployment.t.sol` all still name Intake v1 and a nine-argument VerdictMarkets constructor. Once `maxSettlerReward` is appended, the in-tree manifest no longer matches the constructor and the submission is rejected. The adapter must update all four together.\n- **Low, VerdictMarkets.sol line 296.** `escalate` costs its caller nothing. A stranger with no stake can burn one oracle price of the creator's bounty and push `disputeEnds` back almost 24 hours, once per market. Verified by a scratch test. This is the intended permissionless design, so it is reported as a bounded griefing vector to decide on, and it also shrinks the bounty the new settler rewards draw from.\n- **Info, line 471.** `voidAfter` is unbounded, so a creator with an unanswerable body can lock deposits until `uint64` max. Documented and allowlist-mitigated.\n- **Info, line 189.** Guardian pause and allowlist gate entry only, never claims or settlement. Recorded for the launch policy on pausing since the brief says to change no other behaviour.\n- **Info, line 448.** Adapter map for the reward change: `_releaseBounty` releases the whole remaining bounty, so the reward must be deducted before it runs or the brief's invariant overstates `returnedBounty`.\n\nWhat I checked and found clean: callback authentication pins intake and signer per request, attestations bind to the market's own paid ask, replay keys, the two-ask limit, the retry and escalation windows, fee and payout rounding with the last-claimant remainder, checks-effects-interactions under `nonReentrant`, exact oracle spend, and the conservation invariant.","treeHash":null,"usage":{"cachedInputTokens":1553872,"inputTokens":418,"model":"claude-fable-5-1","outputTokens":36508,"runtime":"claude","turns":38,"wallClockMs":665941}},{"artifacts":[],"attempt":1,"bundleHash":"0f4f5f03074e6175a7456706e72cc6cbcb1ec5644af4854c4da1004b97298f5c","device":"9b2fda471b13b14a","findings":[],"hash":"ae97d6ad22f7e64636923b60b44a4dbc332cbbd9d834e9f073eaa6aaa02c0ea2","nodeId":"7d7e34a6-2821-4774-9d14-03f5c5bb5cb1","outcome":"completed","summary":"Implemented settler rewards and the Intake v2 deployment handoff. `forge build` passed; all 147 tests passed. Independent review found no concrete defect. `web/` and `dist/` remain untouched.\n\nChanges and audit dispositions are documented in [ADAPTATION.md](/home/imd-worker/.identitymd/work/1dab3513-76f3-4a54-a326-db5036c0b8a0/7d7e34a6-2821-4774-9d14-03f5c5bb5cb1/ADAPTATION.md).\n\nSepolia deployment remains pending with the launch service; no transactions were broadcast.","treeHash":"d104605261477d122e872c8374bdd0bb00a81bfd","usage":{"cachedInputTokens":3975040,"inputTokens":146257,"model":"gpt-6-astra","outputTokens":30293,"runtime":"codex","turns":10,"wallClockMs":948706}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"ee2cc12e7dfe571a","findings":[{"citation":"resolved","description":"The brief states the reserve applies 'while the market can still ask the oracle'. _recordSettlerReward approximates that with `m.asks < 2`, but after an accepted first proposal a market with no escalation body (escalationBodyHash == 0) can never ask again: escalate reverts EscalationUnavailable (line 309) and resolve reverts WrongState because the status is Provisional. The same holds for a first proposal accepted at or after params.answerUntil (propose only requires block.timestamp < voidAfter, while escalate goes through _askWindow). In both states the proposer's reward is still reduced to keep one full current oracle price in the bounty, and that withheld amount is later returned to the creator by finalize/voidMarket instead of being paid to the settler. When the oracle price has risen since the ask, the proposer is underpaid by up to the whole settlerReward although the reserve protects nothing. Under the literal formula 'price x (2 - asks used)' the code is consistent, so this is a spec-reading defect rather than a loss of funds; it only moves value from the settler to the creator. Minimal fix that preserves the brief: in _recordSettlerReward, skip the reserve when `action == 1` and no further ask is possible, i.e. when `m.escalationBodyHash == bytes32(0)` or `block.timestamp >= m.params.answerUntil` (the market cannot escalate in either case).","line":467,"path":"src/VerdictMarkets.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {VerdictOracle} from \"src/VerdictOracle.sol\";\nimport {VerdictMarkets} from \"src/VerdictMarkets.sol\";\nimport {VerdictBurnVault} from \"src/VerdictBurnVault.sol\";\nimport {OracleAttestation} from \"src/OracleAttestation.sol\";\nimport {IIntake} from \"src/interfaces/IIntake.sol\";\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ncontract ScratchIMD is ERC20 {\n    constructor() ERC20(\"Test IMD\", \"IMD\") {}\n\n    function mint(address to, uint256 amount) external {\n        _mint(to, amount);\n    }\n}\n\ncontract ScratchIntake is IIntake {\n    uint256 public nonce;\n    mapping(bytes32 => Callback) public callbacks;\n\n    function request(bytes32, bytes calldata, Callback calldata callback, address asset, uint256 amount)\n        external\n        payable\n        returns (bytes32 id)\n    {\n        IERC20(asset).transferFrom(msg.sender, address(this), amount);\n        id = keccak256(abi.encode(address(this), ++nonce));\n        callbacks[id] = callback;\n    }\n\n    function deliver(bytes32 id, OracleAttestation.Attestation calldata a, bytes calldata signature) external {\n        Callback memory cb = callbacks[id];\n        (bool ok,) = cb.target.call{gas: 200_000}(abi.encodeWithSelector(cb.selector, id, a, signature));\n        require(ok, \"callback failed\");\n    }\n}\n\n/// @dev Reserve rule: \"while the market can still ask the oracle, a reward never leaves the remaining\n/// bounty below the current oracle price x (2 - asks used)\". With no escalation body the market can\n/// never ask again once its first proposal is accepted, yet the proposal reward is still clipped by a\n/// full oracle price. The withheld part is later returned to the creator, not paid to the proposer.\ncontract ReserveWithoutAskTest is Test {\n    uint256 internal constant SIGNER_KEY = 0x123456;\n    uint256 internal constant PRICE = 0.5 ether;\n    uint256 internal constant REWARD = 0.1 ether;\n    bytes32 internal constant ACTION = bytes32(\"oracle.request@oracle-1\");\n    address internal creator = makeAddr(\"creator\");\n    address internal resolver = makeAddr(\"resolver\");\n    address internal proposer = makeAddr(\"proposer\");\n    address internal treasury = makeAddr(\"treasury\");\n    ScratchIMD internal token;\n    ScratchIntake internal intake;\n    VerdictOracle internal oracle;\n    VerdictMarkets internal markets;\n    bytes internal body = '{\"v\":1,\"question\":\"primary\"}';\n\n    function setUp() public {\n        vm.warp(1_800_000_000);\n        vm.chainId(11155111);\n        token = new ScratchIMD();\n        intake = new ScratchIntake();\n        oracle =\n            new VerdictOracle(address(intake), address(token), vm.addr(SIGNER_KEY), ACTION, PRICE, address(this), 0);\n        VerdictBurnVault burn = new VerdictBurnVault();\n        markets = new VerdictMarkets(\n            address(oracle), address(token), treasury, address(burn), address(this), 100, 50, 50, 500 ether, 0.25 ether\n        );\n        markets.setCreatorAllowed(creator, true);\n        token.mint(creator, 100 ether);\n        vm.prank(creator);\n        token.approve(address(markets), type(uint256).max);\n    }\n\n    function setPrice(uint256 price) internal {\n        oracle.proposeConfig(VerdictOracle.Config(address(intake), address(token), vm.addr(SIGNER_KEY), ACTION, price));\n        oracle.acceptConfig();\n    }\n\n    function test_proposalRewardIsClippedAlthoughNoAskRemains() public {\n        VerdictMarkets.Params memory p;\n        p.questionHash = keccak256(\"q\");\n        p.answerType = 0;\n        p.dataChainId = 1;\n        p.fromBlock = 100;\n        p.toBlock = 200;\n        p.minPanelSize = 5;\n        p.minAgreed = 4;\n        p.closeAt = uint64(block.timestamp + 1 hours);\n        p.answerFrom = p.closeAt;\n        p.answerUntil = p.answerFrom + 4 days;\n        p.disputeWindow = 1 days;\n        p.voidAfter = p.answerUntil + 1 hours;\n        p.bounty = 2 * PRICE + 5 * REWARD; // 1.5 IMD, the exact minimum\n        p.settlerReward = REWARD;\n        vm.prank(creator);\n        // No escalation body: this market can never ask the oracle a second time after a proposal.\n        uint256 id = markets.createMarket(p, body, \"\", \"ipfs://m\", 0);\n\n        vm.warp(p.answerFrom);\n        vm.prank(resolver);\n        bytes32 rid = markets.resolve(id, body);\n        assertEq(token.balanceOf(resolver), REWARD);\n        assertEq(markets.getMarket(id).bountyRemaining, 0.9 ether);\n\n        OracleAttestation.Attestation memory a;\n        a.requestId = keccak256(\"req\");\n        a.chainId = 1;\n        a.questionHash = p.questionHash;\n        a.answerType = 0;\n        a.answer = abi.encode(true);\n        a.fromBlock = 100;\n        a.toBlock = 200;\n        a.blockHash = keccak256(\"b\");\n        a.panelJobId = keccak256(\"j\");\n        a.panelSize = 5;\n        a.quorum = 4;\n        a.agreed = 5;\n        a.issuedAt = uint64(block.timestamp);\n        a.expiresAt = uint64(block.timestamp + 7 days);\n        (uint8 v, bytes32 r, bytes32 s) = vm.sign(SIGNER_KEY, oracle.attestationDigest(a));\n        intake.deliver(rid, a, abi.encodePacked(r, s, v));\n\n        // The oracle price rises after the ask. No further ask is possible for this market.\n        setPrice(0.85 ether);\n        vm.prank(proposer);\n        markets.propose(id, a);\n        VerdictMarkets.Market memory m = markets.getMarket(id);\n        assertEq(uint8(m.status), uint8(VerdictMarkets.Status.Provisional));\n        assertEq(m.escalationBodyHash, bytes32(0));\n        vm.expectRevert(VerdictMarkets.EscalationUnavailable.selector);\n        markets.escalate(id, body);\n\n        // Expected by the brief's wording: the market cannot ask again, so the full reward is paid.\n        assertEq(token.balanceOf(proposer), REWARD, \"proposer reward clipped although no ask remains\");\n    }\n}","reproduction":"Price 0.5 IMD, settlerReward 0.1, bounty 1.5 (the exact minimum), escalationBody empty. (1) warp to answerFrom; resolver calls resolve(id, body): asks=1, oracleSpend 0.5, reserve 0.5, reward 0.1 paid, bountyRemaining 0.9. (2) Intake delivers a valid 5-seat attestation. (3) Oracle owner raises price to 0.85 (proposeConfig+acceptConfig, delay 0 as deployed). (4) proposer calls propose(id, a). Expected per the brief: the market can never ask again, so reward = min(0.1, 0.9) = 0.1 and bountyRemaining 0.8. Actual: reserve = 0.85, reward = min(0.1, 0.9-0.85) = 0.05 paid to proposer, bountyRemaining 0.85; escalate(id, body) then reverts EscalationUnavailable, and finalize later returns 0.85 - 0.1 = 0.75 to the creator. The scratch test test/scratch/ReserveWithoutAsk.t.sol fails on this tree with '50000000000000000 != 100000000000000000'.","severity":"low","snippet":"        if (action < 2 && m.asks < 2) reserve = oracle.price();","title":"Proposal reward is still clipped by a full oracle-price reserve when the market can no longer ask the oracle"},{"citation":"resolved","description":"escalate is deliberately unrewarded, but the replacement proposal it unlocks is rewarded (line 359, action 1) and anyone may submit it. A reward-seeking bot therefore escalates every market that has an escalation body at zero cost (the imported audit already records that escalation needs no stake and no payment), waits for the escalation answer, and proposes the replacement for settlerReward. The composition 'escalate + propose' nets the escalator exactly the reward the brief says escalation must never earn, and it charges the creator one more oracle price plus one more reward and delays finality by at least 24 hours. The same incentive applies to markets with no stake at all: before this change nobody had a reason to spend the creator's bounty on an ask for an empty market (voidMarket returned the full bounty); now a bot collects resolve, propose and void rewards and the creator's returned bounty drops from 1.5 to 0.7 IMD at the Sepolia configuration. Both are bounded by the creator's own provisioning (2 x price + 5 x reward) and the creator can opt out with settlerReward = 0, so impact is a bounded, non-compounding loss for creators who enable rewards, not a loss of bettor funds. Possible fixes are scope decisions that change agreed behaviour (for example: pay the replacement reward only to an address that holds stake in the market, or pay no replacement reward to the escalator; or skip the resolve reward when pool == 0). Reported so the author can decide knowingly.","line":359,"path":"src/VerdictMarkets.sol","reproduction":"Sepolia parameters: price 0.5, settlerReward 0.1, bounty 1.5, market with escalation body, alice bets 10 IMD on outcome 1. Creator self-settles: resolve (reward 0.1 back to creator), answer delivered, propose (0.1 back). Stranger bot: escalate(id, escalationBody) -> no reward, bountyRemaining falls 0.5; escalation answer (10 seats) delivered; bot calls propose(id, a) -> receives 0.1 IMD. finalize: oracleSpend 1.0, rewardsPaid 0.4, returnedBounty 0.1. Without the bot: oracleSpend 0.5, rewardsPaid 0.3, returnedBounty 0.7. Bot profit 0.1 IMD per market for gas only; creator loses 0.6 IMD extra (price + one reward) and finality is pushed out by >= 24h. Empty-market variant: no bets; bot calls resolve at answerFrom (0.1), propose (0.1), voidMarket at disputeEnds (0.1); creator's returnedBounty 0.7 instead of 1.5. Both sequences run in test/scratch/EscalationProfit.t.sol (passing, logging the figures).","severity":"low","snippet":"        _pay(msg.sender, _recordSettlerReward(id, m, 1));","title":"Rewards make the free, unrewarded escalation profitable for a stranger and pay for asks on markets that cannot benefit, at the creator's expense"}],"hash":"c8ffedbb338f4f7d933ddbc0f78510ab2310c45035fbabc33e1740ca2f7dd140","nodeId":"3962d52c-a08b-4c2f-a772-0c0fedcabf56","outcome":"completed","summary":"Review complete. The findings are in `.imd-findings.json` at the repository root (valid JSON, two findings, coverage rows for all 23 listed entry points plus two invariants and one \"unreached\" row for untested edges).\n\n**Outcome.** The settler-reward implementation is economically sound. The per-market conservation invariant holds, rewards only ever draw on the creator's bounty surplus, the bounty minimum and the reward cap are enforced on both requested and received amounts, terminal ordering pays the settler before the creator, and the full suite of 147 tests passes. I confirmed on Sepolia that the Intake at the version 2 address has code, quotes 0.5 IMD for the action, exposes the version 2 failure-hook selector, and that TestIMD has no pause or blacklist path. No critical, high or medium defect was found.\n\n**Findings, both low severity:**\n\n- **Reserve withheld when no ask remains.** The proposal reward keeps one full current oracle price in reserve whenever fewer than two asks were used, even for a market with no escalation body or a proposal accepted after the answer window, where no further ask is possible. With price 0.5, reward 0.1, bounty 1.5 and a price rise to 0.85, the proposer gets 0.05 instead of 0.1 and the difference goes back to the creator. A scratch test under `test/scratch/` fails on the current code for exactly this. It is a reading of the brief's \"while the market can still ask\" clause, not a loss of funds.\n- **Escalation becomes profitable through the replacement reward.** Escalate pays nothing, but anyone can then propose the replacement and collect the reward. A stranger's free escalation costs the creator one more oracle price plus one reward and delays finality by a day. The same incentive gets empty markets resolved for rewards, dropping the creator's returned bounty from 1.5 to 0.7 IMD. Bounded by what the creator provisioned, and fixing it is a scope decision for the author.\n\n**Not covered.** No test in the tree exercises a rewarded market without an escalation body or a proposal after the answer window, and no fork run against the live Intake was done.","treeHash":null,"usage":{"cachedInputTokens":1657439,"inputTokens":386,"model":"claude-fable-5-1","outputTokens":47315,"runtime":"claude","turns":36,"wallClockMs":758112}},{"artifacts":[],"attempt":1,"bundleHash":"4a559c943817edcb361d8d642930a1d05da2d65f12dfa4f33cc2d9f37ac20399","device":"c0d25825e3f9518b","findings":[],"hash":"cad7286f97c623aeea5dc062faa6b79e49847fba831b88f562628738463e8b2b","nodeId":"5a7a7af0-4193-486f-bcb6-f8d3da274afb","outcome":"completed","summary":"Added nine tests covering reward maximality, events, rejected calls, accounting invariants, and bounty arithmetic boundaries.\n\n`forge build` and `forge test` pass: **156 tests, zero failures or skips**.\n\nOnly `test/` changed. Review notes included; no contract defects reproduced.","treeHash":"0fc9817c3838dfbcfc583da1f7ef8e80a5f57514","usage":{"cachedInputTokens":3355392,"inputTokens":157164,"model":"gpt-6-astra","outputTokens":25002,"runtime":"codex","turns":8,"wallClockMs":824323}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"1c29c7c6e4cf57eb","findings":[{"citation":"resolved","description":"The brief limits the reserve to the period when the market can still ask the oracle: 'While the market can still ask the oracle, a reward never leaves the remaining bounty below the current oracle price x (2 - asks used)'. _recordSettlerReward checks only asks < 2. It ignores whether another ask is still reachable. After the first propose on a market created with an empty escalationBody (escalationBodyHash == 0), the market is Provisional: resolve needs Open, and escalate reverts EscalationUnavailable. The market can never ask again, yet one price is still reserved. The same happens when propose runs after answerUntil (escalate's _askWindow reverts), and when a resolve's 24-hour retry would land at or after answerUntil and no escalation body exists. Whenever the current price has risen so that bountyRemaining - price < settlerReward, the proposer or resolver is paid less than the full reward, or nothing. The withheld amount goes back to the creator in finalize/void. This is an asymmetry between the 'can ask' condition the brief defines and the 'asks < 2' condition the code uses. A fix that keeps the agreed design: for action 1, reserve the price only when !m.escalated && m.escalationBodyHash != 0 && block.timestamp < m.params.answerUntil (and asks < 2). For action 0, also require that a retry or escalation is still reachable before answerUntil.","line":467,"path":"src/VerdictMarkets.sol","reproduction":"Setup as in test/TestBase.sol (PRICE 0.5e18, maxSettlerReward 0.25e18). Creator calls createMarket with settlerReward = 0.25e18, bounty = 2.25e18 (the exact minimum) and escalationBody = \"\" (empty). Alice bets 10e18 on outcome 1. At answerFrom, carol calls resolve: reward 0.25e18, bountyRemaining = 1.5e18. The oracle owner calls proposeConfig/acceptConfig with price 1.4e18 (configDelay 0, so it takes effect at once). The answer is delivered, and bob calls propose. The market is now Provisional with no escalation body and cannot ask again. Expected: bob receives 0.25e18. Actual: reserve = 1.4e18, so bob receives min(0.25e18, 1.5e18 - 1.4e18) = 0.1e18 (verified with a scratch Foundry test: 'assertion failed: 100000000000000000 != 250000000000000000'). At finalize, the creator receives the 0.15e18 shortfall as returned bounty.","severity":"low","snippet":"        if (action < 2 && m.asks < 2) reserve = oracle.price();","title":"Resolve/propose reward keeps an oracle-price reserve even when the market can no longer ask the oracle, underpaying the settler"},{"citation":"resolved","description":"Access-control x trust-gap seam. The deployment passes configDelay = 0 to VerdictOracle, owned by 0x397d..a312, the same address that is the Markets guardian and treasury. acceptConfig (src/VerdictOracle.sol:164-168) swaps intake and signer in the same transaction as proposeConfig. Markets.resolve and Markets.escalate are permissionless, and they always buy through the oracle's current intake and signer. VerdictOracle.request pins whatever intake and signer are current, so a request made after a rotation is answered by the new intake and verified against the new signer. The owner can therefore install their own intake and key, call resolve on any Open market in its answer window, deliver a self-signed attestation with any outcome, and propose it. An escalation would also go to the owner's intake, so the result stands and finalize pays the owner's chosen side. Requests paid before the rotation stay protected, as documented. But the source comment above, and docs/DEPLOYMENT.md ('No ... alternate settlement authority exists'), describe the guardian/owner as unable to influence settlement, and that is not true while configDelay is 0. The brief mandates the zero delay and an unchanged VerdictOracle, so this is reported as a trust assumption to document, not a code defect. A nonzero configDelay (longer than one dispute window) would close it, but that is a scope decision for the requester.","line":11,"path":"src/VerdictMarkets.sol","reproduction":"Using test/TestBase.sol: create() a market. Alice bets 100e18 on 1 and the owner's accomplice bob bets 1e18 on 0. The owner (address(this)) deploys a new MockIntake 'evil', then calls oracle.proposeConfig(Config(evil, token, vm.addr(0xBEEF), ACTION, PRICE)) and oracle.acceptConfig() in the same block. At answerFrom: markets.resolve(id, body) returns rid. evil.deliver(rid, a, sig) runs with a = attestation(id, abi.encode(false), 5) signed by key 0xBEEF; the callback succeeds. markets.propose(id, a), then wait for disputeEnds and markets.finalize(id). Bob's claim pays 98.98e18 (verified in a scratch test). Expected, per the documented model: the owner/guardian cannot influence the outcome. Actual: the owner chose it.","severity":"info","snippet":"/// @notice Immutable parimutuel markets. The guardian controls entry only, never settlement or funds.","title":"Trust assumption: the VerdictOracle owner (zero config delay) can decide any not-yet-asked market, contrary to the 'never settlement' claim"}],"hash":"faaa5f6fb91a77585328d8964372b89cb7fe6dc392c04712487f6c6c57bc2044","nodeId":"88bdd3d1-6745-4b3a-ba96-39ada142f369","outcome":"completed","summary":"I found two problems in the permissions and settler-reward logic, one low and one informational, and confirmed both with scratch Foundry tests. I wrote them to `.imd-findings.json` with a coverage row for each of the 22 entry points listed, plus two rows for the conservation invariants. I changed no project files, and I deleted the scratch tests afterwards.\n\n**Findings**\n\n1. **Low: settlers are underpaid when the market can no longer ask the oracle** (`src/VerdictMarkets.sol:467`). When paying a resolve or propose reward, the contract always holds back one oracle price while fewer than two asks have been used. The brief says to hold it back only while the market can still ask. After the first propose, a market with no escalation body can never ask again; the same is true once `answerUntil` has passed. The money is still held back, so when the oracle price has risen the settler gets less than the full reward.\n   - **Example:** settler reward 0.25, bounty at its minimum of 2.25, no escalation body. The owner raises the price to 1.4 after `resolve`. The proposer is then paid 0.1 instead of 0.25, and the missing 0.15 goes back to the creator at finalize.\n   - **Fix:** for propose, hold back the price only when an escalation is still reachable before `answerUntil`. For resolve, also check that a retry or escalation can still happen before `answerUntil`.\n\n2. **Info: the oracle owner can decide the outcome of any market whose oracle request is not yet paid** (`src/VerdictMarkets.sol:11`; `VerdictOracle.proposeConfig`/`acceptConfig`). With the required `configDelay = 0`, the owner can switch the oracle's intake and signer in a single block. After that, any `resolve` or `escalate` is answered by the owner's intake with an attestation the owner signs.\n   - The scratch test shows an accomplice who bet 1 on the losing side collecting 98.98 after finalize, while the honest bettor's 100 was on the other side.\n   - This contradicts the source comment (\"never settlement or funds\") and `docs/DEPLOYMENT.md` (\"No … alternate settlement authority exists\").\n   - The brief requires the zero delay and no change to `VerdictOracle`, so I've reported it as a trust assumption to document, not a code fix. A non-zero config delay would close it, but that's your scope decision.\n\n**What I covered:** I went through all of `VerdictMarkets` and `VerdictOracle` for the access-control, trust-gap and asymmetry checks:\n- Every guarded function, the two-step guardian and ownership handovers, and renouncing.\n- Pause and allowlist affect entry only; settling and claims still work while paused.\n- The minimum-bounty check is exactly `bounty >= 2 × price + 5 × reward`.\n- `escalate` pays no reward, and finalize and void pay the settler before returning the bounty.\n- Rewards come only from the market's bounty, so the per-market balance invariant holds.\n\n**Leads I dropped:** none of the static-analysis warnings (reentrancy-balance, strict equality, uninitialized locals) showed a defect in my area.\n\n**What I didn't do:** I did not run the full existing test suite, and I did not go deeply into areas outside my assignment, such as attestation decoding or outcome mapping.","treeHash":null,"usage":{"cachedInputTokens":991077,"inputTokens":26,"model":"claude-opus-5-5","outputTokens":17937,"runtime":"claude","turns":14,"wallClockMs":211435}}],"verification":[{"checks":[{"durationMs":90171,"exitCode":0,"name":"build","output":"Compiling 77 files with Solc 0.8.26\nSolc 0.8.26 finished in 89.97s\nCompiler run successful!\nwarning[missing-zero-check]: address parameter is used in a state write or value transfer without a zero-address check\n   ╭▸ src/VerdictOracle.sol:71:9\n   │\n71 │         address intake_,\n   │         ━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/missing-zero-check\n\nwarning[missing-zero-check]: address parameter is used in a state write or value transfer without a zero-address check\n   ╭▸ src/VerdictOracle.sol:72:9\n   │\n72 │         address asset_,\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/VerdictOracle.sol:114:9\n    │\n114 │         emit Requested(intakeRequestId, bodyHash, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/VerdictOracle.sol:102:13\n    │\n102 │         if (token.balanceOf(address(this)) != beforeBalance + cost) revert InexactPayment();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/VerdictOracle.sol:109:13\n    │\n109 │         if (token.balanceOf(address(this)) != beforeBalance) revert InexactPayment();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VerdictOracle.sol:126:13\n    │\n126 │         if (block.timestamp > a.expiresAt) revert AttestationExpired(a.expiresAt);\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/VerdictOracle.sol:127:13\n    │\n127 │         if (a.issuedAt > block.timestamp + ISSUED_AT_TOLERANCE) revert AttestationNotYetValid(a.issuedAt);\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/VerdictOracle.sol:137:9\n    │\n137 │         emit Answered(a.requestId, intakeRequestId, p.bodyHash, attHash);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/VerdictOracle.sol:150:66\n    │\n150 │     function proposeConfig(Config calldata c) external onlyOwner nonReentrant {\n    │                                                                  ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/VerdictOracle.sol:158:48\n    │\n158 │     function acceptConfig() external onlyOwner nonReentrant {\n    │                                                ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VerdictOracle.sol:159:31\n    │\n159 │         if (!configPending || block.timestamp < acceptAfter) revert ConfigNotReady();\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/VerdictMarkets.sol:278:13\n    │\n278 │         if (block.timestamp >= m.params.closeAt) revert OutsideWindow();\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/VerdictMarkets.sol:296:17\n    │\n296 │             if (block.timestamp < m.lastPrimaryAsk + 24 hours) revert RetryNotReady();\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/VerdictMarkets.sol:471:9\n    │\n471 │         emit SettlerRewarded(id, msg.sender, action, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VerdictMarkets.sol:308:13\n    │\n308 │         if (block.timestamp >= m.disputeEnds) revert OutsideWindow();\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/VerdictMarkets.sol:315:9\n    │\n315 │         emit DisputeExtended(id, m.disputeEnds);\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/VerdictMarkets.sol:458:9\n    │\n458 │         emit OracleAsked(id, requestId, escalation, cost);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VerdictMarkets.sol:323:13\n    │\n323 │         if (block.timestamp < m.params.answerFrom) revert OutsideWindow();\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/VerdictMarkets.sol:326:17\n    │\n326 │             if (block.timestamp >= m.disputeEnds) revert OutsideWindow();\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/VerdictMarkets.sol:328:20\n    │\n328 │         } else if (block.timestamp >= m.params.voidAfter) {\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/VerdictMarkets.sol:365:13\n    │\n365 │         if (block.timestamp < m.disputeEnds) revert OutsideWindow();\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/VerdictMarkets.sol:483:9\n    │\n483 │         emit BountyReturned(id, m.creator, bounty);\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/VerdictMarkets.sol:377:9\n    │\n377 │         emit Finalized(id, m.outcome, creatorFee, burnFee, treasuryFee);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VerdictMarkets.sol:387:17\n    │\n387 │             if (block.timestamp < m.params.voidAfter) revert OutsideWindow();\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/VerdictMarkets.sol:390:17\n    │\n390 │             if (block.timestamp < m.disputeEnds) revert OutsideWindow();\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/VerdictMarkets.sol:398:9\n    │\n398 │         emit Voided(id);\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/VerdictMarkets.sol:424:9\n    │\n424 │         emit Claimed(id, msg.sender, amount, refund);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VerdictMarkets.sol:438:13\n    │\n438 │         if (block.timestamp < m.params.answerFrom || block.timestamp >= m.params.answerUntil) revert OutsideWindow();\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/VerdictMarkets.sol:438:54\n    │\n438 │         if (block.timestamp < m.params.answerFrom || block.timestamp >= m.params.answerUntil) revert OutsideWindow();\n    │                                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/VerdictMarkets.sol:455:13\n    │\n455 │         if (collateral.balanceOf(address(this)) != beforeBalance - cost) revert InexactOracleSpend();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/VerdictMarkets.sol:468:33\n    │\n468 │         if (m.bountyRemaining > reserve) amount = Math.min(m.settlerReward, m.bountyRemaining - reserve);\n    │                                 ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VerdictMarkets.sol:501:40\n    │\n501 │                 || p.minAgreed == 0 || p.closeAt <= block.timestamp || p.closeAt > p.answerFrom\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/VerdictMarkets.sol:515:53\n    │\n515 │                 if (p.bounds[i] <= p.bounds[i - 1]) revert InvalidParams();\n    │                                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/VerdictMarkets.sol:522:82\n    │\n522 │                 if (p.answerType == 4 && uint256(p.keys[i]) > type(uint160).max) revert InvalidParams();\n    │                                                                                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/VerdictMarkets.sol:524:49\n    │\n524 │                     if (p.keys[i] == p.keys[j]) revert InvalidParams();\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/VerdictMarkets.sol:517:20\n    │\n517 │             return uint8(p.bounds.length + 1);\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/VerdictMarkets.sol:527:20\n    │\n527 │             return uint8(p.keys.length + 1);\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/VerdictMarkets.sol:554:21\n    │\n554 │                 if (first == p.keys[i]) return i;\n    │                     ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/VerdictMarkets.sol:539:20\n    │\n539 │             return uint8(p.bounds.length);\n    │                    ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/VerdictMarkets.sol:557:16\n    │\n557 │         return uint8(p.keys.length);\n    │                ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/IndependentReview.t.sol:17:9\n   │\n17 │         vm.warp(p.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    ‡\n122 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/IndependentReview.t.sol:63:9\n   │\n63 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/IndependentReview.t.sol:78:9\n   │\n78 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/IndependentReview.t.sol:123:9\n    │\n123 │         vm.warp(p.answerUntil - 1);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/IndependentReview.t.sol:123:9\n    │\n123 │         vm.warp(p.answerUntil - 1);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/IndependentReview.t.sol:183:9\n    │\n183 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/IndependentReview.t.sol:198:9\n    │\n198 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/RevisionIndependentReview.t.sol:11:9\n   │\n11 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/RevisionIndependentReview.t.sol:26:9\n   │\n26 │         vm.warp(markets.getMarket(first).params.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionIndependentReview.t.sol:39:9\n    │\n 39 │         vm.warp(block.timestamp + 1 hours);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionIndependentReview.t.sol:39:9\n    │\n 39 │         vm.warp(block.timestamp + 1 hours);\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/RevisionIndependentReview.t.sol:39:17\n   │\n39 │         vm.warp(block.timestamp + 1 hours);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/RevisionIndependentReview.t.sol:51:9\n   │\n51 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/RevisionIndependentReview.t.sol:66:9\n   │\n66 │         vm.warp(p.answerUntil - 1);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/RevisionRegression.t.sol:11:9\n   │\n11 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/RevisionRegression.t.sol:50:9\n   │\n50 │         vm.warp(p.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/RevisionRegression.t.sol:80:9\n   │\n80 │         vm.warp(markets.getMarket(first).params.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:88:9\n    │\n 88 │         vm.warp(block.timestamp + 24 hours);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:88:9\n    │\n 88 │         vm.warp(block.timestamp + 24 hours);\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/RevisionRegression.t.sol:88:17\n   │\n88 │         vm.warp(block.timestamp + 24 hours);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:101:9\n    │\n101 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:106:9\n    │\n106 │         vm.warp(until - 10 minutes);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:106:9\n    │\n106 │         vm.warp(until - 10 minutes);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:125:9\n    │\n125 │         vm.warp(block.timestamp + 1 minutes);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:125:9\n    │\n125 │         vm.warp(block.timestamp + 1 minutes);\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/RevisionRegression.t.sol:125:17\n    │\n125 │         vm.warp(block.timestamp + 1 minutes);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:139:9\n    │\n139 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/RevisionRegression.t.sol:141:17\n    │\n141 │         vm.warp(block.timestamp + 24 hours);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    ‡\n122 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    ‡\n122 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:210:9\n    │\n210 │         vm.warp(p.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:214:9\n    │\n214 │         vm.warp(p.answerUntil - bound(leadSeed, 1, 1 hours - 1));\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:214:9\n    │\n214 │         vm.warp(p.answerUntil - bound(leadSeed, 1, 1 hours - 1));\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/RevisionRegression.t.sol:219:31\n    │\n219 │         assertGe(extendedEnd, block.timestamp + 24 hours);\n    │                               ━━━━━━━━━━━━━━━\n220 │         vm.warp(p.answerUntil + bound(latencySeed, 1, extendedEnd - p.answerUntil - 1));\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/SettlerIndependentReview.t.sol:88:9\n   │\n88 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/SettlerIndependentReview.t.sol:102:9\n    │\n102 │         vm.warp(markets.getMarket(id).disputeEnds);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/SettlerIndependentReview.t.sol:102:9\n    │\n102 │         vm.warp(markets.getMarket(id).disputeEnds);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/SettlerIndependentReview.t.sol:280:9\n    │\n280 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/VerdictSettlerRewards.t.sol:57:9\n   │\n57 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlerRewards.t.sol:124:9\n    │\n124 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/VerdictSettlerRewards.t.sol:128:17\n    │\n128 │         vm.warp(block.timestamp + 24 hours);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlerRewards.t.sol:164:9\n    │\n164 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlerRewards.t.sol:182:9\n    │\n182 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlerRewards.t.sol:211:9\n    │\n211 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlerRewards.t.sol:294:9\n    │\n294 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/SettlerLifecycleProperties.t.sol:42:13\n   │\n42 │             vm.warp(p.answerFrom);\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/SettlerLifecycleProperties.t.sol:46:25\n   │\n46 │                 vm.warp(block.timestamp + 24 hours);\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/SettlerRewardInvariant.t.sol:182:17\n    │\n182 │         vm.warp(block.timestamp + 14 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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictAtomicity.t.sol:65:9\n    │\n 65 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictAtomicity.t.sol:65:9\n    │\n 65 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictAtomicity.t.sol:157:9\n    │\n157 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictAtomicity.t.sol:164:9\n    │\n164 │         vm.warp(block.timestamp + 24 hours);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictAtomicity.t.sol:164:9\n    │\n164 │         vm.warp(block.timestamp + 24 hours);\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/VerdictAtomicity.t.sol:164:17\n    │\n164 │         vm.warp(block.timestamp + 24 hours);\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/VerdictInvariant.t.sol:164:17\n    │\n164 │         vm.warp(block.timestamp + 14 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/VerdictLifecycleInvariant.t.sol:458:17\n    │\n458 │         vm.warp(block.timestamp + 14 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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/VerdictMarkets.t.sol:46:9\n   │\n46 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:90:9\n    │\n 90 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:90:9\n    │\n 90 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:118:9\n    │\n118 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:118:9\n    │\n118 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:121:9\n    │\n121 │         vm.warp(p.voidAfter + 1);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:121:9\n    │\n121 │         vm.warp(p.voidAfter + 1);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:142:9\n    │\n142 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:154:9\n    │\n154 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:182:9\n    │\n182 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/VerdictMarkets.t.sol:184:17\n    │\n184 │         vm.warp(block.timestamp + 24 hours - 1);\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/VerdictMarkets.t.sol:187:17\n    │\n187 │         vm.warp(block.timestamp + 1);\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/VerdictMarkets.t.sol:191:17\n    │\n191 │         vm.warp(block.timestamp + 24 hours);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:203:9\n    │\n203 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:217:9\n    │\n217 │         vm.warp(p.answerUntil);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:239:9\n    │\n239 │         vm.warp(p.answerUntil - 1);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:257:9\n    │\n257 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:257:9\n    │\n257 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:284:9\n    │\n284 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:319:9\n    │\n319 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:174:9\n    │\n174 │         vm.warp(markets.getMarket(id).params.closeAt - 1);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:273:9\n    │\n273 │         vm.warp(p.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:282:9\n    │\n282 │         vm.warp(markets.getMarket(id).params.answerFrom);\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.revertToState`\n    ╭▸ test/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:360:20\n    │\n360 │         assertTrue(vm.revertToState(snapshot));\n    │                    ────────────────────────── `vm.revertToState` 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.revertToState`\n    ╭▸ test/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:360:20\n    │\n360 │         assertTrue(vm.revertToState(snapshot));\n    │                    ────────────────────────── `vm.revertToState` 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.revertToState`\n    ╭▸ test/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:331:20\n    │\n331 │         assertTrue(vm.revertToState(snapshot));\n    │                    ────────────────────────── `vm.revertToState` 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.revertToState`\n    ╭▸ test/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:331:20\n    │\n331 │         assertTrue(vm.revertToState(snapshot));\n    │                    ────────────────────────── `vm.revertToState` 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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:344:9\n    │\n344 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/VerdictOracle.t.sol:211:17\n    │\n211 │         vm.warp(block.timestamp + 2 days - 1);\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/VerdictOracle.t.sol:238:17\n    │\n238 │         vm.warp(block.timestamp + 1 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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/VerdictOutcomes.t.sol:11:9\n   │\n11 │         vm.warp(p.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictOutcomes.t.sol:11:9\n    │\n 11 │         vm.warp(p.answerFrom);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictOutcomes.t.sol:11:9\n    │\n 11 │         vm.warp(p.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictOutcomes.t.sol:130:9\n    │\n130 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlementProperties.t.sol:178:9\n    │\n178 │         vm.warp(p.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlementProperties.t.sol:195:13\n    │\n195 │             vm.warp(p.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlementProperties.t.sol:205:13\n    │\n205 │             vm.warp(p.voidAfter);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlementProperties.t.sol:205:13\n    │\n205 │             vm.warp(p.voidAfter);\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":37616,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 6 tests for test/OracleConsumerConformance.t.sol:OracleConsumerConformanceTest\n[PASS] test_acceptsAFreshSignatureFromTheVectorKey() (gas: 199666)\n[PASS] test_acceptsTheProtocolSignatureAsDelivered() (gas: 190502)\n[PASS] test_callbackSelectorIsCanonical() (gas: 4480)\n[PASS] test_digestMatchesTheProtocol() (gas: 13408)\n[PASS] test_domainIsConsumerChainAndVersionTwo() (gas: 15761)\n[PASS] test_structHashMatchesIndependentEncoding() (gas: 251625)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 3.54ms (1.53ms CPU time)\n\nRan 1 test for test/SettlerDeployment.t.sol:SettlerDeploymentTest\n[PASS] test_launchHandoffPinsV2AndTenConstructorArguments() (gas: 6021796)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 863.22µs (719.23µs CPU time)\n\nRan 5 tests for test/RevisionIndependentReview.t.sol:RevisionIndependentReviewTest\n[PASS] test_documentedUnusableOwnDeliveryStillBlocksRetry() (gas: 1259665)\n[PASS] test_escalationRejectsIssuanceBeforeItsOwnAsk() (gas: 1995674)\n[PASS] test_identicalBodyOtherMarketAnswerCannotSetOutcome() (gas: 1926375)\n[PASS] test_independentSameBodyCannotBlockOwnRetry() (gas: 1725093)\n[PASS] test_primaryLateIssuanceRemainsOutsideBriefsExplicitRange() (gas: 1362737)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 8.99ms (5.50ms CPU time)\n\nRan 10 tests for test/VerdictSettlerRewards.t.sol:VerdictSettlerRewardsTest\n[PASS] test_bountyArithmeticRejectsImpossiblePriceOrRewardWithoutOverflow() (gas: 702894)\n[PASS] test_bountyMinimumChecksBothRequestedAndReceivedAmounts() (gas: 1192716)\n[PASS] test_eachProposalResolveAndFinalizePaysItsCallerOnceEscalatePaysNothing() (gas: 4702670)\n[PASS] test_priceRiseBeforeResolveClipsRewardToExactReserve() (gas: 3210434)\n[PASS] test_proposalUsesCurrentPriceAndPreservesTheLastAsk() (gas: 4308133)\n[PASS] test_retryResolveIsAlsoRewardedOnce() (gas: 3508684)\n[PASS] test_rewardBoundIsInclusiveAndZeroCapDisablesRewards() (gas: 970760)\n[PASS] test_terminalRewardIsClippedToBountyNeverBettorDepositsOrAnotherMarket() (gas: 3238907)\n[PASS] test_voidWithoutAsksPaysBeforeReturningBountyAndNeverTwice() (gas: 1629700)\n[PASS] test_zeroRewardKeepsLegacyBalancesEventsAndNoNewPriceDependency() (gas: 2845828)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 13.36ms (28.98ms CPU time)\n\nRan 3 tests for test/Deployment.t.sol:DeploymentTest\n[PASS] test_burnVaultHasNoCallablePathOrEtherReceiver() (gas: 1013344)\n[PASS] test_exactSepoliaFactoryDeploymentWithoutDependencyCode() (gas: 20775481)\n[PASS] test_rehearsalRefusesOtherChains() (gas: 207095)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 56.98ms (57.48ms CPU time)\n\nRan 3 tests for test/VerdictImportedAudit.t.sol:VerdictImportedAuditTest\n[PASS] test_creatorCanSetVoidAfterFarInFuture() (gas: 598026)\n[PASS] test_pauseOnlyBlocksEntryAndReleaseReturnsAllUnspentBounty() (gas: 2013101)\n[PASS] test_strangerEscalatesAtNoCostBurnsBountyAndDelays() (gas: 2518937)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 84.13ms (2.61ms CPU time)\n\nRan 15 tests for test/VerdictMarketsValidation.t.sol:VerdictMarketsValidationTest\n[PASS] test_allowlistRemovalAndPermanentDisable() (gas: 1291458)\n[PASS] test_attestationMustMatchEveryMarketFieldAndPanelRequirements() (gas: 5154664)\n[PASS] test_betZeroUnknownOutcomeAndCloseBoundary() (gas: 716041)\n[PASS] test_bodyHashAndBodySizeValidation() (gas: 729322)\n[PASS] test_bountyMustCoverTwoAsksAfterTransferFee() (gas: 236534)\n[PASS] test_creationEmitsBothFullBodies() (gas: 385237)\n[PASS] test_escalationRequiresDoubleCurrentPanelAndCorrectBody() (gas: 2820430)\n[PASS] test_feeCapAndPoolCapConstructor() (gas: 15618)\n[PASS] test_feeOnTransferCreditsOnlyActualBountyAndStakes() (gas: 1209845)\n[PASS] test_firstProposalAtVoidDeadlineCannotResurrectMarket() (gas: 1378732)\n[PASS] test_guardianHandoverIsTwoStepAndNoUnauthorizedPowers() (gas: 370410)\n[PASS] test_invalidTimesPanelsAndTypes() (gas: 614692)\n[PASS] test_minAgreedCanRequireMoreThanMinimumPanelSize() (gas: 1237856)\n[PASS] test_pauseBlocksOnlyEntryAndRenounceRequiresUnpaused() (gas: 3328792)\n[PASS] test_poolCapUsesReceivedBalanceAndFailedBetIsAtomic() (gas: 825795)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 211.65ms (18.64ms CPU time)\n\nRan 6 tests for test/VerdictOracleAdversarial.t.sol:VerdictOracleAdversarialTest\n[PASS] testFuzz_rotationsKeepFourInflightSnapshotsInAnyDeliveryOrder(uint256) (runs: 256, μ: 5459977, ~: 5459977)\n[PASS] test_contractSignerIsPinnedAndRevokedSignatureStoresNothing() (gas: 1500728)\n[PASS] test_everyAttestationFieldIsBoundBySignatureAndStoredHash() (gas: 2610090)\n[PASS] test_expiryAndClockToleranceAreInclusiveAtExactBoundary() (gas: 977218)\n[PASS] test_nonCanonicalAndTruncatedSignaturesCannotConsumePendingRequest() (gas: 829160)\n[PASS] test_pendingOwnerCannotAcceptConfigurationAndFormerOwnerLosesAccess() (gas: 434003)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 225.44ms (228.16ms CPU time)\n\nRan 12 tests for test/IndependentReview.t.sol:IndependentReviewTest\n[PASS] testFuzzReviewActualTransfersConserveInAnyClaimOrder(uint96,uint96,uint96,uint8) (runs: 512, μ: 2634016, ~: 2634245)\nLogs:\n  Bound result 5815\n  Bound result 6989\n  Bound result 10511\n\n[PASS] testReviewAgreementMinimumCanExceedMinimumPanel() (gas: 1710516)\n[PASS] testReviewDonationDoesNotAlterPayoutOrAccounting() (gas: 1831460)\n[PASS] testReviewEscalationCannotBeFirstProposalEvenWithLargePanel() (gas: 1219037)\n[PASS] testReviewEscalationCannotVoidAfterDeadline() (gas: 2306392)\n[PASS] testReviewFailedTokenTransferRollsBackClaim() (gas: 1964911)\n[PASS] testReviewLateReplacementPastVoidRemainsFinalizable() (gas: 2583202)\n[PASS] testReviewMaximumAnswerColdCallback() (gas: 1266872)\nLogs:\n  maximum answer cold callback gas: 140592\n\n[PASS] testReviewMixedMarketsCannotCrossSubsidizeClaims() (gas: 3244354)\n[PASS] testReviewNoWinnerIsVoidableAfterWindowPastVoidAfter() (gas: 1969951)\n[PASS] testReviewRotationPreservesOldCallerAndKey() (gas: 2309371)\n[PASS] testReviewSameAttestationCannotOverwriteDifferentRequest() (gas: 1427982)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 225.68ms (243.66ms CPU time)\n\nRan 7 tests for test/VerdictSettlementProperties.t.sol:VerdictSettlementPropertiesTest\n[PASS] testFuzz_feeSplitsAndRationalPayoutBoundsInEveryClaimOrder(uint256,uint16,uint16,uint16,uint8) (runs: 1000, μ: 2966321, ~: 2971272)\nLogs:\n  Bound result 101\n  Bound result 59\n  Bound result 96\n  Bound result 65365215549032901247\n  Bound result 12065879141657275692\n  Bound result 99777856087542376569\n  Bound result 13100\n\n[PASS] testFuzz_numericOutcomeSatisfiesItsHalfOpenInterval(uint128,uint96,uint256,uint8) (runs: 1000, μ: 1390322, ~: 1379004)\nLogs:\n  Bound result 4\n  Bound result 103000000000000000000\n  Bound result 11000000000000000000\n\n[PASS] test_malformedListsCannotChangeAnAuthenticatedMarketsOutcome() (gas: 2908506)\n[PASS] test_oneWeiLastWinnerReceivesTheRoundingRemainder() (gas: 2279339)\n[PASS] test_oneWeiWinnerMayRoundToZeroButLastClaimStillDrainsExactly() (gas: 2577622)\n[PASS] test_payoutUsesFullPrecisionWhenIntermediateStakeTimesPoolOverflows256Bits() (gas: 2534215)\n[PASS] test_settlementEventsDescribeWholePoolFeesAndUnspentBounty() (gas: 1989237)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 261.18ms (529.61ms CPU time)\n\nRan 11 tests for test/RevisionRegression.t.sol:RevisionRegressionTest\n[PASS] testFuzz_eitherPaidPrimaryRequestCanProposeButCannotReplace(bool,bool) (runs: 256, μ: 2816713, ~: 2815740)\n[PASS] testFuzz_lateEscalationHasFiniteSettlementDeadline(uint32,uint32,uint32,bool) (runs: 256, μ: 2719856, ~: 2490633)\nLogs:\n  Bound result 103690\n  Bound result 1\n  Bound result 2957\n\n[PASS] test_escalationCannotUseAnswerIssuedBeforeItsAsk() (gas: 1997270)\n[PASS] test_identicalEscalationBodiesStillRequireEachMarketsOwnPaidAsk() (gas: 5271284)\n[PASS] test_lateEscalationIssuedAfterAnswerUntilSettlesCorrectedOutcome() (gas: 2826337)\n[PASS] test_otherMarketAnswerCannotSetOutcomeOrBlockRetry() (gas: 2624132)\n[PASS] test_oversizeAnswerRefused() (gas: 983076)\n[PASS] test_renounceRequiresAllowlistDisabledEvenWhenEmpty() (gas: 499255)\n[PASS] test_unusableDeliveryBlocksRetry() (gas: 1259765)\n[PASS] test_zeroBoundRejectedWithoutTakingBounty() (gas: 1572363)\n[PASS] test_zeroDelayAcceptsConfigInSameBlock() (gas: 271514)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 267.28ms (351.79ms CPU time)\n\nRan 20 tests for test/VerdictMarkets.t.sol:VerdictMarketsTest\n[PASS] testFuzz_terminalConservation(uint96,uint96,uint96,uint8,bool) (runs: 512, μ: 1909407, ~: 2219068)\nLogs:\n  Bound result 463240541195133\n  Bound result 2\n  Bound result 233230660319360849\n\n[PASS] test_asksBeforeAnswerFromAndAtOrAfterAnswerUntilRevert() (gas: 562520)\n[PASS] test_assetRotationBlocksAsksButNotRefunds() (gas: 2120548)\n[PASS] test_emptyWinningBucketCannotVoidUntilDisputeEnds() (gas: 1809113)\n[PASS] test_escalationAnswerCannotBeFirstProposal() (gas: 1219454)\n[PASS] test_escalationAskAtAnswerUntilRevertsEvenInsideDisputeWindow() (gas: 1281214)\n[PASS] test_externalSponsorCannotDeliverPrimaryOrEscalation() (gas: 3880222)\n[PASS] test_fullSettlementPaysWholePoolFeesAndExactRemainder() (gas: 2399157)\n[PASS] test_lateEscalationBeyondVoidAfterStillFinalizesWithoutAnswer() (gas: 2498343)\n[PASS] test_lateEscalationReplacementRestartsWindowOnceAndFinalizes() (gas: 2834558)\n[PASS] test_noEscalationBodyAndDuplicateEscalationAsk() (gas: 2703033)\n[PASS] test_priceIncreaseCannotSpendBettorsCollateral() (gas: 2271746)\n[PASS] test_primaryRetryBlockedAfterDeliveryEvenWithoutProposal() (gas: 1191860)\n[PASS] test_proposeAfterAnswerUntilWithTimelyStoredAnswer() (gas: 1473367)\n[PASS] test_provisionalWindowBoundariesAreStrict() (gas: 2322634)\n[PASS] test_secondPrimaryAskAfter24HoursAndMaximumTwoAsks() (gas: 1809739)\n[PASS] test_tokenReentrancyBlockedOnDepositAndClaim() (gas: 2163480)\n[PASS] test_voidNoAnswerRefundsEveryOutcomeAndUnspentBounty() (gas: 1758828)\n[PASS] test_wrongBodiesAndResolveAfterProposalRevertWithoutSpend() (gas: 1517332)\n[PASS] test_zeroAndUnknownClaimsAndUnfinishedClaimsRevert() (gas: 692952)\nSuite result: ok. 20 passed; 0 failed; 0 skipped; finished in 279.09ms (293.39ms CPU time)\n\nRan 7 tests for test/VerdictAtomicity.t.sol:VerdictAtomicityTest\n[PASS] testFuzz_failureAtAnyFinalizeRecipientRollsBackEarlierPayments(uint8,bool) (runs: 64, μ: 2390083, ~: 2387836)\n[PASS] test_failedBountyReturnDoesNotVoidMarketOrPreventLaterRefund() (gas: 1111622)\n[PASS] test_failedCallbackIsNotRefundedButMarketRetryAndSettlementRemainReachable() (gas: 2409792)\n[PASS] test_failedEscalationPaymentCannotExtendOrConsumeDisputeWindow() (gas: 2692212)\n[PASS] test_failedPrimaryPaymentRestoresBountyAskCountTimestampAndAllowances() (gas: 1736994)\n[PASS] test_failedRefundCanBeRetriedAndDoesNotConsumeAnotherUsersClaim() (gas: 1449710)\n[PASS] test_guardBlocksCrossMarketReentryFromAnOtherwiseEligibleClaimant() (gas: 4435937)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 98.04ms (54.73ms CPU time)\n\nRan 10 tests for test/SettlerIndependentReview.t.sol:SettlerIndependentReviewTest\n[PASS] testFuzz_rewardRecipientsMayAlsoBeCreatorWinnerOrTreasury(uint8) (runs: 512, μ: 2257772, ~: 2253409)\n[PASS] testFuzz_rewardReserveUsesPriceAfterPaidAsk(uint256) (runs: 512, μ: 1342447, ~: 1346173)\nLogs:\n  Bound result 214531165122403978\n\n[PASS] test_creatorReturnFailureRevertsFinalizeIncludingEarlierReward() (gas: 2502155)\n[PASS] test_creatorReturnFailureRevertsVoidIncludingEarlierReward() (gas: 1252693)\n[PASS] test_failedProposalRewardLeavesStoredAnswerUsableAndPaysOnceOnRetry() (gas: 1842699)\n[PASS] test_finalizeRewardCallbackSeesCompleteAccountingAndCannotReenter() (gas: 3385133)\n[PASS] test_maximumPriceAfterPaidAskSuppressesRewardWithoutReverting() (gas: 1297383)\n[PASS] test_positiveTerminalRewardsDoNotDependOnAWorkingOraclePrice() (gas: 2803780)\n[PASS] test_rewardFailureRollsBackTheWholePaidAskAndAllowsRetry() (gas: 2014297)\n[PASS] test_voidRewardCallbackSeesCompleteAccountingAndCannotReenter() (gas: 2049715)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 273.23ms (506.21ms CPU time)\n\nRan 1 test for test/SettlerLifecycleProperties.t.sol:SettlerLifecyclePropertiesTest\n[PASS] testFuzz_allLifecyclePathsConserveActualTransfers(uint96,uint96,uint96,uint96,uint8,uint64,bool) (runs: 512, μ: 3518925, ~: 3722227)\nLogs:\n  Bound result 46283089765914747\n  Bound result 26480344841398033044\n  Bound result 253295505026011\n  Bound result 6205622871782234532\n  Bound result 120043844795567065\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 273.43ms (270.00ms CPU time)\n\nRan 1 test for test/VerdictInvariant.t.sol:VerdictInvariantTest\n[PASS] invariant_actualTokensMatchEveryMarketsAccounting() (runs: 128, calls: 8192, reverts: 0)\n\n╭----------------+----------------+-------+---------+----------╮\n| Contract       | Selector       | Calls | Reverts | Discards |\n+==============================================================+\n| VerdictHandler | advance        | 852   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | ask            | 816   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | askEscalation  | 829   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | collect        | 885   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | deliverPrimary | 798   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | enter          | 831   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | proposePrimary | 789   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | replaceOutcome | 760   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | settle         | 808   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | togglePause    | 824   | 0       | 0        |\n╰----------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 2526\n  Bound result 17569\n  Bound result 21585\n  Bound result 7205\n  Bound result 761\n  Bound result 16322\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.05s (2.05s CPU time)\n\nRan 1 test for test/SettlerRewardInvariant.t.sol:SettlerRewardInvariantTest\n[PASS] invariant_actualTokensMatchEveryMarketsAccounting() (runs: 128, calls: 8192, reverts: 0)\n\n╭----------------------+----------------+-------+---------+----------╮\n| Contract             | Selector       | Calls | Reverts | Discards |\n+====================================================================+\n| SettlerRewardHandler | advance        | 747   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | ask            | 782   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | askEscalation  | 749   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | changePrice    | 732   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | collect        | 734   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | deliverPrimary | 706   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | enter          | 746   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | proposePrimary | 774   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | replaceOutcome | 764   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | settle         | 716   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | togglePause    | 742   | 0       | 0        |\n╰----------------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 128\n  Bound result 1161\n  Bound result 1595350662992528470\n  Bound result 0\n  Bound result 1800000000\n  Bound result 17202\n  Bound result 21593\n  Bound result 1938496894975773621\n  Bound result 21554\n  Bound result 7950\n  Bound result 263399517517784643\n  Bound result 7200\n  Bound result 20\n  Bound result 2000000000000000000\n  Bound result 324\n  Bound result 4298\n  Bound result 1792646921850067046\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.10s (2.10s CPU time)\n\nRan 7 tests for test/VerdictOutcomes.t.sol:VerdictOutcomesTest\n[PASS] testFuzz_uintBucketDefinition(uint256) (runs: 512, μ: 1341561, ~: 1341591)\n[PASS] test_addressListUsesFirstElementOnlyAndCanonicalAddressKey() (gas: 4875179)\n[PASS] test_booleanOutcomes() (gas: 2310147)\n[PASS] test_bytes32ListUsesFirstElementOnlyAndEmptyMeansNone() (gas: 6010921)\n[PASS] test_malformedEncodedAnswerCannotSetOutcome() (gas: 1291065)\n[PASS] test_numericBucketsIncludeLowerBoundaryExcludeUpper() (gas: 7221103)\n[PASS] test_twoToEightOutcomesAndSortedUniqueDefinitions() (gas: 1791330)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 2.12s (284.53ms CPU time)\n\nRan 17 tests for test/VerdictOracle.t.sol:VerdictOracleTest\n[PASS] test_bodyLimitsAndExactPaymentRequired() (gas: 586164)\n[PASS] test_configDelayCapAndInvalidConfiguration() (gas: 9288)\n[PASS] test_consumedIntakeIdAndOracleIdCannotBeStoredTwice() (gas: 970867)\n[PASS] test_deliveredAnswerRemainsReadableAfterExpiry() (gas: 524115)\n[PASS] test_expiredFutureMalformedAndTamperedRejected() (gas: 766529)\n[PASS] test_falseAnswerStoredUnder150kGas() (gas: 575739)\nLogs:\n  cold callback gas: 126024\n\n[PASS] test_intakeAndSignerRotationPreservesInflightRequest() (gas: 2174415)\n[PASS] test_maxAnswerUnder150kGas() (gas: 610144)\nLogs:\n  maximum answer cold callback gas: 140592\n\n[PASS] test_replacingConfigProposalRestartsDelay() (gas: 283461)\n[PASS] test_requestPaysExactlyAndPinsConfiguration() (gas: 403481)\n[PASS] test_requestReentrancyFails() (gas: 486117)\n[PASS] test_reusedIntakeRequestIdRollsBackPayment() (gas: 545892)\n[PASS] test_timelockAndOwnable2Step() (gas: 558572)\n[PASS] test_wrongChainDomainStoresNothing() (gas: 417798)\n[PASS] test_wrongConsumerDomainStoresNothing() (gas: 422685)\n[PASS] test_wrongIntakeAndUnknownIdStoreNothing() (gas: 454227)\n[PASS] test_wrongSignerStoresNothingAndNoRefund() (gas: 522092)\nSuite result: ok. 17 passed; 0 failed; 0 skipped; finished in 2.12s (5.96ms CPU time)\n\nRan 4 tests for test/VerdictLifecycleInvariant.t.sol:VerdictLifecycleInvariantTest\n[PASS] invariant_tokensStakesAndFinalityMatchIndependentLedger() (runs: 256, calls: 16384, reverts: 0)\n\n╭-------------------------+------------------------+-------+---------+----------╮\n| Contract                | Selector               | Calls | Reverts | Discards |\n+===============================================================================+\n| VerdictLifecycleHandler | advance                | 1265  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | askEscalation          | 1264  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | askPrimary             | 1270  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | collect                | 1294  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | deliverAnswer          | 1271  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | donate                 | 1251  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | openMarket             | 1234  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | probeBurn              | 1197  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | probeIndependentAnswer | 1314  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | probeTerminal          | 1233  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | settle                 | 1256  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | togglePause            | 1279  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | wager                  | 1256  | 0       | 0        |\n╰-------------------------+------------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 15508\n  Bound result 101000000000000000000\n  Bound result 18575\n  Bound result 20835\n  Bound result 823396707360193659\n  Bound result 499999999999999999\n  Bound result 909260412606129924\n  Bound result 451142838813870617\n  Bound result 8392\n\n[PASS] test_handlerIndependentAnswersCannotBlockRetryOrShopOutcomes() (gas: 10123579)\nLogs:\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 21600\n  Bound result 21600\n  Bound result 21600\n  Bound result 21600\n\n[PASS] test_handlerReachesPrimaryEscalationFailureFinalizeAndRefundPaths() (gas: 16451019)\nLogs:\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 31\n  Bound result 17\n  Bound result 11\n\n[PASS] test_handlerUsesActualLateEscalationIssuanceAndStillDrains() (gas: 9734939)\nLogs:\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 37.50s (37.55s CPU time)\n\nRan 20 test suites in 37.51s (48.18s CPU time): 147 tests passed, 0 failed, 0 skipped (147 total tests)\n","passed":true},{"durationMs":98,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"VerdictMarkets.acceptGuardian()\",\"VerdictMarkets.bet(uint256,uint8,uint256,uint256)\",\"VerdictMarkets.claim(uint256)\",\"VerdictMarkets.createMarket((bytes32,uint8,uint256,uint64,uint64,uint16,uint16,uint64,uint64,uint64,uint32,uint64,uint256[],bytes32[],uint256,uint256),bytes,bytes,string,uint256)\",\"VerdictMarkets.disableAllowlist()\",\"VerdictMarkets.escalate(uint256,bytes)\",\"VerdictMarkets.finalize(uint256)\",\"VerdictMarkets.pause()\",\"VerdictMarkets.propose(uint256,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64))\",\"VerdictMarkets.renounceGuardian()\",\"VerdictMarkets.resolve(uint256,bytes)\",\"VerdictMarkets.setCreatorAllowed(address,bool)\",\"VerdictMarkets.transferGuardian(address)\",\"VerdictMarkets.unpause()\",\"VerdictMarkets.voidMarket(uint256)\",\"VerdictOracle.acceptConfig()\",\"VerdictOracle.acceptOwnership()\",\"VerdictOracle.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"VerdictOracle.proposeConfig((address,address,address,bytes32,uint256))\",\"VerdictOracle.renounceOwnership()\",\"VerdictOracle.request(bytes)\",\"VerdictOracle.transferOwnership(address)\"],\"files\":{\".gitignore\":4,\"ADAPTATION.md\":74,\"DEPENDENCIES.md\":14,\"DESIGN.md\":95,\"LICENSE\":21,\"README.md\":167,\"dist/assets/chain-BQwdJvnv.js\":45,\"dist/assets/index-BbSaev33.css\":1,\"dist/assets/index-ByzN5mJO.js\":1,\"dist/assets/react-DbQ9GvLb.js\":49,\"dist/favicon.svg\":1,\"dist/fonts/archivo-OFL.txt\":93,\"dist/fonts/archivo-expanded-800.woff2\":65,\"dist/fonts/ibm-plex-mono-400.woff2\":58,\"dist/fonts/ibm-plex-mono-500.woff2\":62,\"dist/fonts/ibm-plex-mono-OFL.txt\":93,\"dist/index.html\":6,\"dist/social.png\":106,\"docs/BETTER_INTERFACE_LICENSE.txt\":220,\"docs/DEPLOYMENT.md\":61,\"docs/INDEPENDENT_REVIEW.md\":67,\"docs/REVISION_REVIEW.md\":41,\"docs/SETTLER_INDEPENDENT_REVIEW.md\":79,\"docs/VERIFICATION.md\":41,\"docs/WEBSITE_VALIDATION.md\":131,\"foundry.toml\":23,\"launch.json\":37,\"remappings.txt\":2,\"script/SepoliaParameters.sol\":27,\"src/OracleAttestation.sol\":221,\"src/VerdictBurnVault.sol\":5,\"src/VerdictMarkets.sol\":559,\"src/VerdictOracle.sol\":178,\"src/interfaces/IIntake.sol\":14,\"src/interfaces/IVerdictOracle.sol\":14,\"test/Deployment.t.sol\":102,\"test/IndependentReview.t.sol\":239,\"test/OracleConsumerConformance.t.sol\":162,\"test/RevisionIndependentReview.t.sol\":77,\"test/RevisionRegression.t.sol\":245,\"test/SettlerDeployment.t.sol\":58,\"test/SettlerIndependentReview.t.sol\":353,\"test/SettlerLifecycleProperties.t.sol\":118,\"test/SettlerRewardInvariant.t.sol\":249,\"test/TESTING.md\":87,\"test/TestBase.sol\":136,\"test/VerdictAtomicity.t.sol\":214,\"test/VerdictImportedAudit.t.sol\":61,\"test/VerdictInvariant.t.sol\":213,\"test/VerdictLifecycleInvariant.t.sol\":580,\"test/VerdictMarkets.t.sol\":383,\"test/VerdictMarketsValidation.t.sol\":368,\"test/VerdictOracle.t.sol\":288,\"test/VerdictOracleAdversarial.t.sol\":228,\"test/VerdictOutcomes.t.sol\":148,\"test/VerdictSettlementProperties.t.sol\":228,\"test/VerdictSettlerRewards.t.sol\":310,\"test/mocks/MockIMD.sol\":42,\"test/mocks/MockIntake.sol\":62,\"web/index.html\":2,\"web/package-lock.json\":2003,\"web/package.json\":35,\"web/public/favicon.svg\":1,\"web/public/fonts/archivo-OFL.txt\":93,\"web/public/fonts/archivo-expanded-800.woff2\":65,\"web/public/fonts/ibm-plex-mono-400.woff2\":58,\"web/public/fonts/ibm-plex-mono-500.woff2\":62,\"web/public/fonts/ibm-plex-mono-OFL.txt\":93,\"web/public/social.png\":106,\"web/scripts/browser-check.mjs\":414,\"web/scripts/check-export.mjs\":51,\"web/scripts/isolated.mjs\":108,\"web/scripts/revision-cases.mjs\":179,\"web/scripts/verify-contracts.mjs\":120,\"web/scripts/wallet-check.mjs\":784,\"web/src/App.tsx\":740,\"web/src/CreatePage.tsx\":575,\"web/src/MarketPage.tsx\":884,\"web/src/Portfolio.tsx\":224,\"web/src/abi/VerdictBurnVault.json\":1,\"web/src/abi/VerdictMarkets.json\":1,\"web/src/abi/VerdictOracle.json\":1,\"web/src/abi/provenance.json\":10,\"web/src/chain.ts\":377,\"web/src/components.tsx\":358,\"web/src/config.ts\":75,\"web/src/create.ts\":222,\"web/src/domain.ts\":326,\"web/src/main.tsx\":32,\"web/src/store.tsx\":103,\"web/src/styles.css\":2288,\"web/src/types.ts\":126,\"web/src/wallet.tsx\":385,\"web/tests/chain-fixture.json\":454,\"web/tests/domain.test.ts\":328,\"web/tests/wallet-rpc-fixture.json\":636,\"web/tsconfig.json\":17,\"web/validation/browser-results.json\":193,\"web/validation/contract-verification.json\":25,\"web/validation/export-integrity.json\":80,\"web/validation/revision-before.json\":79,\"web/validation/revision-results.json\":181,\"web/validation/wallet-results.json\":76,\"web/vite.config.ts\":37},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"67bbd6d3dadf1e4cc5964c811decbcebf1948b1fe8212d3a1d3f3d3d708fb702","verifiedTreeHash":"603eabe8f662682c994d7895a37955a5f8e0e82b","verifierVersion":"0.1.0+0e08a464"},{"checks":[{"durationMs":81756,"exitCode":0,"name":"build","output":"Compiling 77 files with Solc 0.8.26\nSolc 0.8.26 finished in 81.59s\nCompiler run successful!\nwarning[missing-zero-check]: address parameter is used in a state write or value transfer without a zero-address check\n   ╭▸ src/VerdictOracle.sol:71:9\n   │\n71 │         address intake_,\n   │         ━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/missing-zero-check\n\nwarning[missing-zero-check]: address parameter is used in a state write or value transfer without a zero-address check\n   ╭▸ src/VerdictOracle.sol:72:9\n   │\n72 │         address asset_,\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/VerdictOracle.sol:114:9\n    │\n114 │         emit Requested(intakeRequestId, bodyHash, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/VerdictOracle.sol:102:13\n    │\n102 │         if (token.balanceOf(address(this)) != beforeBalance + cost) revert InexactPayment();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/VerdictOracle.sol:109:13\n    │\n109 │         if (token.balanceOf(address(this)) != beforeBalance) revert InexactPayment();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VerdictOracle.sol:126:13\n    │\n126 │         if (block.timestamp > a.expiresAt) revert AttestationExpired(a.expiresAt);\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/VerdictOracle.sol:127:13\n    │\n127 │         if (a.issuedAt > block.timestamp + ISSUED_AT_TOLERANCE) revert AttestationNotYetValid(a.issuedAt);\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/VerdictOracle.sol:137:9\n    │\n137 │         emit Answered(a.requestId, intakeRequestId, p.bodyHash, attHash);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/VerdictOracle.sol:150:66\n    │\n150 │     function proposeConfig(Config calldata c) external onlyOwner nonReentrant {\n    │                                                                  ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/VerdictOracle.sol:158:48\n    │\n158 │     function acceptConfig() external onlyOwner nonReentrant {\n    │                                                ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VerdictOracle.sol:159:31\n    │\n159 │         if (!configPending || block.timestamp < acceptAfter) revert ConfigNotReady();\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/VerdictMarkets.sol:278:13\n    │\n278 │         if (block.timestamp >= m.params.closeAt) revert OutsideWindow();\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/VerdictMarkets.sol:296:17\n    │\n296 │             if (block.timestamp < m.lastPrimaryAsk + 24 hours) revert RetryNotReady();\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/VerdictMarkets.sol:471:9\n    │\n471 │         emit SettlerRewarded(id, msg.sender, action, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VerdictMarkets.sol:308:13\n    │\n308 │         if (block.timestamp >= m.disputeEnds) revert OutsideWindow();\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/VerdictMarkets.sol:315:9\n    │\n315 │         emit DisputeExtended(id, m.disputeEnds);\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/VerdictMarkets.sol:458:9\n    │\n458 │         emit OracleAsked(id, requestId, escalation, cost);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VerdictMarkets.sol:323:13\n    │\n323 │         if (block.timestamp < m.params.answerFrom) revert OutsideWindow();\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/VerdictMarkets.sol:326:17\n    │\n326 │             if (block.timestamp >= m.disputeEnds) revert OutsideWindow();\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/VerdictMarkets.sol:328:20\n    │\n328 │         } else if (block.timestamp >= m.params.voidAfter) {\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/VerdictMarkets.sol:365:13\n    │\n365 │         if (block.timestamp < m.disputeEnds) revert OutsideWindow();\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/VerdictMarkets.sol:483:9\n    │\n483 │         emit BountyReturned(id, m.creator, bounty);\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/VerdictMarkets.sol:377:9\n    │\n377 │         emit Finalized(id, m.outcome, creatorFee, burnFee, treasuryFee);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VerdictMarkets.sol:387:17\n    │\n387 │             if (block.timestamp < m.params.voidAfter) revert OutsideWindow();\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/VerdictMarkets.sol:390:17\n    │\n390 │             if (block.timestamp < m.disputeEnds) revert OutsideWindow();\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/VerdictMarkets.sol:398:9\n    │\n398 │         emit Voided(id);\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/VerdictMarkets.sol:424:9\n    │\n424 │         emit Claimed(id, msg.sender, amount, refund);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VerdictMarkets.sol:438:13\n    │\n438 │         if (block.timestamp < m.params.answerFrom || block.timestamp >= m.params.answerUntil) revert OutsideWindow();\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/VerdictMarkets.sol:438:54\n    │\n438 │         if (block.timestamp < m.params.answerFrom || block.timestamp >= m.params.answerUntil) revert OutsideWindow();\n    │                                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/VerdictMarkets.sol:455:13\n    │\n455 │         if (collateral.balanceOf(address(this)) != beforeBalance - cost) revert InexactOracleSpend();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/VerdictMarkets.sol:468:33\n    │\n468 │         if (m.bountyRemaining > reserve) amount = Math.min(m.settlerReward, m.bountyRemaining - reserve);\n    │                                 ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VerdictMarkets.sol:501:40\n    │\n501 │                 || p.minAgreed == 0 || p.closeAt <= block.timestamp || p.closeAt > p.answerFrom\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/VerdictMarkets.sol:515:53\n    │\n515 │                 if (p.bounds[i] <= p.bounds[i - 1]) revert InvalidParams();\n    │                                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/VerdictMarkets.sol:522:82\n    │\n522 │                 if (p.answerType == 4 && uint256(p.keys[i]) > type(uint160).max) revert InvalidParams();\n    │                                                                                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/VerdictMarkets.sol:524:49\n    │\n524 │                     if (p.keys[i] == p.keys[j]) revert InvalidParams();\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/VerdictMarkets.sol:517:20\n    │\n517 │             return uint8(p.bounds.length + 1);\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/VerdictMarkets.sol:527:20\n    │\n527 │             return uint8(p.keys.length + 1);\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/VerdictMarkets.sol:554:21\n    │\n554 │                 if (first == p.keys[i]) return i;\n    │                     ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/VerdictMarkets.sol:539:20\n    │\n539 │             return uint8(p.bounds.length);\n    │                    ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/VerdictMarkets.sol:557:16\n    │\n557 │         return uint8(p.keys.length);\n    │                ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/IndependentReview.t.sol:17:9\n   │\n17 │         vm.warp(p.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    ‡\n122 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/IndependentReview.t.sol:63:9\n   │\n63 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/IndependentReview.t.sol:78:9\n   │\n78 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/IndependentReview.t.sol:123:9\n    │\n123 │         vm.warp(p.answerUntil - 1);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/IndependentReview.t.sol:123:9\n    │\n123 │         vm.warp(p.answerUntil - 1);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/IndependentReview.t.sol:183:9\n    │\n183 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/IndependentReview.t.sol:198:9\n    │\n198 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/RevisionIndependentReview.t.sol:11:9\n   │\n11 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/RevisionIndependentReview.t.sol:26:9\n   │\n26 │         vm.warp(markets.getMarket(first).params.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionIndependentReview.t.sol:39:9\n    │\n 39 │         vm.warp(block.timestamp + 1 hours);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionIndependentReview.t.sol:39:9\n    │\n 39 │         vm.warp(block.timestamp + 1 hours);\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/RevisionIndependentReview.t.sol:39:17\n   │\n39 │         vm.warp(block.timestamp + 1 hours);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/RevisionIndependentReview.t.sol:51:9\n   │\n51 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/RevisionIndependentReview.t.sol:66:9\n   │\n66 │         vm.warp(p.answerUntil - 1);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/RevisionRegression.t.sol:11:9\n   │\n11 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/RevisionRegression.t.sol:50:9\n   │\n50 │         vm.warp(p.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/RevisionRegression.t.sol:80:9\n   │\n80 │         vm.warp(markets.getMarket(first).params.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:88:9\n    │\n 88 │         vm.warp(block.timestamp + 24 hours);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:88:9\n    │\n 88 │         vm.warp(block.timestamp + 24 hours);\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/RevisionRegression.t.sol:88:17\n   │\n88 │         vm.warp(block.timestamp + 24 hours);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:101:9\n    │\n101 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:106:9\n    │\n106 │         vm.warp(until - 10 minutes);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:106:9\n    │\n106 │         vm.warp(until - 10 minutes);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:125:9\n    │\n125 │         vm.warp(block.timestamp + 1 minutes);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:125:9\n    │\n125 │         vm.warp(block.timestamp + 1 minutes);\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/RevisionRegression.t.sol:125:17\n    │\n125 │         vm.warp(block.timestamp + 1 minutes);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:139:9\n    │\n139 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/RevisionRegression.t.sol:141:17\n    │\n141 │         vm.warp(block.timestamp + 24 hours);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    ‡\n122 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    ‡\n122 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:210:9\n    │\n210 │         vm.warp(p.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:214:9\n    │\n214 │         vm.warp(p.answerUntil - bound(leadSeed, 1, 1 hours - 1));\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:214:9\n    │\n214 │         vm.warp(p.answerUntil - bound(leadSeed, 1, 1 hours - 1));\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/RevisionRegression.t.sol:219:31\n    │\n219 │         assertGe(extendedEnd, block.timestamp + 24 hours);\n    │                               ━━━━━━━━━━━━━━━\n220 │         vm.warp(p.answerUntil + bound(latencySeed, 1, extendedEnd - p.answerUntil - 1));\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/SettlerIndependentReview.t.sol:88:9\n   │\n88 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/SettlerIndependentReview.t.sol:102:9\n    │\n102 │         vm.warp(markets.getMarket(id).disputeEnds);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/SettlerIndependentReview.t.sol:102:9\n    │\n102 │         vm.warp(markets.getMarket(id).disputeEnds);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/SettlerIndependentReview.t.sol:280:9\n    │\n280 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/VerdictSettlerRewards.t.sol:57:9\n   │\n57 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlerRewards.t.sol:124:9\n    │\n124 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/VerdictSettlerRewards.t.sol:128:17\n    │\n128 │         vm.warp(block.timestamp + 24 hours);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlerRewards.t.sol:164:9\n    │\n164 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlerRewards.t.sol:182:9\n    │\n182 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlerRewards.t.sol:211:9\n    │\n211 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlerRewards.t.sol:294:9\n    │\n294 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/SettlerLifecycleProperties.t.sol:42:13\n   │\n42 │             vm.warp(p.answerFrom);\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/SettlerLifecycleProperties.t.sol:46:25\n   │\n46 │                 vm.warp(block.timestamp + 24 hours);\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/SettlerRewardInvariant.t.sol:182:17\n    │\n182 │         vm.warp(block.timestamp + 14 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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictAtomicity.t.sol:65:9\n    │\n 65 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictAtomicity.t.sol:65:9\n    │\n 65 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictAtomicity.t.sol:157:9\n    │\n157 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictAtomicity.t.sol:164:9\n    │\n164 │         vm.warp(block.timestamp + 24 hours);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictAtomicity.t.sol:164:9\n    │\n164 │         vm.warp(block.timestamp + 24 hours);\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/VerdictAtomicity.t.sol:164:17\n    │\n164 │         vm.warp(block.timestamp + 24 hours);\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/VerdictInvariant.t.sol:164:17\n    │\n164 │         vm.warp(block.timestamp + 14 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/VerdictLifecycleInvariant.t.sol:458:17\n    │\n458 │         vm.warp(block.timestamp + 14 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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/VerdictMarkets.t.sol:46:9\n   │\n46 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:90:9\n    │\n 90 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:90:9\n    │\n 90 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:118:9\n    │\n118 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:118:9\n    │\n118 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:121:9\n    │\n121 │         vm.warp(p.voidAfter + 1);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:121:9\n    │\n121 │         vm.warp(p.voidAfter + 1);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:142:9\n    │\n142 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:154:9\n    │\n154 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:182:9\n    │\n182 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/VerdictMarkets.t.sol:184:17\n    │\n184 │         vm.warp(block.timestamp + 24 hours - 1);\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/VerdictMarkets.t.sol:187:17\n    │\n187 │         vm.warp(block.timestamp + 1);\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/VerdictMarkets.t.sol:191:17\n    │\n191 │         vm.warp(block.timestamp + 24 hours);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:203:9\n    │\n203 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:217:9\n    │\n217 │         vm.warp(p.answerUntil);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:239:9\n    │\n239 │         vm.warp(p.answerUntil - 1);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:257:9\n    │\n257 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:257:9\n    │\n257 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:284:9\n    │\n284 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:319:9\n    │\n319 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:174:9\n    │\n174 │         vm.warp(markets.getMarket(id).params.closeAt - 1);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:273:9\n    │\n273 │         vm.warp(p.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:282:9\n    │\n282 │         vm.warp(markets.getMarket(id).params.answerFrom);\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.revertToState`\n    ╭▸ test/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:360:20\n    │\n360 │         assertTrue(vm.revertToState(snapshot));\n    │                    ────────────────────────── `vm.revertToState` 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.revertToState`\n    ╭▸ test/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:360:20\n    │\n360 │         assertTrue(vm.revertToState(snapshot));\n    │                    ────────────────────────── `vm.revertToState` 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.revertToState`\n    ╭▸ test/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:331:20\n    │\n331 │         assertTrue(vm.revertToState(snapshot));\n    │                    ────────────────────────── `vm.revertToState` 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.revertToState`\n    ╭▸ test/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:331:20\n    │\n331 │         assertTrue(vm.revertToState(snapshot));\n    │                    ────────────────────────── `vm.revertToState` 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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:344:9\n    │\n344 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/VerdictOracle.t.sol:211:17\n    │\n211 │         vm.warp(block.timestamp + 2 days - 1);\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/VerdictOracle.t.sol:238:17\n    │\n238 │         vm.warp(block.timestamp + 1 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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/VerdictOutcomes.t.sol:11:9\n   │\n11 │         vm.warp(p.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictOutcomes.t.sol:11:9\n    │\n 11 │         vm.warp(p.answerFrom);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictOutcomes.t.sol:11:9\n    │\n 11 │         vm.warp(p.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictOutcomes.t.sol:130:9\n    │\n130 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlementProperties.t.sol:178:9\n    │\n178 │         vm.warp(p.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlementProperties.t.sol:195:13\n    │\n195 │             vm.warp(p.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlementProperties.t.sol:205:13\n    │\n205 │             vm.warp(p.voidAfter);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlementProperties.t.sol:205:13\n    │\n205 │             vm.warp(p.voidAfter);\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":34024,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/SettlerDeployment.t.sol:SettlerDeploymentTest\n[PASS] test_launchHandoffPinsV2AndTenConstructorArguments() (gas: 6021796)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 740.19µs (580.59µs CPU time)\n\nRan 6 tests for test/OracleConsumerConformance.t.sol:OracleConsumerConformanceTest\n[PASS] test_acceptsAFreshSignatureFromTheVectorKey() (gas: 199666)\n[PASS] test_acceptsTheProtocolSignatureAsDelivered() (gas: 190502)\n[PASS] test_callbackSelectorIsCanonical() (gas: 4480)\n[PASS] test_digestMatchesTheProtocol() (gas: 13408)\n[PASS] test_domainIsConsumerChainAndVersionTwo() (gas: 15761)\n[PASS] test_structHashMatchesIndependentEncoding() (gas: 251625)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 1.02ms (1.25ms CPU time)\n\nRan 5 tests for test/RevisionIndependentReview.t.sol:RevisionIndependentReviewTest\n[PASS] test_documentedUnusableOwnDeliveryStillBlocksRetry() (gas: 1259665)\n[PASS] test_escalationRejectsIssuanceBeforeItsOwnAsk() (gas: 1995674)\n[PASS] test_identicalBodyOtherMarketAnswerCannotSetOutcome() (gas: 1926375)\n[PASS] test_independentSameBodyCannotBlockOwnRetry() (gas: 1725093)\n[PASS] test_primaryLateIssuanceRemainsOutsideBriefsExplicitRange() (gas: 1362737)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 4.45ms (3.90ms CPU time)\n\nRan 3 tests for test/Deployment.t.sol:DeploymentTest\n[PASS] test_burnVaultHasNoCallablePathOrEtherReceiver() (gas: 1013344)\n[PASS] test_exactSepoliaFactoryDeploymentWithoutDependencyCode() (gas: 20775481)\n[PASS] test_rehearsalRefusesOtherChains() (gas: 207095)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 31.52ms (31.56ms CPU time)\n\nRan 7 tests for test/VerdictAtomicity.t.sol:VerdictAtomicityTest\n[PASS] testFuzz_failureAtAnyFinalizeRecipientRollsBackEarlierPayments(uint8,bool) (runs: 64, μ: 2387517, ~: 2381462)\n[PASS] test_failedBountyReturnDoesNotVoidMarketOrPreventLaterRefund() (gas: 1111622)\n[PASS] test_failedCallbackIsNotRefundedButMarketRetryAndSettlementRemainReachable() (gas: 2409792)\n[PASS] test_failedEscalationPaymentCannotExtendOrConsumeDisputeWindow() (gas: 2692212)\n[PASS] test_failedPrimaryPaymentRestoresBountyAskCountTimestampAndAllowances() (gas: 1736994)\n[PASS] test_failedRefundCanBeRetriedAndDoesNotConsumeAnotherUsersClaim() (gas: 1449710)\n[PASS] test_guardBlocksCrossMarketReentryFromAnOtherwiseEligibleClaimant() (gas: 4435937)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 73.35ms (74.51ms CPU time)\n\nRan 3 tests for test/VerdictImportedAudit.t.sol:VerdictImportedAuditTest\n[PASS] test_creatorCanSetVoidAfterFarInFuture() (gas: 598026)\n[PASS] test_pauseOnlyBlocksEntryAndReleaseReturnsAllUnspentBounty() (gas: 2013101)\n[PASS] test_strangerEscalatesAtNoCostBurnsBountyAndDelays() (gas: 2518937)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 130.65ms (1.74ms CPU time)\n\nRan 6 tests for test/VerdictOracleAdversarial.t.sol:VerdictOracleAdversarialTest\n[PASS] testFuzz_rotationsKeepFourInflightSnapshotsInAnyDeliveryOrder(uint256) (runs: 256, μ: 5459977, ~: 5459977)\n[PASS] test_contractSignerIsPinnedAndRevokedSignatureStoresNothing() (gas: 1500728)\n[PASS] test_everyAttestationFieldIsBoundBySignatureAndStoredHash() (gas: 2610090)\n[PASS] test_expiryAndClockToleranceAreInclusiveAtExactBoundary() (gas: 977218)\n[PASS] test_nonCanonicalAndTruncatedSignaturesCannotConsumePendingRequest() (gas: 829160)\n[PASS] test_pendingOwnerCannotAcceptConfigurationAndFormerOwnerLosesAccess() (gas: 434003)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 163.09ms (166.73ms CPU time)\n\nRan 10 tests for test/VerdictSettlerRewards.t.sol:VerdictSettlerRewardsTest\n[PASS] test_bountyArithmeticRejectsImpossiblePriceOrRewardWithoutOverflow() (gas: 702894)\n[PASS] test_bountyMinimumChecksBothRequestedAndReceivedAmounts() (gas: 1192716)\n[PASS] test_eachProposalResolveAndFinalizePaysItsCallerOnceEscalatePaysNothing() (gas: 4702670)\n[PASS] test_priceRiseBeforeResolveClipsRewardToExactReserve() (gas: 3210434)\n[PASS] test_proposalUsesCurrentPriceAndPreservesTheLastAsk() (gas: 4308133)\n[PASS] test_retryResolveIsAlsoRewardedOnce() (gas: 3508684)\n[PASS] test_rewardBoundIsInclusiveAndZeroCapDisablesRewards() (gas: 970760)\n[PASS] test_terminalRewardIsClippedToBountyNeverBettorDepositsOrAnotherMarket() (gas: 3238907)\n[PASS] test_voidWithoutAsksPaysBeforeReturningBountyAndNeverTwice() (gas: 1629700)\n[PASS] test_zeroRewardKeepsLegacyBalancesEventsAndNoNewPriceDependency() (gas: 2845828)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 163.73ms (10.89ms CPU time)\n\nRan 15 tests for test/VerdictMarketsValidation.t.sol:VerdictMarketsValidationTest\n[PASS] test_allowlistRemovalAndPermanentDisable() (gas: 1291458)\n[PASS] test_attestationMustMatchEveryMarketFieldAndPanelRequirements() (gas: 5154664)\n[PASS] test_betZeroUnknownOutcomeAndCloseBoundary() (gas: 716041)\n[PASS] test_bodyHashAndBodySizeValidation() (gas: 729322)\n[PASS] test_bountyMustCoverTwoAsksAfterTransferFee() (gas: 236534)\n[PASS] test_creationEmitsBothFullBodies() (gas: 385237)\n[PASS] test_escalationRequiresDoubleCurrentPanelAndCorrectBody() (gas: 2820430)\n[PASS] test_feeCapAndPoolCapConstructor() (gas: 15618)\n[PASS] test_feeOnTransferCreditsOnlyActualBountyAndStakes() (gas: 1209845)\n[PASS] test_firstProposalAtVoidDeadlineCannotResurrectMarket() (gas: 1378732)\n[PASS] test_guardianHandoverIsTwoStepAndNoUnauthorizedPowers() (gas: 370410)\n[PASS] test_invalidTimesPanelsAndTypes() (gas: 614692)\n[PASS] test_minAgreedCanRequireMoreThanMinimumPanelSize() (gas: 1237856)\n[PASS] test_pauseBlocksOnlyEntryAndRenounceRequiresUnpaused() (gas: 3328792)\n[PASS] test_poolCapUsesReceivedBalanceAndFailedBetIsAtomic() (gas: 825795)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 186.06ms (12.00ms CPU time)\n\nRan 17 tests for test/VerdictOracle.t.sol:VerdictOracleTest\n[PASS] test_bodyLimitsAndExactPaymentRequired() (gas: 586164)\n[PASS] test_configDelayCapAndInvalidConfiguration() (gas: 9288)\n[PASS] test_consumedIntakeIdAndOracleIdCannotBeStoredTwice() (gas: 970867)\n[PASS] test_deliveredAnswerRemainsReadableAfterExpiry() (gas: 524115)\n[PASS] test_expiredFutureMalformedAndTamperedRejected() (gas: 766529)\n[PASS] test_falseAnswerStoredUnder150kGas() (gas: 575739)\nLogs:\n  cold callback gas: 126024\n\n[PASS] test_intakeAndSignerRotationPreservesInflightRequest() (gas: 2174415)\n[PASS] test_maxAnswerUnder150kGas() (gas: 610144)\nLogs:\n  maximum answer cold callback gas: 140592\n\n[PASS] test_replacingConfigProposalRestartsDelay() (gas: 283461)\n[PASS] test_requestPaysExactlyAndPinsConfiguration() (gas: 403481)\n[PASS] test_requestReentrancyFails() (gas: 486117)\n[PASS] test_reusedIntakeRequestIdRollsBackPayment() (gas: 545892)\n[PASS] test_timelockAndOwnable2Step() (gas: 558572)\n[PASS] test_wrongChainDomainStoresNothing() (gas: 417798)\n[PASS] test_wrongConsumerDomainStoresNothing() (gas: 422685)\n[PASS] test_wrongIntakeAndUnknownIdStoreNothing() (gas: 454227)\n[PASS] test_wrongSignerStoresNothingAndNoRefund() (gas: 522092)\nSuite result: ok. 17 passed; 0 failed; 0 skipped; finished in 202.34ms (6.17ms CPU time)\n\nRan 20 tests for test/VerdictMarkets.t.sol:VerdictMarketsTest\n[PASS] testFuzz_terminalConservation(uint96,uint96,uint96,uint8,bool) (runs: 512, μ: 1942289, ~: 2219068)\nLogs:\n  Bound result 122048040014776\n  Bound result 1846766223\n  Bound result 26312\n\n[PASS] test_asksBeforeAnswerFromAndAtOrAfterAnswerUntilRevert() (gas: 562520)\n[PASS] test_assetRotationBlocksAsksButNotRefunds() (gas: 2120548)\n[PASS] test_emptyWinningBucketCannotVoidUntilDisputeEnds() (gas: 1809113)\n[PASS] test_escalationAnswerCannotBeFirstProposal() (gas: 1219454)\n[PASS] test_escalationAskAtAnswerUntilRevertsEvenInsideDisputeWindow() (gas: 1281214)\n[PASS] test_externalSponsorCannotDeliverPrimaryOrEscalation() (gas: 3880222)\n[PASS] test_fullSettlementPaysWholePoolFeesAndExactRemainder() (gas: 2399157)\n[PASS] test_lateEscalationBeyondVoidAfterStillFinalizesWithoutAnswer() (gas: 2498343)\n[PASS] test_lateEscalationReplacementRestartsWindowOnceAndFinalizes() (gas: 2834558)\n[PASS] test_noEscalationBodyAndDuplicateEscalationAsk() (gas: 2703033)\n[PASS] test_priceIncreaseCannotSpendBettorsCollateral() (gas: 2271746)\n[PASS] test_primaryRetryBlockedAfterDeliveryEvenWithoutProposal() (gas: 1191860)\n[PASS] test_proposeAfterAnswerUntilWithTimelyStoredAnswer() (gas: 1473367)\n[PASS] test_provisionalWindowBoundariesAreStrict() (gas: 2322634)\n[PASS] test_secondPrimaryAskAfter24HoursAndMaximumTwoAsks() (gas: 1809739)\n[PASS] test_tokenReentrancyBlockedOnDepositAndClaim() (gas: 2163480)\n[PASS] test_voidNoAnswerRefundsEveryOutcomeAndUnspentBounty() (gas: 1758828)\n[PASS] test_wrongBodiesAndResolveAfterProposalRevertWithoutSpend() (gas: 1517332)\n[PASS] test_zeroAndUnknownClaimsAndUnfinishedClaimsRevert() (gas: 692952)\nSuite result: ok. 20 passed; 0 failed; 0 skipped; finished in 213.58ms (229.92ms CPU time)\n\nRan 12 tests for test/IndependentReview.t.sol:IndependentReviewTest\n[PASS] testFuzzReviewActualTransfersConserveInAnyClaimOrder(uint96,uint96,uint96,uint8) (runs: 512, μ: 2634208, ~: 2634209)\nLogs:\n  Bound result 1775\n  Bound result 15447\n  Bound result 3792478065\n\n[PASS] testReviewAgreementMinimumCanExceedMinimumPanel() (gas: 1710516)\n[PASS] testReviewDonationDoesNotAlterPayoutOrAccounting() (gas: 1831460)\n[PASS] testReviewEscalationCannotBeFirstProposalEvenWithLargePanel() (gas: 1219037)\n[PASS] testReviewEscalationCannotVoidAfterDeadline() (gas: 2306392)\n[PASS] testReviewFailedTokenTransferRollsBackClaim() (gas: 1964911)\n[PASS] testReviewLateReplacementPastVoidRemainsFinalizable() (gas: 2583202)\n[PASS] testReviewMaximumAnswerColdCallback() (gas: 1266872)\nLogs:\n  maximum answer cold callback gas: 140592\n\n[PASS] testReviewMixedMarketsCannotCrossSubsidizeClaims() (gas: 3244354)\n[PASS] testReviewNoWinnerIsVoidableAfterWindowPastVoidAfter() (gas: 1969951)\n[PASS] testReviewRotationPreservesOldCallerAndKey() (gas: 2309371)\n[PASS] testReviewSameAttestationCannotOverwriteDifferentRequest() (gas: 1427982)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 218.62ms (227.28ms CPU time)\n\nRan 11 tests for test/RevisionRegression.t.sol:RevisionRegressionTest\n[PASS] testFuzz_eitherPaidPrimaryRequestCanProposeButCannotReplace(bool,bool) (runs: 256, μ: 2816831, ~: 2817907)\n[PASS] testFuzz_lateEscalationHasFiniteSettlementDeadline(uint32,uint32,uint32,bool) (runs: 256, μ: 2714189, ~: 2490502)\nLogs:\n  Bound result 159558\n  Bound result 1\n  Bound result 15561\n\n[PASS] test_escalationCannotUseAnswerIssuedBeforeItsAsk() (gas: 1997270)\n[PASS] test_identicalEscalationBodiesStillRequireEachMarketsOwnPaidAsk() (gas: 5271284)\n[PASS] test_lateEscalationIssuedAfterAnswerUntilSettlesCorrectedOutcome() (gas: 2826337)\n[PASS] test_otherMarketAnswerCannotSetOutcomeOrBlockRetry() (gas: 2624132)\n[PASS] test_oversizeAnswerRefused() (gas: 983076)\n[PASS] test_renounceRequiresAllowlistDisabledEvenWhenEmpty() (gas: 499255)\n[PASS] test_unusableDeliveryBlocksRetry() (gas: 1259765)\n[PASS] test_zeroBoundRejectedWithoutTakingBounty() (gas: 1572363)\n[PASS] test_zeroDelayAcceptsConfigInSameBlock() (gas: 271514)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 235.83ms (439.85ms CPU time)\n\nRan 10 tests for test/SettlerIndependentReview.t.sol:SettlerIndependentReviewTest\n[PASS] testFuzz_rewardRecipientsMayAlsoBeCreatorWinnerOrTreasury(uint8) (runs: 512, μ: 2257649, ~: 2253409)\n[PASS] testFuzz_rewardReserveUsesPriceAfterPaidAsk(uint256) (runs: 512, μ: 1342254, ~: 1346161)\nLogs:\n  Bound result 2016632631729\n\n[PASS] test_creatorReturnFailureRevertsFinalizeIncludingEarlierReward() (gas: 2502155)\n[PASS] test_creatorReturnFailureRevertsVoidIncludingEarlierReward() (gas: 1252693)\n[PASS] test_failedProposalRewardLeavesStoredAnswerUsableAndPaysOnceOnRetry() (gas: 1842699)\n[PASS] test_finalizeRewardCallbackSeesCompleteAccountingAndCannotReenter() (gas: 3385133)\n[PASS] test_maximumPriceAfterPaidAskSuppressesRewardWithoutReverting() (gas: 1297383)\n[PASS] test_positiveTerminalRewardsDoNotDependOnAWorkingOraclePrice() (gas: 2803780)\n[PASS] test_rewardFailureRollsBackTheWholePaidAskAndAllowsRetry() (gas: 2014297)\n[PASS] test_voidRewardCallbackSeesCompleteAccountingAndCannotReenter() (gas: 2049715)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 244.33ms (382.35ms CPU time)\n\nRan 1 test for test/SettlerLifecycleProperties.t.sol:SettlerLifecyclePropertiesTest\n[PASS] testFuzz_allLifecyclePathsConserveActualTransfers(uint96,uint96,uint96,uint96,uint8,uint64,bool) (runs: 512, μ: 3433029, ~: 3432456)\nLogs:\n  Bound result 267501\n  Bound result 86002410\n  Bound result 155020807830913\n  Bound result 3303864741296394276\n  Bound result 687430712\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 253.64ms (252.40ms CPU time)\n\nRan 7 tests for test/VerdictOutcomes.t.sol:VerdictOutcomesTest\n[PASS] testFuzz_uintBucketDefinition(uint256) (runs: 512, μ: 1341469, ~: 1341567)\n[PASS] test_addressListUsesFirstElementOnlyAndCanonicalAddressKey() (gas: 4875179)\n[PASS] test_booleanOutcomes() (gas: 2310147)\n[PASS] test_bytes32ListUsesFirstElementOnlyAndEmptyMeansNone() (gas: 6010921)\n[PASS] test_malformedEncodedAnswerCannotSetOutcome() (gas: 1291065)\n[PASS] test_numericBucketsIncludeLowerBoundaryExcludeUpper() (gas: 7221103)\n[PASS] test_twoToEightOutcomesAndSortedUniqueDefinitions() (gas: 1791330)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 253.68ms (261.04ms CPU time)\n\nRan 7 tests for test/VerdictSettlementProperties.t.sol:VerdictSettlementPropertiesTest\n[PASS] testFuzz_feeSplitsAndRationalPayoutBoundsInEveryClaimOrder(uint256,uint16,uint16,uint16,uint8) (runs: 1000, μ: 2966028, ~: 2971266)\nLogs:\n  Bound result 350\n  Bound result 31\n  Bound result 66\n  Bound result 5338534729402249237\n  Bound result 93577370590318245214\n  Bound result 73138207696770579455\n  Bound result 12345\n\n[PASS] testFuzz_numericOutcomeSatisfiesItsHalfOpenInterval(uint128,uint96,uint256,uint8) (runs: 1000, μ: 1389881, ~: 1379001)\nLogs:\n  Bound result 1\n  Bound result 22805090379\n  Bound result 32884833\n\n[PASS] test_malformedListsCannotChangeAnAuthenticatedMarketsOutcome() (gas: 2908506)\n[PASS] test_oneWeiLastWinnerReceivesTheRoundingRemainder() (gas: 2279339)\n[PASS] test_oneWeiWinnerMayRoundToZeroButLastClaimStillDrainsExactly() (gas: 2577622)\n[PASS] test_payoutUsesFullPrecisionWhenIntermediateStakeTimesPoolOverflows256Bits() (gas: 2534215)\n[PASS] test_settlementEventsDescribeWholePoolFeesAndUnspentBounty() (gas: 1989237)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 253.71ms (508.03ms CPU time)\n\nRan 1 test for test/VerdictInvariant.t.sol:VerdictInvariantTest\n[PASS] invariant_actualTokensMatchEveryMarketsAccounting() (runs: 128, calls: 8192, reverts: 0)\n\n╭----------------+----------------+-------+---------+----------╮\n| Contract       | Selector       | Calls | Reverts | Discards |\n+==============================================================+\n| VerdictHandler | advance        | 822   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | ask            | 796   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | askEscalation  | 801   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | collect        | 812   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | deliverPrimary | 842   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | enter          | 851   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | proposePrimary | 824   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | replaceOutcome | 805   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | settle         | 817   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | togglePause    | 822   | 0       | 0        |\n╰----------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 17336\n  Bound result 4175\n  Bound result 11284\n  Bound result 12443\n  Bound result 3\n  Bound result 1082\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.80s (1.80s CPU time)\n\nRan 1 test for test/SettlerRewardInvariant.t.sol:SettlerRewardInvariantTest\n[PASS] invariant_actualTokensMatchEveryMarketsAccounting() (runs: 128, calls: 8192, reverts: 0)\n\n╭----------------------+----------------+-------+---------+----------╮\n| Contract             | Selector       | Calls | Reverts | Discards |\n+====================================================================+\n| SettlerRewardHandler | advance        | 699   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | ask            | 760   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | askEscalation  | 809   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | changePrice    | 732   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | collect        | 706   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | deliverPrimary | 733   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | enter          | 779   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | proposePrimary | 755   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | replaceOutcome | 731   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | settle         | 760   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | togglePause    | 728   | 0       | 0        |\n╰----------------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 5869\n  Bound result 255\n  Bound result 16400\n  Bound result 1000000000000000007\n  Bound result 6447\n  Bound result 12273\n  Bound result 3599\n  Bound result 15960\n  Bound result 7716\n  Bound result 1400000000000000000\n  Bound result 20\n  Bound result 17\n  Bound result 14180\n  Bound result 999\n  Bound result 14657\n  Bound result 3948\n  Bound result 12329\n  Bound result 11318\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.89s (1.89s CPU time)\n\nRan 4 tests for test/VerdictLifecycleInvariant.t.sol:VerdictLifecycleInvariantTest\n[PASS] invariant_tokensStakesAndFinalityMatchIndependentLedger() (runs: 256, calls: 16384, reverts: 0)\n\n╭-------------------------+------------------------+-------+---------+----------╮\n| Contract                | Selector               | Calls | Reverts | Discards |\n+===============================================================================+\n| VerdictLifecycleHandler | advance                | 1346  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | askEscalation          | 1282  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | askPrimary             | 1233  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | collect                | 1212  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | deliverAnswer          | 1249  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | donate                 | 1261  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | openMarket             | 1230  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | probeBurn              | 1254  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | probeIndependentAnswer | 1277  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | probeTerminal          | 1271  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | settle                 | 1277  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | togglePause            | 1254  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | wager                  | 1238  | 0       | 0        |\n╰-------------------------+------------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 3749\n  Bound result 6\n  Bound result 8160\n  Bound result 885406043358423093\n  Bound result 838482357580828626\n  Bound result 245028227654106732\n  Bound result 700\n  Bound result 150000\n  Bound result 13\n  Bound result 7672\n  Bound result 16182\n  Bound result 7403\n  Bound result 6662\n\n[PASS] test_handlerIndependentAnswersCannotBlockRetryOrShopOutcomes() (gas: 10123579)\nLogs:\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 21600\n  Bound result 21600\n  Bound result 21600\n  Bound result 21600\n\n[PASS] test_handlerReachesPrimaryEscalationFailureFinalizeAndRefundPaths() (gas: 16451019)\nLogs:\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 31\n  Bound result 17\n  Bound result 11\n\n[PASS] test_handlerUsesActualLateEscalationIssuanceAndStillDrains() (gas: 9734939)\nLogs:\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 33.93s (33.96s CPU time)\n\nRan 20 test suites in 33.93s (40.26s CPU time): 147 tests passed, 0 failed, 0 skipped (147 total tests)\n","passed":true},{"durationMs":71,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"VerdictMarkets.acceptGuardian()\",\"VerdictMarkets.bet(uint256,uint8,uint256,uint256)\",\"VerdictMarkets.claim(uint256)\",\"VerdictMarkets.createMarket((bytes32,uint8,uint256,uint64,uint64,uint16,uint16,uint64,uint64,uint64,uint32,uint64,uint256[],bytes32[],uint256,uint256),bytes,bytes,string,uint256)\",\"VerdictMarkets.disableAllowlist()\",\"VerdictMarkets.escalate(uint256,bytes)\",\"VerdictMarkets.finalize(uint256)\",\"VerdictMarkets.pause()\",\"VerdictMarkets.propose(uint256,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64))\",\"VerdictMarkets.renounceGuardian()\",\"VerdictMarkets.resolve(uint256,bytes)\",\"VerdictMarkets.setCreatorAllowed(address,bool)\",\"VerdictMarkets.transferGuardian(address)\",\"VerdictMarkets.unpause()\",\"VerdictMarkets.voidMarket(uint256)\",\"VerdictOracle.acceptConfig()\",\"VerdictOracle.acceptOwnership()\",\"VerdictOracle.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"VerdictOracle.proposeConfig((address,address,address,bytes32,uint256))\",\"VerdictOracle.renounceOwnership()\",\"VerdictOracle.request(bytes)\",\"VerdictOracle.transferOwnership(address)\"],\"files\":{\".gitignore\":4,\"ADAPTATION.md\":74,\"DEPENDENCIES.md\":14,\"DESIGN.md\":95,\"LICENSE\":21,\"README.md\":167,\"dist/assets/chain-BQwdJvnv.js\":45,\"dist/assets/index-BbSaev33.css\":1,\"dist/assets/index-ByzN5mJO.js\":1,\"dist/assets/react-DbQ9GvLb.js\":49,\"dist/favicon.svg\":1,\"dist/fonts/archivo-OFL.txt\":93,\"dist/fonts/archivo-expanded-800.woff2\":65,\"dist/fonts/ibm-plex-mono-400.woff2\":58,\"dist/fonts/ibm-plex-mono-500.woff2\":62,\"dist/fonts/ibm-plex-mono-OFL.txt\":93,\"dist/index.html\":6,\"dist/social.png\":106,\"docs/BETTER_INTERFACE_LICENSE.txt\":220,\"docs/DEPLOYMENT.md\":61,\"docs/INDEPENDENT_REVIEW.md\":67,\"docs/REVISION_REVIEW.md\":41,\"docs/SETTLER_INDEPENDENT_REVIEW.md\":79,\"docs/VERIFICATION.md\":41,\"docs/WEBSITE_VALIDATION.md\":131,\"foundry.toml\":23,\"remappings.txt\":2,\"script/SepoliaParameters.sol\":27,\"src/OracleAttestation.sol\":221,\"src/VerdictBurnVault.sol\":5,\"src/VerdictMarkets.sol\":559,\"src/VerdictOracle.sol\":178,\"src/interfaces/IIntake.sol\":14,\"src/interfaces/IVerdictOracle.sol\":14,\"test/Deployment.t.sol\":102,\"test/IndependentReview.t.sol\":239,\"test/OracleConsumerConformance.t.sol\":162,\"test/RevisionIndependentReview.t.sol\":77,\"test/RevisionRegression.t.sol\":245,\"test/SettlerDeployment.t.sol\":58,\"test/SettlerIndependentReview.t.sol\":353,\"test/SettlerLifecycleProperties.t.sol\":118,\"test/SettlerRewardInvariant.t.sol\":249,\"test/TESTING.md\":87,\"test/TestBase.sol\":136,\"test/VerdictAtomicity.t.sol\":214,\"test/VerdictImportedAudit.t.sol\":61,\"test/VerdictInvariant.t.sol\":213,\"test/VerdictLifecycleInvariant.t.sol\":580,\"test/VerdictMarkets.t.sol\":383,\"test/VerdictMarketsValidation.t.sol\":368,\"test/VerdictOracle.t.sol\":288,\"test/VerdictOracleAdversarial.t.sol\":228,\"test/VerdictOutcomes.t.sol\":148,\"test/VerdictSettlementProperties.t.sol\":228,\"test/VerdictSettlerRewards.t.sol\":310,\"test/mocks/MockIMD.sol\":42,\"test/mocks/MockIntake.sol\":62,\"web/index.html\":2,\"web/package-lock.json\":2003,\"web/package.json\":35,\"web/public/favicon.svg\":1,\"web/public/fonts/archivo-OFL.txt\":93,\"web/public/fonts/archivo-expanded-800.woff2\":65,\"web/public/fonts/ibm-plex-mono-400.woff2\":58,\"web/public/fonts/ibm-plex-mono-500.woff2\":62,\"web/public/fonts/ibm-plex-mono-OFL.txt\":93,\"web/public/social.png\":106,\"web/scripts/browser-check.mjs\":414,\"web/scripts/check-export.mjs\":51,\"web/scripts/isolated.mjs\":108,\"web/scripts/revision-cases.mjs\":179,\"web/scripts/verify-contracts.mjs\":120,\"web/scripts/wallet-check.mjs\":784,\"web/src/App.tsx\":740,\"web/src/CreatePage.tsx\":575,\"web/src/MarketPage.tsx\":884,\"web/src/Portfolio.tsx\":224,\"web/src/abi/VerdictBurnVault.json\":1,\"web/src/abi/VerdictMarkets.json\":1,\"web/src/abi/VerdictOracle.json\":1,\"web/src/abi/provenance.json\":10,\"web/src/chain.ts\":377,\"web/src/components.tsx\":358,\"web/src/config.ts\":75,\"web/src/create.ts\":222,\"web/src/domain.ts\":326,\"web/src/main.tsx\":32,\"web/src/store.tsx\":103,\"web/src/styles.css\":2288,\"web/src/types.ts\":126,\"web/src/wallet.tsx\":385,\"web/tests/chain-fixture.json\":454,\"web/tests/domain.test.ts\":328,\"web/tests/wallet-rpc-fixture.json\":636,\"web/tsconfig.json\":17,\"web/validation/browser-results.json\":193,\"web/validation/contract-verification.json\":25,\"web/validation/export-integrity.json\":80,\"web/validation/revision-before.json\":79,\"web/validation/revision-results.json\":181,\"web/validation/wallet-results.json\":76,\"web/vite.config.ts\":37},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":4673,"exitCode":0,"name":"slither","output":"[high/medium] reentrancy-balance at src/VerdictOracle.sol:94: Reentrancy in VerdictOracle.request(bytes) (src/VerdictOracle.sol#94-115):\n[high/medium] reentrancy-balance at src/VerdictMarkets.sol:441: Reentrancy in VerdictMarkets._ask(uint256,VerdictMarkets.Market,bytes,bool) (src/VerdictMarkets.sol#441-459):\n[medium/high] incorrect-equality at src/VerdictMarkets.sol:486: VerdictMarkets._pull(address,uint256) (src/VerdictMarkets.sol#486-492) uses a dangerous strict equality:\n[medium/medium] uninitialized-local at src/VerdictMarkets.sol:541: VerdictMarkets._outcome(VerdictMarkets.Params,bytes).first (src/VerdictMarkets.sol#541) is a local variable never initialized\n[medium/medium] uninitialized-local at src/VerdictMarkets.sol:464: VerdictMarkets._recordSettlerReward(uint256,VerdictMarkets.Market,uint8).reserve (src/VerdictMarkets.sol#464) is a local variable never initialized\n[low/medium] missing-zero-check at src/VerdictOracle.sol:72: VerdictOracle.constructor(address,address,address,bytes32,uint256,address,uint256).asset_ (src/VerdictOracle.sol#72) lacks a zero-check on :\n[low/medium] missing-zero-check at src/VerdictOracle.sol:71: VerdictOracle.constructor(address,address,address,bytes32,uint256,address,uint256).intake_ (src/VerdictOracle.sol#71) lacks a zero-check on :\n[low/medium] reentrancy-benign at src/VerdictOracle.sol:94: Reentrancy in VerdictOracle.request(bytes) (src/VerdictOracle.sol#94-115):\n[low/medium] timestamp at src/VerdictMarkets.sol:319: VerdictMarkets.propose(uint256,OracleAttestation.Attestation) (src/VerdictMarkets.sol#319-360) uses timestamp for comparisons\n[low/medium] timestamp at src/VerdictMarkets.sol:275: VerdictMarkets.bet(uint256,uint8,uint256,uint256) (src/VerdictMarkets.sol#275-287) uses timestamp for comparisons\n[low/medium] timestamp at src/VerdictMarkets.sol:384: VerdictMarkets.voidMarket(uint256) (src/VerdictMarkets.sol#384-401) uses timestamp for comparisons\n[low/medium] timestamp at src/VerdictOracle.sol:158: VerdictOracle.acceptConfig() (src/VerdictOracle.sol#158-170) uses timestamp for comparisons\n[low/medium] timestamp at src/VerdictMarkets.sol:498: VerdictMarkets._validateParams(VerdictMarkets.Params) (src/VerdictMarkets.sol#498-530) uses timestamp for comparisons\n[low/medium] timestamp at src/VerdictOracle.sol:117: VerdictOracle.onOracleResult(bytes32,OracleAttestation.Attestation,bytes) (src/VerdictOracle.sol#117-138) uses timestamp for comparisons\n[low/medium] timestamp at src/VerdictMarkets.sol:289: VerdictMarkets.resolve(uint256,bytes) (src/VerdictMarkets.sol#289-302) uses timestamp for comparisons\n[low/medium] timestamp at src/VerdictMarkets.sol:304: VerdictMarkets.escalate(uint256,bytes) (src/VerdictMarkets.sol#304-317) uses timestamp for comparisons\n[low/medium] timestamp at src/VerdictMarkets.sol:437: VerdictMarkets._askWindow(VerdictMarkets.Market) (src/VerdictMarkets.sol#437-439) uses timestamp for comparisons\n[low/medium] timestamp at src/VerdictMarkets.sol:362: VerdictMarkets.finalize(uint256) (src/VerdictMarkets.sol#362-382) uses timestamp for comparisons\n[low/medium] timestamp at src/OracleAttestation.sol:157: OracleAttestationConsumer._verifyAttestation(OracleAttestation.Attestation,bytes) (src/OracleAttestation.sol#157-165) uses timestamp for comparisons","passed":true},{"durationMs":589,"exitCode":0,"name":"aderyn","output":"[high] reentrancy-state-change at src/VerdictMarkets.sol:257: Reentrancy: State change after external call (9 places)\n[low] centralization-risk at src/VerdictOracle.sol:14: Centralization Risk (3 places)\n[low] large-numeric-literal at src/VerdictMarkets.sol:368: Large Numeric Literal (3 places)\n[low] literal-instead-of-constant at src/VerdictMarkets.sol:253: Literal Instead of Constant (19 places)\n[low] local-variable-shadowing at src/VerdictOracle.sol:19: Local Variable Shadows State Variable (5 places)\n[low] non-reentrant-not-first at src/VerdictOracle.sol:150: `nonReentrant` is Not the First Modifier (2 places)\n[low] require-revert-in-loop at src/VerdictMarkets.sol:514: Loop Contains `require`/`revert` (3 places)\n[low] state-no-address-check at src/VerdictOracle.sol:83: Address State Variable Set Without Checks (2 places)\n[low] uninitialized-local-variable at src/VerdictMarkets.sol:521: Uninitialized Local Variable (4 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"ae97d6ad22f7e64636923b60b44a4dbc332cbbd9d834e9f073eaa6aaa02c0ea2","verifiedTreeHash":"d104605261477d122e872c8374bdd0bb00a81bfd","verifierVersion":"0.1.0+0e08a464"},{"checks":[{"durationMs":105251,"exitCode":0,"name":"build","output":"Compiling 79 files with Solc 0.8.26\nSolc 0.8.26 finished in 105.06s\nCompiler run successful!\nwarning[missing-zero-check]: address parameter is used in a state write or value transfer without a zero-address check\n   ╭▸ src/VerdictOracle.sol:71:9\n   │\n71 │         address intake_,\n   │         ━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/missing-zero-check\n\nwarning[missing-zero-check]: address parameter is used in a state write or value transfer without a zero-address check\n   ╭▸ src/VerdictOracle.sol:72:9\n   │\n72 │         address asset_,\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/VerdictOracle.sol:114:9\n    │\n114 │         emit Requested(intakeRequestId, bodyHash, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/VerdictOracle.sol:102:13\n    │\n102 │         if (token.balanceOf(address(this)) != beforeBalance + cost) revert InexactPayment();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/VerdictOracle.sol:109:13\n    │\n109 │         if (token.balanceOf(address(this)) != beforeBalance) revert InexactPayment();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VerdictOracle.sol:126:13\n    │\n126 │         if (block.timestamp > a.expiresAt) revert AttestationExpired(a.expiresAt);\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/VerdictOracle.sol:127:13\n    │\n127 │         if (a.issuedAt > block.timestamp + ISSUED_AT_TOLERANCE) revert AttestationNotYetValid(a.issuedAt);\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/VerdictOracle.sol:137:9\n    │\n137 │         emit Answered(a.requestId, intakeRequestId, p.bodyHash, attHash);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/VerdictOracle.sol:150:66\n    │\n150 │     function proposeConfig(Config calldata c) external onlyOwner nonReentrant {\n    │                                                                  ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/VerdictOracle.sol:158:48\n    │\n158 │     function acceptConfig() external onlyOwner nonReentrant {\n    │                                                ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VerdictOracle.sol:159:31\n    │\n159 │         if (!configPending || block.timestamp < acceptAfter) revert ConfigNotReady();\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/VerdictMarkets.sol:278:13\n    │\n278 │         if (block.timestamp >= m.params.closeAt) revert OutsideWindow();\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/VerdictMarkets.sol:296:17\n    │\n296 │             if (block.timestamp < m.lastPrimaryAsk + 24 hours) revert RetryNotReady();\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/VerdictMarkets.sol:471:9\n    │\n471 │         emit SettlerRewarded(id, msg.sender, action, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VerdictMarkets.sol:308:13\n    │\n308 │         if (block.timestamp >= m.disputeEnds) revert OutsideWindow();\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/VerdictMarkets.sol:315:9\n    │\n315 │         emit DisputeExtended(id, m.disputeEnds);\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/VerdictMarkets.sol:458:9\n    │\n458 │         emit OracleAsked(id, requestId, escalation, cost);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VerdictMarkets.sol:323:13\n    │\n323 │         if (block.timestamp < m.params.answerFrom) revert OutsideWindow();\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/VerdictMarkets.sol:326:17\n    │\n326 │             if (block.timestamp >= m.disputeEnds) revert OutsideWindow();\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/VerdictMarkets.sol:328:20\n    │\n328 │         } else if (block.timestamp >= m.params.voidAfter) {\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/VerdictMarkets.sol:365:13\n    │\n365 │         if (block.timestamp < m.disputeEnds) revert OutsideWindow();\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/VerdictMarkets.sol:483:9\n    │\n483 │         emit BountyReturned(id, m.creator, bounty);\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/VerdictMarkets.sol:377:9\n    │\n377 │         emit Finalized(id, m.outcome, creatorFee, burnFee, treasuryFee);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VerdictMarkets.sol:387:17\n    │\n387 │             if (block.timestamp < m.params.voidAfter) revert OutsideWindow();\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/VerdictMarkets.sol:390:17\n    │\n390 │             if (block.timestamp < m.disputeEnds) revert OutsideWindow();\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/VerdictMarkets.sol:398:9\n    │\n398 │         emit Voided(id);\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/VerdictMarkets.sol:424:9\n    │\n424 │         emit Claimed(id, msg.sender, amount, refund);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VerdictMarkets.sol:438:13\n    │\n438 │         if (block.timestamp < m.params.answerFrom || block.timestamp >= m.params.answerUntil) revert OutsideWindow();\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/VerdictMarkets.sol:438:54\n    │\n438 │         if (block.timestamp < m.params.answerFrom || block.timestamp >= m.params.answerUntil) revert OutsideWindow();\n    │                                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/VerdictMarkets.sol:455:13\n    │\n455 │         if (collateral.balanceOf(address(this)) != beforeBalance - cost) revert InexactOracleSpend();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/VerdictMarkets.sol:468:33\n    │\n468 │         if (m.bountyRemaining > reserve) amount = Math.min(m.settlerReward, m.bountyRemaining - reserve);\n    │                                 ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VerdictMarkets.sol:501:40\n    │\n501 │                 || p.minAgreed == 0 || p.closeAt <= block.timestamp || p.closeAt > p.answerFrom\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/VerdictMarkets.sol:515:53\n    │\n515 │                 if (p.bounds[i] <= p.bounds[i - 1]) revert InvalidParams();\n    │                                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/VerdictMarkets.sol:522:82\n    │\n522 │                 if (p.answerType == 4 && uint256(p.keys[i]) > type(uint160).max) revert InvalidParams();\n    │                                                                                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/VerdictMarkets.sol:524:49\n    │\n524 │                     if (p.keys[i] == p.keys[j]) revert InvalidParams();\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/VerdictMarkets.sol:517:20\n    │\n517 │             return uint8(p.bounds.length + 1);\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/VerdictMarkets.sol:527:20\n    │\n527 │             return uint8(p.keys.length + 1);\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/VerdictMarkets.sol:554:21\n    │\n554 │                 if (first == p.keys[i]) return i;\n    │                     ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/VerdictMarkets.sol:539:20\n    │\n539 │             return uint8(p.bounds.length);\n    │                    ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/VerdictMarkets.sol:557:16\n    │\n557 │         return uint8(p.keys.length);\n    │                ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/IndependentReview.t.sol:17:9\n   │\n17 │         vm.warp(p.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    ‡\n122 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/IndependentReview.t.sol:63:9\n   │\n63 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/IndependentReview.t.sol:78:9\n   │\n78 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/IndependentReview.t.sol:123:9\n    │\n123 │         vm.warp(p.answerUntil - 1);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/IndependentReview.t.sol:123:9\n    │\n123 │         vm.warp(p.answerUntil - 1);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/IndependentReview.t.sol:183:9\n    │\n183 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/IndependentReview.t.sol:198:9\n    │\n198 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/RevisionIndependentReview.t.sol:11:9\n   │\n11 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/RevisionIndependentReview.t.sol:26:9\n   │\n26 │         vm.warp(markets.getMarket(first).params.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionIndependentReview.t.sol:39:9\n    │\n 39 │         vm.warp(block.timestamp + 1 hours);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionIndependentReview.t.sol:39:9\n    │\n 39 │         vm.warp(block.timestamp + 1 hours);\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/RevisionIndependentReview.t.sol:39:17\n   │\n39 │         vm.warp(block.timestamp + 1 hours);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/RevisionIndependentReview.t.sol:51:9\n   │\n51 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/RevisionIndependentReview.t.sol:66:9\n   │\n66 │         vm.warp(p.answerUntil - 1);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/RevisionRegression.t.sol:11:9\n   │\n11 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/RevisionRegression.t.sol:50:9\n   │\n50 │         vm.warp(p.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/RevisionRegression.t.sol:80:9\n   │\n80 │         vm.warp(markets.getMarket(first).params.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:88:9\n    │\n 88 │         vm.warp(block.timestamp + 24 hours);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:88:9\n    │\n 88 │         vm.warp(block.timestamp + 24 hours);\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/RevisionRegression.t.sol:88:17\n   │\n88 │         vm.warp(block.timestamp + 24 hours);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:101:9\n    │\n101 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:106:9\n    │\n106 │         vm.warp(until - 10 minutes);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:106:9\n    │\n106 │         vm.warp(until - 10 minutes);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:125:9\n    │\n125 │         vm.warp(block.timestamp + 1 minutes);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:125:9\n    │\n125 │         vm.warp(block.timestamp + 1 minutes);\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/RevisionRegression.t.sol:125:17\n    │\n125 │         vm.warp(block.timestamp + 1 minutes);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:139:9\n    │\n139 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/RevisionRegression.t.sol:141:17\n    │\n141 │         vm.warp(block.timestamp + 24 hours);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    ‡\n122 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    ‡\n122 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:210:9\n    │\n210 │         vm.warp(p.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:214:9\n    │\n214 │         vm.warp(p.answerUntil - bound(leadSeed, 1, 1 hours - 1));\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionRegression.t.sol:214:9\n    │\n214 │         vm.warp(p.answerUntil - bound(leadSeed, 1, 1 hours - 1));\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/RevisionRegression.t.sol:219:31\n    │\n219 │         assertGe(extendedEnd, block.timestamp + 24 hours);\n    │                               ━━━━━━━━━━━━━━━\n220 │         vm.warp(p.answerUntil + bound(latencySeed, 1, extendedEnd - p.answerUntil - 1));\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/SettlerIndependentReview.t.sol:88:9\n   │\n88 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/SettlerIndependentReview.t.sol:102:9\n    │\n102 │         vm.warp(markets.getMarket(id).disputeEnds);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/SettlerIndependentReview.t.sol:102:9\n    │\n102 │         vm.warp(markets.getMarket(id).disputeEnds);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/SettlerIndependentReview.t.sol:280:9\n    │\n280 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/VerdictSettlerRewards.t.sol:57:9\n   │\n57 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlerRewards.t.sol:124:9\n    │\n124 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/VerdictSettlerRewards.t.sol:128:17\n    │\n128 │         vm.warp(block.timestamp + 24 hours);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlerRewards.t.sol:164:9\n    │\n164 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlerRewards.t.sol:182:9\n    │\n182 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlerRewards.t.sol:211:9\n    │\n211 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlerRewards.t.sol:294:9\n    │\n294 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/SettlerLifecycleProperties.t.sol:42:13\n   │\n42 │             vm.warp(p.answerFrom);\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/SettlerLifecycleProperties.t.sol:46:25\n   │\n46 │                 vm.warp(block.timestamp + 24 hours);\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/SettlerRewardInvariant.t.sol:182:17\n    │\n182 │         vm.warp(block.timestamp + 14 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/SettlerRewardSequence.t.sol:391:17\n    │\n391 │         vm.warp(block.timestamp + 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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictAtomicity.t.sol:65:9\n    │\n 65 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictAtomicity.t.sol:65:9\n    │\n 65 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictAtomicity.t.sol:157:9\n    │\n157 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictAtomicity.t.sol:164:9\n    │\n164 │         vm.warp(block.timestamp + 24 hours);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictAtomicity.t.sol:164:9\n    │\n164 │         vm.warp(block.timestamp + 24 hours);\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/VerdictAtomicity.t.sol:164:17\n    │\n164 │         vm.warp(block.timestamp + 24 hours);\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/VerdictInvariant.t.sol:164:17\n    │\n164 │         vm.warp(block.timestamp + 14 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/VerdictLifecycleInvariant.t.sol:458:17\n    │\n458 │         vm.warp(block.timestamp + 14 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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/VerdictMarkets.t.sol:46:9\n   │\n46 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:90:9\n    │\n 90 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:90:9\n    │\n 90 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:118:9\n    │\n118 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:118:9\n    │\n118 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:121:9\n    │\n121 │         vm.warp(p.voidAfter + 1);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:121:9\n    │\n121 │         vm.warp(p.voidAfter + 1);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:142:9\n    │\n142 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:154:9\n    │\n154 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:182:9\n    │\n182 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/VerdictMarkets.t.sol:184:17\n    │\n184 │         vm.warp(block.timestamp + 24 hours - 1);\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/VerdictMarkets.t.sol:187:17\n    │\n187 │         vm.warp(block.timestamp + 1);\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/VerdictMarkets.t.sol:191:17\n    │\n191 │         vm.warp(block.timestamp + 24 hours);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:203:9\n    │\n203 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:217:9\n    │\n217 │         vm.warp(p.answerUntil);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:239:9\n    │\n239 │         vm.warp(p.answerUntil - 1);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:257:9\n    │\n257 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:257:9\n    │\n257 │         vm.warp(markets.getMarket(id).disputeEnds - 1);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:284:9\n    │\n284 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarkets.t.sol:319:9\n    │\n319 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:174:9\n    │\n174 │         vm.warp(markets.getMarket(id).params.closeAt - 1);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:273:9\n    │\n273 │         vm.warp(p.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:282:9\n    │\n282 │         vm.warp(markets.getMarket(id).params.answerFrom);\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.revertToState`\n    ╭▸ test/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:360:20\n    │\n360 │         assertTrue(vm.revertToState(snapshot));\n    │                    ────────────────────────── `vm.revertToState` 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.revertToState`\n    ╭▸ test/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:360:20\n    │\n360 │         assertTrue(vm.revertToState(snapshot));\n    │                    ────────────────────────── `vm.revertToState` 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.revertToState`\n    ╭▸ test/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:331:20\n    │\n331 │         assertTrue(vm.revertToState(snapshot));\n    │                    ────────────────────────── `vm.revertToState` 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.revertToState`\n    ╭▸ test/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:331:20\n    │\n331 │         assertTrue(vm.revertToState(snapshot));\n    │                    ────────────────────────── `vm.revertToState` 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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictMarketsValidation.t.sol:344:9\n    │\n344 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/VerdictOracle.t.sol:211:17\n    │\n211 │         vm.warp(block.timestamp + 2 days - 1);\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/VerdictOracle.t.sol:238:17\n    │\n238 │         vm.warp(block.timestamp + 1 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/TestBase.sol:61:28\n   │\n61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n   │                            ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/VerdictOutcomes.t.sol:11:9\n   │\n11 │         vm.warp(p.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictOutcomes.t.sol:11:9\n    │\n 11 │         vm.warp(p.answerFrom);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictOutcomes.t.sol:11:9\n    │\n 11 │         vm.warp(p.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictOutcomes.t.sol:130:9\n    │\n130 │         vm.warp(markets.getMarket(id).params.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlementProperties.t.sol:178:9\n    │\n178 │         vm.warp(p.answerFrom);\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/TestBase.sol:61:28\n    │\n 61 │         p.closeAt = uint64(block.timestamp + 1 hours);\n    │                            ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlementProperties.t.sol:195:13\n    │\n195 │             vm.warp(p.answerFrom);\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/TestBase.sol:102:29\n    │\n102 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlementProperties.t.sol:205:13\n    │\n205 │             vm.warp(p.voidAfter);\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/TestBase.sol:103:30\n    │\n103 │         a.expiresAt = uint64(block.timestamp + 7 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/VerdictSettlementProperties.t.sol:205:13\n    │\n205 │             vm.warp(p.voidAfter);\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":36605,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/SettlerDeployment.t.sol:SettlerDeploymentTest\n[PASS] test_launchHandoffPinsV2AndTenConstructorArguments() (gas: 6021796)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 815.85µs (680.71µs CPU time)\n\nRan 6 tests for test/OracleConsumerConformance.t.sol:OracleConsumerConformanceTest\n[PASS] test_acceptsAFreshSignatureFromTheVectorKey() (gas: 199666)\n[PASS] test_acceptsTheProtocolSignatureAsDelivered() (gas: 190502)\n[PASS] test_callbackSelectorIsCanonical() (gas: 4480)\n[PASS] test_digestMatchesTheProtocol() (gas: 13408)\n[PASS] test_domainIsConsumerChainAndVersionTwo() (gas: 15761)\n[PASS] test_structHashMatchesIndependentEncoding() (gas: 251625)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 1.04ms (1.24ms CPU time)\n\nRan 3 tests for test/VerdictImportedAudit.t.sol:VerdictImportedAuditTest\n[PASS] test_creatorCanSetVoidAfterFarInFuture() (gas: 598026)\n[PASS] test_pauseOnlyBlocksEntryAndReleaseReturnsAllUnspentBounty() (gas: 2013101)\n[PASS] test_strangerEscalatesAtNoCostBurnsBountyAndDelays() (gas: 2518937)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 9.30ms (6.91ms CPU time)\n\nRan 10 tests for test/VerdictSettlerRewards.t.sol:VerdictSettlerRewardsTest\n[PASS] test_bountyArithmeticRejectsImpossiblePriceOrRewardWithoutOverflow() (gas: 702894)\n[PASS] test_bountyMinimumChecksBothRequestedAndReceivedAmounts() (gas: 1192716)\n[PASS] test_eachProposalResolveAndFinalizePaysItsCallerOnceEscalatePaysNothing() (gas: 4702670)\n[PASS] test_priceRiseBeforeResolveClipsRewardToExactReserve() (gas: 3210434)\n[PASS] test_proposalUsesCurrentPriceAndPreservesTheLastAsk() (gas: 4308133)\n[PASS] test_retryResolveIsAlsoRewardedOnce() (gas: 3509301)\n[PASS] test_rewardBoundIsInclusiveAndZeroCapDisablesRewards() (gas: 970760)\n[PASS] test_terminalRewardIsClippedToBountyNeverBettorDepositsOrAnotherMarket() (gas: 3238907)\n[PASS] test_voidWithoutAsksPaysBeforeReturningBountyAndNeverTwice() (gas: 1629700)\n[PASS] test_zeroRewardKeepsLegacyBalancesEventsAndNoNewPriceDependency() (gas: 2845832)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 20.61ms (17.14ms CPU time)\n\nRan 5 tests for test/RevisionIndependentReview.t.sol:RevisionIndependentReviewTest\n[PASS] test_documentedUnusableOwnDeliveryStillBlocksRetry() (gas: 1259665)\n[PASS] test_escalationRejectsIssuanceBeforeItsOwnAsk() (gas: 1995674)\n[PASS] test_identicalBodyOtherMarketAnswerCannotSetOutcome() (gas: 1926375)\n[PASS] test_independentSameBodyCannotBlockOwnRetry() (gas: 1725093)\n[PASS] test_primaryLateIssuanceRemainsOutsideBriefsExplicitRange() (gas: 1362737)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 67.08ms (6.54ms CPU time)\n\nRan 7 tests for test/VerdictAtomicity.t.sol:VerdictAtomicityTest\n[PASS] testFuzz_failureAtAnyFinalizeRecipientRollsBackEarlierPayments(uint8,bool) (runs: 64, μ: 2389435, ~: 2387836)\n[PASS] test_failedBountyReturnDoesNotVoidMarketOrPreventLaterRefund() (gas: 1111622)\n[PASS] test_failedCallbackIsNotRefundedButMarketRetryAndSettlementRemainReachable() (gas: 2409792)\n[PASS] test_failedEscalationPaymentCannotExtendOrConsumeDisputeWindow() (gas: 2692212)\n[PASS] test_failedPrimaryPaymentRestoresBountyAskCountTimestampAndAllowances() (gas: 1736994)\n[PASS] test_failedRefundCanBeRetriedAndDoesNotConsumeAnotherUsersClaim() (gas: 1449710)\n[PASS] test_guardBlocksCrossMarketReentryFromAnOtherwiseEligibleClaimant() (gas: 4435937)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 76.61ms (79.23ms CPU time)\n\nRan 3 tests for test/Deployment.t.sol:DeploymentTest\n[PASS] test_burnVaultHasNoCallablePathOrEtherReceiver() (gas: 1013344)\n[PASS] test_exactSepoliaFactoryDeploymentWithoutDependencyCode() (gas: 20775481)\n[PASS] test_rehearsalRefusesOtherChains() (gas: 207095)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 277.86ms (40.15ms CPU time)\n\nRan 12 tests for test/IndependentReview.t.sol:IndependentReviewTest\n[PASS] testFuzzReviewActualTransfersConserveInAnyClaimOrder(uint96,uint96,uint96,uint8) (runs: 512, μ: 2634095, ~: 2634233)\nLogs:\n  Bound result 7418\n  Bound result 28629\n  Bound result 4798\n\n[PASS] testReviewAgreementMinimumCanExceedMinimumPanel() (gas: 1710516)\n[PASS] testReviewDonationDoesNotAlterPayoutOrAccounting() (gas: 1831460)\n[PASS] testReviewEscalationCannotBeFirstProposalEvenWithLargePanel() (gas: 1219037)\n[PASS] testReviewEscalationCannotVoidAfterDeadline() (gas: 2306392)\n[PASS] testReviewFailedTokenTransferRollsBackClaim() (gas: 1964911)\n[PASS] testReviewLateReplacementPastVoidRemainsFinalizable() (gas: 2583202)\n[PASS] testReviewMaximumAnswerColdCallback() (gas: 1266872)\nLogs:\n  maximum answer cold callback gas: 140592\n\n[PASS] testReviewMixedMarketsCannotCrossSubsidizeClaims() (gas: 3244354)\n[PASS] testReviewNoWinnerIsVoidableAfterWindowPastVoidAfter() (gas: 1969951)\n[PASS] testReviewRotationPreservesOldCallerAndKey() (gas: 2309371)\n[PASS] testReviewSameAttestationCannotOverwriteDifferentRequest() (gas: 1427982)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 277.90ms (283.31ms CPU time)\n\nRan 11 tests for test/RevisionRegression.t.sol:RevisionRegressionTest\n[PASS] testFuzz_eitherPaidPrimaryRequestCanProposeButCannotReplace(bool,bool) (runs: 256, μ: 2816840, ~: 2817907)\n[PASS] testFuzz_lateEscalationHasFiniteSettlementDeadline(uint32,uint32,uint32,bool) (runs: 256, μ: 2745143, ~: 2953264)\nLogs:\n  Bound result 13805\n  Bound result 3058\n  Bound result 11867\n\n[PASS] test_escalationCannotUseAnswerIssuedBeforeItsAsk() (gas: 1997270)\n[PASS] test_identicalEscalationBodiesStillRequireEachMarketsOwnPaidAsk() (gas: 5271284)\n[PASS] test_lateEscalationIssuedAfterAnswerUntilSettlesCorrectedOutcome() (gas: 2826337)\n[PASS] test_otherMarketAnswerCannotSetOutcomeOrBlockRetry() (gas: 2624132)\n[PASS] test_oversizeAnswerRefused() (gas: 983076)\n[PASS] test_renounceRequiresAllowlistDisabledEvenWhenEmpty() (gas: 499255)\n[PASS] test_unusableDeliveryBlocksRetry() (gas: 1259765)\n[PASS] test_zeroBoundRejectedWithoutTakingBounty() (gas: 1572363)\n[PASS] test_zeroDelayAcceptsConfigInSameBlock() (gas: 271514)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 289.65ms (478.69ms CPU time)\n\nRan 10 tests for test/SettlerIndependentReview.t.sol:SettlerIndependentReviewTest\n[PASS] testFuzz_rewardRecipientsMayAlsoBeCreatorWinnerOrTreasury(uint8) (runs: 512, μ: 2257590, ~: 2253409)\n[PASS] testFuzz_rewardReserveUsesPriceAfterPaidAsk(uint256) (runs: 512, μ: 1342172, ~: 1346161)\nLogs:\n  Bound result 42274329284083149\n\n[PASS] test_creatorReturnFailureRevertsFinalizeIncludingEarlierReward() (gas: 2502155)\n[PASS] test_creatorReturnFailureRevertsVoidIncludingEarlierReward() (gas: 1252693)\n[PASS] test_failedProposalRewardLeavesStoredAnswerUsableAndPaysOnceOnRetry() (gas: 1842699)\n[PASS] test_finalizeRewardCallbackSeesCompleteAccountingAndCannotReenter() (gas: 3385133)\n[PASS] test_maximumPriceAfterPaidAskSuppressesRewardWithoutReverting() (gas: 1297383)\n[PASS] test_positiveTerminalRewardsDoNotDependOnAWorkingOraclePrice() (gas: 2803780)\n[PASS] test_rewardFailureRollsBackTheWholePaidAskAndAllowsRetry() (gas: 2014297)\n[PASS] test_voidRewardCallbackSeesCompleteAccountingAndCannotReenter() (gas: 2049715)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 289.63ms (345.83ms CPU time)\n\nRan 15 tests for test/VerdictMarketsValidation.t.sol:VerdictMarketsValidationTest\n[PASS] test_allowlistRemovalAndPermanentDisable() (gas: 1291458)\n[PASS] test_attestationMustMatchEveryMarketFieldAndPanelRequirements() (gas: 5154664)\n[PASS] test_betZeroUnknownOutcomeAndCloseBoundary() (gas: 716041)\n[PASS] test_bodyHashAndBodySizeValidation() (gas: 729322)\n[PASS] test_bountyMustCoverTwoAsksAfterTransferFee() (gas: 236534)\n[PASS] test_creationEmitsBothFullBodies() (gas: 385237)\n[PASS] test_escalationRequiresDoubleCurrentPanelAndCorrectBody() (gas: 2820430)\n[PASS] test_feeCapAndPoolCapConstructor() (gas: 15618)\n[PASS] test_feeOnTransferCreditsOnlyActualBountyAndStakes() (gas: 1209845)\n[PASS] test_firstProposalAtVoidDeadlineCannotResurrectMarket() (gas: 1378732)\n[PASS] test_guardianHandoverIsTwoStepAndNoUnauthorizedPowers() (gas: 370410)\n[PASS] test_invalidTimesPanelsAndTypes() (gas: 614692)\n[PASS] test_minAgreedCanRequireMoreThanMinimumPanelSize() (gas: 1237856)\n[PASS] test_pauseBlocksOnlyEntryAndRenounceRequiresUnpaused() (gas: 3328792)\n[PASS] test_poolCapUsesReceivedBalanceAndFailedBetIsAtomic() (gas: 825795)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 298.21ms (13.60ms CPU time)\n\nRan 17 tests for test/VerdictOracle.t.sol:VerdictOracleTest\n[PASS] test_bodyLimitsAndExactPaymentRequired() (gas: 586164)\n[PASS] test_configDelayCapAndInvalidConfiguration() (gas: 9288)\n[PASS] test_consumedIntakeIdAndOracleIdCannotBeStoredTwice() (gas: 970867)\n[PASS] test_deliveredAnswerRemainsReadableAfterExpiry() (gas: 524115)\n[PASS] test_expiredFutureMalformedAndTamperedRejected() (gas: 766529)\n[PASS] test_falseAnswerStoredUnder150kGas() (gas: 575739)\nLogs:\n  cold callback gas: 126024\n\n[PASS] test_intakeAndSignerRotationPreservesInflightRequest() (gas: 2174415)\n[PASS] test_maxAnswerUnder150kGas() (gas: 610144)\nLogs:\n  maximum answer cold callback gas: 140592\n\n[PASS] test_replacingConfigProposalRestartsDelay() (gas: 283461)\n[PASS] test_requestPaysExactlyAndPinsConfiguration() (gas: 403481)\n[PASS] test_requestReentrancyFails() (gas: 486117)\n[PASS] test_reusedIntakeRequestIdRollsBackPayment() (gas: 545892)\n[PASS] test_timelockAndOwnable2Step() (gas: 558572)\n[PASS] test_wrongChainDomainStoresNothing() (gas: 417798)\n[PASS] test_wrongConsumerDomainStoresNothing() (gas: 422685)\n[PASS] test_wrongIntakeAndUnknownIdStoreNothing() (gas: 454227)\n[PASS] test_wrongSignerStoresNothingAndNoRefund() (gas: 522092)\nSuite result: ok. 17 passed; 0 failed; 0 skipped; finished in 299.48ms (10.16ms CPU time)\n\nRan 20 tests for test/VerdictMarkets.t.sol:VerdictMarketsTest\n[PASS] testFuzz_terminalConservation(uint96,uint96,uint96,uint8,bool) (runs: 512, μ: 1911626, ~: 2219068)\nLogs:\n  Bound result 120634706\n  Bound result 82887485308467\n  Bound result 1477\n\n[PASS] test_asksBeforeAnswerFromAndAtOrAfterAnswerUntilRevert() (gas: 562520)\n[PASS] test_assetRotationBlocksAsksButNotRefunds() (gas: 2120548)\n[PASS] test_emptyWinningBucketCannotVoidUntilDisputeEnds() (gas: 1809113)\n[PASS] test_escalationAnswerCannotBeFirstProposal() (gas: 1219454)\n[PASS] test_escalationAskAtAnswerUntilRevertsEvenInsideDisputeWindow() (gas: 1281214)\n[PASS] test_externalSponsorCannotDeliverPrimaryOrEscalation() (gas: 3880222)\n[PASS] test_fullSettlementPaysWholePoolFeesAndExactRemainder() (gas: 2399157)\n[PASS] test_lateEscalationBeyondVoidAfterStillFinalizesWithoutAnswer() (gas: 2498343)\n[PASS] test_lateEscalationReplacementRestartsWindowOnceAndFinalizes() (gas: 2834558)\n[PASS] test_noEscalationBodyAndDuplicateEscalationAsk() (gas: 2703033)\n[PASS] test_priceIncreaseCannotSpendBettorsCollateral() (gas: 2271746)\n[PASS] test_primaryRetryBlockedAfterDeliveryEvenWithoutProposal() (gas: 1191860)\n[PASS] test_proposeAfterAnswerUntilWithTimelyStoredAnswer() (gas: 1473367)\n[PASS] test_provisionalWindowBoundariesAreStrict() (gas: 2322634)\n[PASS] test_secondPrimaryAskAfter24HoursAndMaximumTwoAsks() (gas: 1809739)\n[PASS] test_tokenReentrancyBlockedOnDepositAndClaim() (gas: 2163480)\n[PASS] test_voidNoAnswerRefundsEveryOutcomeAndUnspentBounty() (gas: 1758828)\n[PASS] test_wrongBodiesAndResolveAfterProposalRevertWithoutSpend() (gas: 1517332)\n[PASS] test_zeroAndUnknownClaimsAndUnfinishedClaimsRevert() (gas: 692952)\nSuite result: ok. 20 passed; 0 failed; 0 skipped; finished in 299.42ms (314.54ms CPU time)\n\nRan 7 tests for test/VerdictOutcomes.t.sol:VerdictOutcomesTest\n[PASS] testFuzz_uintBucketDefinition(uint256) (runs: 512, μ: 1341513, ~: 1341591)\n[PASS] test_addressListUsesFirstElementOnlyAndCanonicalAddressKey() (gas: 4875179)\n[PASS] test_booleanOutcomes() (gas: 2310147)\n[PASS] test_bytes32ListUsesFirstElementOnlyAndEmptyMeansNone() (gas: 6010921)\n[PASS] test_malformedEncodedAnswerCannotSetOutcome() (gas: 1291065)\n[PASS] test_numericBucketsIncludeLowerBoundaryExcludeUpper() (gas: 7221103)\n[PASS] test_twoToEightOutcomesAndSortedUniqueDefinitions() (gas: 1791330)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 299.70ms (309.08ms CPU time)\n\nRan 6 tests for test/VerdictOracleAdversarial.t.sol:VerdictOracleAdversarialTest\n[PASS] testFuzz_rotationsKeepFourInflightSnapshotsInAnyDeliveryOrder(uint256) (runs: 256, μ: 5459977, ~: 5459977)\n[PASS] test_contractSignerIsPinnedAndRevokedSignatureStoresNothing() (gas: 1500728)\n[PASS] test_everyAttestationFieldIsBoundBySignatureAndStoredHash() (gas: 2610090)\n[PASS] test_expiryAndClockToleranceAreInclusiveAtExactBoundary() (gas: 977218)\n[PASS] test_nonCanonicalAndTruncatedSignaturesCannotConsumePendingRequest() (gas: 829160)\n[PASS] test_pendingOwnerCannotAcceptConfigurationAndFormerOwnerLosesAccess() (gas: 434003)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 299.79ms (305.74ms CPU time)\n\nRan 7 tests for test/SettlerBountyBoundaries.t.sol:SettlerBountyBoundariesTest\n[PASS] testFuzz_exactMinimumAndOneWeiShortAcrossUint256(uint256,uint256) (runs: 1000, μ: 1384782, ~: 1387522)\nLogs:\n  Bound result 5033\n  Bound result 300\n\n[PASS] testFuzz_transferTaxAcceptsExactReceivedMinimumAndRejectsOneWeiLess(uint96,uint16) (runs: 1000, μ: 1252132, ~: 1254284)\nLogs:\n  Bound result 189703513933094487\n  Bound result 25\n\n[PASS] testFuzz_unrepresentableMinimumRevertsBeforeTokenTransfer(uint256,uint256) (runs: 1000, μ: 358551, ~: 358531)\nLogs:\n  Bound result 5033\n  Bound result 92633671389852956338856788006950326282615987732512451231566067206330503714262\n\n[PASS] test_entireUint256SupplyCanBeReturnedWithoutDust() (gas: 1115224)\n[PASS] test_maximumPriceWithRepresentableBountyAndZeroReward() (gas: 1291700)\n[PASS] test_maximumRepresentableRewardBudget() (gas: 1382126)\n[PASS] test_oneWeiPriceAndOneWeiReward() (gas: 1380172)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 299.87ms (776.54ms CPU time)\n\nRan 1 test for test/SettlerLifecycleProperties.t.sol:SettlerLifecyclePropertiesTest\n[PASS] testFuzz_allLifecyclePathsConserveActualTransfers(uint96,uint96,uint96,uint96,uint8,uint64,bool) (runs: 512, μ: 3460148, ~: 3433143)\nLogs:\n  Bound result 14042\n  Bound result 14554\n  Bound result 8913\n  Bound result 2741\n  Bound result 60\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 299.87ms (297.81ms CPU time)\n\nRan 7 tests for test/VerdictSettlementProperties.t.sol:VerdictSettlementPropertiesTest\n[PASS] testFuzz_feeSplitsAndRationalPayoutBoundsInEveryClaimOrder(uint256,uint16,uint16,uint16,uint8) (runs: 1000, μ: 2966412, ~: 2971260)\nLogs:\n  Bound result 478\n  Bound result 14\n  Bound result 3\n  Bound result 29168612340377699232\n  Bound result 57659397013856620997\n  Bound result 84754178140929853138\n  Bound result 15750\n\n[PASS] testFuzz_numericOutcomeSatisfiesItsHalfOpenInterval(uint128,uint96,uint256,uint8) (runs: 1000, μ: 1385920, ~: 1378707)\nLogs:\n  Bound result 2\n  Bound result 4319\n  Bound result 48096\n\n[PASS] test_malformedListsCannotChangeAnAuthenticatedMarketsOutcome() (gas: 2908506)\n[PASS] test_oneWeiLastWinnerReceivesTheRoundingRemainder() (gas: 2279339)\n[PASS] test_oneWeiWinnerMayRoundToZeroButLastClaimStillDrainsExactly() (gas: 2577622)\n[PASS] test_payoutUsesFullPrecisionWhenIntermediateStakeTimesPoolOverflows256Bits() (gas: 2534215)\n[PASS] test_settlementEventsDescribeWholePoolFeesAndUnspentBounty() (gas: 1989237)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 299.88ms (555.10ms CPU time)\n\nRan 1 test for test/VerdictInvariant.t.sol:VerdictInvariantTest\n[PASS] invariant_actualTokensMatchEveryMarketsAccounting() (runs: 128, calls: 8192, reverts: 0)\n\n╭----------------+----------------+-------+---------+----------╮\n| Contract       | Selector       | Calls | Reverts | Discards |\n+==============================================================+\n| VerdictHandler | advance        | 778   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | ask            | 821   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | askEscalation  | 848   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | collect        | 850   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | deliverPrimary | 761   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | enter          | 824   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | proposePrimary | 810   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | replaceOutcome | 820   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | settle         | 873   | 0       | 0        |\n|----------------+----------------+-------+---------+----------|\n| VerdictHandler | togglePause    | 807   | 0       | 0        |\n╰----------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 9702\n  Bound result 17276\n  Bound result 33\n  Bound result 2500\n  Bound result 14930\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.00s (2.00s CPU time)\n\nRan 1 test for test/SettlerRewardInvariant.t.sol:SettlerRewardInvariantTest\n[PASS] invariant_actualTokensMatchEveryMarketsAccounting() (runs: 128, calls: 8192, reverts: 0)\n\n╭----------------------+----------------+-------+---------+----------╮\n| Contract             | Selector       | Calls | Reverts | Discards |\n+====================================================================+\n| SettlerRewardHandler | advance        | 701   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | ask            | 787   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | askEscalation  | 772   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | changePrice    | 732   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | collect        | 742   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | deliverPrimary | 717   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | enter          | 764   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | proposePrimary | 771   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | replaceOutcome | 737   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | settle         | 706   | 0       | 0        |\n|----------------------+----------------+-------+---------+----------|\n| SettlerRewardHandler | togglePause    | 763   | 0       | 0        |\n╰----------------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 13217\n  Bound result 3692618744\n  Bound result 416\n  Bound result 21589\n  Bound result 17302\n  Bound result 49152\n  Bound result 658\n  Bound result 10670\n  Bound result 3600\n  Bound result 16431\n  Bound result 4399\n  Bound result 21554\n  Bound result 10062\n  Bound result 374686479671623681\n  Bound result 21600\n  Bound result 276882209348464009\n  Bound result 983\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.14s (2.14s CPU time)\n\nRan 2 tests for test/SettlerRewardSequence.t.sol:SettlerRewardSequenceTest\n[PASS] invariant_rewardsAreMaximalAndEscrowIsConserved() (runs: 256, calls: 20480, reverts: 0)\n\n╭------------------------------+---------------+-------+---------+----------╮\n| Contract                     | Selector      | Calls | Reverts | Discards |\n+===========================================================================+\n| SettlerRewardSequenceHandler | advance       | 1565  | 0       | 0        |\n|------------------------------+---------------+-------+---------+----------|\n| SettlerRewardSequenceHandler | changePrice   | 1527  | 0       | 0        |\n|------------------------------+---------------+-------+---------+----------|\n| SettlerRewardSequenceHandler | collect       | 1582  | 0       | 0        |\n|------------------------------+---------------+-------+---------+----------|\n| SettlerRewardSequenceHandler | deliverAnswer | 1560  | 0       | 0        |\n|------------------------------+---------------+-------+---------+----------|\n| SettlerRewardSequenceHandler | donate        | 1602  | 0       | 0        |\n|------------------------------+---------------+-------+---------+----------|\n| SettlerRewardSequenceHandler | escalate      | 1535  | 0       | 0        |\n|------------------------------+---------------+-------+---------+----------|\n| SettlerRewardSequenceHandler | openMarket    | 1629  | 0       | 0        |\n|------------------------------+---------------+-------+---------+----------|\n| SettlerRewardSequenceHandler | pauseEntry    | 1577  | 0       | 0        |\n|------------------------------+---------------+-------+---------+----------|\n| SettlerRewardSequenceHandler | probeRejected | 1634  | 0       | 0        |\n|------------------------------+---------------+-------+---------+----------|\n| SettlerRewardSequenceHandler | propose       | 1560  | 0       | 0        |\n|------------------------------+---------------+-------+---------+----------|\n| SettlerRewardSequenceHandler | resolve       | 1536  | 0       | 0        |\n|------------------------------+---------------+-------+---------+----------|\n| SettlerRewardSequenceHandler | settle        | 1535  | 0       | 0        |\n|------------------------------+---------------+-------+---------+----------|\n| SettlerRewardSequenceHandler | wager         | 1638  | 0       | 0        |\n╰------------------------------+---------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 0\n  Bound result 1\n  Bound result 0\n  Bound result 250000000000000000\n  Bound result 0\n  Bound result 100000000000000000\n  Bound result 500000000000000000\n  Bound result 31000000000000000001\n  Bound result 37000000000000000003\n  Bound result 41000000000000000007\n  Bound result 31000000000000000001\n  Bound result 37000000000000000003\n  Bound result 41000000000000000007\n  Bound result 31000000000000000001\n  Bound result 37000000000000000003\n  Bound result 41000000000000000007\n  Bound result 43000000000000000011\n  Bound result 301\n  Bound result 2661\n  Bound result 10921\n  Bound result 600\n  Bound result 6638\n  Bound result 32126\n  Bound result 201428292505659153\n  Bound result 5746\n  Bound result 4288775753\n  Bound result 264337593543950334\n  Bound result 244\n  Bound result 3000000000000000000\n  Bound result 283019655932542976\n  Bound result 9974\n  Bound result 215\n  Bound result 2592000\n  Bound result 50\n  Bound result 102849004506457660\n  Bound result 45641\n  Bound result 6\n  Bound result 10\n  Bound result 259200\n  Bound result 11090\n  Bound result 22000000000000000000\n  Bound result 600\n  Bound result 752568001502916704\n  Bound result 30164\n  Bound result 8074\n  Bound result 23769\n  Bound result 7850\n\n[PASS] test_handlerReachesRetryReplacementClippingAndBothTerminalPaths() (gas: 16898614)\nLogs:\n  Bound result 0\n  Bound result 0\n  Bound result 1\n  Bound result 0\n  Bound result 250000000000000000\n  Bound result 0\n  Bound result 100000000000000000\n  Bound result 500000000000000000\n  Bound result 31000000000000000001\n  Bound result 37000000000000000003\n  Bound result 41000000000000000007\n  Bound result 31000000000000000001\n  Bound result 37000000000000000003\n  Bound result 41000000000000000007\n  Bound result 31000000000000000001\n  Bound result 37000000000000000003\n  Bound result 41000000000000000007\n  Bound result 43000000000000000011\n  Bound result 3600\n  Bound result 1400000000000000000\n  Bound result 500000000000000000\n  Bound result 43200\n  Bound result 43200\n  Bound result 17\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 10.24s (10.25s CPU time)\n\nRan 4 tests for test/VerdictLifecycleInvariant.t.sol:VerdictLifecycleInvariantTest\n[PASS] invariant_tokensStakesAndFinalityMatchIndependentLedger() (runs: 256, calls: 16384, reverts: 0)\n\n╭-------------------------+------------------------+-------+---------+----------╮\n| Contract                | Selector               | Calls | Reverts | Discards |\n+===============================================================================+\n| VerdictLifecycleHandler | advance                | 1251  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | askEscalation          | 1252  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | askPrimary             | 1242  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | collect                | 1233  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | deliverAnswer          | 1238  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | donate                 | 1248  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | openMarket             | 1223  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | probeBurn              | 1248  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | probeIndependentAnswer | 1296  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | probeTerminal          | 1285  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | settle                 | 1267  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | togglePause            | 1335  | 0       | 0        |\n|-------------------------+------------------------+-------+---------+----------|\n| VerdictLifecycleHandler | wager                  | 1266  | 0       | 0        |\n╰-------------------------+------------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 5600\n  Bound result 838\n  Bound result 21045\n  Bound result 307\n\n[PASS] test_handlerIndependentAnswersCannotBlockRetryOrShopOutcomes() (gas: 10123579)\nLogs:\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 21600\n  Bound result 21600\n  Bound result 21600\n  Bound result 21600\n\n[PASS] test_handlerReachesPrimaryEscalationFailureFinalizeAndRefundPaths() (gas: 16451019)\nLogs:\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 31\n  Bound result 17\n  Bound result 11\n\n[PASS] test_handlerUsesActualLateEscalationIssuanceAndStillDrains() (gas: 9734939)\nLogs:\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n  Bound result 0\n  Bound result 101\n  Bound result 202\n  Bound result 307\n\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 36.49s (36.54s CPU time)\n\nRan 22 test suites in 36.49s (54.58s CPU time): 156 tests passed, 0 failed, 0 skipped (156 total tests)\n","passed":true},{"durationMs":66,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"VerdictMarkets.acceptGuardian()\",\"VerdictMarkets.bet(uint256,uint8,uint256,uint256)\",\"VerdictMarkets.claim(uint256)\",\"VerdictMarkets.createMarket((bytes32,uint8,uint256,uint64,uint64,uint16,uint16,uint64,uint64,uint64,uint32,uint64,uint256[],bytes32[],uint256,uint256),bytes,bytes,string,uint256)\",\"VerdictMarkets.disableAllowlist()\",\"VerdictMarkets.escalate(uint256,bytes)\",\"VerdictMarkets.finalize(uint256)\",\"VerdictMarkets.pause()\",\"VerdictMarkets.propose(uint256,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64))\",\"VerdictMarkets.renounceGuardian()\",\"VerdictMarkets.resolve(uint256,bytes)\",\"VerdictMarkets.setCreatorAllowed(address,bool)\",\"VerdictMarkets.transferGuardian(address)\",\"VerdictMarkets.unpause()\",\"VerdictMarkets.voidMarket(uint256)\",\"VerdictOracle.acceptConfig()\",\"VerdictOracle.acceptOwnership()\",\"VerdictOracle.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"VerdictOracle.proposeConfig((address,address,address,bytes32,uint256))\",\"VerdictOracle.renounceOwnership()\",\"VerdictOracle.request(bytes)\",\"VerdictOracle.transferOwnership(address)\"],\"files\":{\".gitignore\":4,\"ADAPTATION.md\":74,\"DEPENDENCIES.md\":14,\"DESIGN.md\":95,\"LICENSE\":21,\"README.md\":167,\"dist/assets/chain-BQwdJvnv.js\":45,\"dist/assets/index-BbSaev33.css\":1,\"dist/assets/index-ByzN5mJO.js\":1,\"dist/assets/react-DbQ9GvLb.js\":49,\"dist/favicon.svg\":1,\"dist/fonts/archivo-OFL.txt\":93,\"dist/fonts/archivo-expanded-800.woff2\":65,\"dist/fonts/ibm-plex-mono-400.woff2\":58,\"dist/fonts/ibm-plex-mono-500.woff2\":62,\"dist/fonts/ibm-plex-mono-OFL.txt\":93,\"dist/index.html\":6,\"dist/social.png\":106,\"docs/BETTER_INTERFACE_LICENSE.txt\":220,\"docs/DEPLOYMENT.md\":61,\"docs/INDEPENDENT_REVIEW.md\":67,\"docs/REVISION_REVIEW.md\":41,\"docs/SETTLER_INDEPENDENT_REVIEW.md\":79,\"docs/VERIFICATION.md\":41,\"docs/WEBSITE_VALIDATION.md\":131,\"foundry.toml\":23,\"remappings.txt\":2,\"script/SepoliaParameters.sol\":27,\"src/OracleAttestation.sol\":221,\"src/VerdictBurnVault.sol\":5,\"src/VerdictMarkets.sol\":559,\"src/VerdictOracle.sol\":178,\"src/interfaces/IIntake.sol\":14,\"src/interfaces/IVerdictOracle.sol\":14,\"test/Deployment.t.sol\":102,\"test/IndependentReview.t.sol\":239,\"test/OracleConsumerConformance.t.sol\":162,\"test/RevisionIndependentReview.t.sol\":77,\"test/RevisionRegression.t.sol\":245,\"test/SETTLER_TEST_REVIEW.md\":95,\"test/SettlerBountyBoundaries.t.sol\":154,\"test/SettlerDeployment.t.sol\":58,\"test/SettlerIndependentReview.t.sol\":353,\"test/SettlerLifecycleProperties.t.sol\":118,\"test/SettlerRewardInvariant.t.sol\":249,\"test/SettlerRewardSequence.t.sol\":481,\"test/TESTING.md\":87,\"test/TestBase.sol\":136,\"test/VerdictAtomicity.t.sol\":214,\"test/VerdictImportedAudit.t.sol\":61,\"test/VerdictInvariant.t.sol\":213,\"test/VerdictLifecycleInvariant.t.sol\":580,\"test/VerdictMarkets.t.sol\":383,\"test/VerdictMarketsValidation.t.sol\":368,\"test/VerdictOracle.t.sol\":288,\"test/VerdictOracleAdversarial.t.sol\":228,\"test/VerdictOutcomes.t.sol\":148,\"test/VerdictSettlementProperties.t.sol\":228,\"test/VerdictSettlerRewards.t.sol\":310,\"test/mocks/MockIMD.sol\":42,\"test/mocks/MockIntake.sol\":62,\"web/index.html\":2,\"web/package-lock.json\":2003,\"web/package.json\":35,\"web/public/favicon.svg\":1,\"web/public/fonts/archivo-OFL.txt\":93,\"web/public/fonts/archivo-expanded-800.woff2\":65,\"web/public/fonts/ibm-plex-mono-400.woff2\":58,\"web/public/fonts/ibm-plex-mono-500.woff2\":62,\"web/public/fonts/ibm-plex-mono-OFL.txt\":93,\"web/public/social.png\":106,\"web/scripts/browser-check.mjs\":414,\"web/scripts/check-export.mjs\":51,\"web/scripts/isolated.mjs\":108,\"web/scripts/revision-cases.mjs\":179,\"web/scripts/verify-contracts.mjs\":120,\"web/scripts/wallet-check.mjs\":784,\"web/src/App.tsx\":740,\"web/src/CreatePage.tsx\":575,\"web/src/MarketPage.tsx\":884,\"web/src/Portfolio.tsx\":224,\"web/src/abi/VerdictBurnVault.json\":1,\"web/src/abi/VerdictMarkets.json\":1,\"web/src/abi/VerdictOracle.json\":1,\"web/src/abi/provenance.json\":10,\"web/src/chain.ts\":377,\"web/src/components.tsx\":358,\"web/src/config.ts\":75,\"web/src/create.ts\":222,\"web/src/domain.ts\":326,\"web/src/main.tsx\":32,\"web/src/store.tsx\":103,\"web/src/styles.css\":2288,\"web/src/types.ts\":126,\"web/src/wallet.tsx\":385,\"web/tests/chain-fixture.json\":454,\"web/tests/domain.test.ts\":328,\"web/tests/wallet-rpc-fixture.json\":636,\"web/tsconfig.json\":17,\"web/validation/browser-results.json\":193,\"web/validation/contract-verification.json\":25,\"web/validation/export-integrity.json\":80,\"web/validation/revision-before.json\":79,\"web/validation/revision-results.json\":181,\"web/validation/wallet-results.json\":76,\"web/vite.config.ts\":37},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"cad7286f97c623aeea5dc062faa6b79e49847fba831b88f562628738463e8b2b","verifiedTreeHash":"0fc9817c3838dfbcfc583da1f7ef8e80a5f57514","verifierVersion":"0.1.0+0e08a464"}]}