{"assessments":[],"deployments":[{"attestationHash":"eec0ed02d6e6ddf904814c60517760335387dd420e3ea01eaece93c32239e55f","chainId":1,"contracts":[{"address":"0x37f5e695c1860ff8aec4bf52842020d31699e2eb","blockNumber":26386921,"name":"Judge","role":"other","txHash":"0x023fb3f58ca32c6b7d25aaeb6d4eaef5dae6b39adfb263b0084a5302d88b7d90"},{"address":"0xe5a08fa59e9b070bde8b303e5dc344937c201bab","blockNumber":26386921,"name":"JudgeEthDoor","role":"other","txHash":"0x023fb3f58ca32c6b7d25aaeb6d4eaef5dae6b39adfb263b0084a5302d88b7d90"}],"id":"0e227d3a-40e5-4692-b168-ed24b1ec2525","manifestHash":"98bb73cd29cab21bb3c83a7fdccd46dbd1f0dbaaac5bf44f856c4bb853792f2e","status":"live"}],"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":"d60032fc-9747-4900-9884-4e0614187089","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"7b023e50ce8ee126db7e1eb7ee5c38408b6c63cfab77c13ca8efdb5b91cb2e11","dependsOn":["audit_imported_code"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"15128eeb8da9fb5ec13c7964e80f936ddc40e718cc0d455d200435c3dc43d6a7","skillId":"adapt-contract-project","tools":[]},"key":"adapt_contract_project","kind":"code","role":"implement","skillHash":"15128eeb8da9fb5ec13c7964e80f936ddc40e718cc0d455d200435c3dc43d6a7","skillId":"adapt-contract-project","state":"accepted"},{"acceptedSubmissionHash":"fa0e99653e51e0d0641f98d377575201faaa1b2e0782ccde6bf9771f94fe9f9d","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","subagents":3,"tools":[]},"key":"audit_economics","kind":"code","role":"review","skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"f859899e65254ff4be7d3801b4be426ad8c21c05c7742435794ac15b8fc1c729","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","subagents":3,"tools":[]},"key":"audit_flow","kind":"code","role":"review","skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"ffbf15250e83dbf5416ad8f36c93b691df405fb1757e1269e6a55f22e5ebf0e1","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"b72293c3366fff3f0b93151bca72cc6cbd189dad31d1ccd1d34dd483f2165a36","skillId":"audit-imported-code","subagents":4,"tools":[]},"key":"audit_imported_code","kind":"code","role":"review","skillHash":"b72293c3366fff3f0b93151bca72cc6cbd189dad31d1ccd1d34dd483f2165a36","skillId":"audit-imported-code","state":"accepted"},{"acceptedSubmissionHash":"92ce670ced8336a9acef5fcad267db31178b8584f1973cbd933309392258187a","dependsOn":["adapt_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"b89279670f5a00f5d26286edee00c97dd158b997031350a01cafe6e0329ad227","skillId":"audit-judge","subagents":4,"tools":[]},"key":"audit_judge","kind":"code","role":"review","skillHash":"b89279670f5a00f5d26286edee00c97dd158b997031350a01cafe6e0329ad227","skillId":"audit-judge","state":"accepted"},{"acceptedSubmissionHash":"3f04af58c3bf494953b060622c9a062a8cc63691c00227c855f4a89d98086b7a","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","subagents":3,"tools":[]},"key":"audit_math","kind":"code","role":"review","skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"b17c2b513b7a4774b09d921ee7e6f26a63c32bae69fe560c9ff121d54ea5327b","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","subagents":3,"tools":[]},"key":"audit_permissions","kind":"code","role":"review","skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"60673ca3dd40b54f97e740af62dafd709b6f17d600e77749cbe6ab362b10c98a","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"6fdf53dea2cd4790031fdbb47e27ec292c3f586041aeeb3eb67e42d703621212","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"1ddb4d02eb75e52d5f38cfd5c9bb54f332687b81929c68880cf1e8a6ab27254d","skillId":"write-foundry-tests","subagents":4,"tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"1ddb4d02eb75e52d5f38cfd5c9bb54f332687b81929c68880cf1e8a6ab27254d","skillId":"write-foundry-tests","state":"accepted"}],"objective":"Launch the two finished contracts in this repository on Ethereum. No token, no website, no owner. They are already written and tested, so review them and deploy them as they are.\n\nDeploy these two, in this order, and nothing else:\n\n1. Judge (src/Judge.sol)\noracleSigner_: 0x5598aa9146215bc13eb26f2c692ad1461fd32982\nintake_: 0xa43e6f75ee006411f79ac1c84120606c2330de82\nasset_: 0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7\npanelSize_: 100\nquorum_: 51\n\n2. JudgeEthDoor (src/JudgeEthDoor.sol)\njudge_: $contract:Judge\nasset_: 0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7\npoolManager_: 0x000000000004444c5dc75cb358380d2e3de08a90\npoolFee_: 10000\npoolTickSpacing_: 200\n\nsrc/Judged.sol, src/JudgedTest.sol and src/examples are not deployed, because other people inherit them in their own contracts. Review src/Judged.sol anyway, since other people's money will sit behind it, and report what you find.\n\nKeep both contracts exactly as they are unless a review finds a critical or high problem. If it does, fix only that, add a test, and say so plainly. In particular, don't change Judge's question wording (its INSTRUCTIONS string and the question function), any function signature or event, or the constructor arguments. Other contracts and the site depend on them, and the wording is what real panels are tested against. Don't add an owner, a setter, an upgrade path, a proxy or a fee. Having none of those is the point of these contracts.\n\nUnit tests: forge test --no-match-path \"test/fork/*\"\n\nReport both deployed addresses, and say whether the deployed bytecode matches this repository at the commit you started from.","parentJobId":null,"planHash":"6c98f969b6bdc6b751d246cefa88f96849ecd8345c8b13a0ff491e00cabbe0d0","previousHash":"b12eaecba4830900df198b2a1232a7a1bf748e60d0c69d3d0f394fa9788092b2","projectId":"d60032fc-9747-4900-9884-4e0614187089","publication":{"commit":"ebedc459d4fa354c29e8d0a996cbe22d612804d3","deliveredAt":"2026-11-10T20:31:12.122Z","repoUrl":"https://github.com/identity-md-launches/launch-3187-launch-two-finished-contracts"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[],"site":null,"snapshotHash":"8ab132fc1ede00f122bcd638eeb6e05f521cef4d1f6dbb1fee7a3bea15ca32ab","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"fdbedee33322a6ef","findings":[],"hash":"3f04af58c3bf494953b060622c9a062a8cc63691c00227c855f4a89d98086b7a","nodeId":"a28c08f7-b93b-43f7-9578-250c54b66d0f","outcome":"completed","summary":"I found no defects in the math of `Judge`, `JudgeEthDoor` or `Judged`, so `.imd-findings.json` has an empty findings list plus one coverage row for each of the 14 entry points (all \"holds\"). This was a review only: I deployed nothing, so I have no deployed addresses and no bytecode comparison to report. That step still needs to run, from the commit this started at (`0f0b3c1`).\n\n**Checks:** all 111 unit tests pass (`forge test --no-match-path \"test/fork/*\"`). Live reads on Ethereum confirmed the setup the constructor arguments assume:\n- The ETH/IMD pool with fee 10000, tick spacing 200 and no hooks exists.\n- The Intake's price for the action is 0.5 IMD, and the asset's symbol is IMD.\n- The oracle signer address is a plain wallet, not a contract.\n\n**What I checked in my area:**\n- **`Judge`, the one-day window:** the deadline check and `verdict()` use the same strict comparison. One second before the day ends the case is still open and an answer is taken. One second after, it reads `NoAnswer` and a late answer is refused, so `NoAnswer` can never turn into `Yes`.\n- **`Judge`, panel size:** the oracle caps a panel at 100 seats. Requiring at least 100 seats, a quorum of at least 51 and `agreed >= quorum` therefore always means a true majority.\n- **`Judge`, question text:** the block numbers are far below the largest number JSON can carry exactly. Control characters become spaces, so only quotes and backslashes get escaped. Trimming the final `}` from the question to build the request is safe because it always ends in one.\n- **`JudgeEthDoor`:** a positive swap amount buys exactly the price in Uniswap v4, and anything other than exactly the price reverts. The ETH spent is checked against the ETH attached, so the refund can't go below zero and returns exactly what wasn't spent. The door has no `receive`, so no stray ETH can mix in.\n- **`Judged`:**\n  - The change sent back is at most the budget, so the inheriting contract's own money is never spent.\n  - The guard on block, sender and value stops a payable multicall or a second ask in one transaction from reusing `msg.value`.\n  - The verdict numbers match `Judge`'s, and each answer runs its hook only once.\n- **The examples:** `JudgeDare`'s stake and refund sums can't go below zero, and its two-day reclaim leaves a late winner at least a day to collect.\n\n**Worth knowing, but none of these is a defect:**\n- On Ethereum, `_judge()` in `Judged` only knows Sepolia and the local test chain. A contract inheriting it will refuse to deploy on Ethereum until the new `Judge` address is added. The README already says so.\n- `JudgeEthDoor` has no slippage limit other than the ETH attached, and `Judged.ask(question, proof)` attaches all of `msg.value`. A caller who attaches a lot can lose most of it to a sandwich trade. The docs say to attach little (0.002 ETH). This sits under economics, not math.\n- The other three areas (permissions, economics, control flow) are covered by the other reviewers.\n\nUnrelated to the review, some files I didn't create now appear untracked in the repo root (`.bashrc`, `.profile`, `.gitconfig`, `.claude/`, `.vscode`, and others). They probably come from the sandbox; I left them alone.","treeHash":null,"usage":{"cachedInputTokens":723901,"cost":{"source":"runtime","usdMicros":1215984},"inputTokens":23,"model":"claude-opus-5-5","outputTokens":20172,"runtime":"claude","turns":12,"wallClockMs":249045}},{"artifacts":[],"attempt":1,"bundleHash":"0f4a53bd6effc53b99dcf8625c12b0d894e81552f4b3e284c3b3b9539e0eb955","device":"f84fad79f165f267","findings":[],"hash":"60673ca3dd40b54f97e740af62dafd709b6f17d600e77749cbe6ab362b10c98a","nodeId":"8f49c398-82b6-46f4-92d9-b55305c23c74","outcome":"completed","summary":"Created [launch.json](/root/.identitymd/work/d60032fc-9747-4900-9884-4e0614187089/8f49c398-82b6-46f4-92d9-b55305c23c74/launch.json) with exactly the two requested contracts, arguments and dependency order. Only the manifest changed.\n\n- Build succeeded; all 111 non-fork tests passed with the specified seed.\n- No critical/high issue found. `Judged.sol` requires an `_judge()` override with confirmed addresses for mainnet use.\n- Sources remain unchanged from `0f0b3c17ba4273b18d807de17bd2ff3479ed2a98`.\n\nNo deployment was broadcast during this manifest task. Both deployed addresses and on-chain bytecode equivalence remain unverified.","treeHash":"def237249d9dbdd9b7a40b6adf32f6ad788da6dd","usage":{"cachedInputTokens":418560,"cost":{"source":"estimated","usdMicros":1364350},"inputTokens":66859,"model":"gpt-6-astra","outputTokens":5544,"runtime":"codex","turns":4,"wallClockMs":166635}},{"artifacts":[],"attempt":1,"bundleHash":"52dcd65bede0ed11a0379f4aa60e49d7a2acb442eb414bf20e9d09b816977c04","device":"3d55f5b0ed8fa3df","findings":[{"description":"The base constructor calls _judge(), whose default routing handles Sepolia and the local test chain only. An inheritor using the base unchanged therefore cannot deploy on Ethereum, even after Judge and JudgeEthDoor are launched there. This limitation was already recorded in ADAPTATION.md. The new consumer tests override routing with their locally deployed pair to exercise the base accounting; that does not resolve the production integration. Once confirmed deployment addresses exist, the default Ethereum routing can be completed without changing either launched contract. No deployment address is guessed in this test-only submission.","line":125,"path":"src/Judged.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {Judged} from \"src/Judged.sol\";\n\ncontract EthereumJudgedInheritor is Judged {\n    function onYes(uint256) internal override {}\n}\n\ncontract EthereumRoutingProof is Test {\n    function test_inheritorCanResolveTheEthereumDeployment() public {\n        vm.chainId(1);\n        // Expected after the Ethereum integration is completed: the base constructor can\n        // resolve its Judge/door pair, without an application overriding its routing.\n        // Actual at the reviewed commit: \"Judged: Judge isn't on this chain\".\n        EthereumJudgedInheritor consumer = new EthereumJudgedInheritor();\n        assertGt(address(consumer).code.length, 0);\n    }\n}","reproduction":"Run the attached standalone Foundry test on chainId 1. Expected once Ethereum integration is complete: constructing a minimal Judged inheritor succeeds and resolves the confirmed Judge/door pair. Actual at starting commit 0f0b3c17ba4273b18d807de17bd2ff3479ed2a98: construction reverts with \"Judged: Judge isn't on this chain\". Executed with forge test --match-path test/scratch/EthereumRouting.proof.t.sol: 0 passed, 1 failed for that exact reason. This is an informational deployment dependency, not a critical/high change to the two launch contracts.","severity":"info","title":"Known post-launch integration step: Judged has no Ethereum routing entry"}],"hash":"6fdf53dea2cd4790031fdbb47e27ec292c3f586041aeeb3eb67e42d703621212","nodeId":"c280c1e4-cc6b-4aa5-ad01-f6053fa712a2","outcome":"completed","summary":"Added 42 tests covering failures, fuzzing, and 16,384 invariant calls.\n\n`forge build` passes. Full suite: **153 passed, 2 fork tests skipped** for missing RPC inputs.\n\nNo critical/high defect found. Reported `Judged`’s known missing Ethereum routing in the [review](test/REVIEW.md).\n\nProduction code remains unchanged from `0f0b3c17`. Neither contract was deployed; deployed addresses and on-chain bytecode equivalence remain unverified.","treeHash":"17f612bfcc53ea4e4b6209f33e3c576f56305736","usage":{"cachedInputTokens":2939136,"cost":{"source":"estimated","usdMicros":6276006},"inputTokens":112762,"model":"gpt-6-astra","outputTokens":44185,"runtime":"codex","turns":9,"wallClockMs":1245842}},{"artifacts":[],"attempt":1,"bundleHash":"1d69df4fc9814a9aa4398e74a1d994f0ad961e4b4500c135c817ecff00311f1d","device":"8e25456c4ae69acf","findings":[],"hash":"7b023e50ce8ee126db7e1eb7ee5c38408b6c63cfab77c13ca8efdb5b91cb2e11","nodeId":"85df20e0-51fb-4b80-bdd9-34ef0abdf8ce","outcome":"completed","summary":"Both contracts are ready to launch exactly as they are. My review found nothing critical or high, so no contract code changed. I did not deploy anything, so I can't give you deployed addresses. IMD's deployer launches through the factory after this step is accepted, and the two addresses come from that launch.\n\n**Does the bytecode match commit `72ba6cd`?** Yes. No file under `src/` changed, and a rebuild of `72ba6cd` in a different directory produced the same creation code:\n\n| Contract | Creation-code keccak |\n| --- | --- |\n| `Judge` | `0x1829917ebd076c11eb136613f10230beab3b22fa8c9d9af0871aaec263be1b55` |\n| `JudgeEthDoor` | `0x65b6f25931cf8685de79b0cdb856a43112a7d3ee297d43124ecf1c9b75de68d6` |\n\nOnce the launch runs, you can check the deployed contracts against these hashes. `ADAPTATION.md` also lists the runtime hashes.\n\n**What I added**\n- **`test/Launch.t.sol`:** deploys `Judge` then `JudgeEthDoor` with your exact arguments on an empty chain 1. It checks every stored value, that the door points at that `Judge`, that neither contract has an owner or admin, and that neither contains a forbidden opcode. It also pins the question wording byte for byte, so any change to it fails the test.\n- **`ADAPTATION.md`:** the changes, the checks, both audit findings and the full review.\n\n**Checks**\n- **Build and unit tests:** `forge build` passes. `forge test --no-match-path \"test/fork/*\"` with the verifier's fuzz seed passes 111 tests: your original 105 plus the 6 new ones.\n- **Mainnet fork test:** passes. A real ask through the door, through `Judged` and in IMD all worked against the live Intake, IMD and Uniswap pool.\n- **Launch rehearsal:** the launch's own deployment check passes with both contracts and your arguments. The owner check couldn't run because a file it needs isn't on this machine; neither contract has an owner.\n- **Live values:** on Ethereum, the 0.5 IMD price and the ETH/IMD pool (fee 10000, tick spacing 200) are live.\n- **IMD's question check:** it accepts the real `Judge` question at panel size 100 with no blockers, and 100 is its current maximum.\n- **Not run:** Slither and Mythril aren't installed here.\n\n**Audit findings** (both reproduce, neither changed)\n1. **`Judged` has no Ethereum entry.** Contracts that inherit it can't deploy on Ethereum yet. Adding the entry needs the real deployed addresses, which don't exist until launch. Once they do, add the `Judge` and door pair to `_judge()` and update the README. `Judged.sol` isn't deployed, so this changes neither deployed contract.\n2. **Panel size 100 is exactly IMD's current maximum.** If IMD ever lowers that limit, every case would be paid for and end with no answer, and only a new `Judge` would fix it. This is a dependency on IMD, not a bug, and the brief rules out a setter.\n\n**Review of `Judged.sol` and the two contracts.** Only low-severity or by-design points came up:\n- **`Judged`, on Sepolia:** anyone who can call the inheriting contract's asking function spends the imdTEST it holds.\n- **`Judged`, once per block:** the same sender can't ask twice in one block with the same amount of ETH.\n- **`Judged`, partly spent ETH:** an inheritor that spends part of the ETH sent before calling the two-argument `ask` pays the difference from its own balance. The docs already say to use `ask(question, proof, budget)` instead.\n- **`Judged`, ids:** questions are stored by id alone, which would only matter if one chain ever had two `Judge` contracts.\n- **`JudgeEthDoor`:** the swap's only price protection is the ETH attached, so a sandwich can take up to that amount. The docs already say to attach little.\n\nThe new files aren't committed, since you didn't ask for a commit.","treeHash":"260df2dedc4d79d65b10ee211913380e484cdef8","usage":{"cachedInputTokens":1028746,"cost":{"source":"runtime","usdMicros":1274203},"inputTokens":32,"model":"claude-opus-5-5","outputTokens":24029,"runtime":"claude","turns":19,"wallClockMs":281923}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"f494611affb5524c","findings":[{"citation":"resolved","description":"Merged from audit_permissions (low) and audit_economics (info); the same root cause. claim() closes the dare only when the pot is empty or the deadline has passed. A Yes verdict does not close it: the pot leaves only when someone calls collect(id). Between a Yes landing on the Judge and collect being called (the winner has a day), claim() still accepts a new claimant, takes their 1% stake into the pot and spends their panel fee through the door. collect(earlier) then pays address(this).balance, which includes the later claimant's stake, to the earlier winner. When the later claimant's own case returns Yes, collect pays them address(this).balance == 0 and deletes claimantOf, so a claimant with a winning verdict loses stake and panel fee. The contract is an example that this launch does not deploy, which is why this is low; a contract copying the pattern with a large pot makes the lost stake material. A minimal fix that keeps the design: refuse claim() once any case of this dare already reads Verdict.Yes (record the first Yes id in collect or check the latest case's verdict in claim), or let a claimant whose stake was placed after a Yes take it back.","line":40,"path":"src/examples/JudgeDare.sol","reproduction":"Reproduced on this tree with test/scratch/ReviewRepro.t.sol test_dareLateClaimantLosesStakeToEarlierWinner (passes = defect present). Setup as test/Judge.t.sol JudgePoolBase with addLiquidity(100 ether); creator deploys JudgeDare{value: 3 ether}(door, rule, now + 7 days). 1) alice: dare.claim{value: 1 ether}(PROOF) -> case A; writer delivers a signed Yes for A; judge.verdict(A) == Yes; nobody collects. 2) bob: dare.claim{value: 1 ether}(PROOF) succeeds (pot 3.03 ETH > 0, deadline a week away); bob's stake 0.0303 ETH stays in the dare and his panel fee is spent. 3) anyone: dare.collect(A) -> alice.balance rises by exactly 3 ether + 0.03 ether + 0.0303 ether (bob's stake); dare balance 0. 4) writer delivers Yes for bob's case B; dare.collect(B) leaves bob.balance unchanged and claimantOf(B) == address(0). Expected: a claim opened after a Yes is refused, or bob's stake comes back on his Yes. Actual: bob's stake and panel fee are gone and his winning claim is closed.","severity":"low","snippet":"        if (pot == 0 || block.timestamp >= deadline) revert DareOver();","title":"JudgeDare.claim keeps taking staked claims after an uncollected Yes, and collect pays the later claimant's stake to the earlier winner"},{"citation":"resolved","description":"Merged from audit_permissions (low), audit_flow (info) and audit_economics (low); one mechanism. The exact-output swap runs to MIN_SQRT_PRICE + 1 and the only ceiling on what it may cost is `if (spent > sent) revert EthShort(spent, sent)` at line 74, i.e. msg.value. There is no caller-supplied maximum, Judged.ask(question, proof) forwards all of msg.value as the budget, and JudgeDare forwards msg.value minus the stake, so whatever a caller attaches above the fair cost is what a searcher who sees the ask in the mempool can make them pay. This is the documented design (the natspec says 'what is attached is the most the swap can cost') and the loss is bounded by the caller's own choice, so it is low, not medium. On the live pool read on 2026-11-10 (pool id 0xb07d640f..., slot0 initialized at tick 67461, in-range liquidity 0x1f8f8113f82eb54d028 = 9.3e21, 1% fee) a sandwich of the README's recommended 0.002 ETH budget costs more in pool fees than it extracts, so today the exposure is a caller who attaches far more than the price. No code change is recommended for this launch: the function signature is fixed by the brief, and a future door can add a maxSpend argument without touching Judge. Document that Judged users pass a budget close to the quoted cost.","line":69,"path":"src/JudgeEthDoor.sol","reproduction":"Reproduced on this tree with test/scratch/ReviewRepro.t.sol test_doorSandwichOnThinPool. Setup as test/Judge.t.sol JudgePoolBase.setUpPool() (1 ETH = 1 IMD at tick 0, range -6000..6000, fee 10000, spacing 200, no hook) with addLiquidity(10 ether). Quiet pool: alice door.ask{value: 1 ether}(RULE, PROOF) costs 531632110579479002 wei. Revert state. Searcher swaps 2 ETH exact-input zeroForOne through the PoolManager, then alice sends the same door.ask{value: 1 ether}: it succeeds and costs 771035533507610947 wei (spent <= msg.value, so no EthShort); the searcher sells its IMD back and ends 198664402902316901 wei richer. Expected: a caller-chosen maximum near the quoted price. Actual: the maximum is whatever was attached; pushing further than the budget allows makes the ask revert EthShort and the victim then loses nothing, so the harm is capped at msg.value minus the fair cost.","severity":"low","snippet":"            SwapParams({zeroForOne: true, amountSpecified: int256(price), sqrtPriceLimitX96: TickMath.MIN_SQRT_PRICE + 1}),","title":"JudgeEthDoor.ask has no spend bound other than msg.value: on a thin pool a front-run takes most of an attached budget, and Judged forwards the whole msg.value by default"},{"citation":"resolved","description":"Merged from audit_permissions (low) and audit_flow (info): the trust assumptions on IMD's Intake, recorded as privileged powers rather than a bypass. price() is intake.priceOf(ACTION, asset), which the Intake's owner (live: 0x047F606fD5b2BaA5f5C6c4aB8958E45CB6B054B7, read from the chain on 2026-11-10; live price 0.5 IMD, callbackGas 200000, writer 0x3d3C0Df7C1a17d384545e9D7C8228897bD9625CB) sets with setPrice at any time. ask() has no fee ceiling parameter and pulls fee from msg.sender with safeTransferFrom. A caller that approved Judge for more than one price (the repository's own tests approve type(uint256).max in fund()) can have that whole allowance moved to IMD's treasury by a setPrice that lands before their ask. Callers through JudgeEthDoor are bounded by msg.value and Judged's token path approves exactly price() in the same transaction, so only direct Judge.ask callers with standing approvals are exposed. Separately, the Intake owner can lower callbackGas below what onOracleResult needs so every callback fails, and the writer can complete any pending request with status 1 or 2 (onOracleFailure) or an unverifiable attestation; each ends the case in NoAnswer. None of these can produce a wrong Yes or No, which is what the Judge natspec promises, and the same party already controls the signer, so this adds little new trust. No change to the deployed contract is recommended (ask's signature is fixed by the brief); document for integrators that direct callers approve exactly price() per ask.","line":98,"path":"src/Judge.sol","reproduction":"Reproduced on this tree with test/scratch/ReviewRepro.t.sol test_standingApprovalPaysWhateverTheIntakeOwnerSets. Setup as test/Judge.t.sol JudgeBase: alice holds 10 IMD and has approved Judge for type(uint256).max. 1) Intake owner: intake.setPrice(bytes32(\"oracle.request@oracle-1\"), imd, 10 ether). 2) alice: judge.ask(RULE, PROOF). Expected by alice: 0.5 IMD leaves. Actual: imd.balanceOf(alice) == 0 and imd.balanceOf(treasury) == 10 ether for one case. Writer path: for a pending case, writer calls intake.complete(requestId, 2, 0, \"\", abi.encode(requestId, 2, \"disagreed\", 0, 0, \"\")) and verdict(id) becomes NoAnswer permanently (existing test test_aFailureEndsTheCaseWithNoRuling).","severity":"low","snippet":"        uint256 fee = price();","title":"Judge.ask pulls whatever price the Intake owner has set at that moment, so a standing approval above one price is spendable by the Intake owner; the Intake owner and writer can also end any case in No"},{"citation":"resolved","description":"Merged from audit_permissions (info), write_foundry_tests (info), audit_flow (low) and audit_economics (info); one root cause. Judged's constructor calls _judge(), which knows Sepolia (11155111) and the forge stand-in chain (31337) only, so `new EggDare()` or any Judged child reverts on chain 1. This is the expected pre-launch state (README: 'On Ethereum Judged reverts with Judge isn't on this chain until then'; test/fork/JudgeFork.t.sol says the same) and the safe direction, since nothing can be funded against a missing Judge, so it is informational and not a defect in the two contracts being deployed. It is recorded so the post-launch step is not lost: once both addresses are confirmed, _judge() needs `if (block.chainid == 1) return (<Judge>, <JudgeEthDoor>);`, the README address table needs the same, and the Sepolia entry's door stays address(0). Until then the only ways to use the Ethereum Judge are Judge.ask / JudgeEthDoor.ask directly or overriding _judge() as the fork test's ForkedEggDare does. Changing it touches neither Judge nor JudgeEthDoor.","line":128,"path":"src/Judged.sol","reproduction":"Reproduced on this tree with test/scratch/ReviewRepro.t.sol test_judgedRevertsOnEthereum: vm.chainId(1); new EggDare(); reverts with \"Judged: Judge isn't on this chain\". The tester's proof .imd/reads/proofs/Proof_cad1aa18795c.t.sol fails for the same reason. Expected after launch: a Judged child deploys on Ethereum and asks through the launched door. Actual today: construction is impossible on chain 1.","severity":"info","snippet":"        revert(\"Judged: Judge isn't on this chain\");","title":"Judged has no Ethereum (chain 1) entry: every contract inheriting it reverts at construction on the chain this launch targets until _judge() gains the deployed addresses"},{"citation":"resolved","description":"Own finding (Pashov Boundary pass). claim() appends 101 bytes to the creator's rule (\" The claimant is \" + a 42-byte address + \": the proof must show this address did it.\") before passing it to the door, and Judge._plain refuses a rule over MAX_RULE_BYTES = 500. The constructor stores rule_ without checking its length, so a dare created with a rule of 400 bytes or more takes the creator's pot and can never be claimed: every claim() reverts with TextTooLong(length, 500) before anything is paid. Nothing is lost: reclaim() returns the pot to the creator two days after the deadline, and the contract is an example that is not deployed, so this is informational. A one-line check in the constructor (bytes(rule_).length <= 399) would turn the mistake into a revert at creation.","line":43,"path":"src/examples/JudgeDare.sol","reproduction":"Reproduced on this tree with test/scratch/ReviewRepro2.t.sol test_dareWithA400ByteRuleCanNeverBeClaimed. Setup as test/Judge.t.sol JudgePoolBase with addLiquidity(100 ether). creator: new JudgeDare{value: 3 ether}(door, <400 bytes of 'a'>, now + 7 days) succeeds. alice: dare.claim{value: 1 ether}(\"Paris\") reverts TextTooLong(501, 500). The same with a 399-byte rule claims successfully. dare.reclaim() reverts TooEarly until deadline + 2 days, then returns the 3 ETH to the creator. Expected: a rule the dare can never ask is refused at construction. Actual: the pot sits unclaimable for the dare's whole life.","severity":"info","snippet":"        string memory named = string.concat(rule, \" The claimant is \", Strings.toHexString(msg.sender), \": the proof must show this address did it.\");","title":"JudgeDare accepts a rule of any length at construction, but a rule over 399 bytes makes every claim revert TextTooLong and locks the pot until reclaim"}],"hash":"92ce670ced8336a9acef5fcad267db31178b8584f1973cbd933309392258187a","nodeId":"c133b9c3-d71e-47a3-a164-4d9dd25f0bb8","outcome":"completed","summary":"The review is complete and written to `.imd-findings.json`. No file outside the findings file and the disposable `test/scratch/` directory was changed.\n\n**Verdict: no critical or high defect in Judge, JudgeEthDoor or Judged.** Both launch contracts can ship as they are. Judge binds every answer to the intake caller, the case's own question hash, the panel it asked for and its EIP-712 domain, and refuses late or repeated decisions. JudgeEthDoor buys exactly the price, caps spend at the ETH attached and refunds last. Judged keeps the pot apart from the budget, blocks same-block repeat asks and guards settlement and refund reentry. The full unit suite passes.\n\n| Check | Result |\n| --- | --- |\n| `forge test --no-match-path \"test/fork/*\"` | 153 passed, 0 failed |\n| Source, foundry.toml, lib since starting commit 0f0b3c1 | unchanged |\n| launch.json | schema-valid, arguments in declaration order, notes 2588 chars |\n\n**Findings kept, after reproducing each against the code:**\n\n1. **Low, JudgeDare.claim** still takes staked claims after an uncollected Yes, and `collect` pays the later stake to the earlier winner. Merged from permissions and economics. Example contract, not deployed.\n2. **Low, JudgeEthDoor.ask** has no slippage bound other than msg.value. Merged from three specialists. On a 10 ETH test pool a 2 ETH front-run raised one ask's cost from 0.53 to 0.77 ETH at a profit. The live pool's depth makes a sandwich of the recommended 0.002 ETH budget unprofitable today. Documented design, no code change recommended.\n3. **Low, Judge.ask** pulls whatever price the Intake owner sets, so a standing unlimited approval is spendable by that owner. Merged with the Intake trust assumptions on callback gas and the writer. No wrong Yes or No is possible. No code change recommended.\n4. **Info, Judged** has no chain 1 entry, so every inheritor reverts at construction on Ethereum until the launched addresses are added. Merged from four reports. Expected pre-launch state and a post-launch to-do.\n5. **Info, own finding**: JudgeDare accepts a rule of any length, but a rule over 399 bytes makes every claim revert and locks the pot until reclaim. Example contract only.\n\nNothing was dropped: every specialist finding reproduced. All four were recalibrated to low or info because none loses funds in the deployed contracts.\n\n**Live dependencies** were read from Ethereum at block 26386887: the Intake sells the action in IMD at 0.5, the callback stipend is 200k, the signer is an EOA, and the ETH/IMD 1% pool with spacing 200 is initialized with about 9.3e21 liquidity.\n\n**Deployed addresses and bytecode:** neither contract has been deployed yet. This review runs before the factory launch, so there are no addresses to report and the deployed bytecode cannot be compared with the repository. The source is unchanged since the starting commit, so a later comparison should match once the launch runs.\n\n**Coverage:** all 14 entry points answered, plus rows for the manifest and the live dependencies. Judged users on Ethereum should wait for the `_judge()` update or override it with the confirmed addresses.","treeHash":null,"usage":{"cachedInputTokens":1197154,"cost":{"source":"runtime","usdMicros":4775124},"inputTokens":354,"model":"claude-fable-5-1","outputTokens":37441,"runtime":"claude","turns":32,"wallClockMs":672370}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"93c37f17670e4d98","findings":[{"citation":"resolved","description":"Asymmetry between claim and collect (Asymmetry guide, step 3; Trust Gap seam economics x asymmetry). `claim` closes the dare only when `pot == 0` or the deadline has passed. A Yes verdict does not close it: the pot leaves only when someone calls `collect`. In the window between a Yes landing on the Judge and `collect` being called (minutes to the full day the winner is given), `claim` still accepts a new claimant, takes their 1% stake into the pot and spends their panel fee. `collect(id)` then pays `address(this).balance`, which includes the later claimant's stake, to the earlier winner. When the later claimant's own case comes back Yes, `collect` pays them `address(this).balance == 0` and deletes `claimantOf`, so they lose stake and panel fee with a winning verdict. The contract is an example, not deployed in this launch, which is why this is low; a contract inheriting the pattern with a large pot would make the lost stake material. A minimal fix that keeps the design is to record the winning id when a Yes is first observed (or in `collect`) and have `claim` revert `DareOver` once any case of this dare reads `Verdict.Yes`; since `claim` already pays for a Judge call, checking the stored last id's verdict is cheap.","line":40,"path":"src/examples/JudgeDare.sol","reproduction":"Setup as test/Judge.t.sol JudgeDareTest (pot 3 ETH, pool with 100e18 liquidity). 1) alice: dare.claim{value: 1 ether}(proof) -> case A; writer delivers a signed Yes for A; nobody calls collect yet. 2) bob: dare.claim{value: 1 ether}(proof) succeeds (pot 3.03 ETH > 0, deadline a week away); bob pays stake 0.0303 ETH plus the panel's ~0.5 IMD worth of ETH. 3) anyone: dare.collect(A) -> alice receives 3 ETH + 0.03 + 0.0303 (bob's stake); dare balance 0. 4) writer delivers Yes for bob's case B; dare.collect(B) pays bob 0 and deletes claimantOf[B]. Expected: a claim opened after a Yes is refused, or bob's stake is returned on his Yes. Actual: bob's stake and fee are gone and his winning claim is closed. Verified in a scratch test (ReviewDareLateClaimant) on this tree: bob.balance unchanged by collect(B), claimantOf(B)==0.","severity":"low","snippet":"        if (pot == 0 || block.timestamp >= deadline) revert DareOver();","title":"JudgeDare keeps taking staked claims after an uncollected Yes, and the first collector takes the later claimant's stake"},{"citation":"resolved","description":"Trust Gap seam access x economics. `ask` is permissionless and swaps for exactly `price` IMD with the price limit at MIN_SQRT_PRICE + 1 and no maximum input other than `if (spent > sent) revert EthShort(spent, sent)` at line 74. The pool is Uniswap v4's public ETH/IMD 1% pool, so any searcher who sees the ask in the mempool can buy IMD first, let the ask fill at the moved price, and sell back: the asker loses up to `msg.value` minus the fair cost. The contract's own comment says this is the design (\"what is attached is the most the swap can cost\"), and the live cost is tiny (the fork run on Ethereum spent 594,473,147,348,667 wei for 0.5 IMD), so the loss is bounded by what the caller chooses to attach. It is recorded because the repository's own example (JudgeDare's tests attach 1 ETH, and `claim` forwards `msg.value - stake` whole) and any Judged contract that forwards its caller's `msg.value` as the budget hand that whole buffer to the sandwicher, and neither Judged nor the door offers a way to pass a tighter cap. The function signature is fixed by the brief, so the mitigation is documentation and caller discipline: Judged users should pass a budget close to the quoted cost. No code change in the deployed contracts is recommended for this launch.","line":69,"path":"src/JudgeEthDoor.sol","reproduction":"Setup as test/Judge.t.sol JudgePoolBase with addLiquidity(100 ether) (price 1 ETH = 1 IMD, range -6000..6000). Quiet pool: alice door.ask{value: 1 ether}(RULE, PROOF) spends 507,588,447,286,939,750 wei. Then revert state; attacker swaps 25 ETH -> IMD through the PoolManager (exact input, zeroForOne); alice sends the same door.ask{value: 1 ether}: spent is 790,921,377,140,418,412 wei, 1.56x the quiet cost, and the ask succeeds because spent <= msg.value. With a larger front-run that leaves just enough IMD in range, spent approaches 1 ether. Expected: a caller-chosen maximum near the quoted price. Actual: the maximum is whatever was attached. Verified in scratch test ReviewDoorSandwich on this tree.","severity":"low","snippet":"            SwapParams({zeroForOne: true, amountSpecified: int256(price), sqrtPriceLimitX96: TickMath.MIN_SQRT_PRICE + 1}),","title":"JudgeEthDoor's only slippage bound is msg.value: a front-run can take almost everything attached, so callers that attach a buffer overpay"},{"citation":"resolved","description":"Trust Gap seam access x economics, recorded as a privileged-power trust assumption rather than a bypass. `price()` is `intake.priceOf(ACTION, asset)`, which the Intake's owner (live: 0x047F606fD5b2BaA5f5C6c4aB8958E45CB6B054B7, Ownable2Step) sets with `setPrice` at any time. `ask` has no fee ceiling parameter and pulls `fee` from `msg.sender` by `safeTransferFrom`. A caller that approved Judge for more than one price (the repository's own tests approve `type(uint256).max` in `fund`) can have that whole allowance moved to IMD's treasury by a `setPrice` that lands before their `ask`. Callers through JudgeEthDoor are bounded by msg.value, and Judged's token path approves exactly `price()` in the same transaction, so only direct `Judge.ask` callers with standing approvals are exposed. The same party already controls the writer and the signer, so this adds little new trust, and the brief fixes `ask`'s signature; the recommendation is to document that integrators approve exactly `price()` per ask. No change to the deployed contract is recommended.","line":98,"path":"src/Judge.sol","reproduction":"Setup as test/Judge.t.sol JudgeBase: alice holds 10 IMD and has approved Judge for type(uint256).max. 1) Intake owner: intake.setPrice(bytes32(\"oracle.request@oracle-1\"), imd, 10 ether). 2) alice: judge.ask(RULE, PROOF). Expected by alice: 0.5 IMD leaves. Actual: imd.balanceOf(alice) == 0 and imd.balanceOf(treasury) == 10 ether for one case. Verified in scratch test ReviewPriceRaise on this tree.","severity":"low","snippet":"        uint256 fee = price();\n        if (fee == 0) revert NotSold();\n        asset.safeTransferFrom(msg.sender, address(this), fee);","title":"Judge.ask pulls whatever price the Intake owner has set at that moment, so an unlimited approval to Judge is spendable by IMD's owner"},{"citation":"resolved","description":"`_judge()` returns addresses for Sepolia (11155111) and the forge stand-in (31337) only; the constructor calls it, so `new EggDare()` or any `Judged` child reverts on chain 1. This is the expected pre-launch state (test/fork/JudgeFork.t.sol says 'until Judged has Ethereum's own address'), not a defect in the two contracts being deployed, and it is the safe direction: nothing can be funded against a missing Judge. It is recorded so the post-launch step is not forgotten: once the two addresses are known, `_judge()` needs `if (block.chainid == 1) return (judge, door);` and the Sepolia door, which is `address(0)` today, stays as it is. Changing it does not touch Judge or JudgeEthDoor.","line":128,"path":"src/Judged.sol","reproduction":"vm.chainId(1); new EggDare(); reverts with \"Judged: Judge isn't on this chain\". Expected after launch: a Judged child deploys on Ethereum and asks through the launched door. Actual today: deployment is impossible on chain 1. Verified in scratch test ReviewJudgedChain1 on this tree.","severity":"info","snippet":"        revert(\"Judged: Judge isn't on this chain\");","title":"Judged has no Ethereum (chain 1) entry, so every contract inheriting it reverts at deployment on the chain this launch targets until the library is updated with the deployed addresses"}],"hash":"b17c2b513b7a4774b09d921ee7e6f26a63c32bae69fe560c9ff121d54ea5327b","nodeId":"98c5704d-87f9-4284-a774-b46aaebbeec8","outcome":"completed","summary":"The review is complete. The findings file is written, the scratch tests are removed, and no tracked file changed.\n\n**Outcome: no critical or high defect in the permission model of Judge or JudgeEthDoor. Deploy both as they are.** The findings file holds four low or informational items and a coverage row for all 14 entry points plus three invariants.\n\n**What I checked, in my area (Access Control, Trust Gap, Asymmetry)**\n\n- Judge's two callbacks are reachable only from the immutable Intake, refuse unknown or settled cases, bind the answer to the case by a question hash that contains the case id and the judge's address, verify the EIP-712 signature in the judge's own domain, and refuse a late answer before checking the signature. NoAnswer can never become Yes. The oracle signer has no exposed setter.\n- JudgeEthDoor's unlock callback accepts only the PoolManager, which only calls back its own unlocker. Refunds go last, so reentry only opens another self-funded case.\n- Judged, which other people's money sits behind: the asked-key and change arithmetic hold against a payable multicall, a reentering refund and the token path. Settle is anyone-callable by design, one-shot, and the busy flag blocks reentry from a payout.\n- Live Ethereum at block 26386778: Intake v2 sells the action at 0.5 IMD, IMD has 18 decimals, the ETH/IMD 1%/200 pool is initialized with liquidity, the signer is an EOA. The Ethereum fork test passes against them. All 111 unit tests pass.\n\n**Findings recorded**\n\n1. Low. JudgeDare keeps taking staked claims after an uncollected Yes. A later claimant's stake and fee go to the earlier winner. Example contract, not deployed.\n2. Low. JudgeEthDoor's only slippage bound is the attached ETH. A front-run raised the cost from 0.508 to 0.791 ETH in a scratch run. Documented design, bounded by the caller.\n3. Low. Judge pulls whatever price the Intake owner has set at that moment, so a standing unlimited approval to Judge is spendable by IMD's owner. A trust assumption on a party already trusted as writer and signer.\n4. Info. Judged has no chain 1 entry, so inheriting contracts cannot deploy on Ethereum until the launched addresses are added to its address table.\n\n**Deployment status**\n\nNothing is deployed yet. There are no addresses to report and no deployed bytecode to compare. The tree at commit 0f0b3c1 builds with the required bytecode hash setting, and the Launch test pins the brief's constructor arguments. After launch, Judged's address table needs the two Ethereum addresses added.","treeHash":null,"usage":{"cachedInputTokens":1031773,"cost":{"source":"runtime","usdMicros":5491952},"inputTokens":258,"model":"claude-fable-5-1","outputTokens":41822,"runtime":"claude","turns":27,"wallClockMs":686970}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"a0f92fec784312b7","findings":[{"citation":"resolved","description":"Judged.constructor() calls _judge(), which only knows Sepolia (11155111) and anvil (31337). On Ethereum (chain id 1) it reverts, so EggDare and any other contract inheriting Judged cannot be deployed there, and an existing one could not ask. This is not a defect in the two contracts being launched and must not be fixed before the launch (the addresses do not exist yet), but it is the integration path the brief, README and site advertise. After the deployer confirms both addresses, add `if (block.chainid == 1) return (<Judge>, <JudgeEthDoor>);` to _judge() and the README address table, and re-run test_itKnowsWhereJudgeIs. Until then the only way to use the Ethereum Judge is to call Judge.ask / JudgeEthDoor.ask directly or to override _judge() as test/fork/JudgeFork.t.sol's ForkedEggDare does.","line":126,"path":"src/Judged.sol","reproduction":"forge test (no fork): vm.chainId(1); new EggDare(); -> reverts with \"Judged: Judge isn't on this chain\" (verified with test/scratch/JudgedOnEthereum.t.sol, which passes on this tree). Expected after launch: construction succeeds and claim{value: 0.002 ether}(proof) opens a case on the launched Judge through the launched door.","severity":"low","snippet":"        if (block.chainid == 11155111) return (0x4958501caedC8E3824c8B6E09EB449f5c97Dbe1D, address(0));\n        if (block.chainid == 31337) return (JUDGE_STAND_IN, JUDGE_STAND_IN);\n        revert(\"Judged: Judge isn't on this chain\");","title":"Judged has no Ethereum entry: every contract that inherits it reverts at construction on chain 1, so the launched Judge is unreachable through Judged until src/Judged.sol is updated with the deployed "},{"citation":"resolved","description":"The exact-output swap runs to MIN_SQRT_PRICE + 1 and the only ceiling on what it costs is `spent > sent` (EthShort). This is the documented design (\"what is attached is the most the swap can cost\"). Quantified against the live pool read on 2026-11-10 (slot0 tick 67460, in-range liquidity ~9.3e21, 1% fee): doubling the ETH cost of 0.5 IMD needs ~94 ETH of attacker volume and ~1.9 ETH of pool fees to extract ~0.0006 ETH from one ask, so a sandwich is unprofitable and the exposure is only a caller who attaches far more than the price. No change to the contracts is proposed; keep the README guidance (attach ~0.002 ETH) and prefer Judged.ask(question, proof, budget) with a small budget in contracts that forward large msg.value, as JudgeDare does with 1 ETH claims in its tests.","line":69,"path":"src/JudgeEthDoor.sol","reproduction":"test/Judge.t.sol JudgePoolBase (100 ether liquidity, ticks -6000..6000, 1:1 start): attacker first swaps ETH->IMD to push the price toward the upper tick, then alice calls door.ask{value: 1 ether}(RULE, PROOF): the ask succeeds and alice pays up to ~0.91 ETH for a 0.5 IMD price instead of ~0.505 ETH; attacker swaps back and loses ~2% of its volume in fees, more than alice overpaid. Expected: bounded by msg.value, which is what happens; reported as a documented trust assumption, not a defect.","severity":"info","snippet":"            SwapParams({zeroForOne: true, amountSpecified: int256(price), sqrtPriceLimitX96: TickMath.MIN_SQRT_PRICE + 1}),","title":"JudgeEthDoor.ask has no slippage bound other than msg.value; Judged passes the whole msg.value by default and JudgeDare passes msg.value minus the stake"},{"citation":"resolved","description":"Judge has no price cap: ask() pulls whatever intake.priceOf(ACTION, asset) says at that moment (live value 0.5 IMD, owner 0x047F606f...). A caller that approved Judge for more than one price (as test/Judge.t.sol's fund() does with type(uint256).max) pays whatever the Intake owner has set when the ask is mined. JudgeEthDoor bounds this by msg.value and Judged's token path approves exactly price() in the same transaction, so only direct Judge.ask callers with standing approvals are exposed. Separately, the Intake owner can lower callbackGas (live 200,000; onOracleResult needs under 100,000) so that every callback runs out of gas, and the writer can complete any pending request with status 1 or 2 (onOracleFailure) or with an unverifiable attestation, which ends the case in NoAnswer. None of these can produce a wrong Yes or No, which is what the Judge natspec promises. No change proposed: document for integrators that direct callers should approve exactly price() per ask.","line":127,"path":"src/Judge.sol","reproduction":"Direct caller: alice approves Judge for type(uint256).max; Intake owner calls setPrice(ACTION, IMD, 100 ether); alice's pending judge.ask(rule, proof) is mined after it and pulls 100 IMD (test/Judge.t.sol test_thePriceIsTheIntakesOwn shows the price is read live). Writer: for a case with a valid Yes available, the writer calls intake.complete(requestId, 2, 0, \"\", abi.encode(requestId, 2, \"disagreed\", 0, 0, \"\")) and verdict(id) becomes NoAnswer permanently (test_aFailureEndsTheCaseWithNoRuling). Expected: by design; no path to a wrong signed verdict was found.","severity":"info","snippet":"        return intake.priceOf(ACTION, address(asset));","title":"Trust assumptions on IMD's Intake: its owner sets the price and the callback stipend, and its writer alone decides whether a case ends in a signed verdict or in NoAnswer"}],"hash":"f859899e65254ff4be7d3801b4be426ad8c21c05c7742435794ac15b8fc1c729","nodeId":"41afd468-9644-4c29-bba5-b64f7035553a","outcome":"completed","summary":"Review complete. The findings file is written at `.imd-findings.json` and the tree is otherwise unchanged.\n\n**Outcome for the launch.** No critical or high defect in `Judge` or `JudgeEthDoor` under the Execution Trace, Periphery and First Principles passes. Both contracts should ship exactly as they are. The unit suite passes with 111 tests on this tree.\n\n**Deployed addresses and bytecode.** This is a predeployment review, so no addresses exist yet and I cannot state a match against a live deployment. What the deployer must compare against is pinned: both creation-code hashes rebuilt from this tree equal the ones recorded in ADAPTATION.md for commit 72ba6cd, and the source is unchanged since.\n\n| Contract | Creation-code keccak on this tree |\n| --- | --- |\n| Judge | 0x1829917e…be1b55 |\n| JudgeEthDoor | 0x65b6f259…de68d6 |\n\n**Live dependencies checked on Ethereum.** The Intake has code and sells the action at 0.5 IMD with a 200k callback stipend. The oracle signer is a plain EOA, so verification stays well under the stipend. IMD is an 18-decimal token. The v4 pool keyed (ETH, IMD, fee 10000, spacing 200, no hook) is initialised and has liquidity.\n\n**Findings reported.**\n- **Low, Judged.sol.** Its chain table knows only Sepolia and anvil, so any contract inheriting Judged reverts at construction on chain 1. Verified with a scratch test. This cannot be fixed before launch since the addresses do not exist yet. It is the follow-up to do once both addresses are confirmed.\n- **Info, JudgeEthDoor.** The only swap cost bound is attached ETH. Quantified against the live pool, a sandwich costs the attacker far more in 1% fees than it extracts, so this stays a documented trust assumption.\n- **Info, Judge.** Trust on IMD's Intake: the owner sets price and callback gas, the writer can end any case in NoAnswer. None of these can produce a wrong signed verdict. Direct callers should approve exactly one price per ask.\n\n**Coverage.** All 14 listed entry points have a row, 13 hold and one references the info finding on the door, plus three invariant rows including the live dependency check.","treeHash":null,"usage":{"cachedInputTokens":975449,"cost":{"source":"runtime","usdMicros":5857338},"inputTokens":258,"model":"claude-fable-5-1","outputTokens":39658,"runtime":"claude","turns":30,"wallClockMs":792359}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"fd5402086dce252e","findings":[{"citation":"resolved","description":"The door swaps for exactly price() IMD with sqrtPriceLimitX96 = MIN_SQRT_PRICE + 1 and the only cap on what the swap may cost is `spent > sent` (line 74), i.e. msg.value. There is no caller-supplied maximum, and Judged.ask(question, proof) forwards ALL of msg.value as the budget, so whatever a user attaches is what a searcher can make them pay. The README states this ('what is attached is the most the swap can cost'), so it is a documented trade-off and the loss is bounded by the caller's own choice, which is why this is low rather than medium. It is reported because it is the one lever in the economics an unprivileged party can pull, and because the bound depends on pool depth: on IMD's live pool (liquidity ~9.3e21 at ~841 IMD/ETH, fair cost ~0.00059 ETH per ask as the fork test shows) a 1% pool fee makes a sandwich of the recommended 0.002 ETH budget unprofitable, but if liquidity thins or a user attaches generously the sandwich is profitable. Measured on the repository's own test pool (JudgePoolBase, 1:1 start price, range -6000..6000, 1% fee): liquidity 100e18, budget 1 ETH, searcher pushes 20 ETH: victim pays 0.729 ETH instead of 0.5076 fair, searcher loses 0.148 ETH (not profitable). Liquidity 10e18, budget 1 ETH, push 2 ETH: victim pays 0.771 ETH instead of 0.532 fair (overpays 0.239 ETH), searcher nets +0.199 ETH. Pushing further than the budget allows makes the victim's ask revert with EthShort (0xd613b22d) and the victim loses nothing, so the harm is capped at msg.value - fair cost. Minimal fix that preserves every signature in the brief: none without an ABI change; the cheapest mitigation is documentation, which already exists, plus a maxSpend argument on a future door (a new door costs Judge nothing, as the contract's own comment says). No code change is recommended for this launch.","line":69,"path":"src/JudgeEthDoor.sol","reproduction":"Setup as test/Judge.t.sol JudgePoolBase.setUpPool() with addLiquidity(10 ether). Searcher S (any contract that can unlock the PoolManager) swaps 2 ETH zeroForOne into the ETH/IMD pool (fee 10000, spacing 200, no hook). Alice then calls door.ask{value: 1 ether}(RULE, PROOF). Expected (fair, no front-run): Alice's balance falls by 0.531632110579479002 ETH. Actual: it falls by 0.771035533507610947 ETH, the door refunds only 0.229 ETH, and S then sells its IMD back and ends 0.198664402902316901 ETH richer than before. With push 3 ETH the ask reverts EthShort and Alice loses nothing. Scratch test: test/scratch/Sandwich.t.sol test_grid (not a proof; low severity).","severity":"low","snippet":"        BalanceDelta delta = poolManager.swap(\n            key,\n            SwapParams({zeroForOne: true, amountSpecified: int256(price), sqrtPriceLimitX96: TickMath.MIN_SQRT_PRICE + 1}),\n            \"\"\n        );\n        if (uint256(int256(delta.amount1())) != price) revert IncompleteSwap();\n        uint256 spent = uint256(-int256(delta.amount0()));\n        if (spent > sent) revert EthShort(spent, sent);","title":"JudgeEthDoor.ask has no spend bound other than msg.value: the exact-output swap runs to MIN_SQRT_PRICE, so a price move or sandwich before the ask takes up to the whole attached budget"},{"citation":"resolved","description":"The brief launches Judge and JudgeEthDoor on Ethereum and says users inherit Judged. Judged's constructor calls _judge(), which knows Sepolia (11155111) and Anvil (31337) only, so `new EggDare()` on chain 1 reverts 'Judged: Judge isn't on this chain'. Nothing is lost (it fails before any money can be sent to the contract, as intended) and the README says the address is added after the launch, so this is an after-launch item, not a defect in the deployed contracts: once addresses exist, line 126's pattern must gain `if (block.chainid == 1) return (<Judge>, <JudgeEthDoor>);` and the Sepolia entry's door stays address(0). Recorded so the judge sees the dependency between this launch and the library people will actually copy.","line":128,"path":"src/Judged.sol","reproduction":"vm.chainId(1); new EggDare(); -> reverts with 'Judged: Judge isn't on this chain'. Expected after launch: deploys and _judge() returns the two launched addresses.","severity":"info","snippet":"    function _judge() internal view virtual returns (address judge, address door) {\n        if (block.chainid == 11155111) return (0x4958501caedC8E3824c8B6E09EB449f5c97Dbe1D, address(0));\n        if (block.chainid == 31337) return (JUDGE_STAND_IN, JUDGE_STAND_IN);\n        revert(\"Judged: Judge isn't on this chain\");\n    }","title":"Judged._judge() has no Ethereum entry: any contract inheriting Judged reverts in its constructor on chain 1 until the file is updated with the launched Judge and JudgeEthDoor addresses"},{"citation":"resolved","description":"claim() gates only on pot > 0 and the deadline. Between a Yes verdict on claim A and anyone calling collect(A), the pot is still full, so claimant B can pay the panel price and a stake of pot/100; collect(A) then pays A address(this).balance, which includes B's stake, and B's own later Yes collects 0 (collect pays the empty balance). The README documents 'if there's one prize, close it on the first' and 'a stake left in the pot comes back to whoever wins in the end', and the contract is an example that is not deployed, so this is informational: a seam between execution (claim's gate) and intent (one prize). A tighter example would refuse claim() once any open case reads Yes, or let B withdraw a stake placed after a Yes.","line":40,"path":"src/examples/JudgeDare.sol","reproduction":"JudgeDare with 1 ETH pot (test/Judge.t.sol JudgeDareTest setup). Alice claim{value: 0.02 ether}(PROOF) -> case 1; deliver a signed Yes for case 1. Bob claim{value: 0.02 ether}(PROOF) -> case 2; pot is now 1.01 ETH plus Bob's stake 0.0101. Anyone calls collect(1): Alice receives 1.0201 ETH including Bob's 0.0101 stake. Deliver Yes for case 2 and collect(2): Bob receives 0. Expected by a claimant reading 'a winner gets theirs back': Bob's stake returned or his claim refused once a Yes is pending collection.","severity":"info","snippet":"    function claim(string calldata proof) external payable returns (uint256 id) {\n        uint256 pot = address(this).balance - msg.value;\n        if (pot == 0 || block.timestamp >= deadline) revert DareOver();\n        uint256 stake = pot / 100;\n        if (msg.value <= stake) revert StakeShort(stake, msg.value);\n        string memory named = string.concat(rule, \" The claimant is \", Strings.toHexString(msg.sender), \": the proof must show this address did it.\");\n        id = door.ask{value: msg.value - stake}(named, proof);\n        claimantOf[id] = msg.sender;\n        _pay(msg.sender, address(this).balance - pot - stake);\n    }","title":"JudgeDare.claim accepts new claims (price + 1% stake) after a Yes has already landed but before collect(), and that stake goes to the earlier winner"}],"hash":"fa0e99653e51e0d0641f98d377575201faaa1b2e0782ccde6bf9771f94fe9f9d","nodeId":"e8f01e29-7a9d-4de0-904f-834a93defd90","outcome":"completed","summary":"Review complete. The findings file is written at `.imd-findings.json` with 3 findings and 21 coverage rows, and the working tree is otherwise unchanged.\n\n**Outcome: no critical or high defects in the economics of Judge, JudgeEthDoor or Judged.** Nothing needs fixing before launch, and I changed no contract.\n\n**What I checked, from the Economic Security, Invariant and Flow Gap guides**\n\n- Value flow in `Judge.ask`: the caller pays exactly the live price, the Intake takes it in the same call, and Judge holds nothing afterwards. Confirmed in unit tests and on a mainnet fork against the real Intake.\n- Verdict finality: an answer after the one-day window is refused, a failure callback can only produce NoAnswer, and the view and write paths agree at the boundary.\n- The door's swap and refund: exact output, refund last, zero balance after, and a thin pool or short ETH reverts without cost. Confirmed on a fork of IMD's live pool, where an ask cost about 0.00059 ETH and the change came back.\n- Judged's accounting: the budget cap, the change computed as a balance delta, the one-ask-per-block-sender-value guard, and the busy flag around hooks. I found no path where an ask spends the inheriting contract's own pot.\n- Live dependencies: the IMD token moves exact amounts with no fee on transfer. The Intake sells this action at 0.5 IMD with a 200k callback stipend. The ETH/IMD pool with fee 10000 and spacing 200 exists with liquidity. The signer is a plain EOA.\n\n**Findings**\n\n1. Low. `JudgeEthDoor.ask` has no spend bound except `msg.value`. A sandwich before the ask takes up to the whole attached budget. On the test pool with thin liquidity a searcher netted 0.2 ETH while the victim overpaid 0.24 ETH on a 1 ETH budget. On a deep pool the 1% fee makes it unprofitable, and the README already documents the bound. No code change recommended.\n2. Info. `Judged._judge()` has no Ethereum entry, so anything inheriting Judged reverts on chain 1 until the launched addresses are added after deployment.\n3. Info. `JudgeDare.claim` still accepts claims after a Yes has landed but before `collect`, and that claimant's stake goes to the earlier winner. Documented design in an example contract.\n\n**Deployed addresses and bytecode**\n\nNo Ethereum deployment exists yet, so there are no mainnet addresses to report. The deployed Sepolia Judge's runtime bytecode has the same length as this tree's compiled Judge, with differences confined to short runs at immutable slots. The brief's constructor arguments are exactly what `test/Launch.t.sol` pins.\n\n**One trust assumption to keep in view:** IMD's Intake owner can raise the price or stop selling. On Ethereum the door bounds every ask by the ETH attached, but on the token path, used where no door exists, one ask spends whatever the inheriting contract holds at the current price.","treeHash":null,"usage":{"cachedInputTokens":1264416,"cost":{"source":"runtime","usdMicros":5688170},"inputTokens":354,"model":"claude-fable-5-1","outputTokens":47103,"runtime":"claude","turns":40,"wallClockMs":801536}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"9506ecec995bdbf9","findings":[{"citation":"resolved","description":"_judge() knows only Sepolia and the local stand-in. Its constructor calls _judge(), so on Ethereum every Judged inheritor (e.g. src/examples/EggDare.sol) reverts at deployment until the deployed Judge and JudgeEthDoor addresses are added, as a (judge, door) pair with door.judge() == judge. The README (line 183) states this is intended until Ethereum launches, and no funds are at risk, because deployment reverts before anyone can pay. It is recorded as the follow-up this launch creates: Judged.sol and JudgedTest.sol are not deployed, so updating them after launch changes neither deployed bytecode.","line":126,"path":"src/Judged.sol","reproduction":"On a chain-1 fork (or with vm.chainId(1)), `new EggDare()` reverts with \"Judged: Judge isn't on this chain\". Expected after launch: it deploys and asks through the Ethereum JudgeEthDoor. test/fork/JudgeFork.t.sol works around this with ForkedEggDare overriding _judge().","severity":"info","snippet":"        if (block.chainid == 11155111) return (0x4958501caedC8E3824c8B6E09EB449f5c97Dbe1D, address(0));\n        if (block.chainid == 31337) return (JUDGE_STAND_IN, JUDGE_STAND_IN);\n        revert(\"Judged: Judge isn't on this chain\");","title":"Judged has no Ethereum entry, so no contract inheriting it can deploy on chain 1 once Judge launches"},{"citation":"resolved","description":"Every body asks for panelSize 100 with quorum 51, and both are immutable. POST https://api.imd.fun/requests/check (checked 2026-11-10) returns limits {minPanelSize:5, maxPanelSize:100} and accepts 100. With 101 it gives the blocker \"the flat price covers a panel of up to 100; asked for 101\". So the deployment arguments are valid today, with no headroom. If the plane ever lowers maxPanelSize below 100, each ask still pays 0.5 IMD to the Intake, and the request is refused (status 1). onOracleFailure then sets NoAnswer, or the case reaches NoAnswer after a day. The Judge then charges for every case and never answers one, and the only remedy is a new Judge. This is a trust assumption on the plane, not a code defect; no change is recommended under the no-setter design.","line":206,"path":"src/Judge.sol","reproduction":"State: plane limits.maxPanelSize = N < 100. Input: judge.ask(\"The proof must name the capital of France.\", \"Paris\") with 0.5 IMD approved. Actual: 0.5 IMD moves to the Intake treasury, the plane refuses the body, verdict(id) ends NoAnswer. Expected: a case the price was paid for is answerable. Today (N = 100) the same call is accepted.","severity":"info","snippet":"            ',\"allowAmbiguous\":true,\"panelSize\":',\n            bytes(Strings.toString(panelSize)),","title":"Judge's immutable panelSize 100 equals the plane's current maximum, so a lower cap would refuse every case after charging for it"}],"hash":"ffbf15250e83dbf5416ad8f36c93b691df405fb1757e1269e6a55f22e5ebf0e1","nodeId":"24b53e71-bcae-4cd5-aefb-675a4b31f0d3","outcome":"completed","summary":"I found nothing critical, high or medium in Judge, JudgeEthDoor or Judged, so I left both contracts exactly as they are. I did not deploy anything, so I have no deployed addresses to report. This was a review only: it signs and broadcasts nothing, and I didn't read any wallet keys. The real deployment happens later, through the launch factory.\n\n**Bytecode at the starting commit `72ba6cd1622932b712eae23b2649fac44a41d1a5`:** both contracts compile here, so the later deployment can be checked against these hashes:\n\n| | creation-code keccak | runtime keccak (before immutables are filled in) |\n|---|---|---|\n| Judge | `0x1829917e…be1b55` | `0x216c3a25…d8eed4` |\n| JudgeEthDoor | `0x65b6f259…de68d6` | `0xaaeffc60…95a411` |\n\nJudge's runtime is 12,575 bytes and the door's is 3,314, both under the 24,576-byte limit. Neither constructor calls another contract, and neither contract has an owner, setter, proxy or forbidden opcode.\n\n**What I ran:**\n- **Unit tests:** `forge test --no-match-path \"test/fork/*\"` passed, 105 of 105.\n- **Mainnet fork test** (`test/fork/JudgeFork.t.sol`, using a public RPC): passed. The IMD/ETH pool you specified (fee 10000, tick spacing 200, no hooks) exists and the door's swap settles correctly. The Intake takes the 0.5 IMD price, and a case costs about 0.0006 ETH.\n- **Price manipulation (sandwich attack) on the door:** I ran a temporary test on the fork and found no risk. The pool is deep: a 0.1 ETH front-run raises the user's cost by 0.06%, while the attacker loses about 0.0022 ETH to fees. I deleted the temporary test afterwards.\n- **Panel size:** the oracle's live check endpoint gives a maximum panel of 100. It accepts your 100 seats and refuses 101, so your arguments are valid today with no headroom.\n\n**Findings** (both info, written to `.imd-findings.json`):\n1. **`src/Judged.sol:126`:** Judged only knows the Sepolia and local test addresses, so any contract inheriting it fails to deploy on Ethereum. Your README already says this lasts until Ethereum launches, and no money is at risk. After launch, add the Ethereum Judge and door as a pair. That edit doesn't change either deployed contract.\n2. **`src/Judge.sol:206`:** Judge always asks for 100 seats, which is exactly the oracle's current maximum, and the panel size can't be changed after deployment. If the oracle ever lowers that maximum, every case would still be charged 0.5 IMD and then end with no answer, and only a new Judge would fix it. This is a risk from depending on the oracle, not a bug, and I'm not recommending a change.\n\n**What I read:**\n- **Fully:** `src/Judge.sol`, `src/JudgeEthDoor.sol`, `src/Judged.sol`, `src/OracleAttestation.sol`, `src/OracleQuestion.sol`, `src/JudgedTest.sol`, `src/interfaces/*`, `src/examples/EggDare.sol` and `src/examples/JudgeDare.sol`.\n- **Partly:** the tests, the `Intake` copy in `test/support/` (its header), the README and the protected launch tests.\n- **Not read:** `site/`, `dist/` apart from the deployment JSON, and the real Intake's source on chain (the fork test runs against it).\n\nI had no helpers, so I made the guide's twelve review passes myself.\n\n**What I checked:**\n- Judge's callback accepts only calls from the Intake, and only for a case it asked that is still open. It requires the signed question hash and a panel at least as large as it asked for.\n- The question can't run past the 2,000-character limit: the longest possible one is about 1,946 characters plus the case number.\n- The proof text can't close its own `[PROOF]` brackets.\n- Judged's guards against asking twice, re-entry and miscounted change all held up.\n\nThe one remaining risk is one Judged's README already documents: on Sepolia, anyone can spend an inheriting contract's imdTEST.","treeHash":null,"usage":{"cachedInputTokens":1176601,"cost":{"source":"runtime","usdMicros":1422451},"inputTokens":35,"model":"claude-opus-5-5","outputTokens":27547,"runtime":"claude","turns":18,"wallClockMs":344757}}],"verification":[{"checks":[{"durationMs":8538,"exitCode":0,"name":"build","output":"Compiling 108 files with Solc 0.8.26\nSolc 0.8.26 finished in 8.35s\nCompiler run successful!\n","passed":true},{"durationMs":215,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/Judged.t.sol:JudgedWithoutTheHelperTest\n[PASS] test_saysWhatToDo() (gas: 818880)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 396.08µs (207.09µs CPU time)\n\nRan 3 tests for test/Judge.t.sol:JudgeConformanceTest\n[PASS] test_digestMatchesTheProtocol() (gas: 10579)\n[PASS] test_theIntakeReachesBothFunctions() (gas: 652)\n[PASS] test_theProtocolsSignatureRecoversFromTheJudgesDigest() (gas: 21506)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 1.22ms (576.17µs CPU time)\n\nRan 10 tests for test/Judge.t.sol:JudgeEthDoorTest\n[PASS] test_aCallerThatTakesNoRefundIsToldSoAndLosesNothing() (gas: 1152479)\n[PASS] test_aPoolTooThinForThePriceReverts() (gas: 504342)\n[PASS] test_aRefundThatOpensAnotherCaseIsJustAnotherCase() (gas: 1478389)\n[PASS] test_aTokenLeftSyncedEarlierInTheTransactionDoesNotStopAnAsk() (gas: 1025387)\n[PASS] test_badTextCostsNothing() (gas: 443738)\n[PASS] test_ethBuysExactlyThePriceAndTheRestComesBack() (gas: 1016575)\n[PASS] test_exactlyEnoughLeavesNothingToRefund() (gas: 1651098)\n[PASS] test_nobodyButThePoolManagerRunsTheSwap() (gas: 326265)\n[PASS] test_strayEthIsRefused() (gas: 70940)\n[PASS] test_tooLittleEthRevertsAndCostsNothing() (gas: 378121)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 8.24ms (13.77ms CPU time)\n\nRan 45 tests for test/Judged.t.sol:JudgedStandInTest\n[PASS] test_aBudgetCantReachPastWhatWasSent() (gas: 849979)\n[PASS] test_aBudgetOfNothingGetsThePlainMessage() (gas: 874750)\n[PASS] test_aCallerThatCantTakeChangeCostsNothing() (gas: 328500)\n[PASS] test_aDayOfSilenceEndsInNoAnswerAndCanStillSettle() (gas: 1082951)\n[PASS] test_aDevsOwnVmTypesWorkBesideIt() (gas: 173191)\n[PASS] test_aFunctionThatIsntPayableGetsThePlainMessage() (gas: 791992)\n[PASS] test_aMulticallCantGetRoundItWithATrailingByte() (gas: 1028904)\n[PASS] test_aMulticallOfOneStillWorks() (gas: 1004765)\n[PASS] test_aPayableMulticallCantSpendThePot() (gas: 1028806)\n[PASS] test_aReceiveThatRefusesTheChangeRevertsAndCostsNothing() (gas: 875805)\n[PASS] test_aSecondAskInOneCallCantSpendThePot() (gas: 939876)\n[PASS] test_aSecondYesCantCallInFromThePayout() (gas: 1483075)\n[PASS] test_aStakeStaysAndOnlyTheBudgetsChangeGoesBack() (gas: 972456)\n[PASS] test_aWinnerThatRefusesMoneyStaysOpenUntilTheyTakeIt() (gas: 1351332)\n[PASS] test_aYesStaysYesAfterTheDay() (gas: 227305)\n[PASS] test_anAnswerComesFromTheJudgeThatWasAsked() (gas: 1257317)\n[PASS] test_anIdNobodyAskedStaysPending() (gas: 11163)\n[PASS] test_anotherChainSaysSo() (gas: 63005)\n[PASS] test_anotherValueInTheSameBlockIsAnotherQuestion() (gas: 308825)\n[PASS] test_askingFromTheChangeIsRefused() (gas: 1138830)\n[PASS] test_askingFromTheChangeRevertsTheWholeThing() (gas: 391905)\n[PASS] test_asksSayWhoAndWhichId() (gas: 172418)\n[PASS] test_calledAgainFromThePayoutItDoesntPayTwice() (gas: 1267602)\n[PASS] test_cantActWhileVoting() (gas: 212032)\n[PASS] test_eachAnswerRunsItsOwnHookOnItsOwnId() (gas: 1681718)\n[PASS] test_fundingTheContractIsAPlainSend() (gas: 33107)\n[PASS] test_itKnowsWhereJudgeIs() (gas: 784336)\n[PASS] test_itWontDeployWhereThereIsNoJudge() (gas: 142095)\n[PASS] test_itWontPayNobody() (gas: 1017629)\n[PASS] test_noAnswerPaysNobody() (gas: 280823)\n[PASS] test_noEthGetsAPlainMessage() (gas: 58621)\n[PASS] test_noPaysNobody() (gas: 280767)\n[PASS] test_paysASmartWalletThatTransferWouldStarve() (gas: 1265169)\n[PASS] test_settlingFromTheChangeIsRefused() (gas: 1518350)\n[PASS] test_spendingPartOfWhatWasSentWithABudgetLeavesThePotWhole() (gas: 952014)\n[PASS] test_strangersIdsAreRefused() (gas: 203926)\n[PASS] test_theBudgetIsTheMostTheSwapCanCost() (gas: 889430)\n[PASS] test_theChangeGoesBackToWhoeverAsked() (gas: 168198)\n[PASS] test_theHelperMovesTheClockAsAnAnswerWould() (gas: 218914)\n[PASS] test_theHelperWontAnswerTwiceOrAfterTheDay() (gas: 451980)\n[PASS] test_theSameSenderAndValueTwiceInABlockAskOnce() (gas: 344839)\n[PASS] test_thereIsAlwaysChangeAsOnARealPool() (gas: 243955)\n[PASS] test_tooLittleEthRevertsAndCostsNothing() (gas: 85728)\n[PASS] test_twoPeopleInABlockAreTwoQuestions() (gas: 313331)\n[PASS] test_yesPaysAliceOnce() (gas: 337718)\nSuite result: ok. 45 passed; 0 failed; 0 skipped; finished in 12.17ms (21.46ms CPU time)\n\nRan 2 tests for test/fork/JudgeFork.t.sol:JudgeForkTest\n[SKIP] test_ethereum() (gas: 0)\n[SKIP] test_sepolia() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 2 skipped; finished in 19.06ms (242.41µs CPU time)\n\nRan 6 tests for test/Launch.t.sol:LaunchTest\n[PASS] test_askOnAnEmptyChainRevertsWithoutOpeningACase() (gas: 236841)\n[PASS] test_doorPointsAtTheJudgeLaunchedBeforeIt() (gas: 34452)\n[PASS] test_judgeHoldsTheBriefsArguments() (gas: 42534)\n[PASS] test_neitherHasAnOwner() (gas: 141294)\n[PASS] test_questionWordingIsUnchanged() (gas: 56866)\n[PASS] test_runtimeFitsAndHasNoForbiddenOpcodes() (gas: 5485179)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 19.14ms (19.72ms CPU time)\n\nRan 11 tests for test/Judge.t.sol:JudgeDareTest\n[PASS] test_aClaimKeepsThePotAndTheStakeAndRefundsTheRest() (gas: 705554)\n[PASS] test_aDareThatPaidOutTakesNoMoreClaims() (gas: 894534)\n[PASS] test_aRuleTheJudgeCannotTakeStillLetsTheCreatorTakeThePotBack() (gas: 1479520)\n[PASS] test_aWinnerThatRefusesPaymentLeavesThePotInPlace() (gas: 1103831)\n[PASS] test_aYesFromAnotherCaseMovesNothing() (gas: 745355)\n[PASS] test_aYesPaysThePotToTheClaimantWhoeverCollects() (gas: 913770)\n[PASS] test_afterTheDeadlineNoClaimsAndTheCreatorTakesWhatIsLeft() (gas: 811818)\n[PASS] test_eachTryCostsAStakeAndTheStakeGrowsWithThePot() (gas: 767215)\n[PASS] test_nobodyTopsUpThePot() (gas: 38000)\n[PASS] test_nothingButAYesMovesThePot() (gas: 2295178)\n[PASS] test_theRuleNamesTheClaimantSoACopiedProofIsAnotherQuestion() (gas: 1882889)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 16.58ms (26.51ms CPU time)\n\nRan 24 tests for test/Judge.t.sol:JudgeTest\n[PASS] test_aBadSignatureIsRefused() (gas: 4535603)\n[PASS] test_aFailureEndsTheCaseWithNoRuling() (gas: 629546)\n[PASS] test_aNoIsRecordedNotReverted() (gas: 605878)\n[PASS] test_aPanelWeakerThanTheCaseAskedForIsRefused() (gas: 1653849)\n[PASS] test_aQuietCaseIsOverAfterADayAndALateAnswerIsRefused() (gas: 617795)\n[PASS] test_aRefusalEndsTheCaseToo() (gas: 571365)\n[PASS] test_aStrangerPayingForAnAnswerAndNamingTheJudgeGetsNoVerdict() (gas: 776386)\n[PASS] test_aVerdictIsFinal() (gas: 686926)\n[PASS] test_aYesIsAYes() (gas: 610843)\n[PASS] test_anAnswerOfAnotherTypeIsRefused() (gas: 599813)\n[PASS] test_anExpiredAttestationIsRefused() (gas: 587712)\n[PASS] test_anUnknownRequestIsRefusedAndAnUnknownCaseReadsPending() (gas: 103556)\n[PASS] test_answersSwappedBetweenTwoCasesAreRefused() (gas: 1185635)\n[PASS] test_askSendsTheBodyTheOracleTakesAndPinsItsHash() (gas: 543071)\n[PASS] test_badTextRevertsBeforeAnythingIsPaid() (gas: 410858)\n[PASS] test_eachCaseHasItsOwnQuestion() (gas: 1633371)\n[PASS] test_hostileTextStaysInsideItsBrackets() (gas: 814293)\n[PASS] test_onlyAMajorityPanelCanBeDeployed() (gas: 986487)\n[PASS] test_onlyTheIntakeCallsBack() (gas: 566348)\n[PASS] test_theAskerPaysOnePriceAndNothingStaysBehind() (gas: 778475)\n[PASS] test_theCallbackFitsTheStipendWithRoomToSpare() (gas: 568182)\nLogs:\n  callback gas: 59139\n\n[PASS] test_theLongestCaseFitsWhatTheOracleTakes() (gas: 571709)\n[PASS] test_thePriceIsTheIntakesOwn() (gas: 841419)\n[PASS] test_whatAnAskCosts() (gas: 1687758)\nLogs:\n  ask gas, short text, first case: 520097\n  ask gas, longest text: 1066465\n\nSuite result: ok. 24 passed; 0 failed; 0 skipped; finished in 19.22ms (67.99ms CPU time)\n\nRan 11 tests for test/Judged.t.sol:JudgedOnTheRealThingTest\n[PASS] test_aPayableMulticallCantSpendThePotOnTheRealDoor() (gas: 1620385)\n[PASS] test_aQuestionAskedAroundItIsAStrangers() (gas: 750937)\n[PASS] test_aRealYesAndARealNoRunTheirHooksOnce() (gas: 1729428)\n[PASS] test_aRefusalAndADayOfSilenceRunNoAnswer() (gas: 1455858)\n[PASS] test_paysWithEthAndTheChangeComesBack() (gas: 658245)\nLogs:\n  ask through Judged, gas: 733273\n\n[PASS] test_theStandInAndTheRealVerdictNumbersAgree() (gas: 541)\n[PASS] test_theStandInRefusesWhatTheRealOneRefuses() (gas: 3682676)\n[PASS] test_tooLittleEthIsTheDoorsOwnErrorTheStandInsToo() (gas: 154674)\n[PASS] test_withoutADoorItPaysInTheToken() (gas: 1627676)\n[PASS] test_withoutADoorNoChangeMeansNoCall() (gas: 1518398)\n[PASS] test_withoutADoorOrTheTokenItReverts() (gas: 1094649)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 15.43ms (23.49ms CPU time)\n\nRan 9 test suites in 23.00ms (111.45ms CPU time): 111 tests passed, 0 failed, 2 skipped (113 total tests)\n","passed":true},{"durationMs":154,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"EggDare.claim(string)\",\"EggDare.receive()\",\"EggDare.settle(uint256)\",\"Judge.ask(string,string)\",\"Judge.onOracleFailure(bytes32,uint8,bytes32,uint16,uint16,bytes)\",\"Judge.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"JudgeDare.claim(string)\",\"JudgeDare.collect(uint256)\",\"JudgeDare.receive()\",\"JudgeDare.reclaim()\",\"JudgeEthDoor.ask(string,string)\",\"JudgeEthDoor.unlockCallback(bytes)\",\"JudgeStandIn.answer(uint256,uint8)\",\"JudgeStandIn.ask(string,string)\"],\"files\":{\".gitignore\":7,\"ADAPTATION.md\":136,\"DESIGN.md\":31,\"LICENSE\":21,\"README.md\":194,\"dist/abi/Judge.json\":1,\"dist/abi/JudgeEthDoor.json\":1,\"dist/assets/ccip-CQQTyd0_.js\":1,\"dist/assets/dist-7et0wmat.js\":3,\"dist/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff\":60,\"dist/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2\":58,\"dist/assets/index-BB5R1v-O.css\":1,\"dist/assets/index-F11-2Iby.js\":44,\"dist/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2\":95,\"dist/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2\":88,\"dist/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2\":48,\"dist/assets/inter-greek-wght-normal-CkhJZR-_.woff2\":66,\"dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2\":329,\"dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2\":207,\"dist/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2\":37,\"dist/favicon.svg\":1,\"dist/imd-deployment.json\":28,\"dist/index.html\":37,\"dist/og.png\":344,\"dist/skill.md\":189,\"foundry.toml\":20,\"launch.json\":26,\"site/index.html\":36,\"site/package.json\":29,\"site/pnpm-lock.yaml\":1101,\"site/public/abi/Judge.json\":1,\"site/public/abi/JudgeEthDoor.json\":1,\"site/public/favicon.svg\":1,\"site/public/imd-deployment.json\":28,\"site/public/og.png\":344,\"site/public/skill.md\":189,\"site/src/App.tsx\":434,\"site/src/AskPanel.tsx\":228,\"site/src/CasePage.tsx\":227,\"site/src/ask.ts\":149,\"site/src/cases.ts\":171,\"site/src/deployment.ts\":115,\"site/src/main.tsx\":45,\"site/src/snippet.ts\":52,\"site/src/styles.css\":1112,\"site/src/text.ts\":114,\"site/src/wallet-marks.ts\":6,\"site/src/wallet.tsx\":195,\"site/tsconfig.json\":17,\"site/vite.config.ts\":11,\"src/Judge.sol\":232,\"src/JudgeEthDoor.sol\":82,\"src/Judged.sol\":134,\"src/JudgedTest.sol\":108,\"src/OracleAttestation.sol\":221,\"src/OracleQuestion.sol\":255,\"src/examples/EggDare.sol\":19,\"src/examples/JudgeDare.sol\":70,\"src/interfaces/IIntake.sol\":24,\"src/interfaces/IJudge.sol\":32,\"test/Judge.t.sol\":940,\"test/Judged.t.sol\":940,\"test/Launch.t.sol\":125,\"test/fork/JudgeFork.t.sol\":216,\"test/support/DeployJudge.s.sol\":43,\"test/support/Intake.sol\":322,\"test/support/MockERC20.sol\":49,\"wrangler.jsonc\":8},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"60673ca3dd40b54f97e740af62dafd709b6f17d600e77749cbe6ab362b10c98a","verifiedTreeHash":"def237249d9dbdd9b7a40b6adf32f6ad788da6dd","verifierVersion":"0.1.0+15e8bc6b"},{"checks":[{"durationMs":11474,"exitCode":0,"name":"build","output":"Compiling 117 files with Solc 0.8.26\nSolc 0.8.26 finished in 11.27s\nCompiler run successful!\n","passed":true},{"durationMs":20582,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/JudgeProperties.t.sol:OracleQuestionProtocolVectorTest\n[PASS] test_questionHashMatchesProtocolVector() (gas: 34752)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.11ms (166.99µs CPU time)\n\nRan 1 test for test/Judged.t.sol:JudgedWithoutTheHelperTest\n[PASS] test_saysWhatToDo() (gas: 818880)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.31ms (198.56µs CPU time)\n\nRan 1 test for test/LaunchBatch.t.sol:LaunchBatchTest\n[PASS] test_factoryDeploysExactlyTheTwoApplicationsInOneCall() (gas: 3664126)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.46ms (521.25µs CPU time)\n\nRan 6 tests for test/JudgePaymentFailures.t.sol:JudgePaymentFailuresTest\n[PASS] test_failedApprovalRollsBackPayersTransfer() (gas: 932520)\n[PASS] test_falseReturnOnFirstPullRevertsTheMutation() (gas: 930877)\n[PASS] test_falseReturnOnIntakePullRevertsBothTransfers() (gas: 1076306)\n[PASS] test_forceApproveClearsAResidualAllowanceForResetFirstToken() (gas: 606074)\n[PASS] test_intakeRevertRollsBackPaymentApprovalAndCounter() (gas: 883584)\n[PASS] test_tokensWithoutReturnDataCanPayThroughBothHops() (gas: 588620)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 11.66ms (14.84ms CPU time)\n\nRan 10 tests for test/Judge.t.sol:JudgeEthDoorTest\n[PASS] test_aCallerThatTakesNoRefundIsToldSoAndLosesNothing() (gas: 1152479)\n[PASS] test_aPoolTooThinForThePriceReverts() (gas: 504342)\n[PASS] test_aRefundThatOpensAnotherCaseIsJustAnotherCase() (gas: 1478389)\n[PASS] test_aTokenLeftSyncedEarlierInTheTransactionDoesNotStopAnAsk() (gas: 1025387)\n[PASS] test_badTextCostsNothing() (gas: 443738)\n[PASS] test_ethBuysExactlyThePriceAndTheRestComesBack() (gas: 1016575)\n[PASS] test_exactlyEnoughLeavesNothingToRefund() (gas: 1651098)\n[PASS] test_nobodyButThePoolManagerRunsTheSwap() (gas: 326265)\n[PASS] test_strayEthIsRefused() (gas: 70940)\n[PASS] test_tooLittleEthRevertsAndCostsNothing() (gas: 378121)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 991.16ms (15.10ms CPU time)\n\nRan 24 tests for test/Judge.t.sol:JudgeTest\n[PASS] test_aBadSignatureIsRefused() (gas: 4535603)\n[PASS] test_aFailureEndsTheCaseWithNoRuling() (gas: 629546)\n[PASS] test_aNoIsRecordedNotReverted() (gas: 605878)\n[PASS] test_aPanelWeakerThanTheCaseAskedForIsRefused() (gas: 1653849)\n[PASS] test_aQuietCaseIsOverAfterADayAndALateAnswerIsRefused() (gas: 617795)\n[PASS] test_aRefusalEndsTheCaseToo() (gas: 571365)\n[PASS] test_aStrangerPayingForAnAnswerAndNamingTheJudgeGetsNoVerdict() (gas: 776386)\n[PASS] test_aVerdictIsFinal() (gas: 686926)\n[PASS] test_aYesIsAYes() (gas: 610843)\n[PASS] test_anAnswerOfAnotherTypeIsRefused() (gas: 599813)\n[PASS] test_anExpiredAttestationIsRefused() (gas: 587712)\n[PASS] test_anUnknownRequestIsRefusedAndAnUnknownCaseReadsPending() (gas: 103556)\n[PASS] test_answersSwappedBetweenTwoCasesAreRefused() (gas: 1185635)\n[PASS] test_askSendsTheBodyTheOracleTakesAndPinsItsHash() (gas: 543071)\n[PASS] test_badTextRevertsBeforeAnythingIsPaid() (gas: 410858)\n[PASS] test_eachCaseHasItsOwnQuestion() (gas: 1633371)\n[PASS] test_hostileTextStaysInsideItsBrackets() (gas: 814293)\n[PASS] test_onlyAMajorityPanelCanBeDeployed() (gas: 986487)\n[PASS] test_onlyTheIntakeCallsBack() (gas: 566348)\n[PASS] test_theAskerPaysOnePriceAndNothingStaysBehind() (gas: 778475)\n[PASS] test_theCallbackFitsTheStipendWithRoomToSpare() (gas: 568182)\nLogs:\n  callback gas: 59139\n\n[PASS] test_theLongestCaseFitsWhatTheOracleTakes() (gas: 571709)\n[PASS] test_thePriceIsTheIntakesOwn() (gas: 841419)\n[PASS] test_whatAnAskCosts() (gas: 1687758)\nLogs:\n  ask gas, short text, first case: 520097\n  ask gas, longest text: 1066465\n\nSuite result: ok. 24 passed; 0 failed; 0 skipped; finished in 1.11s (52.67ms CPU time)\n\nRan 11 tests for test/Judged.t.sol:JudgedOnTheRealThingTest\n[PASS] test_aPayableMulticallCantSpendThePotOnTheRealDoor() (gas: 1620385)\n[PASS] test_aQuestionAskedAroundItIsAStrangers() (gas: 750937)\n[PASS] test_aRealYesAndARealNoRunTheirHooksOnce() (gas: 1729428)\n[PASS] test_aRefusalAndADayOfSilenceRunNoAnswer() (gas: 1455858)\n[PASS] test_paysWithEthAndTheChangeComesBack() (gas: 658245)\nLogs:\n  ask through Judged, gas: 733273\n\n[PASS] test_theStandInAndTheRealVerdictNumbersAgree() (gas: 541)\n[PASS] test_theStandInRefusesWhatTheRealOneRefuses() (gas: 3682676)\n[PASS] test_tooLittleEthIsTheDoorsOwnErrorTheStandInsToo() (gas: 154674)\n[PASS] test_withoutADoorItPaysInTheToken() (gas: 1627676)\n[PASS] test_withoutADoorNoChangeMeansNoCall() (gas: 1518398)\n[PASS] test_withoutADoorOrTheTokenItReverts() (gas: 1094649)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 1.11s (22.79ms CPU time)\n\nRan 5 tests for test/JudgedAdversarial.t.sol:JudgedAdversarialTest\n[PASS] testFuzz_onlyTheExplicitStakeStaysAndRelayerCannotStealReward(uint256,uint256) (runs: 1000, μ: 1002754, ~: 1002691)\nLogs:\n  Bound result 255\n  Bound result 2000000000000000094\n\n[PASS] test_payoutCannotOpenACaseOrSettleAnotherYes() (gas: 2292808)\n[PASS] test_refundCannotSettleAnOlderYesOrOpenAnotherQuestion() (gas: 2000206)\n[PASS] test_refusedChangeRollsBackCaseStakeAndPoolAndCanRetrySameBlock() (gas: 1637312)\n[PASS] test_rejectingWinnerCanRetryAndCannotBlockAnotherWinner() (gas: 2118733)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 1.12s (1.09s CPU time)\n\nRan 11 tests for test/Judge.t.sol:JudgeDareTest\n[PASS] test_aClaimKeepsThePotAndTheStakeAndRefundsTheRest() (gas: 705554)\n[PASS] test_aDareThatPaidOutTakesNoMoreClaims() (gas: 894534)\n[PASS] test_aRuleTheJudgeCannotTakeStillLetsTheCreatorTakeThePotBack() (gas: 1479520)\n[PASS] test_aWinnerThatRefusesPaymentLeavesThePotInPlace() (gas: 1103831)\n[PASS] test_aYesFromAnotherCaseMovesNothing() (gas: 745355)\n[PASS] test_aYesPaysThePotToTheClaimantWhoeverCollects() (gas: 913770)\n[PASS] test_afterTheDeadlineNoClaimsAndTheCreatorTakesWhatIsLeft() (gas: 811818)\n[PASS] test_eachTryCostsAStakeAndTheStakeGrowsWithThePot() (gas: 767215)\n[PASS] test_nobodyTopsUpThePot() (gas: 38000)\n[PASS] test_nothingButAYesMovesThePot() (gas: 2295178)\n[PASS] test_theRuleNamesTheClaimantSoACopiedProofIsAnotherQuestion() (gas: 1882889)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 1.22s (32.72ms CPU time)\n\nRan 17 tests for test/JudgeProperties.t.sol:JudgePropertiesTest\n[PASS] testFuzz_allSignedFieldsAreAuthenticated(uint8) (runs: 1000, μ: 592723, ~: 592695)\nLogs:\n  Bound result 13\n\n[PASS] testFuzz_caseDeadlineCannotReopen(uint256,bool) (runs: 1000, μ: 1173870, ~: 1173917)\nLogs:\n  Bound result 31449664\n\n[PASS] testFuzz_failedTokenPullDoesNotLeaveAGhostCase(uint256) (runs: 1000, μ: 877486, ~: 877210)\nLogs:\n  Bound result 430117985794680272\n\n[PASS] testFuzz_minimumPanelIsRequired(uint16,uint16,uint16) (runs: 1000, μ: 586630, ~: 585998)\nLogs:\n  Bound result 143\n  Bound result 41\n  Bound result 15\n\n[PASS] testFuzz_nonAsciiAtEveryPositionRevertsBeforePayment(uint256,uint8,bool) (runs: 1000, μ: 204773, ~: 197674)\nLogs:\n  Bound result 28\n  Bound result 228\n\n[PASS] testFuzz_priceIsPaidExactlyIncludingOneWei(uint256) (runs: 1000, μ: 574798, ~: 574608)\nLogs:\n  Bound result 7284568350120274857\n\n[PASS] test_answerAtTheExactCaseDeadlineIsAccepted() (gas: 634179)\n[PASS] test_emptyAndTruncatedSignaturesAreRejected() (gas: 703084)\n[PASS] test_expiredAttestationDoesNotConsumeTheCase() (gas: 663352)\n[PASS] test_expiryAndClockToleranceAreInclusive() (gas: 1179337)\n[PASS] test_failedDeliveryCanTimeOutWithoutBlockingNewCases() (gas: 1106186)\n[PASS] test_futureAttestationOneSecondBeyondToleranceIsRejected() (gas: 577626)\n[PASS] test_highSSignatureIsRejected() (gas: 582525)\n[PASS] test_oneWeiPriceAndFullBalancePayment() (gas: 1032634)\n[PASS] test_signatureForAnotherChainIsRejected() (gas: 589298)\n[PASS] test_signedMalformedBooleanDoesNotConsumeCase() (gas: 747921)\n[PASS] test_zeroSignerCannotBeDeployed() (gas: 316014)\nSuite result: ok. 17 passed; 0 failed; 0 skipped; finished in 1.25s (6.03s CPU time)\n\nRan 3 tests for test/Judge.t.sol:JudgeConformanceTest\n[PASS] test_digestMatchesTheProtocol() (gas: 10579)\n[PASS] test_theIntakeReachesBothFunctions() (gas: 652)\n[PASS] test_theProtocolsSignatureRecoversFromTheJudgesDigest() (gas: 21506)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 1.25s (1.57ms CPU time)\n\nRan 2 tests for test/fork/JudgeFork.t.sol:JudgeForkTest\n[SKIP] test_ethereum() (gas: 0)\n[SKIP] test_sepolia() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 2 skipped; finished in 1.25s (213.78µs CPU time)\n\nRan 7 tests for test/JudgeEthDoorProperties.t.sol:JudgeEthDoorPropertiesTest\n[PASS] testFuzz_exactOutputAndRefundConserveBothAssets(uint256,uint256,uint256) (runs: 1000, μ: 984415, ~: 984188)\nLogs:\n  Bound result 579101041044267782\n  Bound result 500000000000000000000\n  Bound result 10000000000000000000\n\n[PASS] testFuzz_nestedRefundsAreFundedByTheirOwnCaller(uint8) (runs: 1000, μ: 1847790, ~: 1634298)\nLogs:\n  Bound result 3\n\n[PASS] testFuzz_oneWeiBelowTheQuoteRollsBackEverything(uint256) (runs: 1000, μ: 1944770, ~: 1944500)\nLogs:\n  Bound result 254\n\n[PASS] test_donatedEthAndTokensDoNotSubsidizeTheNextAsker() (gas: 1148122)\n[PASS] test_invalidTextAfterTheSwapRevertsPoolState() (gas: 587451)\n[PASS] test_partialOutputCannotSpendDustOrChargeForACase() (gas: 696085)\n[PASS] test_refundFailureRevertsPoolPriceAndPaymentThenAnotherUserSucceeds() (gas: 1879637)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 1.25s (3.47s CPU time)\n\nRan 6 tests for test/Launch.t.sol:LaunchTest\n[PASS] test_askOnAnEmptyChainRevertsWithoutOpeningACase() (gas: 236841)\n[PASS] test_doorPointsAtTheJudgeLaunchedBeforeIt() (gas: 34452)\n[PASS] test_judgeHoldsTheBriefsArguments() (gas: 42534)\n[PASS] test_neitherHasAnOwner() (gas: 141294)\n[PASS] test_questionWordingIsUnchanged() (gas: 56866)\n[PASS] test_runtimeFitsAndHasNoForbiddenOpcodes() (gas: 5485179)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 1.25s (18.74ms CPU time)\n\nRan 3 tests for test/JudgeQuestionProperties.t.sol:JudgeQuestionPropertiesTest\n[PASS] testFuzz_asciiBodyRoundTrips(uint256,uint256,uint256) (runs: 256, μ: 3580996, ~: 3583115)\nLogs:\n  Bound result 220\n  Bound result 103\n\n[PASS] test_everyAsciiByteIncludingAllJsonEscapes() (gas: 2533534)\n[PASS] test_maximumTextLengthAndMaximumEscaping() (gas: 6214242)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 1.37s (1.43s CPU time)\n\nRan 45 tests for test/Judged.t.sol:JudgedStandInTest\n[PASS] test_aBudgetCantReachPastWhatWasSent() (gas: 849979)\n[PASS] test_aBudgetOfNothingGetsThePlainMessage() (gas: 874750)\n[PASS] test_aCallerThatCantTakeChangeCostsNothing() (gas: 328500)\n[PASS] test_aDayOfSilenceEndsInNoAnswerAndCanStillSettle() (gas: 1082951)\n[PASS] test_aDevsOwnVmTypesWorkBesideIt() (gas: 173191)\n[PASS] test_aFunctionThatIsntPayableGetsThePlainMessage() (gas: 791992)\n[PASS] test_aMulticallCantGetRoundItWithATrailingByte() (gas: 1028904)\n[PASS] test_aMulticallOfOneStillWorks() (gas: 1004765)\n[PASS] test_aPayableMulticallCantSpendThePot() (gas: 1028806)\n[PASS] test_aReceiveThatRefusesTheChangeRevertsAndCostsNothing() (gas: 875805)\n[PASS] test_aSecondAskInOneCallCantSpendThePot() (gas: 939876)\n[PASS] test_aSecondYesCantCallInFromThePayout() (gas: 1483075)\n[PASS] test_aStakeStaysAndOnlyTheBudgetsChangeGoesBack() (gas: 972456)\n[PASS] test_aWinnerThatRefusesMoneyStaysOpenUntilTheyTakeIt() (gas: 1351332)\n[PASS] test_aYesStaysYesAfterTheDay() (gas: 227305)\n[PASS] test_anAnswerComesFromTheJudgeThatWasAsked() (gas: 1257317)\n[PASS] test_anIdNobodyAskedStaysPending() (gas: 11163)\n[PASS] test_anotherChainSaysSo() (gas: 63005)\n[PASS] test_anotherValueInTheSameBlockIsAnotherQuestion() (gas: 308825)\n[PASS] test_askingFromTheChangeIsRefused() (gas: 1138830)\n[PASS] test_askingFromTheChangeRevertsTheWholeThing() (gas: 391905)\n[PASS] test_asksSayWhoAndWhichId() (gas: 172418)\n[PASS] test_calledAgainFromThePayoutItDoesntPayTwice() (gas: 1267602)\n[PASS] test_cantActWhileVoting() (gas: 212032)\n[PASS] test_eachAnswerRunsItsOwnHookOnItsOwnId() (gas: 1681718)\n[PASS] test_fundingTheContractIsAPlainSend() (gas: 33107)\n[PASS] test_itKnowsWhereJudgeIs() (gas: 784336)\n[PASS] test_itWontDeployWhereThereIsNoJudge() (gas: 142095)\n[PASS] test_itWontPayNobody() (gas: 1017629)\n[PASS] test_noAnswerPaysNobody() (gas: 280823)\n[PASS] test_noEthGetsAPlainMessage() (gas: 58621)\n[PASS] test_noPaysNobody() (gas: 280767)\n[PASS] test_paysASmartWalletThatTransferWouldStarve() (gas: 1265169)\n[PASS] test_settlingFromTheChangeIsRefused() (gas: 1518350)\n[PASS] test_spendingPartOfWhatWasSentWithABudgetLeavesThePotWhole() (gas: 952014)\n[PASS] test_strangersIdsAreRefused() (gas: 203926)\n[PASS] test_theBudgetIsTheMostTheSwapCanCost() (gas: 889430)\n[PASS] test_theChangeGoesBackToWhoeverAsked() (gas: 168198)\n[PASS] test_theHelperMovesTheClockAsAnAnswerWould() (gas: 218914)\n[PASS] test_theHelperWontAnswerTwiceOrAfterTheDay() (gas: 451980)\n[PASS] test_theSameSenderAndValueTwiceInABlockAskOnce() (gas: 344839)\n[PASS] test_thereIsAlwaysChangeAsOnARealPool() (gas: 243955)\n[PASS] test_tooLittleEthRevertsAndCostsNothing() (gas: 85728)\n[PASS] test_twoPeopleInABlockAreTwoQuestions() (gas: 313331)\n[PASS] test_yesPaysAliceOnce() (gas: 337718)\nSuite result: ok. 45 passed; 0 failed; 0 skipped; finished in 1.37s (18.10ms CPU time)\n\nRan 2 tests for test/JudgeInvariant.t.sol:JudgeInvariantTest\n[PASS] invariant_accountingAndCaseLifecycles() (runs: 256, calls: 16384, reverts: 0)\n\n╭-----------------------+---------------+-------+---------+----------╮\n| Contract              | Selector      | Calls | Reverts | Discards |\n+====================================================================+\n| JudgeInvariantHandler | advanceTime   | 1467  | 0       | 0        |\n|-----------------------+---------------+-------+---------+----------|\n| JudgeInvariantHandler | answer        | 1495  | 0       | 0        |\n|-----------------------+---------------+-------+---------+----------|\n| JudgeInvariantHandler | askEther      | 1550  | 0       | 0        |\n|-----------------------+---------------+-------+---------+----------|\n| JudgeInvariantHandler | askToken      | 1469  | 0       | 0        |\n|-----------------------+---------------+-------+---------+----------|\n| JudgeInvariantHandler | badCallback   | 1493  | 0       | 0        |\n|-----------------------+---------------+-------+---------+----------|\n| JudgeInvariantHandler | claimVault    | 1479  | 0       | 0        |\n|-----------------------+---------------+-------+---------+----------|\n| JudgeInvariantHandler | donate        | 1505  | 0       | 0        |\n|-----------------------+---------------+-------+---------+----------|\n| JudgeInvariantHandler | oracleFailure | 1436  | 0       | 0        |\n|-----------------------+---------------+-------+---------+----------|\n| JudgeInvariantHandler | rejectedAsk   | 1480  | 0       | 0        |\n|-----------------------+---------------+-------+---------+----------|\n| JudgeInvariantHandler | setPrice      | 1478  | 0       | 0        |\n|-----------------------+---------------+-------+---------+----------|\n| JudgeInvariantHandler | settle        | 1532  | 0       | 0        |\n╰-----------------------+---------------+-------+---------+----------╯\n\nLogs:\n  Bound result 10000\n  Bound result 1800000000\n  Bound result 11281\n  Bound result 10000000000000000\n  Bound result 25\n  Bound result 172800\n  Bound result 650603603826144271\n  Bound result 300\n  Bound result 1000000000\n  Bound result 60694\n  Bound result 63\n  Bound result 1\n  Bound result 4708107594723847\n  Bound result 629\n  Bound result 2907\n  Bound result 86\n  Bound result 17123\n  Bound result 20646\n  Bound result 6928\n  Bound result 363523773954249005\n  Bound result 15\n  Bound result 6348\n  Bound result 1036\n  Bound result 17434\n  Bound result 635080794988755014\n  Bound result 99999999999999999\n  Bound result 893180453620777375\n  Bound result 414282546059\n  Bound result 85216\n  Bound result 990000000000000000\n  Bound result 6037\n  Bound result 1000000000\n\n[PASS] test_handlerReachesPaymentSettlementFailureAndTimeout() (gas: 7346418)\nLogs:\n  Bound result 0\n  Bound result 99999999999999991\n  Bound result 0\n  Bound result 0\n  Bound result 1\n  Bound result 10\n  Bound result 0\n  Bound result 86401\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 1\n  Bound result 0\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 20.38s (20.39s CPU time)\n\nRan 17 test suites in 20.39s (34.93s CPU time): 153 tests passed, 0 failed, 2 skipped (155 total tests)\n","passed":true},{"durationMs":181,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"EggDare.claim(string)\",\"EggDare.receive()\",\"EggDare.settle(uint256)\",\"Judge.ask(string,string)\",\"Judge.onOracleFailure(bytes32,uint8,bytes32,uint16,uint16,bytes)\",\"Judge.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"JudgeDare.claim(string)\",\"JudgeDare.collect(uint256)\",\"JudgeDare.receive()\",\"JudgeDare.reclaim()\",\"JudgeEthDoor.ask(string,string)\",\"JudgeEthDoor.unlockCallback(bytes)\",\"JudgeStandIn.answer(uint256,uint8)\",\"JudgeStandIn.ask(string,string)\"],\"files\":{\".gitignore\":7,\"ADAPTATION.md\":136,\"DESIGN.md\":31,\"LICENSE\":21,\"README.md\":194,\"dist/abi/Judge.json\":1,\"dist/abi/JudgeEthDoor.json\":1,\"dist/assets/ccip-CQQTyd0_.js\":1,\"dist/assets/dist-7et0wmat.js\":3,\"dist/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff\":60,\"dist/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2\":58,\"dist/assets/index-BB5R1v-O.css\":1,\"dist/assets/index-F11-2Iby.js\":44,\"dist/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2\":95,\"dist/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2\":88,\"dist/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2\":48,\"dist/assets/inter-greek-wght-normal-CkhJZR-_.woff2\":66,\"dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2\":329,\"dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2\":207,\"dist/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2\":37,\"dist/favicon.svg\":1,\"dist/imd-deployment.json\":28,\"dist/index.html\":37,\"dist/og.png\":344,\"dist/skill.md\":189,\"foundry.toml\":20,\"site/index.html\":36,\"site/package.json\":29,\"site/pnpm-lock.yaml\":1101,\"site/public/abi/Judge.json\":1,\"site/public/abi/JudgeEthDoor.json\":1,\"site/public/favicon.svg\":1,\"site/public/imd-deployment.json\":28,\"site/public/og.png\":344,\"site/public/skill.md\":189,\"site/src/App.tsx\":434,\"site/src/AskPanel.tsx\":228,\"site/src/CasePage.tsx\":227,\"site/src/ask.ts\":149,\"site/src/cases.ts\":171,\"site/src/deployment.ts\":115,\"site/src/main.tsx\":45,\"site/src/snippet.ts\":52,\"site/src/styles.css\":1112,\"site/src/text.ts\":114,\"site/src/wallet-marks.ts\":6,\"site/src/wallet.tsx\":195,\"site/tsconfig.json\":17,\"site/vite.config.ts\":11,\"src/Judge.sol\":232,\"src/JudgeEthDoor.sol\":82,\"src/Judged.sol\":134,\"src/JudgedTest.sol\":108,\"src/OracleAttestation.sol\":221,\"src/OracleQuestion.sol\":255,\"src/examples/EggDare.sol\":19,\"src/examples/JudgeDare.sol\":70,\"src/interfaces/IIntake.sol\":24,\"src/interfaces/IJudge.sol\":32,\"test/Judge.t.sol\":940,\"test/JudgeEthDoorProperties.t.sol\":199,\"test/JudgeInvariant.t.sol\":137,\"test/JudgePaymentFailures.t.sol\":137,\"test/JudgeProperties.t.sol\":294,\"test/JudgeQuestionProperties.t.sol\":113,\"test/Judged.t.sol\":940,\"test/JudgedAdversarial.t.sol\":172,\"test/Launch.t.sol\":125,\"test/LaunchBatch.t.sol\":54,\"test/REVIEW.md\":47,\"test/fork/JudgeFork.t.sol\":216,\"test/support/DeployJudge.s.sol\":43,\"test/support/Intake.sol\":322,\"test/support/JudgeInvariantHandler.sol\":395,\"test/support/MockERC20.sol\":49,\"wrangler.jsonc\":8},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"6fdf53dea2cd4790031fdbb47e27ec292c3f586041aeeb3eb67e42d703621212","verifiedTreeHash":"17f612bfcc53ea4e4b6209f33e3c576f56305736","verifierVersion":"0.1.0+15e8bc6b"},{"checks":[{"durationMs":8099,"exitCode":0,"name":"build","output":"Compiling 108 files with Solc 0.8.26\nSolc 0.8.26 finished in 7.83s\nCompiler run successful!\n","passed":true},{"durationMs":318,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/Judged.t.sol:JudgedWithoutTheHelperTest\n[PASS] test_saysWhatToDo() (gas: 818880)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 10.20ms (6.31ms CPU time)\n\nRan 2 tests for test/fork/JudgeFork.t.sol:JudgeForkTest\n[SKIP] test_ethereum() (gas: 0)\n[SKIP] test_sepolia() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 2 skipped; finished in 19.21ms (11.01ms CPU time)\n\nRan 45 tests for test/Judged.t.sol:JudgedStandInTest\n[PASS] test_aBudgetCantReachPastWhatWasSent() (gas: 849979)\n[PASS] test_aBudgetOfNothingGetsThePlainMessage() (gas: 874750)\n[PASS] test_aCallerThatCantTakeChangeCostsNothing() (gas: 328500)\n[PASS] test_aDayOfSilenceEndsInNoAnswerAndCanStillSettle() (gas: 1082951)\n[PASS] test_aDevsOwnVmTypesWorkBesideIt() (gas: 173191)\n[PASS] test_aFunctionThatIsntPayableGetsThePlainMessage() (gas: 791992)\n[PASS] test_aMulticallCantGetRoundItWithATrailingByte() (gas: 1028904)\n[PASS] test_aMulticallOfOneStillWorks() (gas: 1004765)\n[PASS] test_aPayableMulticallCantSpendThePot() (gas: 1028806)\n[PASS] test_aReceiveThatRefusesTheChangeRevertsAndCostsNothing() (gas: 875805)\n[PASS] test_aSecondAskInOneCallCantSpendThePot() (gas: 939876)\n[PASS] test_aSecondYesCantCallInFromThePayout() (gas: 1483075)\n[PASS] test_aStakeStaysAndOnlyTheBudgetsChangeGoesBack() (gas: 972456)\n[PASS] test_aWinnerThatRefusesMoneyStaysOpenUntilTheyTakeIt() (gas: 1351332)\n[PASS] test_aYesStaysYesAfterTheDay() (gas: 227305)\n[PASS] test_anAnswerComesFromTheJudgeThatWasAsked() (gas: 1257317)\n[PASS] test_anIdNobodyAskedStaysPending() (gas: 11163)\n[PASS] test_anotherChainSaysSo() (gas: 63005)\n[PASS] test_anotherValueInTheSameBlockIsAnotherQuestion() (gas: 308825)\n[PASS] test_askingFromTheChangeIsRefused() (gas: 1138830)\n[PASS] test_askingFromTheChangeRevertsTheWholeThing() (gas: 391905)\n[PASS] test_asksSayWhoAndWhichId() (gas: 172418)\n[PASS] test_calledAgainFromThePayoutItDoesntPayTwice() (gas: 1267602)\n[PASS] test_cantActWhileVoting() (gas: 212032)\n[PASS] test_eachAnswerRunsItsOwnHookOnItsOwnId() (gas: 1681718)\n[PASS] test_fundingTheContractIsAPlainSend() (gas: 33107)\n[PASS] test_itKnowsWhereJudgeIs() (gas: 784336)\n[PASS] test_itWontDeployWhereThereIsNoJudge() (gas: 142095)\n[PASS] test_itWontPayNobody() (gas: 1017629)\n[PASS] test_noAnswerPaysNobody() (gas: 280823)\n[PASS] test_noEthGetsAPlainMessage() (gas: 58621)\n[PASS] test_noPaysNobody() (gas: 280767)\n[PASS] test_paysASmartWalletThatTransferWouldStarve() (gas: 1265169)\n[PASS] test_settlingFromTheChangeIsRefused() (gas: 1518350)\n[PASS] test_spendingPartOfWhatWasSentWithABudgetLeavesThePotWhole() (gas: 952014)\n[PASS] test_strangersIdsAreRefused() (gas: 203926)\n[PASS] test_theBudgetIsTheMostTheSwapCanCost() (gas: 889430)\n[PASS] test_theChangeGoesBackToWhoeverAsked() (gas: 168198)\n[PASS] test_theHelperMovesTheClockAsAnAnswerWould() (gas: 218914)\n[PASS] test_theHelperWontAnswerTwiceOrAfterTheDay() (gas: 451980)\n[PASS] test_theSameSenderAndValueTwiceInABlockAskOnce() (gas: 344839)\n[PASS] test_thereIsAlwaysChangeAsOnARealPool() (gas: 243955)\n[PASS] test_tooLittleEthRevertsAndCostsNothing() (gas: 85728)\n[PASS] test_twoPeopleInABlockAreTwoQuestions() (gas: 313331)\n[PASS] test_yesPaysAliceOnce() (gas: 337718)\nSuite result: ok. 45 passed; 0 failed; 0 skipped; finished in 21.54ms (17.24ms CPU time)\n\nRan 11 tests for test/Judge.t.sol:JudgeDareTest\n[PASS] test_aClaimKeepsThePotAndTheStakeAndRefundsTheRest() (gas: 705554)\n[PASS] test_aDareThatPaidOutTakesNoMoreClaims() (gas: 894534)\n[PASS] test_aRuleTheJudgeCannotTakeStillLetsTheCreatorTakeThePotBack() (gas: 1479520)\n[PASS] test_aWinnerThatRefusesPaymentLeavesThePotInPlace() (gas: 1103831)\n[PASS] test_aYesFromAnotherCaseMovesNothing() (gas: 745355)\n[PASS] test_aYesPaysThePotToTheClaimantWhoeverCollects() (gas: 913770)\n[PASS] test_afterTheDeadlineNoClaimsAndTheCreatorTakesWhatIsLeft() (gas: 811818)\n[PASS] test_eachTryCostsAStakeAndTheStakeGrowsWithThePot() (gas: 767215)\n[PASS] test_nobodyTopsUpThePot() (gas: 38000)\n[PASS] test_nothingButAYesMovesThePot() (gas: 2295178)\n[PASS] test_theRuleNamesTheClaimantSoACopiedProofIsAnotherQuestion() (gas: 1882889)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 23.36ms (29.34ms CPU time)\n\nRan 24 tests for test/Judge.t.sol:JudgeTest\n[PASS] test_aBadSignatureIsRefused() (gas: 4535603)\n[PASS] test_aFailureEndsTheCaseWithNoRuling() (gas: 629546)\n[PASS] test_aNoIsRecordedNotReverted() (gas: 605878)\n[PASS] test_aPanelWeakerThanTheCaseAskedForIsRefused() (gas: 1653849)\n[PASS] test_aQuietCaseIsOverAfterADayAndALateAnswerIsRefused() (gas: 617795)\n[PASS] test_aRefusalEndsTheCaseToo() (gas: 571365)\n[PASS] test_aStrangerPayingForAnAnswerAndNamingTheJudgeGetsNoVerdict() (gas: 776386)\n[PASS] test_aVerdictIsFinal() (gas: 686926)\n[PASS] test_aYesIsAYes() (gas: 610843)\n[PASS] test_anAnswerOfAnotherTypeIsRefused() (gas: 599813)\n[PASS] test_anExpiredAttestationIsRefused() (gas: 587712)\n[PASS] test_anUnknownRequestIsRefusedAndAnUnknownCaseReadsPending() (gas: 103556)\n[PASS] test_answersSwappedBetweenTwoCasesAreRefused() (gas: 1185635)\n[PASS] test_askSendsTheBodyTheOracleTakesAndPinsItsHash() (gas: 543071)\n[PASS] test_badTextRevertsBeforeAnythingIsPaid() (gas: 410858)\n[PASS] test_eachCaseHasItsOwnQuestion() (gas: 1633371)\n[PASS] test_hostileTextStaysInsideItsBrackets() (gas: 814293)\n[PASS] test_onlyAMajorityPanelCanBeDeployed() (gas: 986487)\n[PASS] test_onlyTheIntakeCallsBack() (gas: 566348)\n[PASS] test_theAskerPaysOnePriceAndNothingStaysBehind() (gas: 778475)\n[PASS] test_theCallbackFitsTheStipendWithRoomToSpare() (gas: 568182)\nLogs:\n  callback gas: 59139\n\n[PASS] test_theLongestCaseFitsWhatTheOracleTakes() (gas: 571709)\n[PASS] test_thePriceIsTheIntakesOwn() (gas: 841419)\n[PASS] test_whatAnAskCosts() (gas: 1687758)\nLogs:\n  ask gas, short text, first case: 520097\n  ask gas, longest text: 1066465\n\nSuite result: ok. 24 passed; 0 failed; 0 skipped; finished in 24.27ms (90.03ms CPU time)\n\nRan 11 tests for test/Judged.t.sol:JudgedOnTheRealThingTest\n[PASS] test_aPayableMulticallCantSpendThePotOnTheRealDoor() (gas: 1620385)\n[PASS] test_aQuestionAskedAroundItIsAStrangers() (gas: 750937)\n[PASS] test_aRealYesAndARealNoRunTheirHooksOnce() (gas: 1729428)\n[PASS] test_aRefusalAndADayOfSilenceRunNoAnswer() (gas: 1455858)\n[PASS] test_paysWithEthAndTheChangeComesBack() (gas: 658245)\nLogs:\n  ask through Judged, gas: 733273\n\n[PASS] test_theStandInAndTheRealVerdictNumbersAgree() (gas: 541)\n[PASS] test_theStandInRefusesWhatTheRealOneRefuses() (gas: 3682676)\n[PASS] test_tooLittleEthIsTheDoorsOwnErrorTheStandInsToo() (gas: 154674)\n[PASS] test_withoutADoorItPaysInTheToken() (gas: 1627676)\n[PASS] test_withoutADoorNoChangeMeansNoCall() (gas: 1518398)\n[PASS] test_withoutADoorOrTheTokenItReverts() (gas: 1094649)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 25.65ms (28.49ms CPU time)\n\nRan 10 tests for test/Judge.t.sol:JudgeEthDoorTest\n[PASS] test_aCallerThatTakesNoRefundIsToldSoAndLosesNothing() (gas: 1152479)\n[PASS] test_aPoolTooThinForThePriceReverts() (gas: 504342)\n[PASS] test_aRefundThatOpensAnotherCaseIsJustAnotherCase() (gas: 1478389)\n[PASS] test_aTokenLeftSyncedEarlierInTheTransactionDoesNotStopAnAsk() (gas: 1025387)\n[PASS] test_badTextCostsNothing() (gas: 443738)\n[PASS] test_ethBuysExactlyThePriceAndTheRestComesBack() (gas: 1016575)\n[PASS] test_exactlyEnoughLeavesNothingToRefund() (gas: 1651098)\n[PASS] test_nobodyButThePoolManagerRunsTheSwap() (gas: 326265)\n[PASS] test_strayEthIsRefused() (gas: 70940)\n[PASS] test_tooLittleEthRevertsAndCostsNothing() (gas: 378121)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 25.92ms (20.04ms CPU time)\n\nRan 3 tests for test/Judge.t.sol:JudgeConformanceTest\n[PASS] test_digestMatchesTheProtocol() (gas: 10579)\n[PASS] test_theIntakeReachesBothFunctions() (gas: 652)\n[PASS] test_theProtocolsSignatureRecoversFromTheJudgesDigest() (gas: 21506)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 28.77ms (10.06ms CPU time)\n\nRan 6 tests for test/Launch.t.sol:LaunchTest\n[PASS] test_askOnAnEmptyChainRevertsWithoutOpeningACase() (gas: 236841)\n[PASS] test_doorPointsAtTheJudgeLaunchedBeforeIt() (gas: 34452)\n[PASS] test_judgeHoldsTheBriefsArguments() (gas: 42534)\n[PASS] test_neitherHasAnOwner() (gas: 141294)\n[PASS] test_questionWordingIsUnchanged() (gas: 56866)\n[PASS] test_runtimeFitsAndHasNoForbiddenOpcodes() (gas: 5485179)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 28.70ms (18.28ms CPU time)\n\nRan 9 test suites in 31.29ms (207.63ms CPU time): 111 tests passed, 0 failed, 2 skipped (113 total tests)\n","passed":true},{"durationMs":146,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"EggDare.claim(string)\",\"EggDare.receive()\",\"EggDare.settle(uint256)\",\"Judge.ask(string,string)\",\"Judge.onOracleFailure(bytes32,uint8,bytes32,uint16,uint16,bytes)\",\"Judge.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"JudgeDare.claim(string)\",\"JudgeDare.collect(uint256)\",\"JudgeDare.receive()\",\"JudgeDare.reclaim()\",\"JudgeEthDoor.ask(string,string)\",\"JudgeEthDoor.unlockCallback(bytes)\",\"JudgeStandIn.answer(uint256,uint8)\",\"JudgeStandIn.ask(string,string)\"],\"files\":{\".gitignore\":7,\"ADAPTATION.md\":136,\"DESIGN.md\":31,\"LICENSE\":21,\"README.md\":194,\"dist/abi/Judge.json\":1,\"dist/abi/JudgeEthDoor.json\":1,\"dist/assets/ccip-CQQTyd0_.js\":1,\"dist/assets/dist-7et0wmat.js\":3,\"dist/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff\":60,\"dist/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2\":58,\"dist/assets/index-BB5R1v-O.css\":1,\"dist/assets/index-F11-2Iby.js\":44,\"dist/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2\":95,\"dist/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2\":88,\"dist/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2\":48,\"dist/assets/inter-greek-wght-normal-CkhJZR-_.woff2\":66,\"dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2\":329,\"dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2\":207,\"dist/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2\":37,\"dist/favicon.svg\":1,\"dist/imd-deployment.json\":28,\"dist/index.html\":37,\"dist/og.png\":344,\"dist/skill.md\":189,\"foundry.toml\":20,\"site/index.html\":36,\"site/package.json\":29,\"site/pnpm-lock.yaml\":1101,\"site/public/abi/Judge.json\":1,\"site/public/abi/JudgeEthDoor.json\":1,\"site/public/favicon.svg\":1,\"site/public/imd-deployment.json\":28,\"site/public/og.png\":344,\"site/public/skill.md\":189,\"site/src/App.tsx\":434,\"site/src/AskPanel.tsx\":228,\"site/src/CasePage.tsx\":227,\"site/src/ask.ts\":149,\"site/src/cases.ts\":171,\"site/src/deployment.ts\":115,\"site/src/main.tsx\":45,\"site/src/snippet.ts\":52,\"site/src/styles.css\":1112,\"site/src/text.ts\":114,\"site/src/wallet-marks.ts\":6,\"site/src/wallet.tsx\":195,\"site/tsconfig.json\":17,\"site/vite.config.ts\":11,\"src/Judge.sol\":232,\"src/JudgeEthDoor.sol\":82,\"src/Judged.sol\":134,\"src/JudgedTest.sol\":108,\"src/OracleAttestation.sol\":221,\"src/OracleQuestion.sol\":255,\"src/examples/EggDare.sol\":19,\"src/examples/JudgeDare.sol\":70,\"src/interfaces/IIntake.sol\":24,\"src/interfaces/IJudge.sol\":32,\"test/Judge.t.sol\":940,\"test/Judged.t.sol\":940,\"test/Launch.t.sol\":125,\"test/fork/JudgeFork.t.sol\":216,\"test/support/DeployJudge.s.sol\":43,\"test/support/Intake.sol\":322,\"test/support/MockERC20.sol\":49,\"wrangler.jsonc\":8},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"7b023e50ce8ee126db7e1eb7ee5c38408b6c63cfab77c13ca8efdb5b91cb2e11","verifiedTreeHash":"260df2dedc4d79d65b10ee211913380e484cdef8","verifierVersion":"0.1.0+15e8bc6b"}]}