{"assessments":[],"deployments":[],"fuzz":[],"identity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"interpretation":"Records acceptance and evidence. Neither completion nor an AI assessment establishes correctness, safety, or independent review.","jobId":"56a73729-fd7c-445f-a74a-70a9e726513d","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"8841e823ef205134a95c97a1af16c42fffbd6fff11349581061c6c49599a8e31","dependsOn":["audit_imported_code"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"a2cea02e8b33e91eeb784e0e5eaeb571cd62cd69e768d335d5834e24b3aa46e5","skillId":"adapt-contract-project","tools":[]},"key":"adapt_contract_project","kind":"code","role":"implement","skillHash":"a2cea02e8b33e91eeb784e0e5eaeb571cd62cd69e768d335d5834e24b3aa46e5","skillId":"adapt-contract-project","state":"accepted"},{"acceptedSubmissionHash":null,"dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_economics","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"working"},{"acceptedSubmissionHash":null,"dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_flow","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"working"},{"acceptedSubmissionHash":"8913887051c330dd2a2f9cd701148f0418bc55289dfc8ccc5f5553fd0b45fa34","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"9897597976b0e72440db7ca402d225aea20f3d37205ba53e7df2400ff80f29cc","skillId":"audit-imported-code","tools":[]},"key":"audit_imported_code","kind":"code","role":"review","skillHash":"9897597976b0e72440db7ca402d225aea20f3d37205ba53e7df2400ff80f29cc","skillId":"audit-imported-code","state":"accepted"},{"acceptedSubmissionHash":null,"dependsOn":["adapt_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"3014f1ea5961918ca059453a484bf4c8bcbbfc2248dbe31d94ac7c5cdf8f50bd","skillId":"audit-judge","tools":[]},"key":"audit_judge","kind":"code","role":"review","skillHash":"3014f1ea5961918ca059453a484bf4c8bcbbfc2248dbe31d94ac7c5cdf8f50bd","skillId":"audit-judge","state":"waiting"},{"acceptedSubmissionHash":null,"dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_math","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"working"},{"acceptedSubmissionHash":null,"dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_permissions","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"working"},{"acceptedSubmissionHash":null,"dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"failed"},{"acceptedSubmissionHash":null,"dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","state":"working"}],"objective":"The launch deploys only src/CabalGate.sol on Ethereum mainnet (chain id 1), for the live CabalHook 0xf41b6ff942a082c0d320a0c151310ac2a922a0c0 from launch 953. Do not deploy or change CabalHook or CabalCoin.\n\nWHY THE LAST ATTEMPT (launch 990) PARKED: the launch checks deploy the gate in an empty EVM with no chain state. The constructor called the hook (initialized, poolManager, cabal, poolKey, imd) and required intake and imd to have code, so it reverted (\"application constructor failed\"). The constructor must therefore make NO external calls and NO code-length checks.\n\nCONSTRUCTOR, flat arguments in this order: hook, poolManager, cabal, currency0, currency1, fee, tickSpacing, initialOwner, intake, imd, signer, action, maxBuyAmount, maxSellAmount, maxImpactBps, maxDriftBps, panelSize, quorum, windowHours. Store hook, poolManager and cabal as immutables (keep the hook() and cabal() getters: hook.setGate requires gate.hook() == the hook and gate.cabal() == CABAL). Build the PoolKey from currency0, currency1, fee, tickSpacing and hooks = hook. Create QuestionBuilder and ImpactEstimator as now (their constructors only store values). Build the Config inside with oracleVerifier = address(this) and boolAnswerType = 0 and run the same validation, minus anything that reads another contract: check non-zero addresses, currency0 < currency1, cabal is one of the two currencies, imd is the other, and the numeric limits as before.\nkeccak256(abi.encode(hook.poolKey())) == keccak256(abi.encode(stored key)), and hook.gate() == address(this); revert InvalidConfig otherwise. Keep the existing block.chainid == 1 check there. The owner's later reconfiguration may keep its intake/imd code-length checks, since it runs on the live chain.\n\nChange nothing else in the gate: the oracle struct, type string, domain, request flow, fees and limits stay exactly as audited.\n\nManifest constructorArgs: \"0xf41b6ff942a082c0d320a0c151310ac2a922a0c0\", \"0x000000000004444c5dc75cb358380d2e3de08a90\", \"0x450e5910decee15c3ac056e3ed66cb5ea3dd33be\", \"0x450e5910decee15c3ac056e3ed66cb5ea3dd33be\", \"0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7\", \"12500\", \"60\", \"$owner\", \"0x1397434cd35e8a9c8ac312a61d3a285eb31dea56\", \"0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7\", \"0x5598aa9146215bc13eb26f2c692ad1461fd32982\", \"0x6f7261636c652e72657175657374406f7261636c652d31000000000000000000\", \"1000000000000000000000000\", \"10000000000000000000000000\", \"300\", \"500\", \"30\", \"20\", \"1\".\n(These are the live hook's values read on 2026-10-08: poolManager 0x0000…8a90, cabal 0x450e…33be, poolKey (0x450e…33be, 0xd34a…63b7, 12500, 60, hook), imd 0xd34a…63b7, gate unset.)\n\nTESTS: a test that deploys CabalGate with these constructor arguments where NO code exists at the hook, intake, imd or pool manager addresses, and asserts it deploys (this is what the launch checks do). Then, with a mock hook that reports initialized, poolKey, poolManager, imd, cabal and gate like the live one: a request succeeds once the hook's gate is set; a request reverts when any of those reads mismatch (wrong poolKey, wrong cabal, wrong imd, gate unset); setGate accepts the deployed gate and refuses a second one.\n\nAfter launch the hook's owner (0xfc3c…1774, the owner of launch 953's hook) calls hook.setGate(gate) once.\n\nDo not launch any token or Cabal hook again, only CabalGate.","parentJobId":null,"planHash":"8bbc6d0afbc6411cf37ab2cd3f536d697f9e802c451e23ba26ecba0af47048a1","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"56a73729-fd7c-445f-a74a-70a9e726513d","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1128-launch-deploys-only-src-cabalgate-sol"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51231","feedbackHash":"c9eb11480162585777a883cdfefabc446d6cf12c53303b8c7be7c7a868ddefcb","nodeKey":"adapt_contract_project","submissionHash":"b4e5abf2067edc74fe2b74e0163c4df0fe2aec7d1cde251ec22d85a0e0d65d4c","tag1":"verification:checks","tag2":"acceptance-v2","value":0},{"agentId":"51154","feedbackHash":"ee84645d3cfc02efb59806ff8ca044cab9f6a9466e21d156a093bdd5e0901400","nodeKey":"adapt_contract_project","submissionHash":"8841e823ef205134a95c97a1af16c42fffbd6fff11349581061c6c49599a8e31","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52254","feedbackHash":"f2fb8678b71e0b9a92046ecc470df16154375247376a843121aaf4a2490f219e","nodeKey":"audit_imported_code","submissionHash":"8913887051c330dd2a2f9cd701148f0418bc55289dfc8ccc5f5553fd0b45fa34","tag1":"review:submission","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"43dfef7f3495055125ed70be6ce006cf340a9ea739a5259f5cec90324085585d","state":"blocked","submissions":[{"artifacts":[],"attempt":2,"bundleHash":"574a2e9c790801da1a933bae130b272c2dc7393a1af28494adb53d61c19770fc","device":"27168b1ff68f84d2","findings":[],"hash":"8841e823ef205134a95c97a1af16c42fffbd6fff11349581061c6c49599a8e31","nodeId":"14e85cbb-2386-4e83-b3e4-1251524e603c","outcome":"completed","summary":"Done. The gate now deploys in an empty EVM, builds and tests pass, and the stale manifest is gone.\n\n**What changed in `src/CabalGate.sol`**\n- The constructor takes the nineteen flat words in the brief's order and makes no external calls and no code-length checks. It stores hook, poolManager and cabal as immutables, builds the PoolKey from the currency, fee and tick-spacing words with the hook as `hooks`, and validates only chain-free facts: non-zero addresses, currency0 below currency1, cabal is one currency and imd the other, tick spacing fits int24, and the numeric limits as before. Tick spacing is a `uint24` word narrowed to `int24` because the launch ABI has no signed integers.\n- Every submission now requires the hook to report this gate, this CABAL, this IMD and exactly the stored pool key, reverting `InvalidConfig` before any oracle payment. The key is compared as raw return data against a hash computed once in the constructor, which kept the runtime small.\n- The owner's `configure` keeps the live checks the constructor cannot make: Intake and IMD have code and IMD equals the hook's IMD.\n- Panel size and quorum are bounded to the oracle's accepted 2 to 300 range. This fixes the reproduced low audit finding where a configuration with quorum 1 burned every request's fee.\n- The unused `mainnetConfig` view was removed. The submission checks pushed the runtime over EIP-170, and the audit named that view as the safe place to recover bytes.\n\n**Size, which matters for the floor's check**\n\n| Artifact | Bytes |\n| --- | --- |\n| Runtime (limit 24,576) | 24,443 |\n| Creation code plus 19 words (limit 49,152) | 38,011 |\n\n**Tests**: 166 pass in 25 suites, including the three invariant campaigns. The rewritten `test/GateLaunch.t.sol` deploys the gate with the manifest words where no code exists at the hook, PoolManager, Intake, IMD or CABAL addresses, then uses a mock hook at the live address to cover the one-time owner binding refusing a second gate, buy and sell requests that succeed only once the hook reports the gate, and requests refused when the hook reports another key, CABAL, IMD or gate. Edge-case, fixture and adversarial tests were updated to the new constructor and bounds.\n\n**Other files**: `launch.json` was deleted because it carried the thirteen-word constructor that parked launch 990 and the manifest step writes the new one. `ADAPTATION.md` lists every change, the audit disposition and the measured sizes. `docs/DEPLOYMENT.md` now transcribes the nineteen values and tells the hook owner to compare the hook's pool key hash with the manifest key before the permanent `setGate` call, since the hook checks only `hook()` and `cabal()`.\n\n**One thing to flag**: the previous attempt died during the checker's build, and a full build of this suite takes about four minutes and 3.5 GB here because the tests compile the real PoolManager through the IR pipeline. I kept my additions compact and did not add new heavy test contracts, but the suite's baseline cost is unchanged.","treeHash":"39ff23e6ba9586c7bd3bb135baac7fba5cbc1e0c","usage":{"cachedInputTokens":5580907,"inputTokens":1058,"model":"claude-fable-5-1","outputTokens":89939,"runtime":"claude","turns":81,"wallClockMs":1829422}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"584bd638e7e022f0","findings":[{"citation":"resolved","description":"The constructor calls launchHook.initialized(), poolManager(), cabal() and poolKey() (lines 142-146) and then _configure (line 217) requires cfg.intake.code.length != 0, cfg.imd == hook.imd() and cfg.imd.code.length != 0. The launch floor (.imd/reads/protected/evm_contracts/Contracts.protected.t.sol) deploys the gate by CREATE2 in a fresh EVM with no code at the hook, intake, IMD or PoolManager addresses; a call to a codeless address that must return data reverts in Solidity, so the constructor reverts and the probe fails with 'application constructor failed'. This is exactly why launch 990 parked. The constructor must take hook, poolManager, cabal, currency0, currency1, fee, tickSpacing, initialOwner, intake, imd, signer, action and the seven limits as flat words, store hook/poolManager/cabal as immutables, build the PoolKey locally, and validate only pure facts (non-zero addresses, currency0 < currency1, cabal is one currency and imd the other, numeric limits). The hook-dependent checks (hook.gate() == this, hook.poolKey() == stored key) belong in _submit, which already checks hook.gate(); the owner's configure may keep its code-length checks. Launch 990 confirmed on 2026-10-09 against mainnet (public RPC): hook.gate() is still 0x0, hook.owner() is 0xFc3C962FAD2C1cC77f1a0d46e7B8a2De79A21774, poolKey is (0x450e...33BE, 0xD34a...63B7, 12500, 60, hook), Intake.priceOf(action, IMD) is 0.5 IMD, so the manifest words in the brief are correct and only the constructor blocks the launch.","line":142,"path":"src/CabalGate.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {CabalGate} from \"src/CabalGate.sol\";\n\n/// @dev The protected floor's CREATE2 probe, as the launch checks run it: an empty EVM, no chain state.\ncontract EmptyChainFactory {\n    function deploy(bytes memory code, bytes32 salt) external returns (address deployed) {\n        require(code.length > 0 && code.length <= 49_152, \"invalid init code\");\n        assembly (\"memory-safe\") {\n            deployed := create2(0, add(code, 32), mload(code), salt)\n        }\n        require(deployed != address(0) && deployed.code.length > 0, \"application constructor failed\");\n    }\n}\n\n/// @notice Launch 990 parked because the CabalGate constructor reads the hook (initialized, poolManager, cabal,\n///         poolKey, imd) and requires code at intake and imd. The launch checks deploy in an EVM where none of those\n///         addresses has code, so the constructor reverts. This test deploys the gate with the brief's nineteen\n///         manifest words in exactly that state and asserts it deploys. It fails on the current source\n///         (\"application constructor failed\") and passes once the constructor makes no external calls and no\n///         code-length checks.\ncontract ProofConstructorNeedsChainStateTest is Test {\n    address internal constant HOOK = 0xf41B6Ff942a082C0d320a0C151310ac2A922a0c0;\n    address internal constant POOL_MANAGER = 0x000000000004444c5dc75cB358380D2e3dE08A90;\n    address internal constant CABAL = 0x450e5910DEcEe15c3AC056E3ed66Cb5ea3Dd33BE;\n    address internal constant IMD = 0xD34a99Bc0f67aE1bbd63C660e6d0b0dd03E263B7;\n    address internal constant INTAKE = 0x1397434cd35e8a9C8aC312A61D3A285EB31dea56;\n    address internal constant SIGNER = 0x5598Aa9146215Bc13eb26f2c692Ad1461Fd32982;\n    bytes32 internal constant ACTION = 0x6f7261636c652e72657175657374406f7261636c652d31000000000000000000;\n\n    function test_gateDeploysInAnEmptyEvmWithTheManifestWords() public {\n        vm.chainId(1);\n        address owner = makeAddr(\"launch owner resolves $owner\");\n        // The launch checks' precondition: nothing the constructor could call exists.\n        assertEq(HOOK.code.length, 0, \"hook must have no code in this rehearsal\");\n        assertEq(POOL_MANAGER.code.length, 0, \"pool manager must have no code in this rehearsal\");\n        assertEq(INTAKE.code.length, 0, \"intake must have no code in this rehearsal\");\n        assertEq(IMD.code.length, 0, \"imd must have no code in this rehearsal\");\n        assertEq(CABAL.code.length, 0, \"cabal must have no code in this rehearsal\");\n\n        // Manifest constructorArgs, flat, in the brief's order: hook, poolManager, cabal, currency0, currency1,\n        // fee, tickSpacing, initialOwner, intake, imd, signer, action, maxBuyAmount, maxSellAmount, maxImpactBps,\n        // maxDriftBps, panelSize, quorum, windowHours. Every value is one static ABI word, as the factory sends it.\n        bytes memory arguments = abi.encode(\n            HOOK,\n            POOL_MANAGER,\n            CABAL,\n            CABAL,\n            IMD,\n            uint256(12500),\n            uint256(60),\n            owner,\n            INTAKE,\n            IMD,\n            SIGNER,\n            ACTION,\n            uint256(1000000000000000000000000),\n            uint256(10000000000000000000000000),\n            uint256(300),\n            uint256(500),\n            uint256(30),\n            uint256(20),\n            uint256(1)\n        );\n        assertEq(arguments.length, 19 * 32);\n        bytes memory creation = bytes.concat(vm.getCode(\"CabalGate.sol:CabalGate\"), arguments);\n        assertLe(creation.length, 49_152, \"init code exceeds the factory bound\");\n\n        EmptyChainFactory factory = new EmptyChainFactory();\n        CabalGate gate = CabalGate(factory.deploy(creation, keccak256(\"launch 990 retry\")));\n\n        assertGt(address(gate).code.length, 0);\n        assertLe(address(gate).code.length, 24_576, \"runtime exceeds EIP-170\");\n        assertEq(address(gate.hook()), HOOK, \"hook() getter must return the supplied hook\");\n        assertEq(address(gate.cabal()), CABAL, \"cabal() getter must return the supplied CABAL\");\n        assertEq(address(gate.poolManager()), POOL_MANAGER);\n        assertEq(gate.owner(), owner);\n        assertEq(gate.configVersion(), 1);\n        CabalGate.Config memory cfg = gate.configuration();\n        assertEq(cfg.intake, INTAKE);\n        assertEq(cfg.imd, IMD);\n        assertEq(cfg.signer, SIGNER);\n        assertEq(cfg.oracleVerifier, address(gate));\n        assertEq(cfg.action, ACTION);\n        assertEq(cfg.maxBuyAmount, 1000000000000000000000000);\n        assertEq(cfg.maxSellAmount, 10000000000000000000000000);\n        assertEq(cfg.maxImpactBps, 300);\n        assertEq(cfg.maxDriftBps, 500);\n        assertEq(cfg.panelSize, 30);\n        assertEq(cfg.quorum, 20);\n        assertEq(cfg.windowHours, 1);\n        assertEq(cfg.boolAnswerType, 0);\n    }\n}","reproduction":"State: an EVM where 0xf41b...a0c0 (hook), 0x0000...8a90 (PoolManager), 0x1397...ea56 (Intake) and 0xd34a...63b7 (IMD) have no code (the protected floor's setUp). Input: create2 of CabalGate creation code ++ the 19 manifest words (or the current 13). Expected: the gate deploys and hook()/cabal()/poolManager()/configuration() return the supplied words. Actual: the first external call launchHook.initialized() reverts (no code at the callee), so create2 returns 0 and the probe reverts 'application constructor failed'. Run: forge test --match-path test/scratch/Proof_ConstructorNeedsChainState.t.sol -> [FAIL: application constructor failed].","severity":"high","snippet":"        if (!launchHook.initialized()) revert InvalidConfig();","title":"Constructor needs live chain state (hook calls and code-length checks), so the launch check's empty-EVM deployment reverts"},{"citation":"resolved","description":"The committed manifest lists 13 constructorArgs (hook, $owner, intake, imd, signer, action, limits) and its notes state 'The constructor requires an initialized hook and obtains poolManager, poolKey and CABAL from it; Intake and IMD must have code', which is the behaviour the brief forbids. The brief's manifest has 19 words in the order hook, poolManager, cabal, currency0, currency1, fee, tickSpacing, $owner, intake, imd, signer, action, maxBuyAmount, maxSellAmount, maxImpactBps, maxDriftBps, panelSize, quorum, windowHours. Once the constructor is rewritten, a manifest with 13 words makes the constructor's ABI decoding revert (too little data), and a manifest left as is reproduces the launch 990 failure. The notes also must stop asserting the hook is read in the constructor. Everything else in the file is schema-valid: kind evm_contracts, one contract named CabalGate, strings everywhere, notes under 4000 characters, no extra keys.","line":6,"path":"launch.json","reproduction":"Input: the current launch.json constructorArgs (13 strings) with the brief's 19-parameter constructor. Expected: 19 ABI words, one per parameter in declaration order. Actual: 13 words; the constructor's argument decoder reverts on short data (and with the current constructor the deployment reverts for the reason in the high finding). Verification: compare launch.json lines 7-19 (13 entries) with the brief's list (19 entries); the second entry is $owner where the brief's second entry is the PoolManager 0x000000000004444c5dc75cb358380d2e3de08a90.","severity":"medium","snippet":"      \"constructorArgs\": [","title":"launch.json still carries the 13-word constructor that parked launch 990, not the brief's 19 words"},{"citation":"resolved","description":"_configure only requires quorum != 0, quorum <= panelSize and panelSize <= 1000. The oracle's request body (oracle-consumer skill, 'The body') accepts panelSize and quorum only in 2..300 with quorum <= panelSize; a body outside that range is refused (status 1), no callback is made and the price is spent. The gate copies cfg.panelSize and cfg.quorum into the body verbatim (QuestionBuilder.build). So a configuration with quorum 1, or panelSize 301..1000, is accepted on chain and makes every subsequent submission pay the Intake price for a request that can never be answered; the requester discovers this only after the one-hour deadline and clears the request without refund. test/AdversarialOracle.t.sol line 237-240 even pins (panelSize 1000, quorum 1000) as an accepted edge. The owner is trusted, but the gate already validates these fields, and validates them against the wrong range. Minimal fix: require 2 <= cfg.quorum && cfg.panelSize <= 300 (the launch values 30/20 are inside).","line":222,"path":"src/CabalGate.sol","reproduction":"State: the gate as deployed (panelSize 30, quorum 20). Call: owner configure(cfg) with cfg.quorum = 1 (or cfg.panelSize = 1000, cfg.quorum = 1000). Expected: revert InvalidConfig. Actual: accepted, configVersion increments. Then ALICE submitBuyRequest(100e18, 'reason'): 0.5 IMD is pulled and forwarded to the Intake, the emitted body contains \"quorum\":1 (or \"panelSize\":1000), which the oracle refuses; no onOracleResult is ever delivered, ALICE's slot stays occupied until block.timestamp >= deadline (1 hour) and clearRequest returns nothing.","severity":"low","snippet":"                || cfg.quorum > cfg.panelSize || cfg.panelSize > 1000 || cfg.windowHours == 0 || cfg.windowHours > 24","title":"configure accepts panelSize/quorum values the oracle refuses, so every request under such a config burns its 0.5 IMD with no callback"},{"citation":"resolved","description":"GateLaunchFixture.setUp etches a MockLaunchHook at the hook address and MockIntake/MockERC20 at the Intake and IMD addresses before every deployment, and test_constructorRequiresHookInitializedAndDependencyCode (lines 196-211) asserts that deployment FAILS when any of those has no code, which is the opposite of what the launch floor requires. That is how a constructor that cannot run in the launch checks passed 162 local tests. The brief asks for a test that deploys the gate with the manifest words where no code exists at the hook, intake, IMD or PoolManager addresses and asserts success, followed by mock-hook tests of the submission-time binding checks (request succeeds once hook.gate() is set; reverts on wrong poolKey, wrong cabal, wrong imd, unset gate) and of setGate accepting the gate once and refusing a second. None of these exists today; the scratch proof attached to the high finding is the first of them.","line":71,"path":"test/GateLaunch.t.sol","reproduction":"Run forge test --match-path test/GateLaunch.t.sol: all pass. Remove the three vm.etch lines (71-73) or run the attached scratch proof: the constructor reverts. Expected: a passing test with no code at HOOK, INTAKE, IMD and the PoolManager, mirroring Contracts.protected.t.sol. Actual: test_constructorRequiresHookInitializedAndDependencyCode at line 196 expects 'application constructor failed' in that state.","severity":"low","snippet":"        vm.etch(HOOK, address(new MockLaunchHook(hookOwner)).code);","title":"Launch rehearsal tests etch mock code at the dependency addresses, so the suite never exercises the empty-EVM state the launch checks run in"},{"citation":"resolved","description":"forge inspect src/CabalGate.sol:CabalGate deployedBytecode is 23,967 bytes (limit 24,576; the protected floor asserts this). The adaptation adds a keccak256(abi.encode(hook.poolKey())) comparison in _submit, a PoolKey built from constructor words and extra validation, all of which grow the runtime. If the limit is crossed the floor fails with 'runtime exceeds EIP-170'. mainnetConfig() (lines 169-189) is a view that nothing on chain or in production calls and is a safe place to recover bytes if needed; the brief otherwise forbids other changes. Init code is 36,970 bytes plus 19*32 = 37,578, well under 49,152.","line":169,"path":"src/CabalGate.sol","reproduction":"Measurement on the current tree: forge inspect src/CabalGate.sol:CabalGate deployedBytecode | wc -c -> 23,967 bytes of runtime. Expected after adaptation: <= 24,576. Actual: unknown until built; re-measure and include the number in the adaptation notes.","severity":"info","snippet":"    function mainnetConfig(uint128 maxBuy, uint128 maxSell, uint16 impact, uint16 drift)","title":"Runtime is 609 bytes under EIP-170; the required submission-time poolKey check and the 19-word constructor must be measured against the limit"},{"citation":"resolved","description":"The evm-contracts launch supports constructor arguments of type address, uint8..uint256, bool and bytes32 only. The brief's tickSpacing word ('60') feeds PoolKey.tickSpacing, which is int24. If the new constructor declares the parameter as int24, the manifest/ABI validation refuses it. Declare it as uint24 (or uint8) and cast to int24 when building the key; 60 fits either way and the ABI word is identical. fee is uint24 and needs no change.","line":127,"path":"src/CabalGate.sol","reproduction":"Input: a constructor with parameter 'int24 tickSpacing'. Expected: manifest accepts '60'. Actual: the policy's supported-type list excludes signed integers, so the contract entry is rejected before deployment. With 'uint24 tickSpacing' and int24(uint24(tickSpacing)) inside, the same word deploys.","severity":"info","snippet":"    constructor(","title":"PoolKey.tickSpacing is int24; the constructor must declare it as an unsigned word because the launch ABI forbids signed integers"},{"citation":"resolved","description":"The live hook (bytecode read from mainnet on 2026-10-09, same 10,034-byte runtime as the repo's CabalHook, differing only in immutables) binds a gate once and refuses any replacement. Today the gate's key cannot be wrong because the constructor copies it from the hook; after the adaptation the key comes from manifest words. If a word is wrong (fee 3000, tickSpacing 10, currencies swapped relative to the brief's check) the gate still deploys, setGate still accepts it (it only compares hook() and cabal()), and then the brief's _submit check keccak256(abi.encode(hook.poolKey())) == keccak256(abi.encode(_key)) makes every request revert InvalidConfig with no recovery path, since the hook refuses a second gate. The manifest words in the brief match the live key, so this is a procedural guard: before the one-time setGate, the hook owner should recompute keccak256(abi.encode(hook.poolKey())) and compare it with the key the gate was built from (a test in the adaptation can assert it from the same constants), not just gate.hook() and gate.cabal().","line":116,"path":"src/CabalHook.sol","reproduction":"State (post-adaptation): gate deployed with currency0 = CABAL, currency1 = IMD, fee = 3000, tickSpacing = 60, hook = live hook. Call: hook owner setGate(gate). Expected: refused. Actual: accepted (hook() and cabal() match). Then any submitBuyRequest reverts InvalidConfig forever and hook.setGate(otherGate) reverts InvalidGate. Today's code is not affected because _key is read from the hook.","severity":"info","snippet":"                || address(IGateBinding(candidate).hook()) != address(this)","title":"hook.setGate checks only hook() and cabal(); once the key is constructor-supplied, a gate with a wrong fee/tickSpacing/currency order can be bound forever"}],"hash":"8913887051c330dd2a2f9cd701148f0418bc55289dfc8ccc5f5553fd0b45fa34","nodeId":"cf09d78d-66be-4a82-b1c3-44ac4f111b2d","outcome":"completed","summary":"Review complete. Findings are in `.imd-findings.json` (7 findings, one with a proof). No tracked file was changed; the only writes are the findings file and the scratch proof, both git-ignored.\n\n**What was read.** Every source file in `src/` (CabalGate, CabalHook, CabalCoin, QuestionBuilder, ImpactEstimator, HookFlags, the five libraries, IIntake), the full test suite, launch.json, ADAPTATION.md, docs, and the pinned skills and protected floor test. The suite builds and all 162 tests pass. I also read the live mainnet hook and Intake over a public RPC: gate is unset, the owner is 0xFc3C…1774, the pool key and PoolManager match the brief, the price is 0.5 IMD, and the live hook runtime is byte-for-byte the repo's CabalHook apart from immutables. Nothing was unreachable.\n\n**Findings, most severe first.**\n\n- **High, src/CabalGate.sol:142.** The constructor calls the hook (initialized, poolManager, cabal, poolKey, imd) and requires code at intake and IMD. In the launch floor's empty EVM the first call reverts and the probe reports \"application constructor failed\", which is why launch 990 parked. The proof in `test/scratch/Proof_ConstructorNeedsChainState.t.sol` deploys the gate with the brief's 19 manifest words and no code at any dependency address. It fails today for that reason and passes once the constructor makes no external calls or code checks.\n- **Medium, launch.json:6.** The committed manifest still lists the 13 old words and its notes describe the hook-reading constructor. Against the 19-parameter constructor the words decode short, and left as is it reproduces the parked outcome.\n- **Low, src/CabalGate.sol:222.** The owner can configure quorum 1 or panelSize up to 1000. The oracle only accepts 2 to 300, so every request under such a config pays 0.5 IMD and is never answered.\n- **Low, test/GateLaunch.t.sol:71.** The launch rehearsal etches mock code at the hook, Intake and IMD addresses, and one test asserts deployment must fail without that code. The suite therefore never ran in the state the launch checks use, and none of the brief's required tests exist yet.\n- **Info.** Runtime is 23,967 bytes, 609 under EIP-170, before the adapter adds the submission-time pool-key check. The tickSpacing word must be declared unsigned since the launch ABI forbids signed integers. The live hook's one-time setGate only compares hook() and cabal(), so a gate built from a wrong key word would be bound irreversibly; the hook owner should compare the key hash before binding.\n\n**Trust assumptions, not defects.** The owner can swap the Intake, signer and verifier, and a user pays whatever the configured Intake quotes. Signatures are ECDSA-only, so an ERC-1271 registry signer would never verify. Refused or undecided oracle requests are never refunded. All three are already recorded in ADAPTATION.md.\n\nThe runtime paths of the gate (request, callback, execution, settlement, fee accounting, replay protection) held up against the checklist. I found no loss-of-funds or accounting defect there.","treeHash":null,"usage":{"cachedInputTokens":1973899,"inputTokens":418,"model":"claude-fable-5-1","outputTokens":35306,"runtime":"claude","turns":45,"wallClockMs":727309}},{"artifacts":[],"attempt":1,"bundleHash":"84fa29d4ea7d202b08427ee7885d0682642d61d53fd471154e1822dc0c8a6e8e","device":"1507f63d3f1b973a","findings":[],"hash":"b4e5abf2067edc74fe2b74e0163c4df0fe2aec7d1cde251ec22d85a0e0d65d4c","nodeId":"14e85cbb-2386-4e83-b3e4-1251524e603c","outcome":"completed","summary":"","treeHash":"c471222cac5aeff6b3a57f07d4fec47c5cfa33f4","usage":{"cachedInputTokens":7560670,"inputTokens":1860,"model":"claude-fable-5-1","outputTokens":58831,"runtime":"claude","turns":61,"wallClockMs":1548393}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"56e50117311155be","findings":[],"hash":"ddf3874cbb2397b677b9039ce795daf639d37d7736255b8d346194ee9ad07f2e","nodeId":"4010b189-0512-42e1-96bc-f23a082b9813","outcome":"failed","summary":"needs input: The accepted src/CabalGate.sol constructor takes nineteen flat static words in the order the brief fixed (hook, poolManager, cabal, currency0, currency1, fee, tickSpacing, initialOwner, intake, imd, signer, action, maxBuyAmount, maxSellAmount, maxImpactBps, maxDriftBps, panelSize, quorum, windowHours). The launch manifest schema rejects any constructorArgs list longer than sixteen entries (launch_manifest check: 'contracts.0.constructorArgs: Too big: expected array to have <=16 items'). A manifest with sixteen or fewer words would not ABI-encode against the accepted constructor and the factory rehearsal would revert, so no valid launch.json can describe the accepted implementation. The constructor signature must be reduced to at most sixteen parameters, which is a source change outside this manifest-only assignment (only launch.json may be written). — Which reduction of the CabalGate constructor to at most sixteen words do you approve for a new build task before the manifest is written","treeHash":null,"usage":{"cachedInputTokens":685548,"inputTokens":452,"model":"claude-fable-5-1","outputTokens":9616,"runtime":"claude","turns":19,"wallClockMs":493483}}],"verification":[{"checks":[{"durationMs":134812,"exitCode":0,"name":"build","output":"Compiling 120 files with Solc 0.8.26\nSolc 0.8.26 finished in 134.55s\nCompiler run successful with warnings:\nWarning (2018): Function state mutability can be restricted to view\n   --> test/GateFactoryEdges.t.sol:233:5:\n    |\n233 |     function test_protocolVectorPinsAllFifteenFieldsTypeStringAndDomain() public {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[encode-packed-collision]: `abi.encodePacked()` called with multiple dynamic type arguments; hash collisions possible\n   ╭▸ src/libraries/CanonicalRequest.sol:21:13\n   │\n21 │ ┏             abi.encodePacked(\n22 │ ┃                 '{\"answerType\":\"bool\",\"chainId\":1,\"definitions\":{',\n23 │ ┃                 definitions,\n24 │ ┃                 '},\"evidence\":\"panel\",\"question\":\"',\n   ‡ ┃\n30 │ ┃                 \"}}\"\n31 │ ┃             )\n   │ ┗━━━━━━━━━━━━━┛\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/encode-packed-collision\n\nwarning[encode-packed-collision]: `abi.encodePacked()` called with multiple dynamic type arguments; hash collisions possible\n    ╭▸ src/QuestionBuilder.sol:98:16\n    │\n 98 │           body = abi.encodePacked(\n    │ ┏━━━━━━━━━━━━━━━━┛\n 99 │ ┃             '{\"answerType\":\"bool\",\"chainId\":1,\"consumer\":{\"chainId\":1,\"verifyingContract\":\"',\n100 │ ┃             c.verifier.toHexString(),\n101 │ ┃             '\"},\"definitions\":{',\n    ‡ ┃\n112 │ ┃             \"}}\"\n113 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/encode-packed-collision\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/libraries/Json.sol:44:31\n   │\n44 │                 if (c < 0x20) revert ForbiddenCharacter();\n   │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/libraries/Json.sol:56:22\n   │\n56 │                 else revert InvalidUTF8();\n   │                      ━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/libraries/Json.sol:57:36\n   │\n57 │                 if (src + n > end) revert InvalidUTF8();\n   │                                    ━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/libraries/Json.sol:59:43\n   │\n59 │                 if (d < 0x80 || d > 0xbf) revert InvalidUTF8();\n   │                                           ━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/libraries/Json.sol:61:64\n   │\n61 │                     if (c == 0xc2 && (d == 0xab || d == 0xbb)) revert ForbiddenCharacter();\n   │                                                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/libraries/Json.sol:66:23\n   │\n66 │                     ) revert InvalidUTF8();\n   │                       ━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/libraries/Json.sol:68:47\n   │\n68 │                     if (d < 0x80 || d > 0xbf) revert InvalidUTF8();\n   │                                               ━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/libraries/Json.sol:71:51\n   │\n71 │                         if (d < 0x80 || d > 0xbf) revert InvalidUTF8();\n   │                                                   ━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[uninitialized-local]: local variable is read before being initialized\n   ╭▸ src/libraries/Json.sol:92:16\n   │\n92 │         while (i < s.length) {\n   │                ━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/libraries/Json.sol:99:18\n   │\n99 │             else revert InvalidUTF8();\n   │                  ━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/libraries/Json.sol:100:35\n    │\n100 │             if (i + n > s.length) revert InvalidUTF8();\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/libraries/Json.sol:103:43\n    │\n103 │                 if (d < 0x80 || d > 0xbf) revert InvalidUTF8();\n    │                                           ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/libraries/Json.sol:110:19\n    │\n110 │                 ) revert InvalidUTF8();\n    │                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/libraries/Json.sol:127:21\n    │\n127 │                 out[k++] = \"\\\\\";\n    │                     ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[missing-events-access-control]: `_executing` is changed without an event but is used for access control\n    ╭▸ src/CabalGate.sol:431:9\n    │\n431 │         _executing = false;\n    │         ━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[unsafe-typecast]: typecast can truncate values\n  ╭▸ src/libraries/MainnetDefaults.sol:9:54\n  │\n9 │     address internal constant IDENTITY_NFT = address(bytes20(hex\"0000ec93127baa929e58e97dd0095a2bfb38ec1d\"));\n  │                                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n  │\n  ├ note: consider disabling this lint if you're certain the cast is safe\n  │       \n  │       // casting to 'bytes20' is safe because [explain why]\n  │       // forge-lint: disable-next-line(unsafe-typecast)\n  │       \n  │       \n  ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/libraries/MainnetDefaults.sol:10:40\n   │\n10 │     bytes32 internal constant ACTION = bytes32(\"oracle.request@oracle-1\");\n   │                                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'bytes32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[boolean-cst]: misuse of a boolean constant\n   ╭▸ src/ImpactEstimator.sol:71:83\n   │\n71 │             if (compressed < minCompressed || compressed > maxCompressed) return (false, 0);\n   │                                                                                   ━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\n\nwarning[boolean-cst]: misuse of a boolean constant\n   ╭▸ src/ImpactEstimator.sol:78:29\n   │\n78 │                     return (true, (compressed - int24(uint24(bitPos - BitMath.mostSignificantBit(masked)))) * spacing);\n   │                             ━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\n\nwarning[boolean-cst]: misuse of a boolean constant\n   ╭▸ src/ImpactEstimator.sol:84:29\n   │\n84 │                     return (true, (compressed + int24(uint24(BitMath.leastSignificantBit(masked) - bitPos))) * spacing);\n   │                             ━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\n\nwarning[boolean-cst]: misuse of a boolean constant\n   ╭▸ src/ImpactEstimator.sol:89:17\n   │\n89 │         return (false, 0);\n   │                 ━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/CabalGate.sol:228:9\n    │\n228 │         emit Configured(configVersion, cfg);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/CabalGate.sol:160:34\n    │\n160 │                 || tickSpacing > uint24(type(int24).max)\n    │                                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/CabalGate.sol:166:70\n    │\n166 │             Currency.wrap(currency0), Currency.wrap(currency1), fee, int24(tickSpacing), IHooks(address(launchHook))\n    │                                                                      ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/ImpactEstimator.sol:45:25\n   │\n45 │             liquidity = uint128(uint256(entered));\n   │                         ━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint128' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/ImpactEstimator.sol:45:33\n   │\n45 │             liquidity = uint128(uint256(entered));\n   │                                 ━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint256' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/ImpactEstimator.sol:59:46\n   │\n59 │         return PriceMath.movement(sqrtPrice, uint160(end));\n   │                                              ━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint160' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/CabalGate.sol:210:64\n    │\n210 │     function configure(Config calldata cfg) external onlyOwner nonReentrant {\n    │                                                                ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/ImpactEstimator.sol:72:29\n   │\n72 │             int16 wordPos = int16(compressed >> 8);\n   │                             ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'int16' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/ImpactEstimator.sol:73:34\n   │\n73 │             uint8 bitPos = uint8(uint256(int256(compressed)) & 0xff);\n   │                                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint256' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/CabalGate.sol:222:90\n    │\n222 │                 || cfg.maxBuyAmount == 0 || cfg.maxSellAmount == 0 || cfg.maxBuyAmount > uint128(type(int128).max)\n    │                                                                                          ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/CabalGate.sol:223:40\n    │\n223 │                 || cfg.maxSellAmount > uint128(type(int128).max) || cfg.maxImpactBps == 0 || cfg.maxImpactBps > 5000\n    │                                        ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[missing-zero-check]: address parameter is used in a state write or value transfer without a zero-address check\n    ╭▸ src/CabalHook.sol:113:22\n    │\n113 │     function setGate(address candidate) external onlyOwner {\n    │                      ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-zero-check\n\nwarning[reentrancy-no-eth]: external call can be reentered before `activeRequest` is updated\n    ╭▸ src/CabalGate.sol:285:14\n    │\n285 │           id = IIntake(cfg.intake)\n    │ ┏━━━━━━━━━━━━━━┛\n286 │ ┃             .request(cfg.action, body, IIntake.Callback(address(this), this.onOracleResult.selector), cfg.imd, price);\n    │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/CabalGate.sol:304:9\n    │\n304 │         emit RequestSubmitted(id, msg.sender, buy, amount, question, body);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/CabalGate.sol:288:13\n    │\n288 │         if (payment.balanceOf(address(this)) != beforePayment) revert UnsupportedToken();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/CabalGate.sol:294:24\n    │\n294 │             createdAt: uint64(block.timestamp),\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/CabalGate.sol:295:23\n    │\n295 │             deadline: uint64(block.timestamp + REQUEST_TIMEOUT),\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/CabalGate.sol:298:21\n    │\n298 │             amount: uint128(amount),\n    │                     ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/CabalGate.sol:315:35\n    │\n315 │         if (block.chainid != 1 || block.timestamp >= r.deadline) revert Expired();\n    │                                   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/CabalGate.sol:321:74\n    │\n321 │                 || a.agreed > a.panelSize || a.issuedAt < r.createdAt || a.issuedAt > block.timestamp + CLOCK_TOLERANCE\n    │                                                                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/CabalGate.sol:322:20\n    │\n322 │                 || a.expiresAt <= block.timestamp || a.expiresAt <= a.issuedAt\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/CabalGate.sol:337:38\n    │\n337 │             r.approvedUntil = uint64(until < a.expiresAt ? until : a.expiresAt);\n    │                                      ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/CabalGate.sol:342:9\n    │\n342 │         emit OracleResult(requestId, a.requestId, approved, r.approvedUntil);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/CabalGate.sol:337:31\n    │\n337 │             r.approvedUntil = uint64(until < a.expiresAt ? until : a.expiresAt);\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/CabalGate.sol:359:33\n    │\n359 │             if (!staleConfig && block.timestamp < r.deadline) revert InvalidRequest();\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/CabalGate.sol:361:33\n    │\n361 │             if (!staleConfig && block.timestamp < r.approvedUntil) revert InvalidRequest();\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[missing-zero-check]: address parameter is used in a state write or value transfer without a zero-address check\n    ╭▸ src/CabalHook.sol:126:31\n    │\n126 │     function beforeInitialize(address sender, PoolKey calldata key, uint160) external onlyManager returns (bytes4) {\n    │                               ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-zero-check\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/CabalGate.sol:393:13\n    │\n393 │         if (block.timestamp >= r.approvedUntil) revert Expired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/CabalGate.sol:423:9\n    │\n423 │         emit RequestExecuted(id, r.amount, output, fee);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/CabalGate.sol:415:44\n    │\n415 │             if (h.units == 0) h.firstBuy = uint64(block.timestamp);\n    │                                            ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/CabalHook.sol:163:19\n    │\n163 │         feeBase = uint256(amount < 0 ? -amount : amount);\n    │                   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/CabalHook.sol:176:16\n    │\n176 │         return (volume / 400) * 2;\n    │                ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/CabalGate.sol:455:26\n    │\n455 │         uint256 output = uint256(outputDelta);\n    │                          ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/CabalGate.sol:487:13\n    │\n487 │         if (token.balanceOf(address(this)) != beforeBalance + amount) revert UnsupportedToken();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/CabalGate.sol:507:13\n    │\n507 │             IDENTITY_NFT.staticcall{gas: 30000}(abi.encodeWithSignature(\"balanceOf(address)\", user));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/CabalHook.sol:235:13\n    │\n235 │             poolManager.modifyLiquidity(_key, ModifyLiquidityParams(lower, upper, int256(liquidity), 0), \"\");\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/CabalHook.sol:249:13\n    │\n249 │             poolManager.take(currency, address(this), uint128(delta));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/CabalHook.sol:252:13\n    │\n252 │             poolManager.sync(currency);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/CabalHook.sol:254:17\n    │\n254 │             if (poolManager.settle() != owed) revert UnsupportedToken();\n    │                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/CabalHook.sol:183:15\n    │\n183 │         fee = half * 2;\n    │               ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/CabalHook.sol:179:45\n    │\n179 │     function finishSwap() external onlyGate nonReentrant returns (uint256 fee) {\n    │                                             ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/CabalHook.sol:195:9\n    │\n195 │         emit FeePaid(volume, half, half);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/CabalHook.sol:189:17\n    │\n189 │             if (imd.balanceOf(address(this)) != beforeBalance + fee) revert UnsupportedToken();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/CabalHook.sol:202:9\n    │\n202 │         poolManager.unlock(abi.encode(lower, upper));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/CabalHook.sol:202:9\n    │\n202 │         poolManager.unlock(abi.encode(lower, upper));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/CabalHook.sol:237:9\n    │\n237 │ ┏         emit ProtocolLiquidityAdded(\n238 │ ┃             lower, upper, uint128(liquidity), Currency.unwrap(token0 ? _key.currency0 : _key.currency1), amount\n239 │ ┃         );\n    │ ┗━━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/CabalHook.sol:209:33\n    │\n209 │         (BalanceDelta delta,) = poolManager.modifyLiquidity(_key, ModifyLiquidityParams(lower, upper, 0, 0), \"\");\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/CabalHook.sol:221:22\n    │\n221 │         int24 grid = tick / 60 * 60;\n    │                      ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/CabalHook.sol:233:25\n    │\n233 │         if (liquidity > uint256(uint128(type(int128).max))) revert InvalidRange();\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/CabalHook.sol:233:33\n    │\n233 │         if (liquidity > uint256(uint128(type(int128).max))) revert InvalidRange();\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/CabalHook.sol:235:13\n    │\n235 │             poolManager.modifyLiquidity(_key, ModifyLiquidityParams(lower, upper, int256(liquidity), 0), \"\");\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/CabalHook.sol:235:83\n    │\n235 │             poolManager.modifyLiquidity(_key, ModifyLiquidityParams(lower, upper, int256(liquidity), 0), \"\");\n    │                                                                                   ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/CabalHook.sol:238:27\n    │\n238 │             lower, upper, uint128(liquidity), Currency.unwrap(token0 ? _key.currency0 : _key.currency1), amount\n    │                           ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/CabalHook.sol:249:55\n    │\n249 │             poolManager.take(currency, address(this), uint128(delta));\n    │                                                       ━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/CabalHook.sol:251:28\n    │\n251 │             uint256 owed = uint256(-int256(delta));\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/invariant/GateOnlyRequests.t.sol:108:45\n    │\n108 │         if (r.version == expectedVersion && block.timestamp < expiry) return;\n    │                                             ━━━━━━━━━━━━━━━\n    ‡\n117 │         vm.warp(block.timestamp + bound(secondsSeed, 0, 3601));\n    │         ────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/invariant/GateOnlyRequests.t.sol:86:13\n    │\n 86 │         if (block.timestamp >= r.deadline) return;\n    │             ━━━━━━━━━━━━━━━\n    ‡\n117 │         vm.warp(block.timestamp + bound(secondsSeed, 0, 3601));\n    │         ────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/invariant/GateOnlyRequests.t.sol:247:29\n    │\n117 │         vm.warp(block.timestamp + bound(secondsSeed, 0, 3601));\n    │         ────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    ‡\n247 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/invariant/GateOnlyRequests.t.sol:248:30\n    │\n117 │         vm.warp(block.timestamp + bound(secondsSeed, 0, 3601));\n    │         ────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    ‡\n248 │         a.expiresAt = uint64(block.timestamp + 900);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/invariant/GateOnlyRequests.t.sol:93:57\n    │\n 93 │             assertEq(gate.getRequest(id).approvedUntil, block.timestamp + 300);\n    │                                                         ━━━━━━━━━━━━━━━\n    ‡\n117 │         vm.warp(block.timestamp + bound(secondsSeed, 0, 3601));\n    │         ────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/invariant/GateOnlyRequests.t.sol:117:17\n    │\n117 │         vm.warp(block.timestamp + bound(secondsSeed, 0, 3601));\n    │         ────────━━━━━━━━━━━━━━━─────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\n","passed":true},{"durationMs":8285,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 2 tests for test/OracleLiveVector.t.sol:OracleLiveVectorTest\n[PASS] test_livePayloadDecodesAndSignatureRecoversToBriefSigner() (gas: 50913)\n[PASS] test_liveQuestionHashIsCanonicalKeccak() (gas: 189084)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 1.18ms (1.27ms CPU time)\n\nRan 1 test for test/Trading.t.sol:ReverseTokenOnlySeedTest\n[PASS] test_firstBuyOnFreshManagerWithOnlyCabalSeeded() (gas: 5205640)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 13.50ms (5.92ms CPU time)\n\nRan 5 tests for test/CabalCoin.t.sol:CabalCoinTest\n[PASS] testFuzz_transferConservesSupply(uint256) (runs: 256, μ: 83125, ~: 83399)\nLogs:\n  Bound result 92\n\n[PASS] test_allowanceAndInsufficientBalances() (gas: 197125)\n[PASS] test_launchSupplyMetadataAndPlainTransfer() (gas: 119450)\n[PASS] test_noAdministrativeMint() (gas: 36108)\n[PASS] test_runtimeNoEscapeHatches() (gas: 625143)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 29.22ms (10.83ms CPU time)\n\nRan 1 test for test/GateLaunch.t.sol:GateEmptyEvmLaunchTest\n[PASS] test_gateDeploysInAnEmptyEvmWithTheManifestWords() (gas: 28030480)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 29.28ms (29.12ms CPU time)\n\nRan 1 test for test/Trading.t.sol:TokenOnlySeedTest\n[PASS] test_firstBuyOnFreshManagerWithOnlyCabalSeeded() (gas: 5202507)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 65.28ms (2.29ms CPU time)\n\nRan 1 test for test/Oracle.t.sol:OracleGasTest\n[PASS] test_callbackFitsBelow200kColdTransaction() (gas: 2041560)\nLogs:\n  callback gas including external call: 78063\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 66.31ms (2.86ms CPU time)\n\nRan 5 tests for test/Launch.t.sol:ReverseOrderLaunchTest\n[PASS] test_manifestArgumentsLaunchInOneTransaction() (gas: 64815)\n[PASS] test_secondPoolThroughTheLaunchedHookIsRefused() (gas: 79097)\n[PASS] test_tradingWorksOnTheFactoryLaunchedPool() (gas: 9582420)\n[PASS] test_unspecifiedOwnerIsTheLaunchOriginatorWhoBindsTheGate() (gas: 8196768)\n[PASS] test_zeroOwnerFallsBackToTheOriginatorAndExplicitOwnerIsKept() (gas: 193201216)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 77.15ms (68.66ms CPU time)\n\nRan 2 tests for test/SubmissionGas.t.sol:SubmissionGasTest\n[PASS] test_longestReasonStaysUnderBudget() (gas: 1255330)\n[PASS] test_shortBuyAndSellStayUnderBudget() (gas: 1121402)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 108.90ms (2.07ms CPU time)\n\nRan 7 tests for test/HookBinding.t.sol:HookBindingTest\n[PASS] test_buySubmissionRequiresHookHandoffBeforeCharging() (gas: 27904126)\n[PASS] test_compoundOnARangeTheHookDoesNotOwnRevertsAndChangesNothing() (gas: 5623463)\n[PASS] test_feeStateMachineBlocksSwapsAndCompoundingUntilTheGateSettles() (gas: 592361)\n[PASS] test_firstValidPoolBindsTheHookSoDeploymentAndInitializationMustBeAtomic() (gas: 13687939)\n[PASS] test_initializationRefusesNativeCurrencyMisorderedKeysAndKeysNamingAnotherHook() (gas: 4760220)\n[PASS] test_liquidityDonationsAndFeeClaimsPassBeforeAndAfterBindingWhileSwapsNeverDo() (gas: 15028426)\n[PASS] test_sellSubmissionRequiresHookHandoffBeforeCharging() (gas: 28441285)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 111.45ms (41.01ms CPU time)\n\nRan 1 test for test/OracleSigner.t.sol:OracleSignerTest\n[PASS] test_registrySignatureIsNotAnEOASignatureForTheConfiguredSigner() (gas: 4988822)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 119.99ms (3.53ms CPU time)\n\nRan 9 tests for test/GateFactoryEdges.t.sol:GateFactoryEdgesTest\n[PASS] testFuzz_flatWordsPreserveValidConfiguration(uint128,uint128,uint16,uint16,uint16,uint16,uint8) (runs: 256, μ: 8073154, ~: 8073122)\nLogs:\n  Bound result 1\n  Bound result 50280972822995746186458110123057628\n  Bound result 10\n  Bound result 10\n  Bound result 27\n  Bound result 4\n  Bound result 10\n\n[PASS] test_constructorRejectsDirtyHighBitsInEveryNarrowWord() (gas: 20707250)\n[PASS] test_constructorRejectsTruncatedStaticArguments() (gas: 22207025)\n[PASS] test_factoryOwnerHandoverRequiresAcceptanceAndPreservesBinding() (gas: 8574269)\n[PASS] test_failedConfigurationRollsBackHelpersAndTheAddressStaysFree() (gas: 11140602)\n[PASS] test_helpersAreCreatedByEachGateAndExistingDependenciesStayIntact() (gas: 16162087)\n[PASS] test_hookRejectsMissingCodeWrongHookWrongCabalAndDuplicateBinding() (gas: 8196078)\n[PASS] test_pinnedValidNumericEdges() (gas: 16137138)\n[PASS] test_protocolVectorPinsAllFifteenFieldsTypeStringAndDomain() (gas: 15449)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 141.28ms (156.88ms CPU time)\n\nRan 9 tests for test/GateLaunch.t.sol:GateLaunchTest\n[PASS] test_constructorIgnoresDependencyCodeAndHookState() (gas: 16011666)\n[PASS] test_existingHookOwnerBindsGateOnceAndRefusesSecondGate() (gas: 16191392)\n[PASS] test_explicitOwnerControlsConfigurationInsteadOfFactory() (gas: 8293607)\n[PASS] test_factoryDeploysOnlyGateWithAllNineteenManifestWords() (gas: 28532832)\n[PASS] test_flatConstructorRetainsEveryValidation() (gas: 81027076)\n[PASS] test_hookRefusesGateWithSwappedTokenRoles() (gas: 8371363)\n[PASS] test_ownerConfigureKeepsLiveDependencyChecksAndOracleBounds() (gas: 9261025)\n[PASS] test_requestRevertsWhenTheHookReportsAnotherKeyCabalImdOrGate() (gas: 12778085)\n[PASS] test_requestSucceedsOnlyOnceTheHookReportsThisGate() (gas: 14711313)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 200.83ms (45.54ms CPU time)\n\nRan 5 tests for test/Launch.t.sol:LaunchTest\n[PASS] test_manifestArgumentsLaunchInOneTransaction() (gas: 64815)\n[PASS] test_secondPoolThroughTheLaunchedHookIsRefused() (gas: 78641)\n[PASS] test_tradingWorksOnTheFactoryLaunchedPool() (gas: 9547880)\n[PASS] test_unspecifiedOwnerIsTheLaunchOriginatorWhoBindsTheGate() (gas: 8196370)\n[PASS] test_zeroOwnerFallsBackToTheOriginatorAndExplicitOwnerIsKept() (gas: 80857111)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 280.29ms (41.00ms CPU time)\n\nRan 16 tests for test/AdversarialOracle.t.sol:AdversarialOracleTest\n[PASS] testFuzz_malformedSignatureLengthCannotConsumeRequest(uint8) (runs: 1000, μ: 4508780, ~: 4508627)\nLogs:\n  Bound result 18\n\n[PASS] test_attestationIssuedBeforeSubmissionIsRefused() (gas: 4588977)\n[PASS] test_callbackHasNoDependencyOnTokenNftIntakeOrPoolReads() (gas: 4632939)\n[PASS] test_configurationRejectsEveryInvalidBoundaryWithoutAdvancingVersion() (gas: 2306671)\n[PASS] test_everySignedFieldRejectsPostSignatureMutation() (gas: 22128370)\n[PASS] test_explicitVerifierReplacesGateInDomainAndBody() (gas: 4992210)\n[PASS] test_failedOraclePaymentLeavesNoRequestAndCanRetry() (gas: 3886681)\n[PASS] test_identicalReasonFromAnotherUserDoesNotShareAttestation() (gas: 6655838)\n[PASS] test_mainnetDefaultsMatchAssignment() (gas: 65703)\n[PASS] test_rejectedAndClearedIdsCannotReplayOrAlterNewActiveRequest() (gas: 10985891)\n[PASS] test_rejectionReleasesSlotAndResubmissionNeedsFreshDecision() (gas: 7693973)\n[PASS] test_signatureRejectsHighSAndInvalidV() (gas: 4683745)\n[PASS] test_signatureRejectsWrongNameVersionAndDomainChain() (gas: 4860681)\n[PASS] test_timeoutAndApprovalBoundaryAtLastPermittedSecond() (gas: 5220117)\n[PASS] test_zeroOraclePriceAndZeroReturnedIdAreHandledAtomically() (gas: 3808019)\n[PASS] test_zeroVerifierMeansThisGateAndIsStoredResolved() (gas: 3748615)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 957.13ms (950.46ms CPU time)\n\nRan 20 tests for test/Trading.t.sol:ReverseOrderTradingTest\n[PASS] testFuzz_roundTripAccounting(uint256) (runs: 256, μ: 9663610, ~: 9666630)\nLogs:\n  Bound result 999000000000000000093\n\n[PASS] test_buyAndSellBurnFeesOwnLiquidityAndTrackBasis() (gas: 10034843)\n[PASS] test_callbacksOnlyManagerAndPermissionsMatch() (gas: 233460)\n[PASS] test_driftFromOtherTradesDoesNotInvalidateApprovalUntilDriftCap() (gas: 23928363)\n[PASS] test_estimateMatchesExecutionWithActiveLiquidity() (gas: 5218964)\n[PASS] test_executeWithInlineMinimumNeedsNoSeparateCall() (gas: 10663530)\n[PASS] test_executionRequiresRequesterCorrectSideApprovalAndOnce() (gas: 5248565)\n[PASS] test_expiryAtFiveMinutesAndClear() (gas: 4636966)\n[PASS] test_factoryCanAddCollectFeesAndRemoveDespiteSwapGate() (gas: 5566910)\n[PASS] test_fullSaleClearsBasisAndWeightedBuys() (gas: 13171107)\n[PASS] test_initializationOnceByAnySenderWithLaunchParametersAndImmutablePairAfterBinding() (gas: 15958313)\n[PASS] test_liquidityChangeCannotBypassActualImpactLimit() (gas: 5342823)\n[PASS] test_minOutputMandatoryAndFailedExecutionRollsBackAllTransfers() (gas: 5975057)\n[PASS] test_onePoolOneGateAndNoExactOutput() (gas: 117361)\n[PASS] test_protocolOwnedLiquidityAloneKeepsSubmissionsOpen() (gas: 10300256)\n[PASS] test_protocolPositionCannotBeWithdrawnAndCanCompound() (gas: 5364936)\n[PASS] test_runtimeSizeAndNoEscapeHatches() (gas: 4453777)\n[PASS] test_swapsOutsideGateRevertBothWays() (gas: 100600)\n[PASS] test_transferThatReturnsSuccessWithoutPaymentRejected() (gas: 342627)\n[PASS] test_transferredHoldingsHaveUnknownBasisAndRecordsReconcile() (gas: 11588088)\nSuite result: ok. 20 passed; 0 failed; 0 skipped; finished in 1.07s (1.16s CPU time)\n\nRan 3 tests for test/OracleLatency.t.sol:OracleLatencyTest\n[PASS] test_deliveryAtOldExpiryRetainsFullApproval() (gas: 5329984)\n[PASS] test_deliveryJustBeforeOldExpiryRetainsFullApproval() (gas: 5330072)\n[PASS] test_deliveryJustBeforeRequestDeadlineRetainsFullApproval() (gas: 5330138)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 1.30s (7.99ms CPU time)\n\nRan 7 tests for test/HookBinding.t.sol:ReverseOrderHookBindingTest\n[PASS] test_buySubmissionRequiresHookHandoffBeforeCharging() (gas: 39738304)\n[PASS] test_compoundOnARangeTheHookDoesNotOwnRevertsAndChangesNothing() (gas: 5657783)\n[PASS] test_feeStateMachineBlocksSwapsAndCompoundingUntilTheGateSettles() (gas: 593669)\n[PASS] test_firstValidPoolBindsTheHookSoDeploymentAndInitializationMustBeAtomic() (gas: 24877374)\n[PASS] test_initializationRefusesNativeCurrencyMisorderedKeysAndKeysNamingAnotherHook() (gas: 15427341)\n[PASS] test_liquidityDonationsAndFeeClaimsPassBeforeAndAfterBindingWhileSwapsNeverDo() (gas: 26221970)\n[PASS] test_sellSubmissionRequiresHookHandoffBeforeCharging() (gas: 40290359)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 1.31s (123.63ms CPU time)\n\nRan 7 tests for test/QuestionProperties.t.sol:QuestionPropertiesTest\n[PASS] testFuzz_jsonRoundTripsUntrustedPrintableAscii(bytes,bool,uint128) (runs: 1000, μ: 5044481, ~: 5541955)\n[PASS] test_emptyReasonIsQuotedAndLeftForPanelJudgment() (gas: 9346155)\n[PASS] test_everyAsciiControlCharacterRefusedQuoteBackslashAndDelSurvive() (gas: 15890019)\n[PASS] test_guillemetsRefusedAnywhereOtherLatin1Accepted() (gas: 9970465)\n[PASS] test_invalidUtf8NeverEntersOracleJson() (gas: 243913)\n[PASS] test_questionNeverExceedsTwoThousandCharactersAtMaximalValues() (gas: 2373470)\n[PASS] test_unicodeScalarLimitsIncludeAllUtf8Widths() (gas: 67874956)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 1.32s (1.53s CPU time)\n\nRan 7 tests for test/ReasonEscaping.t.sol:ReasonEscapingTest\n[PASS] testFuzz_arbitraryBytesAreJudgedLikeAnIndependentDecoder(bytes) (runs: 1000, μ: 16193, ~: 12759)\n[PASS] testFuzz_oneCorruptedByteIsJudgedLikeAnIndependentDecoder(bytes32,uint16,uint16,uint8) (runs: 1000, μ: 286889, ~: 185509)\nLogs:\n  Bound result 276\n  Bound result 341\n\n[PASS] testFuzz_wellFormedTextOfEveryWidthIsCountedEscapedAndQuotedExactly(bytes32,uint16) (runs: 1000, μ: 2084075, ~: 1844350)\nLogs:\n  Bound result 190\n\n[PASS] test_byteBoundBeforeContentAndScalarBoundAfterIt() (gas: 1479560)\n[PASS] test_escapedQuestionHashesLikeTheParsedBody() (gas: 2977892)\n[PASS] test_quotesAndBackslashesAreEscapedBetweenMultibyteText() (gas: 32360)\n[PASS] test_truncatedLeadByteAtTheEndIsRefusedWhateverFollowsInMemory() (gas: 28243)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 1.32s (2.65s CPU time)\n\nRan 20 tests for test/Trading.t.sol:TradingTest\n[PASS] testFuzz_roundTripAccounting(uint256) (runs: 256, μ: 9629044, ~: 9632063)\nLogs:\n  Bound result 999000000000000000093\n\n[PASS] test_buyAndSellBurnFeesOwnLiquidityAndTrackBasis() (gas: 10000499)\n[PASS] test_callbacksOnlyManagerAndPermissionsMatch() (gas: 232988)\n[PASS] test_driftFromOtherTradesDoesNotInvalidateApprovalUntilDriftCap() (gas: 23796677)\n[PASS] test_estimateMatchesExecutionWithActiveLiquidity() (gas: 5185001)\n[PASS] test_executeWithInlineMinimumNeedsNoSeparateCall() (gas: 10583138)\n[PASS] test_executionRequiresRequesterCorrectSideApprovalAndOnce() (gas: 5214320)\n[PASS] test_expiryAtFiveMinutesAndClear() (gas: 4637031)\n[PASS] test_factoryCanAddCollectFeesAndRemoveDespiteSwapGate() (gas: 5527899)\n[PASS] test_fullSaleClearsBasisAndWeightedBuys() (gas: 13137418)\n[PASS] test_initializationOnceByAnySenderWithLaunchParametersAndImmutablePairAfterBinding() (gas: 57087463)\n[PASS] test_liquidityChangeCannotBypassActualImpactLimit() (gas: 5335130)\n[PASS] test_minOutputMandatoryAndFailedExecutionRollsBackAllTransfers() (gas: 5899249)\n[PASS] test_onePoolOneGateAndNoExactOutput() (gas: 117096)\n[PASS] test_protocolOwnedLiquidityAloneKeepsSubmissionsOpen() (gas: 10205469)\n[PASS] test_protocolPositionCannotBeWithdrawnAndCanCompound() (gas: 5330535)\n[PASS] test_runtimeSizeAndNoEscapeHatches() (gas: 4453777)\n[PASS] test_swapsOutsideGateRevertBothWays() (gas: 100605)\n[PASS] test_transferThatReturnsSuccessWithoutPaymentRejected() (gas: 342675)\n[PASS] test_transferredHoldingsHaveUnknownBasisAndRecordsReconcile() (gas: 11484128)\nSuite result: ok. 20 passed; 0 failed; 0 skipped; finished in 1.32s (1.33s CPU time)\n\nRan 22 tests for test/Oracle.t.sol:OracleTest\n[PASS] testFuzz_attestationFieldsAreBound(uint8) (runs: 256, μ: 4484147, ~: 4482348)\nLogs:\n  Bound result 4\n\n[PASS] test_280UnicodeCharactersAccepted281Rejected() (gas: 7551853)\n[PASS] test_approvalNeverOutlivesAttestation() (gas: 4530004)\n[PASS] test_attestationCannotBeReusedForAnotherRequest() (gas: 7827686)\n[PASS] test_badSignerDomainAndTampering() (gas: 4810916)\n[PASS] test_bodyIsCanonicalJsonWithConsumerAndStoredEscapedQuestion() (gas: 14363554)\n[PASS] test_configuredPanelParametersFlowIntoBodyAndChecks() (gas: 4966937)\n[PASS] test_controlCharactersAndGuillemetsRejected() (gas: 3946320)\n[PASS] test_intakeFailureUnderpaymentDuplicateIdAndReentry() (gas: 7830902)\n[PASS] test_liveFormatDeliveryWithDistinctOracleIdApproves() (gas: 4551732)\n[PASS] test_malformedUTF8Rejected() (gas: 249790)\n[PASS] test_oldPendingUsesSnapshotIntakeSignerAndDomain() (gas: 5799924)\n[PASS] test_onlyIntakeOnlyPendingReplayAndUnknownIds() (gas: 4644635)\n[PASS] test_oracleClockMayRunSlightlyAheadAndValidityMayBeLong() (gas: 4529900)\n[PASS] test_ownerConfigSnapshotsInvalidatesOldExecutionAndCanClear() (gas: 6130621)\n[PASS] test_questionHashMustMatchStoredQuestionAndWindow() (gas: 6933761)\n[PASS] test_quotesInsideReasonCannotCloseTheDelimiter() (gas: 4381054)\n[PASS] test_sellQuestionIncludesHoldingsPriceBasisTimeNftAndReason() (gas: 11330781)\n[PASS] test_submitPaysExactlyQuotedPriceAndRevokesAllowance() (gas: 3478532)\n[PASS] test_timeoutClearsNoLateCallbackNoTradeFundsEscrowed() (gas: 6655465)\n[PASS] test_trueApprovesForFiveMinutesAndFalseRejects() (gas: 7792450)\n[PASS] test_wrongChainAndSizeAndConcurrentRequestRejected() (gas: 3655388)\nSuite result: ok. 22 passed; 0 failed; 0 skipped; finished in 1.32s (1.30s CPU time)\n\nRan 9 tests for test/EconomicProperties.t.sol:EconomicPropertiesTest\n[PASS] testFuzz_feeCannotExceedHalfPercentAndRoundingIsBounded(uint256) (runs: 1000, μ: 17470, ~: 17696)\n[PASS] testFuzz_priceMovementSymmetricMonotoneAndBounded(uint160,uint160,uint160) (runs: 1000, μ: 51278, ~: 51230)\nLogs:\n  Bound result 3552\n  Bound result 1461501637330902918203684832716283019655932542974\n  Bound result 1461501637330902918203684832716283019655932542974\n\n[PASS] testFuzz_repeatedBuySellCannotCreateImd(uint256,uint8) (runs: 1000, μ: 16346734, ~: 17458566)\nLogs:\n  Bound result 333643558896542\n  Bound result 2\n\n[PASS] test_feeAndPriceKnownBoundaries() (gas: 58487)\n[PASS] test_insufficientExecutionAllowancePreservesApprovalAndCanRetry() (gas: 5472990)\n[PASS] test_realTradesAtFeeRoundingEdges() (gas: 23364977)\n[PASS] test_sellApprovalSurvivesBalanceDropAndExecutesOnceRestored() (gas: 9891494)\n[PASS] test_sellLargerThanTrackedHoldingsClearsTheRecordWithoutUnderflow() (gas: 9678863)\n[PASS] test_sellSlippageFailureRollsBackFeePositionAndCostBasis() (gas: 10260509)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 1.32s (1.28s CPU time)\n\nRan 2 tests for test/invariant/GateOnlyRequests.t.sol:GateOnlyRequestsInvariantTest\n[PASS]\nGateOnlyRequestsInvariantTest invariants:\n[PASS] invariant_gatePreservesDonationsAndChargesOnlyTheRequester\n[PASS] invariant_requestStatesSnapshotsAndBindingRemainConsistent\n GateOnlyRequestsInvariantTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭------------------------+--------------------+-------+---------+----------╮\n| Contract               | Selector           | Calls | Reverts | Discards |\n+==========================================================================+\n| GateOnlyRequestHandler | advance            | 1636  | 0       | 0        |\n|------------------------+--------------------+-------+---------+----------|\n| GateOnlyRequestHandler | clear              | 1629  | 0       | 0        |\n|------------------------+--------------------+-------+---------+----------|\n| GateOnlyRequestHandler | cycle              | 1622  | 0       | 0        |\n|------------------------+--------------------+-------+---------+----------|\n| GateOnlyRequestHandler | donate             | 1610  | 0       | 0        |\n|------------------------+--------------------+-------+---------+----------|\n| GateOnlyRequestHandler | reconfigure        | 1662  | 0       | 0        |\n|------------------------+--------------------+-------+---------+----------|\n| GateOnlyRequestHandler | refuseCallback     | 1654  | 0       | 0        |\n|------------------------+--------------------+-------+---------+----------|\n| GateOnlyRequestHandler | refusePayment      | 1629  | 0       | 0        |\n|------------------------+--------------------+-------+---------+----------|\n| GateOnlyRequestHandler | refuseUnauthorized | 1596  | 0       | 0        |\n|------------------------+--------------------+-------+---------+----------|\n| GateOnlyRequestHandler | request            | 1692  | 0       | 0        |\n|------------------------+--------------------+-------+---------+----------|\n| GateOnlyRequestHandler | resolve            | 1654  | 0       | 0        |\n╰------------------------+--------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 224\n  Bound result 16803\n  Bound result 500000000000000000\n  Bound result 1000000000000000000\n  Bound result 10973527\n  Bound result 828417\n  Bound result 1645\n  Bound result 0\n  Bound result 3898454\n  Bound result 1527\n  Bound result 543145807640700717\n  Bound result 1001\n  Bound result 1633\n  Bound result 22118\n  Bound result 23\n  Bound result 500000000000000000\n  Bound result 1000000000000000000\n  Bound result 15\n  Bound result 21259\n  Bound result 200\n  Bound result 1398\n  Bound result 971880845463515079\n  Bound result 3218\n  Bound result 12705\n  Bound result 500000000000000000\n  Bound result 1000000000000000000\n  Bound result 300\n  Bound result 20\n  Bound result 22\n  Bound result 16\n  Bound result 394\n  Bound result 480766375000403080\n  Bound result 1408\n  Bound result 4\n  Bound result 11\n  Bound result 8218\n  Bound result 280743323735687043\n  Bound result 1000000000000000000\n  Bound result 136275314817270205\n\n[PASS] test_handlerExercisesPaymentsFailuresBothAnswersAndClearing() (gas: 18838876)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 0\n  Bound result 1\n  Bound result 300\n  Bound result 500000000000000000\n  Bound result 1000000000000000000\n  Bound result 500000000000000000\n  Bound result 1000000000000000000\n  Bound result 300\n  Bound result 500000000000000000\n  Bound result 1000000000000000000\n  Bound result 3600\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 24\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 7.26s (7.26s CPU time)\n\nRan 2 tests for test/invariant/CabalInvariant.t.sol:CabalInvariantTest\n[PASS] invariant_conservationSettlementLifecycleAndLockedPol() (runs: 256, calls: 16384, reverts: 0)\n\n╭--------------+--------------------+-------+---------+----------╮\n| Contract     | Selector           | Calls | Reverts | Discards |\n+================================================================+\n| CabalHandler | advance            | 1526  | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| CabalHandler | clear              | 1461  | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| CabalHandler | compound           | 1526  | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| CabalHandler | donate             | 1451  | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| CabalHandler | execute            | 1500  | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| CabalHandler | reconfigure        | 1446  | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| CabalHandler | rejectBadExecution | 1487  | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| CabalHandler | request            | 1458  | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| CabalHandler | resolve            | 1560  | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| CabalHandler | trade              | 1479  | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| CabalHandler | transfer           | 1490  | 0       | 0        |\n╰--------------+--------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 821096873977831687793\n  Bound result 0\n  Bound result 2\n  Bound result 999999999999999999664\n  Bound result 0\n  Bound result 0\n  Bound result 11659\n  Bound result 200\n  Bound result 999999999999999999614\n  Bound result 0\n  Bound result 298\n  Bound result 61\n  Bound result 0\n  Bound result 261\n  Bound result 206050003949151543170\n  Bound result 941245665355568664546\n  Bound result 0\n  Bound result 2646\n  Bound result 7\n  Bound result 5712082\n  Bound result 19\n  Bound result 26031907730635\n  Bound result 130\n  Bound result 1\n  Bound result 15\n  Bound result 124\n  Bound result 92\n\n[PASS] test_handlerExercisesSuccessFailureExpiryAndCompounding() (gas: 16353806)\nLogs:\n  Bound result 100000000000000000000\n  Bound result 10000000000000000000\n  Bound result 10000000000000000000\n  Bound result 3601\n  Bound result 10000000000000000000\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 8.15s (8.14s CPU time)\n\nRan 2 tests for test/invariant/CabalInvariant.t.sol:CabalReverseInvariantTest\n[PASS] invariant_conservationSettlementLifecycleAndLockedPol() (runs: 256, calls: 16384, reverts: 0)\n\n╭--------------+--------------------+-------+---------+----------╮\n| Contract     | Selector           | Calls | Reverts | Discards |\n+================================================================+\n| CabalHandler | advance            | 1526  | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| CabalHandler | clear              | 1461  | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| CabalHandler | compound           | 1526  | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| CabalHandler | donate             | 1451  | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| CabalHandler | execute            | 1500  | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| CabalHandler | reconfigure        | 1446  | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| CabalHandler | rejectBadExecution | 1487  | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| CabalHandler | request            | 1458  | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| CabalHandler | resolve            | 1560  | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| CabalHandler | trade              | 1479  | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| CabalHandler | transfer           | 1490  | 0       | 0        |\n╰--------------+--------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 8081\n  Bound result 29\n  Bound result 2\n  Bound result 999999999999999999664\n  Bound result 0\n  Bound result 0\n  Bound result 11055\n  Bound result 200\n  Bound result 999999999999999999614\n  Bound result 0\n  Bound result 298\n  Bound result 61\n  Bound result 0\n  Bound result 3400\n  Bound result 206050003949151543170\n  Bound result 957273030537742351976\n  Bound result 600486548829932293\n  Bound result 2646\n  Bound result 7\n  Bound result 5712082\n  Bound result 15\n  Bound result 26031907730635\n  Bound result 130\n  Bound result 1\n  Bound result 366179171551254073360\n  Bound result 10\n  Bound result 164\n  Bound result 92\n  Bound result 999999999999999999667\n\n[PASS] test_handlerExercisesSuccessFailureExpiryAndCompounding() (gas: 16395913)\nLogs:\n  Bound result 100000000000000000000\n  Bound result 10000000000000000000\n  Bound result 10000000000000000000\n  Bound result 3601\n  Bound result 10000000000000000000\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 8.18s (8.19s CPU time)\n\nRan 25 test suites in 8.18s (36.04s CPU time): 166 tests passed, 0 failed, 0 skipped (166 total tests)\n","passed":true},{"durationMs":79,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"CabalCoin.approve(address,uint256)\",\"CabalCoin.transfer(address,uint256)\",\"CabalCoin.transferFrom(address,address,uint256)\",\"CabalGate.acceptOwnership()\",\"CabalGate.clearRequest(bytes32)\",\"CabalGate.configure((address,address,address,address,bytes32,uint128,uint128,uint16,uint16,uint16,uint16,uint8,uint8))\",\"CabalGate.executeBuyRequest(bytes32)\",\"CabalGate.executeBuyRequest(bytes32,uint256)\",\"CabalGate.executeSellRequest(bytes32)\",\"CabalGate.executeSellRequest(bytes32,uint256)\",\"CabalGate.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"CabalGate.renounceOwnership()\",\"CabalGate.setSlippageLimit(bytes32,uint256)\",\"CabalGate.submitBuyRequest(uint256,string)\",\"CabalGate.submitSellRequest(uint256,string)\",\"CabalGate.transferOwnership(address)\",\"CabalGate.unlockCallback(bytes)\",\"CabalHook.acceptOwnership()\",\"CabalHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"CabalHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"CabalHook.compound(int24,int24)\",\"CabalHook.finishSwap()\",\"CabalHook.renounceOwnership()\",\"CabalHook.setGate(address)\",\"CabalHook.setIMD(address)\",\"CabalHook.transferOwnership(address)\",\"CabalHook.unlockCallback(bytes)\"],\"files\":{\".gitignore\":4,\"ADAPTATION.md\":80,\"README.md\":59,\"docs/DEPLOYMENT.md\":80,\"docs/ORACLE.md\":97,\"docs/SECURITY.md\":29,\"docs/dependencies.json\":26,\"foundry.toml\":20,\"script/HookSaltMiner.sol\":23,\"src/CabalCoin.sol\":11,\"src/CabalGate.sol\":511,\"src/CabalHook.sol\":257,\"src/HookFlags.sol\":29,\"src/ImpactEstimator.sol\":91,\"src/QuestionBuilder.sol\":124,\"src/interfaces/IIntake.sol\":41,\"src/libraries/CanonicalRequest.sol\":34,\"src/libraries/DataStore.sol\":27,\"src/libraries/Json.sol\":145,\"src/libraries/MainnetDefaults.sol\":11,\"src/libraries/OracleSignature.sol\":42,\"src/libraries/PriceMath.sol\":14,\"test/AdversarialOracle.t.sol\":337,\"test/CabalCoin.t.sol\":62,\"test/CabalFixture.sol\":362,\"test/EconomicProperties.t.sol\":188,\"test/GateFactoryEdges.t.sol\":271,\"test/GateLaunch.t.sol\":542,\"test/GateLaunchChecks.md\":54,\"test/HookBinding.t.sol\":359,\"test/Launch.t.sol\":137,\"test/Oracle.t.sol\":439,\"test/OracleLatency.t.sol\":44,\"test/OracleLiveVector.t.sol\":81,\"test/OracleSigner.t.sol\":41,\"test/QuestionProperties.t.sol\":264,\"test/README.md\":23,\"test/ReasonEscaping.t.sol\":373,\"test/SubmissionGas.t.sol\":67,\"test/Trading.t.sol\":493,\"test/invariant/CabalHandler.sol\":355,\"test/invariant/CabalInvariant.t.sol\":75,\"test/invariant/GateOnlyRequests.t.sol\":400,\"test/mocks/MockERC20.sol\":13,\"test/mocks/MockIntake.sol\":93},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":8240,"exitCode":0,"name":"slither","output":"[high/medium] reentrancy-balance at src/CabalGate.sol:239: Reentrancy in CabalGate._submit(bool,uint256,string) (src/CabalGate.sol#239-305):\n[high/medium] reentrancy-balance at src/CabalGate.sol:239: Reentrancy in CabalGate._submit(bool,uint256,string) (src/CabalGate.sol#239-305):\n[medium/medium] divide-before-multiply at src/CabalHook.sol:218: CabalHook._addSingleSided(bool,uint256) (src/CabalHook.sol#218-240) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/CabalHook.sol:179: CabalHook.finishSwap() (src/CabalHook.sol#179-196) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/CabalHook.sol:175: CabalHook.feeFor(uint256) (src/CabalHook.sol#175-177) performs a multiplication on the result of a division:\n[medium/high] incorrect-equality at src/CabalGate.sol:495: CabalGate._reduceHolding(CabalGate.Holding,uint256) (src/CabalGate.sol#495-503) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/CabalHook.sol:218: CabalHook._addSingleSided(bool,uint256) (src/CabalHook.sol#218-240) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/CabalGate.sol:239: CabalGate._submit(bool,uint256,string) (src/CabalGate.sol#239-305) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/CabalGate.sol:495: CabalGate._reduceHolding(CabalGate.Holding,uint256) (src/CabalGate.sol#495-503) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/CabalHook.sol:218: CabalHook._addSingleSided(bool,uint256) (src/CabalHook.sol#218-240) uses a dangerous strict equality:\n[medium/medium] reentrancy-no-eth at src/CabalGate.sol:239: Reentrancy in CabalGate._submit(bool,uint256,string) (src/CabalGate.sol#239-305):\n[medium/medium] reentrancy-no-eth at src/CabalGate.sol:388: Reentrancy in CabalGate._execute(bytes32,bool,uint256) (src/CabalGate.sol#388-424):\n[medium/medium] uninitialized-local at src/libraries/Json.sol:94: Json.length(bytes).n (src/libraries/Json.sol#94) is a local variable never initialized\n[medium/medium] unused-return at src/CabalHook.sol:218: CabalHook._addSingleSided(bool,uint256) (src/CabalHook.sol#218-240) ignores return value by (None,tick,None,None) = poolManager.getSlot0(_key.toId()) (src/CabalHook.sol#220)\n[medium/medium] unused-return at src/CabalHook.sol:206: CabalHook.unlockCallback(bytes) (src/CabalHook.sol#206-214) ignores return value by (delta,None) = poolManager.modifyLiquidity(_key,ModifyLiquidityParams(lower,upper,0,0),) (src/CabalHook.sol#209)\n[medium/medium] unused-return at src/ImpactEstimator.sol:33: ImpactEstimator.estimate(bool,uint256) (src/ImpactEstimator.sol#33-60) ignores return value by (sqrtPrice,tick,None,None) = poolManager.getSlot0(poolId) (src/ImpactEstimator.sol#35)\n[medium/medium] unused-return at src/CabalHook.sol:199: CabalHook.compound(int24,int24) (src/CabalHook.sol#199-204) ignores return value by poolManager.unlock(abi.encode(lower,upper)) (src/CabalHook.sol#202)\n[medium/medium] unused-return at src/CabalGate.sol:426: CabalGate.unlockCallback(bytes) (src/CabalGate.sol#426-464) ignores return value by (afterPrice,None,None,None) = poolManager.getSlot0(_key.toId()) (src/CabalGate.sol#452)\n[medium/medium] unused-return at src/CabalGate.sol:239: CabalGate._submit(bool,uint256,string) (src/CabalGate.sol#239-305) ignores return value by (sqrtPrice,None,None,None) = poolManager.getSlot0(_key.toId()) (src/CabalGate.sol#255)\n[medium/medium] unused-return at src/CabalGate.sol:426: CabalGate.unlockCallback(bytes) (src/CabalGate.sol#426-464) ignores return value by (beforePrice,None,None,None) = poolManager.getSlot0(_key.toId()) (src/CabalGate.sol#441)\n[medium/medium] unused-return at src/CabalGate.sol:388: CabalGate._execute(bytes32,bool,uint256) (src/CabalGate.sol#388-424) ignores return value by (current,None,None,None) = poolManager.getSlot0(_key.toId()) (src/CabalGate.sol#400)\n[medium/medium] unused-return at src/ImpactEstimator.sol:33: ImpactEstimator.estimate(bool,uint256) (src/ImpactEstimator.sol#33-60) ignores return value by (None,liquidityNet) = poolManager.getTickLiquidity(poolId,next) (src/ImpactEstimator.sol#41)\n[medium/medium] unused-return at src/CabalHook.sol:218: CabalHook._addSingleSided(bool,uint256) (src/CabalHook.sol#218-240) ignores return value by (delta,None) = poolManager.modifyLiquidity(_key,ModifyLiquidityParams(lower,upper,int256(liquidity),0),) (src/CabalHook.sol#234-235)\n[low/medium] missing-zero-check at src/CabalHook.sol:126: CabalHook.beforeInitialize(address,PoolKey,uint160).sender (src/CabalHook.sol#126) lacks a zero-check on :\n[low/medium] reentrancy-benign at src/CabalGate.sol:239: Reentrancy in CabalGate._submit(bool,uint256,string) (src/CabalGate.sol#239-305):\n[low/medium] reentrancy-benign at src/CabalHook.sol:199: Reentrancy in CabalHook.compound(int24,int24) (src/CabalHook.sol#199-204):\n[low/medium] reentrancy-benign at src/CabalGate.sol:388: Reentrancy in CabalGate._execute(bytes32,bool,uint256) (src/CabalGate.sol#388-424):\n[low/medium] reentrancy-events at src/CabalHook.sol:206: Reentrancy in CabalHook.unlockCallback(bytes) (src/CabalHook.sol#206-214):\n[low/medium] reentrancy-events at src/CabalHook.sol:218: Reentrancy in CabalHook._addSingleSided(bool,uint256) (src/CabalHook.sol#218-240):\n[low/medium] reentrancy-events at src/CabalHook.sol:206: Reentrancy in CabalHook.unlockCallback(bytes) (src/CabalHook.sol#206-214):\n[low/medium] timestamp at src/CabalGate.sol:388: CabalGate._execute(bytes32,bool,uint256) (src/CabalGate.sol#388-424) uses timestamp for comparisons\n[low/medium] timestamp at src/CabalGate.sol:311: CabalGate.onOracleResult(bytes32,Attestation,bytes) (src/CabalGate.sol#311-343) uses timestamp for comparisons\n[low/medium] timestamp at src/CabalGate.sol:354: CabalGate.clearRequest(bytes32) (src/CabalGate.sol#354-368) uses timestamp for comparisons\n[low/medium] timestamp at src/CabalGate.sol:239: CabalGate._submit(bool,uint256,string) (src/CabalGate.sol#239-305) uses timestamp for comparisons","passed":true},{"durationMs":671,"exitCode":0,"name":"aderyn","output":"[high] abi-encode-packed-hash-collision at src/QuestionBuilder.sol:98: `abi.encodePacked()` Hash Collision (3 places)\n[high] reentrancy-state-change at src/CabalGate.sol:325: Reentrancy: State change after external call (5 places)\n[low] centralization-risk at src/CabalGate.sol:29: Centralization Risk (5 places)\n[low] division-before-multiplication at src/CabalHook.sol:221: Incorrect Order of Division and Multiplication\n[low] internal-function-used-once at src/HookFlags.sol:22: Internal Function Used Only Once\n[low] large-numeric-literal at src/CabalCoin.sol:9: Large Numeric Literal (12 places)\n[low] literal-instead-of-constant at src/CabalGate.sol:223: Literal Instead of Constant (78 places)\n[low] modifier-used-only-once at src/CabalHook.sol:91: Modifier Invoked Only Once\n[low] non-reentrant-not-first at src/CabalGate.sol:210: `nonReentrant` is Not the First Modifier (2 places)\n[low] require-revert-in-loop at src/ImpactEstimator.sol:70: Loop Contains `require`/`revert` (2 places)\n[low] state-change-without-event at src/CabalGate.sol:426: State Change Without Event (3 places)\n[low] state-no-address-check at src/CabalHook.sol:135: Address State Variable Set Without Checks\n[low] unchecked-return at src/CabalHook.sol:202: Unchecked Return\n[low] uninitialized-local-variable at src/ImpactEstimator.sol:70: Uninitialized Local Variable (2 places)\n[low] unused-public-function at src/CabalHook.sol:175: Public Function Not Used Internally","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"8841e823ef205134a95c97a1af16c42fffbd6fff11349581061c6c49599a8e31","verifiedTreeHash":"39ff23e6ba9586c7bd3bb135baac7fba5cbc1e0c","verifierVersion":"0.1.0+8af37dff"},{"checks":[{"durationMs":300025,"exitCode":137,"name":"build","output":"Compiling 120 files with Solc 0.8.26\n","passed":false}],"detail":"build failed with exit code 137","evaluation":"checks","profile":"foundry","status":"rejected","submissionHash":"b4e5abf2067edc74fe2b74e0163c4df0fe2aec7d1cde251ec22d85a0e0d65d4c","verifiedTreeHash":"c471222cac5aeff6b3a57f07d4fec47c5cfa33f4","verifierVersion":"0.1.0+5d71dfd4"}]}