{"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":"6e8264fd-0574-4350-8fb0-9058496d00f3","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"43e5bc42a34212b4529423ad8946afa90094ee573bbb1b8e179d88ec1f63cfbc","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_economics","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"7b16564d51aed37d52284cae1fa1e4ed5f252e05d245752935f7ac2c93f60adc","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_flow","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":null,"dependsOn":["build_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"af3aa01159bbf354f621cafa5c0006f6169e0938a8b015be508b7377dbf165bc","skillId":"audit-judge","tools":[]},"key":"audit_judge","kind":"code","role":"review","skillHash":"af3aa01159bbf354f621cafa5c0006f6169e0938a8b015be508b7377dbf165bc","skillId":"audit-judge","state":"waiting"},{"acceptedSubmissionHash":"a6f311fb5e57f90877e99d9ac656c77ca29b2a40b34043d1a38c640d6decde59","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_math","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"566439ba5aab25764454d01f65b10e0501b04dee7f5d178a9ec10a4121162c65","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_permissions","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"42d9230343d8c7e947d57a31376c532b8a1a7e811d3986023f3e8e47f8be3ce5","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"6b8d2c2ebd3301cff2be8edb1e1cc6ba65c858c02fe7247be81722b969842265","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"6b8d2c2ebd3301cff2be8edb1e1cc6ba65c858c02fe7247be81722b969842265","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":null,"dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"failed"},{"acceptedSubmissionHash":"53b6750595aa704e937586c33d05293a7cadcbb8bacc7d89ff8229afddd3b1e7","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","state":"accepted"}],"objective":"A custom token: Democratizing Collectable Acquisions (DCA).\nToken name: Democratizing Collectable Acquisions\nToken symbol: DCA\nToken supply: 1,000,000,000 with 18 decimals, all minted once to the deployer in the constructor.\nWhat it does: A custom token: Democratizing Collectable Acquisions (DCA).\n\nToken name: Democratizing Collectable Acquisions\n\nToken symbol: DCA\n\nToken supply: 1,000,000,000 with 18 decimals, all minted once to the deployer in the constructor.\n\nWhat it does: Add a fixed 5% hook fee on both buys and sells in the launch pool. This is additional to IMD’s mandatory platform/pool fee.\n\nCollect the hook fee exclusively in FWA:\n\nOn buys, take it from the FWA paid in.\n\nOn sells, take it from the FWA paid out.\n\nAll FWA collected by this hook belongs to this fixed fee recipient:\n\n0xCAE0B01E56cB164ce866A137d3528658b2FCBd4b\n\nKeep collected fees in the hook until a permissionless claimFees() call sends them only to that recipient. Neither the fee percentage nor recipient can be changed.\n\nUse a standard token with no wallet-to-wallet transfer tax. No anti-sniper tax, blacklist, wallet limits, router whitelist, NFT functionality, oracle, staking, website, image or socials.","parentJobId":null,"planHash":"e67266be9d116bcac2e31cc406fe611ba6738c9c12874318b0f42df7d67f192b","previousHash":"6f2c6e04fae8c2b3fecbd843a8f3918f9bce5eaf41e795bf7babb2604132ff66","projectId":"6e8264fd-0574-4350-8fb0-9058496d00f3","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1464-democratizing-collectable-acquisions"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"52257","feedbackHash":"84e7038019c86366e8be6668fca68181aa03322d366d6faafd0ab3cff27ebf14","nodeKey":"audit_economics","submissionHash":"43e5bc42a34212b4529423ad8946afa90094ee573bbb1b8e179d88ec1f63cfbc","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52021","feedbackHash":"63d78bf8a056fec7c6cfcd7e9cd368f30f5d81db2b57e93e5e21d7fcb47ed187","nodeKey":"audit_flow","submissionHash":"7b16564d51aed37d52284cae1fa1e4ed5f252e05d245752935f7ac2c93f60adc","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"50995","feedbackHash":"a2cba9d67b8b79fd57e460163211dfb63005ce89650f0c0755b6a1dbb432a321","nodeKey":"audit_math","submissionHash":"a6f311fb5e57f90877e99d9ac656c77ca29b2a40b34043d1a38c640d6decde59","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51530","feedbackHash":"a3bdea07ab2f774fe83ee415d989c95d8235ffffe9dc7dff3c2543fe83e41ed5","nodeKey":"audit_permissions","submissionHash":"566439ba5aab25764454d01f65b10e0501b04dee7f5d178a9ec10a4121162c65","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51354","feedbackHash":"72468279c01c56cbb8b0033f1f93fc8b016831e89dd0f196d53f82c6dd7e9b9f","nodeKey":"write_foundry_tests","submissionHash":"53b6750595aa704e937586c33d05293a7cadcbb8bacc7d89ff8229afddd3b1e7","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"a9375a4e5d49bbcc792e326b441e626cf3dc4b970998f886471c554739c2dc67","state":"blocked","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"e54711bd1fbb0d02","findings":[],"hash":"2301a2b74e5c28d619bcda26cfcee36dd36219bba35a6234749f4d51539c806c","nodeId":"86dc7a9a-47e0-40c9-b938-cd011af6ab46","outcome":"failed","summary":"needs input: The accepted implementation cannot deliver the required 5% FWA fee through a manifest-only custom_token repair. DCAHook's constructor requires an address whose low 14 bits are 0x20cc, but custom_token application deployment does not mine its salt. The accepted production contracts contain no callable hook deployer: HookMiner is an internal library and PrepareHook only calculates salts. The permitted manifest fields cannot select a hook salt or attach DCAHook to the launch pool; the supplied protected harness initializes that pool with PoolInitializationGuard. Removing DCAHook would omit the requested fee. A prerequisite accepted implementation and deployment integration must support mined hook deployment and selection of DCAHook when initializing the launch pool. This requires work outside the only authorized deliverable, launch.json. The existing manifest and accepted files were left unchanged. forge build succeeded and forge test reported 76 passed, 0 failed; these local tests do not","treeHash":null,"usage":{"cachedInputTokens":624640,"inputTokens":76900,"model":"gpt-6-astra","outputTokens":8974,"runtime":"codex","turns":8,"wallClockMs":285914}},{"artifacts":[],"attempt":1,"bundleHash":"a31a377c40c9ab73187bbfba5d2acfd25421b5a8a7096dbccfcbf9d8b4063c20","device":"107def308610130e","findings":[],"hash":"42d9230343d8c7e947d57a31376c532b8a1a7e811d3986023f3e8e47f8be3ce5","nodeId":"02cbe075-81b6-42c8-93a6-eb1069ba3bc0","outcome":"completed","summary":"Implemented the fixed-supply DCA token and immutable 5% FWA fee hook, with permissionless claims paying only the specified recipient.\n\nVerified offline: build passed, 76 tests passed, formatting passed.\n\nDeployment requirements and partial-fill behavior are documented in [README.md](/home/imd/.identitymd/work/6e8264fd-0574-4350-8fb0-9058496d00f3/02cbe075-81b6-42c8-93a6-eb1069ba3bc0/README.md). The launch pool must be configured to use `DCAHook`.","treeHash":"978c4e6e72825cde2f400e5139d5bad57f0fbc4a","usage":{"cachedInputTokens":1859456,"inputTokens":120278,"model":"gpt-6-astra","outputTokens":34322,"runtime":"codex","turns":7,"wallClockMs":885957}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"22c9b760d0a15149","findings":[{"citation":"resolved","description":"Flow-gap finding (execution x periphery x first principles). The requester's objective is a 5% FWA hook fee 'in the launch pool'. A Uniswap v4 pool has exactly one hook, fixed in its PoolKey at initialization. The floor this launch is judged against (.imd/reads/protected/custom_token/Token.protected.t.sol, _key() at line 345-350 and setUp at 165-175) initializes the launch pool with `IHooks(poolHook)` where poolHook is the factory's PoolInitializationGuard, and the launch.json schema for kind custom_token has no hooks field (pool is only pairedCurrency/fee/tickSpacing/initialPrice). DCAHook can therefore only ever be an application contract beside that pool. Its own pool (getPoolKey(): same currencies, fee 12500, tickSpacing 60, hooks = DCAHook) is a different PoolId; beforeInitialize at line 91 lets only `launchFactory` (the msg.sender of the hook's constructor, line 61) initialize it, and the factory's custom_token flow initializes only its guard pool. End state after a launch as currently scoped: traders buy and sell DCA in the launch pool with FWA and pay zero hook fee; pendingFees() stays 0 forever; claimFees() returns 0; the fee recipient 0xCAE0B01E56cB164ce866A137d3528658b2FCBd4b receives nothing; neither the requester, the fee recipient nor anyone else can open the hook pool afterwards (OnlyLaunchFactory), and the guard pool's hook cannot be changed after initialization. The README (line 93) acknowledges this dependency but the launch kind named in the job (custom token) does not provide the hook-capable path; the fwa-v2 reference names `univ4_hook` as the launch kind that deploys the hook as the pool's hook. Also note for the manifest step: application contracts may only use $token, $requester or $contract:EarlierName, so the hook's first constructor argument must be written as the static PoolManager address 0x000000000004444c5dc75cb358380d2e3de08a90, and POOL_FEE/TICK_SPACING are hardcoded to 12500/60, so a launch policy with any other pool fee or spacing makes the hook pool un-initializable (InvalidPool). Needed decision: either launch this project under the hook-capable launch kind so the factory initializes the pool with hooks = DCAHook, or accept that the custom_token launch carries no fee. No code change alone fixes it, so no proof test is attached.","line":91,"path":"src/DCAHook.sol","reproduction":"State: real PoolManager, DCAToken deployed by a factory F via CREATE2, DCAHook deployed by F with a mined salt (launchFactory = F). Calls: (1) F initializes PoolKey(sorted(DCA,FWA), 12500, 60, hooks = guard-only hook) at sqrtPrice 2^96 (exactly what the protected harness does), seeds 1e24 liquidity in [-60000, 60000]; (2) a trader does an exact-input buy of 100 FWA in that pool. Expected per the job: 5 FWA accrue to the hook / recipient. Actual: trader pays exactly 100 FWA, hook.pendingFees() == 0, hook.claimFees() returns 0, FWA.balanceOf(FEE_RECIPIENT) == 0. (3) Any address other than F calls PoolManager.initialize(hook.getPoolKey(), 2^96): reverts WrappedError(hook, beforeInitialize, OnlyLaunchFactory(), HookCallFailed()). Reproduced in test/scratch/LaunchWiring.t.sol::test_GuardPoolChargesNoFeeAndHookPoolInitializableOnlyByFactory (passes, i.e. the described behaviour is what the code does).","severity":"medium","snippet":"        if (sender != launchFactory) revert OnlyLaunchFactory();","title":"Under the custom_token launch flow the launch pool is built with the factory's initialization guard as its hook, so no trade in the launch pool pays the 5% FWA fee, and the DCAHook pool can never be i"},{"citation":"resolved","description":"Deployment-flow gap. Hooks.validateHookPermissions reverts HookAddressNotValid(address) whenever the hook's own address does not carry exactly the five flag bits 0x20cc in its low 14 bits, so only 1 in 16384 CREATE2 salts (and essentially no CREATE deployment) succeeds. The protected harness deploys every application contract with a deployer-chosen salt (IMD_PROJECT_SALT_i) and requires `deployed.code.length > 0` ('constructor failed'), and launch.json's contracts entries carry only {contract, constructorArgs}: there is no field through which the mined salt from script/PrepareHook.s.sol can reach the deployer. If the deployer derives salts the way it does for the token (bytes32(launchNumber)) or any other non-mined way, the DCAHook constructor reverts, LaunchProbe.deploy reverts 'constructor failed', and the launch cannot be deployed at all (no funds lost; the launch is blocked until re-submitted). This is a configuration/service gap rather than an arithmetic defect: the needed evidence is that the deployer supports hook-flag salt mining for this contract (or the hook-capable launch kind handles it). If it does not, the author must either obtain that support or the launch cannot include this hook. No proof test is attached because no code change alone makes it pass.","line":63,"path":"src/DCAHook.sol","reproduction":"Calls: (a) from any factory contract F, `new DCAHook(IPoolManager(0x000000000004444c5dc75cB358380D2e3dE08A90), token)` with plain CREATE: reverts HookAddressNotValid(predictedAddress) because predicted & 0x3fff != 0x20cc. (b) CREATE2 from F with salt bytes32(uint256(7)) (a deterministic salt like the one the floor uses for the token): the init code reverts and F's create2 returns address(0). Expected for a launch: the hook deploys at the deployer's chosen address. Actual: deployment reverts unless the salt was mined with HookMiner.find for exactly (F, creationCode, constructor args). Reproduced in test/scratch/LaunchWiring.t.sol::test_UnminedDeploymentRevertsInConstructor.","severity":"medium","snippet":"        Hooks.validateHookPermissions(IHooks(address(this)), getHookPermissions());","title":"DCAHook's constructor reverts unless the deployer mines a CREATE2 salt whose address ends in 0x20cc; the manifest has no salt field, so a deployer that derives salts deterministically fails the whole "},{"citation":"resolved","description":"Invariant/path-divergence note. beforeSwap commits the 5% fee on the full specified FWA amount via BeforeSwapDelta before the pool runs; afterSwap then requires the pool to have consumed exactly amountSpecified + fee and otherwise reverts PartialFill. Uniswap v4 pools fill up to the price limit and return a partial delta instead of reverting, and the same hook pool's exact-output buy / exact-input sell paths (lines 136-143) accept partial fills and tax the actual FWA leg. The asymmetry means two swaps that differ only in which side is specified behave differently under the same price limit: one reverts, the other fills and charges 5% of the actual FWA. No funds are lost and the revert is atomic (fees, price and balances roll back; verified by the repo's test_PartialExactInputBuyRevertsAndRollsBack), and the README documents it, so this is a design trade-off for the author to confirm rather than a loss path. A fee charged in afterSwap on the actual FWA delta (as the unspecified paths already do) would remove the asymmetry if partial fills are wanted.","line":134,"path":"src/DCAHook.sol","reproduction":"State: hook pool and a hookless control pool, both at sqrtPrice 2^96 with 1e24 liquidity in [-60000, 60000] (HookTestBase.setUp). Input: exact-input buy of 1000 FWA (amountSpecified = -1000e18, FWA side in) with sqrtPriceLimitX96 = TickMath.getSqrtPriceAtTick(-1) (FWA is currency0) in both pools. Control pool: fills partially, FWA delta -50631645632907436987 (about 50.6 FWA in), DCA out 49996250312472658710. Hook pool: reverts WrappedError(hook, afterSwap, PartialFill(), HookCallFailed()). Same limit with an exact-output buy of 1000 DCA in the hook pool: fills partially, FWA delta -53296469087270986302, fee = 2664823454363549315 (5% of actual input). Reproduced in test/scratch/PartialFill.t.sol.","severity":"low","snippet":"            if (fwaDelta != params.amountSpecified + int256(fee)) revert PartialFill();","title":"Exact-input buys and exact-output sells revert on any partial fill, so a buyer who protects slippage with sqrtPriceLimitX96 gets a revert where the same pool without the hook (and the hook's own exact"}],"hash":"43e5bc42a34212b4529423ad8946afa90094ee573bbb1b8e179d88ec1f63cfbc","nodeId":"61b75338-b16a-4264-9ac7-08e22aaa40f5","outcome":"completed","summary":"The findings file is in place and intentionally excluded from git by the harness, with no source files changed. The review is complete.\n\n**Outcome.** The hook's fee arithmetic and custody are sound in every mode I traced. The defects I found are in how this hook meets the launch flow, not in its math. Three findings are recorded in `.imd-findings.json` with a 12-row coverage record.\n\n**Findings**\n\n- **Medium, launch pool never carries the fee.** The custom-token floor builds the launch pool with the factory's initialization guard as its hook, and the manifest has no hooks field. DCAHook's own pool is a different pool that only the deploying factory may initialize. Reproduced: a 100 FWA buy in a guard-hooked pool with the same currencies pays no fee, and any other caller initializing the hook pool reverts with OnlyLaunchFactory. The fix is a launch-kind decision, so no proof test is attached.\n- **Medium, deployment needs a mined salt the manifest cannot express.** The constructor reverts unless the address ends in the 0x20cc flag bits. Reproduced with a plain CREATE and with a deterministic CREATE2 salt, both revert. Evidence needed from the deployer that it mines hook salts for application contracts.\n- **Low, partial-fill asymmetry.** Exact-input buys and exact-output sells revert on any partial fill while the other two modes fill and tax the actual leg. Reproduced with a price-limited 1000 FWA buy that partially fills in the control pool but reverts in the hook pool. Documented by the author, so reported as a trade-off to confirm.\n\n**What holds.** All four swap modes charge exactly floor(gross/20) of the real FWA leg in both currency orderings, the hook's delta nets to zero through claim minting, the net-to-gross inverse is minimal and exact, claims are chunked above the int128 limit, and the payout path reaches only the fixed recipient through a PoolManager-side transfer that FWA permits. The repo's 76 tests and both stateful invariant suites pass. The static-analysis leads (unused unlock return, missing event in the callback) are not defects.\n\n**Not verified.** The real FWA token's transfer-allowance mechanism is visible only as an ABI; I relied on the supplied rule that transfers with the PoolManager on one side are permitted.","treeHash":null,"usage":{"cachedInputTokens":1604262,"inputTokens":386,"model":"claude-fable-5-1","outputTokens":42580,"runtime":"claude","turns":34,"wallClockMs":549871}},{"artifacts":[],"attempt":1,"bundleHash":"8d9e9a0fa77a6ece509e02032938cdad35ef69525ae63b93c4574a5fc4a0cb86","device":"992fb0c2029425f3","findings":[],"hash":"53b6750595aa704e937586c33d05293a7cadcbb8bacc7d89ff8229afddd3b1e7","nodeId":"84ae68bb-9129-4892-8ffe-c299eeb54185","outcome":"completed","summary":"Added adversarial tests and multi-actor invariants covering token allowances, fee rounding, payout failures, batch rollback, and fee conservation.\n\nOnly `test/` changed. No implementation defects were reproduced.\n\nValidation: `forge build` succeeds; `forge test` passes all 111 tests with no failures or skips.","treeHash":"e2b39cc0e697e834b02255d1cd7271abad5578ac","usage":{"cachedInputTokens":2420992,"inputTokens":130371,"model":"gpt-6-astra","outputTokens":20615,"runtime":"codex","turns":7,"wallClockMs":557164}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"5ded77c3c883b7b0","findings":[{"citation":"resolved","description":"Area: Trust Gap (access x first principles) and Access Control. The hook only charges its fee inside the pool whose key is getPoolKey() = (DCA, FWA, 12500, 60, hooks = DCAHook). That pool exists only if PoolManager.initialize is called with this exact key, and beforeInitialize (line 91) refuses every initializer except launchFactory, the address that deployed the hook (line 61). This project is judged as a custom_token launch (.imd/reads/protected/custom_token/Token.protected.t.sol). In that flow the factory deploys the token and the application contracts by CREATE2, then initializes and seeds ONE pool whose hooks field is its own PoolInitializationGuard (protected test lines 165-175 and 345-350: `IHooks(poolHook)` with the manifest's IMD_POOL_FEE / IMD_TICK_SPACING), and the custom_token launch.json pool object has no hooks key (kind/token/contracts/pool{pairedCurrency,fee,tickSpacing,initialPrice}/economics/notes; an extra key refuses the file). So the launch pool traders actually use is (DCA, FWA, 12500, 60, guard): DCAHook.beforeSwap/afterSwap are never invoked, pendingFees() stays 0, claimFees() returns 0 forever, and FEE_RECIPIENT 0xCAE0...Bd4b receives nothing, while the brief requires a 5% FWA fee on every buy and sell in the launch pool. The breakage is permanent: a v4 pool's hook cannot change after initialization, the hook has no owner or setter, and the OnlyLaunchFactory guard means the requester, the recipient or any third party who later tries to create the fee pool is refused (the factory has no post-launch step that would call initialize with hooks = DCAHook). The README (lines 93-94) acknowledges that 'merely deploying the hook as an application beside the default initialization-guard pool does not install a fee' and defers to a 'hook-capable deployment path', but no such path exists in the custom_token kind: the reference describes a separate univ4_hook kind that 'deploys only the hook and the token'. Fix is a scope decision, not a code patch: either launch this project as the univ4_hook kind (so the factory initializes getPoolKey() and launchFactory == the initializer), or accept that a custom_token launch cannot carry a FWA-denominated swap fee and tell the requester. Dropping the OnlyLaunchFactory check alone does not help: the factory's fee-free pool would still be the launch pool. The salt problem in finding 2 is a second, independent blocker of the same root cause.","line":91,"path":"src/DCAHook.sol","reproduction":"State: real v4 PoolManager; FWA mock at 0xa0Df17B5aC76ABaBA36E1450E2cbCd18A620C845; factory probe F. Steps, exactly as the custom_token floor performs them: (1) F CREATE2-deploys DCAToken (salt = launch number) and receives 1e27 DCA; (2) F CREATE2-deploys a beforeInitialize-only guard at a 0x2000-flag address; (3) F CREATE2-deploys DCAHook(poolManager, token) at a mined 0x20cc address, so hook.launchFactory() == F; (4) F calls PoolManager.initialize((DCA,FWA,12500,60,guard), 2^96) and seeds 1e24 liquidity single-sided in DCA; (5) an ordinary trader swaps exact-input 100e18 FWA for DCA, then sells all DCA back. Expected (brief): hook.pendingFees() >= 5e18 after the buy, more after the sell; claimFees() pays that to 0xCAE0B01E56cB164ce866A137d3528658b2FCBd4b. Actual: hook.pendingFees() == 0, claimFees() returns 0, recipient balance 0 (test/scratch/CustomTokenLaunchHookInert.t.sol: `[FAIL: no hook fee accrued on a buy and a sell in the launch pool: 0 <= 0] test_launchPoolBuyAndSellAccrueTheHookFee()`). (6) The requester 0x1ee3...413d or the recipient then calls PoolManager.initialize(hook.getPoolKey(), 2^96): reverts WrappedError(hook, beforeInitialize, OnlyLaunchFactory(), HookCallFailed()). Control: re-running step (4) with hooks = DCAHook makes the same test pass (fee 5e18 on the buy, paid to the recipient), which is what a hook-capable launch kind would do.","severity":"high","snippet":"        if (sender != launchFactory) revert OnlyLaunchFactory();","title":"Under the custom_token launch flow the fee pool is never created: the factory seeds its guard-hook pool, and beforeInitialize lets only the factory create DCAHook's pool, so the 5% FWA fee is never ch"},{"citation":"resolved","description":"Area: Trust Gap at the deployment boundary (access control hands out roles in the constructor; the constructor itself has a precondition the launch flow cannot express). Line 63 calls Hooks.validateHookPermissions, which reverts HookAddressNotValid unless address(this) & 0x3fff == 0x20cc. That is only satisfied by a mined CREATE2 salt (about 1 in 16384 salts). The custom_token launch.json contracts entries are {contract, constructorArgs} only; the protected harness deploys each application contract with a salt the verifier supplies (IMD_PROJECT_SALT_i) and requires the deployment to succeed (`require(deployed != address(0) && deployed.code.length > 0, 'constructor failed')`). If that salt is derived rather than mined against this exact creation code, constructor args and the factory address, the hook constructor reverts and with it the whole launch (setUp of every protected test fails; on chain, ProjectFactory.launchCustom reverts). README lines 80 and 91 push this onto the deployer ('Prepare the hook's CREATE2 address using the actual deploying factory ... The low address bits must be 0x20cc') but nothing in the repository, the manifest schema or the described service does it. Needed evidence before admission: the deployer's salt derivation for application contracts, or confirmation that the launch kind used mines hook salts (the univ4_hook kind presumably does). Mining must be redone whenever the token address, the compiler settings or the factory address changes, because all three enter the init-code hash. Severity is medium rather than high because the failure is a revert before any funds move; it blocks the deliverable rather than losing value.","line":63,"path":"src/DCAHook.sol","reproduction":"Inputs: factory probe F; creation code = type(DCAHook).creationCode ++ abi.encode(0x000000000004444c5dc75cB358380D2e3dE08A90, token). For salt = bytes32(uint256(launchNumber)) with launchNumber in 1..64 (the convention the floor uses for the token's salt), F.deploy(code, salt) reverts 'constructor failed' (inner revert Hooks.HookAddressNotValid(predicted)) for all 64 values (test/scratch/HookSaltDemo.t.sol logs `launch numbers 1..64 whose salt reverts the hook constructor: 64`). The repository's own test/Deployment.t.sol test_WrongHookAddressBitsAreRejected shows the same revert for the first non-matching salt. Expected for a launch: the application contract deploys with whatever salt the deployer assigns. Actual: deployment succeeds only for a salt mined so that address & 0x3fff == 0x20cc.","severity":"medium","snippet":"        Hooks.validateHookPermissions(IHooks(address(this)), getHookPermissions());","title":"DCAHook can only be constructed at a CREATE2 address whose low 14 bits are 0x20cc; the custom_token manifest carries no salt, so unless the deployer mines one for application contracts the launch tran"}],"hash":"566439ba5aab25764454d01f65b10e0501b04dee7f5d178a9ec10a4121162c65","nodeId":"ae825c78-8e12-4820-be0c-875ff05e65a4","outcome":"completed","summary":"The review is complete. Findings and coverage are in `.imd-findings.json`, no source files were changed, and the scratch tests live only under the gitignored `test/scratch/`.\n\n**Outcome.** The hook's own permission model is sound, but the deliverable as judged cannot collect its fee. Two findings, both at the deployment boundary.\n\n- **High. The fee pool never exists under the custom_token launch.** The factory initializes and seeds one pool whose hook is its own `PoolInitializationGuard`, with no `hooks` key in the manifest to say otherwise. DCAHook charges only inside the pool with itself as the hook, and `beforeInitialize` at `src/DCAHook.sol:91` lets only the deploying factory create that pool. The factory has no such step, so every buy and sell in the launch pool pays nothing, `claimFees()` returns zero forever, and the requester, the recipient and third parties are all refused when they try to create the fee pool later. The proof test models the floor's exact flow and fails with `0 <= 0` for pending fees. The identical flow passes when the launch pool is wired to DCAHook, so the remedy is a scope decision: launch as the `univ4_hook` kind or tell the requester a custom_token launch cannot carry a FWA-denominated swap fee.\n- **Medium. The hook constructor only succeeds at a mined CREATE2 address.** The flag check at `src/DCAHook.sol:63` reverts unless the address's low 14 bits are `0x20cc`. The custom_token manifest carries no salt, and the floor deploys application contracts with a verifier-supplied salt. All 64 launch-number salts I tried revert the constructor, which would revert the whole launch transaction. Needed evidence before admission: how the deployer derives application-contract salts.\n\n**What held.** `afterSwap`, `claimFees`, `unlockCallback`, both `view` callbacks, and the three token functions were traced for guards, state writes and failure paths: callbacks authenticate the manager and the fixed pool id, the unlock callback is reachable only from the hook's own `unlock`, claims are never approved or operator-granted, FWA leaves the manager only to the fixed recipient for exactly the burned amount, and the four swap modes charge a symmetric rounded 5% of gross FWA in both currency orderings. The slither and aderyn leads are not defects. The repository's 76 tests pass.\n\n**Caveats for the judge.** The first finding's fix is outside the code, so the proof can only pass once the launch kind wires the hook. Under a hook-capable kind, `launchFactory` is whoever runs the hook's constructor, so the factory must deploy the hook directly rather than through a helper, or its own `initialize` will revert. I did not verify the deployer's salt policy or the real factory's bytecode, since neither is in the tree.","treeHash":null,"usage":{"cachedInputTokens":1909401,"inputTokens":450,"model":"claude-fable-5-1","outputTokens":58581,"runtime":"claude","turns":42,"wallClockMs":877644}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"229c8cb0d9067fbe","findings":[{"citation":"resolved","description":"First-principles / execution-trace finding about the deployment leg. DCAHook's constructor binds three assumptions that nothing in the custom_token launch flow enforces: (1) its own address must carry the hook flag bits 0x20cc, so it must be deployed by CREATE2 at a salt mined for that purpose (src/DCAHook.sol:63, src/HookMiner.sol:17); (2) the launch pool must be initialized with PoolKey.hooks == this contract, otherwise beforeSwap/afterSwap are never invoked and no fee exists (src/DCAHook.sol:62, 84-93); (3) PoolManager.initialize must be called directly by the address that deployed the hook (src/DCAHook.sol:61, 91). The protected floor for this launch kind (.imd/reads/protected/custom_token/Token.protected.t.sol) models the factory as deploying application contracts at deployer-supplied salts (IMD_PROJECT_SALT_i, lines 186-197) and initializing the launch pool with the platform's PoolInitializationGuard as hooks (lines 165-175 and _key() at 345-350). The custom_token manifest schema in the assignment has no contract salt field and no pool.hooks field, and the reference names a separate univ4_hook launch kind as the one that deploys a hook into the pool. Consequences on the custom_token path: with any salt the requester did not mine (probability 16383/16384 per salt), the hook constructor reverts HookAddressNotValid and the factory's CREATE2 deploy fails, so the whole launch transaction reverts; with a mined salt the hook deploys as a sibling contract, but the pool the factory opens has the guard as its hook, every buy and sell in it pays zero hook fee, FEE_RECIPIENT never receives anything, and because a v4 pool's hook is part of its PoolId the launch pool can never be re-pointed at DCAHook. The README states the dependency in prose but nothing in the tree or the manifest schema enforces it. This is not fixable in src: a v4 hook fee can only exist if the factory creates the pool with the hook. Needed evidence before admission: the factory's hook-capable path (the univ4_hook kind or an equivalent), its ABI showing that it accepts or mines a CREATE2 salt with the 0x20cc bits for the hook's exact init code (type(DCAHook).creationCode ++ abi.encode(poolManager, token), with the canonical mainnet PoolManager that script/PrepareHook.s.sol:16 hardcodes), that it initializes PoolKey(sorted(DCA,FWA), 12500, 60, DCAHook), and that the initialize call originates from the same address that executed the CREATE2 (otherwise beforeInitialize reverts OnlyLaunchFactory at src/DCAHook.sol:91). If no such path exists for this launch kind, the brief's hook fee cannot be delivered and the scope decision belongs to the requester.","line":61,"path":"src/DCAHook.sol","reproduction":"Replicating the floor harness with the real vendored PoolManager (scratch test test/scratch/LaunchWiring.t.sol, two cases, both observed). Case A, deployer-chosen salt: factory F (a CREATE2 deployer standing at the factory address) deploys DCAToken at salt bytes32(uint256(7)) as the floor does, then deploys abi.encodePacked(type(DCAHook).creationCode, abi.encode(poolManager, token)) at the same salt convention bytes32(uint256(7)). Predicted address low 14 bits != 0x20cc. Expected (brief): hook deployed. Actual: constructor reverts Hooks.HookAddressNotValid(predicted); the factory's deploy reverts 'constructor failed'; nothing is launched. Case B, mined salt but floor pool key: F deploys DCAHook at the salt HookMiner.find(F, initCodeHash, 0, 1e6) returns, deploys the floor's initialization guard at a 0x2000-bit address, calls PoolManager.initialize(PoolKey(sorted(DCA, FWA), 12500, 60, IHooks(guard)), 2^96) and seeds 1e24 single-sided DCA liquidity. A trader buys with 100 FWA exact-input (gets DCA > 0) and sells all of it back (DCA balance 0). Expected (brief): hook.pendingFees() == 5e18 after the buy plus 5% of the sell's gross FWA. Actual: hook.pendingFees() == 0, hook.claimFees() returns 0, FWA balance of 0xCAE0B01E56cB164ce866A137d3528658b2FCBd4b stays 0, DCAHook.beforeInitialize/beforeSwap/afterSwap are never called. PoolId.unwrap(key.toId()) != PoolId.unwrap(hook.poolId()); initializing hook.getPoolKey() afterwards succeeds but creates an empty second pool, and re-initializing the launch pool with the hook reverts PoolAlreadyInitialized. No src-level Foundry proof is attached because no change to src/ can make a guard-hook pool charge the fee; the fix is in the launch path or manifest kind.","severity":"high","snippet":"        launchFactory = msg.sender;\n        poolId = getPoolKey().toId();\n        Hooks.validateHookPermissions(IHooks(address(this)), getHookPermissions());","title":"The custom_token launch path cannot install DCAHook: the hook needs a mined CREATE2 salt and PoolKey.hooks == DCAHook, neither of which the launch flow provides, so the launch either reverts at deploy"},{"citation":"resolved","description":"Assumption chain between the hook and the manifest step. The hook computes its immutable poolId from POOL_FEE = 12_500 and TICK_SPACING = 60 (src/DCAHook.sol:62, 79-82) and beforeInitialize rejects any other key with InvalidPool before checking the caller (src/DCAHook.sol:90). The pool fee and tick spacing of the launch pool are not written by this repository: they come from launch.json pool.fee / pool.tickSpacing (IMD_POOL_FEE / IMD_TICK_SPACING in the floor), which the manifest step copies from the launch policy. The assignment's example manifest for this launch uses 12500 and 60, so the constants agree today; but nothing binds the two, and the hook offers no way to recover if they disagree, because the key is fixed at construction. If the manifest step or policy emits any other value, PoolManager.initialize reverts inside the hook callback and, since the factory initializes and seeds in the launch transaction, the launch reverts. Minimal fix that preserves the intended design: keep the constants but have the manifest step assert pool.fee == DCAHook.POOL_FEE() and pool.tickSpacing == DCAHook.TICK_SPACING() before submission; alternatively let beforeInitialize accept the first key presented by launchFactory (currencies still checked) and record its PoolId then, so the factory's policy value is what binds.","line":27,"path":"src/DCAHook.sol","reproduction":"With the vendored PoolManager and a correctly deployed hook (test/scratch/EdgePaths.t.sol, test_OtherManifestFeeOrSpacingBricksInitialize, both currency orders): launchFactory calls manager.initialize(PoolKey(currency0, currency1, 10000, 60, IHooks(hook)), 79228162514264337593543950336). Expected by a manifest carrying pool.fee 10000: pool opens. Actual: revert CustomRevert.WrappedError(hook, IHooks.beforeInitialize.selector, InvalidPool(), HookCallFailed()). Same with PoolKey(currency0, currency1, 12500, 200, hook). The existing test test_RejectsOtherFeeTickSpacingCurrencyAndHook in test/DCAHook.t.sol:255-279 shows the identical revert for fee 3000 and spacing 10.","severity":"low","snippet":"    uint24 public constant POOL_FEE = 12_500;\n    int24 public constant TICK_SPACING = 60;","title":"Pool fee and tick spacing are hardcoded in the hook, so a manifest or policy that opens the launch pool with any other fee or spacing makes the factory's initialize revert and the launch transaction f"}],"hash":"7b16564d51aed37d52284cae1fa1e4ed5f252e05d245752935f7ac2c93f60adc","nodeId":"a0d7833a-0fbb-4d56-8df4-63a7932374e7","outcome":"completed","summary":"Review complete. The findings file is written and validated, no tracked file was changed, and the full suite (92 tests including my scratch demonstrations) passes.\n\n**Outcome**\n\nI audited the control flow of `DCAHook` and `DCAToken` against the Execution Trace, Periphery and First Principles guides, tracing every swap mode in both currency orders through the vendored v4 `Hooks.beforeSwap`/`afterSwap` delta math, the ERC-6909 claim custody, and the claim-and-payout unlock. The on-chain fee logic is correct: 5% of gross FWA on all four swap modes, DCA never taxed, the hook's FWA delta returns to zero after every swap, partial fills on the committed leg roll back atomically, and claims can only reach the constant recipient. Scratch tests I added for paths the suite did not cover (liquidity exhaustion, sells into an empty FWA side, claims between swaps) all behaved as documented.\n\n**Findings recorded in `.imd-findings.json`**\n\n- **High, deployment wiring.** On the custom_token launch path, as the protected floor models it, the factory opens the pool with the platform's initialization guard as its hook and deploys application contracts at deployer-chosen salts. DCAHook needs a mined CREATE2 salt and `PoolKey.hooks == DCAHook`, and neither is expressible in the manifest. I reproduced both outcomes with the real PoolManager: a deployer-style salt makes the hook constructor revert and the launch fails, and with a mined salt the launch pool charges zero fee forever since a v4 pool's hook is immutable. This is not fixable in `src/`. The finding states the evidence the manifest step needs (a hook-capable factory path, likely the univ4_hook kind, that mines the salt, sets the hook, and initializes from the deployer address).\n- **Low, manifest coupling.** Pool fee and tick spacing are hardcoded in the hook, so a manifest or policy with any other value makes the factory's initialize revert inside `beforeInitialize`. Reproduced with fee 10000 and spacing 200.\n\n**Coverage**\n\nAll six listed entry points have rows (five hold, `afterSwap` holds with the caveat that it is only reachable if the pool is wired to the hook), plus rows for `beforeSwap`, `beforeInitialize`, the constructor, the miner script, and two invariants. Nothing was left unreached. Static-analysis leads (unused `unlock` return, event, literal) were checked and are not defects.\n\n**Not covered**\n\nI could not verify the live factory ABI or the real FWA transfer rule beyond the pinned skill text, which the claim payout relies on (PoolManager-side transfers allowed).","treeHash":null,"usage":{"cachedInputTokens":2406770,"inputTokens":610,"model":"claude-fable-5-1","outputTokens":73944,"runtime":"claude","turns":41,"wallClockMs":1019597}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"b5e3297a04468fd3","findings":[{"citation":"resolved","description":"Math Precision guide: fees should round in the protocol's favour. feeOnGross floors, and feeOnNet ((net - 1) / 19) is the exact minimal inverse of that floor, so every swap whose gross FWA leg is below 20 base units (2e-17 FWA) accrues zero fee, and every larger swap under-collects by strictly less than 1 base unit against an exact 5%. The loss is at most 1 wei per swap, does not compound, and each swap costs far more in gas than the fee it skips, so this is not exploitable; it is recorded because the Numerical Gap seam (boundary x precision) is real and the README already states it. No change is required; if the author prefers protocol-favouring rounding, feeOnGross would become (gross + 19) / 20 with feeOnNet re-derived to match, which changes the documented rule.","line":156,"path":"src/DCAHook.sol","reproduction":"Both currency orderings, pool at sqrtPrice 2^96 with 1e24 liquidity in [-60000, 60000] (test/helpers/HookTestBase.sol setUp). (1) Exact-input buy amountSpecified = -19: beforeSwap fee = 19/20 = 0; afterSwap fee 0; pendingFees() stays 0 although 0.95 wei would be 5%. (2) Exact-output sell amountSpecified = +19 FWA: feeOnNet(19) = 18/19 = 0; trader pays 21 wei DCA, receives 19 wei FWA, pendingFees() stays 0. (3) Exact-input sell of 1 wei DCA: pool output 0 FWA, fwaDelta = 0 passes the sell-side check (fwaDelta < 0 is false), fee 0, swap succeeds. (4) Exact-input buy of 20 wei: fee 1, pool receives 19, trader receives 17 wei DCA. Verified by running these swaps against the vendored PoolManager; expected under the documented floor rule and matched exactly.","severity":"info","snippet":"        return gross / 20;","title":"Hook fee rounds down, so FWA legs below 20 base units pay no fee (documented, dust-level)"},{"citation":"resolved","description":"Outside the math area but material to the deliverable. The hook can only be attached to a pool at initialization, and beforeInitialize only accepts the deploying factory as initializer. The protected custom_token harness (.imd/reads/protected/custom_token/Token.protected.t.sol, _key()) initializes the launch pool with hooks = PoolInitializationGuard, not DCAHook, and no other party can later create the DCAHook pool. If the production launchCustom path behaves like the harness, the 5% FWA fee is never charged on the pool traders actually use, and nothing on chain fails to signal it. The README documents this as a wiring responsibility; it is recorded here so the manifest/deployer step is checked for a hook-capable initialization rather than assumed. Not a code defect in DCAHook: an unprivileged party cannot cause or exploit it, and funds are not at risk.","line":91,"path":"src/DCAHook.sol","reproduction":"State: factory deploys DCAToken and DCAHook (CREATE2, flags 0x20cc). The factory then initializes PoolKey(token, FWA, 12500, 60, hooks = guard) as in the protected test and seeds it. Any trader swap on that key: DCAHook.beforeSwap/afterSwap are never invoked, hook.pendingFees() stays 0, FEE_RECIPIENT never receives FWA. Attempting instead to initialize hook.getPoolKey() from any address other than the factory reverts OnlyLaunchFactory (test_InitializationCannotBeFrontRun in test/DCAHook.t.sol), so only the factory can ever install the fee pool.","severity":"info","snippet":"        if (sender != launchFactory) revert OnlyLaunchFactory();","title":"Fee applies only if the launch initializes the pool with DCAHook as PoolKey.hooks; the custom_token floor flow uses the guard hook and never touches it"}],"hash":"a6f311fb5e57f90877e99d9ac656c77ca29b2a40b34043d1a38c640d6decde59","nodeId":"5f1bc89a-e0c5-44fb-83d3-bba9feb5b390","outcome":"completed","summary":"Review complete. The findings file is written at `.imd-findings.json`, the scratch tests are removed, and no source or configuration file was changed.\n\n**Result: no math defect that moves value.** I checked the Math Precision, Boundary and Numerical Gap guides against `src/DCAHook.sol` and `src/DCAToken.sol`, tracing all four swap modes through the vendored Uniswap v4 Hooks and PoolManager delta code, in both currency orderings and with a protocol fee switched on.\n\nWhat held:\n- **Fee arithmetic.** Every mode charges exactly floor(gross / 20) of the actual FWA leg. The net-to-gross inverse is the exact minimal inverse of that floor, verified algebraically and by fuzz.\n- **Partial fills.** Buys with a specified FWA input and sells with a specified FWA output revert atomically when under-filled. The other two modes tax only the actual FWA delta.\n- **Bounds.** Amounts are bounded to int128 before any negation or cast, grossed-up amounts are rejected when they would overflow, and claim payouts are capped per call with the remainder still claimable.\n- **Claim path.** Permissionless, reentrancy-guarded, pays only the fixed recipient through burn plus take inside the hook's own unlock, and reverts whole on a failed payout.\n- **Token.** Unmodified OpenZeppelin ERC-20 with the stated fixed supply.\n\nTwo informational notes were recorded, neither opening a revision:\n1. The fee rounds down, so FWA legs under 20 base units pay nothing and each swap under-collects by less than 1 wei. Dust-level, documented in the README, concrete inputs given.\n2. Outside my area: the 5% fee exists only if the launch initializes the pool with the hook as `PoolKey.hooks`. The protected custom_token harness initializes with the guard hook, so the manifest and deployer step should be checked for a hook-capable path.\n\nThe coverage record answers all six listed entry points as `holds`, plus five invariant rows. The static-analysis leads were checked: the unused return on `unlock()` is benign, and the remaining aderyn lines are style-only.","treeHash":null,"usage":{"cachedInputTokens":857862,"inputTokens":290,"model":"claude-fable-5-1","outputTokens":30420,"runtime":"claude","turns":29,"wallClockMs":427928}}],"verification":[{"checks":[{"durationMs":5452,"exitCode":0,"name":"build","output":"Compiling 88 files with Solc 0.8.26\nSolc 0.8.26 finished in 5.21s\nCompiler run successful!\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/DCAHook.sol:106:30\n    │\n106 │                 ? feeOnGross(uint256(-params.amountSpecified))\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/DCAHook.sol:107:28\n    │\n107 │                 : feeOnNet(uint256(params.amountSpecified));\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/DCAHook.sol:132:36\n    │\n132 │             fee = buy ? feeOnGross(uint256(-params.amountSpecified)) : feeOnNet(uint256(params.amountSpecified));\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/DCAHook.sol:132:81\n    │\n132 │             fee = buy ? feeOnGross(uint256(-params.amountSpecified)) : feeOnNet(uint256(params.amountSpecified));\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/DCAHook.sol:134:54\n    │\n134 │             if (fwaDelta != params.amountSpecified + int256(fee)) revert PartialFill();\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/DCAHook.sol:135:27\n    │\n135 │             gross = buy ? uint256(-params.amountSpecified) : uint256(fwaDelta);\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/DCAHook.sol:135:62\n    │\n135 │             gross = buy ? uint256(-params.amountSpecified) : uint256(fwaDelta);\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/DCAHook.sol:137:27\n    │\n137 │             uint256 net = uint256(-fwaDelta);\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/DCAHook.sol:141:21\n    │\n141 │             gross = uint256(fwaDelta);\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[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/DCAHook.sol:182:9\n    │\n182 │         poolManager.unlock(\"\");\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/DCAHook.sol:182:9\n    │\n182 │         poolManager.unlock(\"\");\n    │         ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\n","passed":true},{"durationMs":1818,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 7 tests for test/DCAToken.t.sol:DCATokenTest\n[PASS] testFuzz_WalletTransfersAreUntaxed(uint256) (runs: 256, μ: 150857, ~: 151640)\nLogs:\n  Bound result 2176\n\n[PASS] test_ApprovalTransferFromAndInfiniteApproval() (gas: 285319)\n[PASS] test_FactoryReceivesSupplyAndLaunchAllocationsArriveWhole() (gas: 504856)\n[PASS] test_InsufficientBalanceAndAllowanceRevert() (gas: 124739)\n[PASS] test_MetadataAndEntireSupplyMintedOnce() (gas: 64311)\n[PASS] test_NoMintPauseBlacklistSeizeOrUpgradePowers() (gas: 619116)\n[PASS] test_ZeroRecipientRevertsAndSelfTransferPreservesBalance() (gas: 72110)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 8.59ms (8.80ms CPU time)\n\nRan 31 tests for test/DCAHook.t.sol:DCAHookFwaCurrency1Test\n[PASS] testFuzz_FeeConservationAcrossSwapModes(bool,bool,uint256) (runs: 256, μ: 524546, ~: 517864)\nLogs:\n  Bound result 281965910671161320188\n\n[PASS] testFuzz_RoundingInverseIsMinimalAndExactlyFivePercent(uint256) (runs: 256, μ: 13870, ~: 13675)\nLogs:\n  Bound result 8869\n\n[PASS] test_BatchedSwapsCollectOncePerSwapAndSettle() (gas: 351448)\n[PASS] test_BuyExactInputChargesFivePercentOfFwaPaidIn() (gas: 513243)\n[PASS] test_BuyExactOutputIncludesFeeInTotalFwaPaid() (gas: 513479)\n[PASS] test_CallbackFromManagerWithoutClaimReverts() (gas: 36787)\n[PASS] test_ClaimBeforeFeesIsNoop() (gas: 37441)\n[PASS] test_ClaimIncludesDonatedFwaClaims() (gas: 344370)\n[PASS] test_ClaimInsideAnExistingUnlockRevertsWithoutLosingFees() (gas: 349458)\n[PASS] test_ClaimsAboveSignedDeltaLimitRemainClaimableInChunks() (gas: 406508)\n[PASS] test_ClaimsCannotBeStolenByAnOperatorOrAllowance() (gas: 250825)\n[PASS] test_DirectCallbacksRequireManager() (gas: 101627)\n[PASS] test_DustBuyRoundsFeeDown() (gas: 339135)\n[PASS] test_FailedPayoutPreservesAllClaimsAndCanRetry() (gas: 454025)\n[PASS] test_FeeAndRecipientCannotBeChanged() (gas: 188763)\n[PASS] test_FwaMockRejectsOrdinaryTransferButClaimSucceeds() (gas: 360952)\n[PASS] test_InitializationCannotBeFrontRun() (gas: 49536)\n[PASS] test_LiquidityHasNoHookFeeAndCanBeRemoved() (gas: 152484)\n[PASS] test_PartialExactInputBuyRevertsAndRollsBack() (gas: 161984)\n[PASS] test_PartialExactInputSellOnlyTaxesActualFwaOutput() (gas: 215811)\n[PASS] test_PartialExactOutputBuyOnlyTaxesActualFwaInput() (gas: 196865)\n[PASS] test_PartialExactOutputSellRevertsAndRollsBack() (gas: 126282)\n[PASS] test_PayoutReentrancyCannotClaimTwice() (gas: 391211)\n[PASS] test_PermissionlessClaimPaysOnlyFixedRecipientAndRepeatIsNoop() (gas: 788207)\n[PASS] test_PermissionsMatchActualMinedAddress() (gas: 34997)\n[PASS] test_RejectsOtherFeeTickSpacingCurrencyAndHook() (gas: 189810)\n[PASS] test_RejectsZeroAndOutOfRangeAmounts() (gas: 115377)\n[PASS] test_SellExactInputChargesFivePercentOfGrossFwaOutput() (gas: 529072)\n[PASS] test_SellExactOutputReceivesRequestedNetFwa() (gas: 528495)\n[PASS] test_SingleSidedLaunchSeedsWithoutFwaAndFirstBuyCanFundItsFee() (gas: 988086)\n[PASS] test_SwapCallbacksRejectDifferentPoolEvenFromManager() (gas: 57749)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 95.29ms (75.58ms CPU time)\n\nRan 31 tests for test/DCAHook.t.sol:DCAHookFwaCurrency0Test\n[PASS] testFuzz_FeeConservationAcrossSwapModes(bool,bool,uint256) (runs: 256, μ: 524354, ~: 522750)\nLogs:\n  Bound result 296862148282949569536\n\n[PASS] testFuzz_RoundingInverseIsMinimalAndExactlyFivePercent(uint256) (runs: 256, μ: 13870, ~: 13675)\nLogs:\n  Bound result 13513\n\n[PASS] test_BatchedSwapsCollectOncePerSwapAndSettle() (gas: 357149)\n[PASS] test_BuyExactInputChargesFivePercentOfFwaPaidIn() (gas: 525785)\n[PASS] test_BuyExactOutputIncludesFeeInTotalFwaPaid() (gas: 523411)\n[PASS] test_CallbackFromManagerWithoutClaimReverts() (gas: 36787)\n[PASS] test_ClaimBeforeFeesIsNoop() (gas: 37441)\n[PASS] test_ClaimIncludesDonatedFwaClaims() (gas: 350672)\n[PASS] test_ClaimInsideAnExistingUnlockRevertsWithoutLosingFees() (gas: 355760)\n[PASS] test_ClaimsAboveSignedDeltaLimitRemainClaimableInChunks() (gas: 406508)\n[PASS] test_ClaimsCannotBeStolenByAnOperatorOrAllowance() (gas: 257127)\n[PASS] test_DirectCallbacksRequireManager() (gas: 101436)\n[PASS] test_DustBuyRoundsFeeDown() (gas: 346307)\n[PASS] test_FailedPayoutPreservesAllClaimsAndCanRetry() (gas: 460327)\n[PASS] test_FeeAndRecipientCannotBeChanged() (gas: 188763)\n[PASS] test_FwaMockRejectsOrdinaryTransferButClaimSucceeds() (gas: 367254)\n[PASS] test_InitializationCannotBeFrontRun() (gas: 49536)\n[PASS] test_LiquidityHasNoHookFeeAndCanBeRemoved() (gas: 152484)\n[PASS] test_PartialExactInputBuyRevertsAndRollsBack() (gas: 168120)\n[PASS] test_PartialExactInputSellOnlyTaxesActualFwaOutput() (gas: 209754)\n[PASS] test_PartialExactOutputBuyOnlyTaxesActualFwaInput() (gas: 202712)\n[PASS] test_PartialExactOutputSellRevertsAndRollsBack() (gas: 120268)\n[PASS] test_PayoutReentrancyCannotClaimTwice() (gas: 397513)\n[PASS] test_PermissionlessClaimPaysOnlyFixedRecipientAndRepeatIsNoop() (gas: 794501)\n[PASS] test_PermissionsMatchActualMinedAddress() (gas: 34997)\n[PASS] test_RejectsOtherFeeTickSpacingCurrencyAndHook() (gas: 189810)\n[PASS] test_RejectsZeroAndOutOfRangeAmounts() (gas: 115344)\n[PASS] test_SellExactInputChargesFivePercentOfGrossFwaOutput() (gas: 516342)\n[PASS] test_SellExactOutputReceivesRequestedNetFwa() (gas: 518375)\n[PASS] test_SingleSidedLaunchSeedsWithoutFwaAndFirstBuyCanFundItsFee() (gas: 1000479)\n[PASS] test_SwapCallbacksRejectDifferentPoolEvenFromManager() (gas: 57558)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 124.42ms (78.79ms CPU time)\n\nRan 5 tests for test/Deployment.t.sol:DeploymentTest\n[PASS] test_InvalidConstructorArgumentsRevert() (gas: 5417)\n[PASS] test_NoExternalCallsEvenIfTokenIsNotYetDeployed() (gas: 3960430)\n[PASS] test_PreparationDeploysExactPredictedAddressOnEmptyChain() (gas: 101709516)\n[PASS] test_PreparationRejectsMissingAddressesAndExhaustedSearch() (gas: 1707581)\n[PASS] test_WrongHookAddressBitsAreRejected() (gas: 251808)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 139.58ms (153.27ms CPU time)\n\nRan 1 test for test/DCAInvariant.t.sol:DCAInvariantFwa1Test\n[PASS]\nDCAInvariantFwa1Test invariants:\n[PASS] invariant_ConservationOfBothTokensAndFixedSupply\n[PASS] invariant_FeeClaimsPlusPayoutsEqualAllAccruedFees\n[PASS] invariant_TransientAccountingAlwaysSettled\n DCAInvariantFwa1Test invariants (runs: 128, calls: 4096, reverts: 0)\n\n╭------------+----------+-------+---------+----------╮\n| Contract   | Selector | Calls | Reverts | Discards |\n+====================================================+\n| FeeHandler | claim    | 2010  | 0       | 0        |\n|------------+----------+-------+---------+----------|\n| FeeHandler | swap     | 2086  | 0       | 0        |\n╰------------+----------+-------+---------+----------╯\n\nLogs:\n  Bound result 99999999999999999985\n  Bound result 44361084823705962269\n  Bound result 11939906005600446012\n  Bound result 17966\n  Bound result 500\n  Bound result 500\n  Bound result 500\n  Bound result 72770655728687944097\n  Bound result 12500\n  Bound result 15002\n  Bound result 85\n  Bound result 17421\n  Bound result 2717559728142005332\n  Bound result 85470547260055645128\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.62s (1.56s CPU time)\n\nRan 1 test for test/DCAInvariant.t.sol:DCAInvariantFwa0Test\n[PASS]\nDCAInvariantFwa0Test invariants:\n[PASS] invariant_ConservationOfBothTokensAndFixedSupply\n[PASS] invariant_FeeClaimsPlusPayoutsEqualAllAccruedFees\n[PASS] invariant_TransientAccountingAlwaysSettled\n DCAInvariantFwa0Test invariants (runs: 128, calls: 4096, reverts: 0)\n\n╭------------+----------+-------+---------+----------╮\n| Contract   | Selector | Calls | Reverts | Discards |\n+====================================================+\n| FeeHandler | claim    | 2010  | 0       | 0        |\n|------------+----------+-------+---------+----------|\n| FeeHandler | swap     | 2086  | 0       | 0        |\n╰------------+----------+-------+---------+----------╯\n\nLogs:\n  Bound result 99999999999999999985\n  Bound result 44361084823705962269\n  Bound result 11939906005600446012\n  Bound result 95153711438512253658\n  Bound result 500\n  Bound result 500\n  Bound result 500\n  Bound result 72770655728687944097\n  Bound result 12500\n  Bound result 15962\n  Bound result 3280\n  Bound result 18576\n  Bound result 2717559728142005332\n  Bound result 1282\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.66s (1.55s CPU time)\n\nRan 6 test suites in 1.67s (3.65s CPU time): 76 tests passed, 0 failed, 0 skipped (76 total tests)\n","passed":true},{"durationMs":81,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"DCAHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"DCAHook.claimFees()\",\"DCAHook.unlockCallback(bytes)\",\"DCAToken.approve(address,uint256)\",\"DCAToken.transfer(address,uint256)\",\"DCAToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"DEPENDENCIES.json\":130,\"README.md\":117,\"SECURITY.md\":39,\"foundry.toml\":19,\"remappings.txt\":4,\"script/PrepareHook.s.sol\":20,\"src/DCAHook.sol\":208,\"src/DCAToken.sol\":14,\"src/HookMiner.sol\":21,\"test/DCAHook.t.sol\":391,\"test/DCAInvariant.t.sol\":113,\"test/DCAToken.t.sol\":126,\"test/Deployment.t.sol\":98,\"test/helpers/HookTestBase.sol\":101,\"test/helpers/PoolRouter.sol\":112,\"test/helpers/RestrictedFWA.sol\":43},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":2059,"exitCode":0,"name":"slither","output":"[medium/medium] unused-return at src/DCAHook.sol:176: DCAHook.claimFees() (src/DCAHook.sol#176-183) ignores return value by poolManager.unlock() (src/DCAHook.sol#182)","passed":true},{"durationMs":856,"exitCode":0,"name":"aderyn","output":"[low] large-numeric-literal at src/DCAHook.sol:26: Large Numeric Literal (2 places)\n[low] state-change-without-event at src/DCAHook.sol:185: State Change Without Event\n[low] unchecked-return at src/DCAHook.sol:182: Unchecked Return\n[low] uninitialized-local-variable at src/HookMiner.sol:13: Uninitialized Local Variable","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"42d9230343d8c7e947d57a31376c532b8a1a7e811d3986023f3e8e47f8be3ce5","verifiedTreeHash":"978c4e6e72825cde2f400e5139d5bad57f0fbc4a","verifierVersion":"0.1.0+7ff5db2c"},{"checks":[{"durationMs":5640,"exitCode":0,"name":"build","output":"Compiling 92 files with Solc 0.8.26\nSolc 0.8.26 finished in 5.47s\nCompiler run successful!\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/DCAHook.sol:106:30\n    │\n106 │                 ? feeOnGross(uint256(-params.amountSpecified))\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/DCAHook.sol:107:28\n    │\n107 │                 : feeOnNet(uint256(params.amountSpecified));\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/DCAHook.sol:132:36\n    │\n132 │             fee = buy ? feeOnGross(uint256(-params.amountSpecified)) : feeOnNet(uint256(params.amountSpecified));\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/DCAHook.sol:132:81\n    │\n132 │             fee = buy ? feeOnGross(uint256(-params.amountSpecified)) : feeOnNet(uint256(params.amountSpecified));\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/DCAHook.sol:134:54\n    │\n134 │             if (fwaDelta != params.amountSpecified + int256(fee)) revert PartialFill();\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/DCAHook.sol:135:27\n    │\n135 │             gross = buy ? uint256(-params.amountSpecified) : uint256(fwaDelta);\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/DCAHook.sol:135:62\n    │\n135 │             gross = buy ? uint256(-params.amountSpecified) : uint256(fwaDelta);\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/DCAHook.sol:137:27\n    │\n137 │             uint256 net = uint256(-fwaDelta);\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/DCAHook.sol:141:21\n    │\n141 │             gross = uint256(fwaDelta);\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[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/DCAHook.sol:182:9\n    │\n182 │         poolManager.unlock(\"\");\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/DCAHook.sol:182:9\n    │\n182 │         poolManager.unlock(\"\");\n    │         ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\n","passed":true},{"durationMs":9365,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 5 tests for test/DCATokenEdges.t.sol:DCATokenEdgesTest\n[PASS] test_ApprovalReplacementRevocationAndReapprovalAreEffectiveImmediately() (gas: 332874)\n[PASS] test_Uint256MaxTransfersFailWithoutChangingBalancesOrInfiniteAllowance() (gas: 209044)\n[PASS] test_WholeSupplyTransferFromSelfConsumesAllowanceWithoutChangingBalance() (gas: 273579)\n[PASS] test_ZeroAddressesCannotBeApprovedOrUsedAsMintBurnPathsEvenForZeroAmount() (gas: 125073)\n[PASS] test_ZeroTransfersFromEmptyWalletEmitEventsWithoutApprovalOrTax() (gas: 135267)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 1.20ms (1.61ms CPU time)\n\nRan 7 tests for test/DCAToken.t.sol:DCATokenTest\n[PASS] testFuzz_WalletTransfersAreUntaxed(uint256) (runs: 256, μ: 151360, ~: 151664)\nLogs:\n  Bound result 628042345829967821106093532\n\n[PASS] test_ApprovalTransferFromAndInfiniteApproval() (gas: 285319)\n[PASS] test_FactoryReceivesSupplyAndLaunchAllocationsArriveWhole() (gas: 504856)\n[PASS] test_InsufficientBalanceAndAllowanceRevert() (gas: 124739)\n[PASS] test_MetadataAndEntireSupplyMintedOnce() (gas: 64311)\n[PASS] test_NoMintPauseBlacklistSeizeOrUpgradePowers() (gas: 619116)\n[PASS] test_ZeroRecipientRevertsAndSelfTransferPreservesBalance() (gas: 72110)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 5.84ms (7.45ms CPU time)\n\nRan 12 tests for test/DCAHookEdges.t.sol:DCAHookEdgesFwa1Test\n[PASS] testFuzz_GrossFeeHasBoundedRemainderOverEntireUint256Domain(uint256) (runs: 1000, μ: 9822, ~: 9822)\n[PASS] testFuzz_NetInversionIsExactAndMinimalThroughSignedBoundary(uint256) (runs: 1000, μ: 29690, ~: 29471)\nLogs:\n  Bound result 317003292960304150321239646387125582\n\n[PASS] testFuzz_SenderAndHookDataCannotChangeFixedBuyFee(address,bytes) (runs: 1000, μ: 38992, ~: 38990)\n[PASS] test_AfterSwapRejectsWrongFwaSignsForAllFourModes() (gas: 150331)\n[PASS] test_AllInvalidAmountEdgesRejectedByBothCallbacks() (gas: 851089)\n[PASS] test_BeforeSwapAcceptsSignedEdgesWithoutNarrowingOrPoolFeeOverride() (gas: 50529)\n[PASS] test_FailedSecondSwapRollsBackFirstSwapAndItsFees() (gas: 617223)\n[PASS] test_FeeRoundingPinnedBoundaries() (gas: 144932)\n[PASS] test_FwaClaimIgnoresUnrelatedCurrencyClaims() (gas: 357704)\n[PASS] test_InitializedTickCrossingChargesFwaAndPreservesPoolFees() (gas: 1677103)\n[PASS] test_LargestRepresentableNetAcceptedAndNextWeiRejected() (gas: 33983)\n[PASS] test_RemovingAllLiquidityCannotConsumeAccruedFees() (gas: 767349)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 63.95ms (66.29ms CPU time)\n\nRan 31 tests for test/DCAHook.t.sol:DCAHookFwaCurrency1Test\n[PASS] testFuzz_FeeConservationAcrossSwapModes(bool,bool,uint256) (runs: 256, μ: 524958, ~: 531314)\nLogs:\n  Bound result 18129\n\n[PASS] testFuzz_RoundingInverseIsMinimalAndExactlyFivePercent(uint256) (runs: 256, μ: 13902, ~: 13675)\nLogs:\n  Bound result 79747574459009211880518598811577130\n\n[PASS] test_BatchedSwapsCollectOncePerSwapAndSettle() (gas: 351448)\n[PASS] test_BuyExactInputChargesFivePercentOfFwaPaidIn() (gas: 513243)\n[PASS] test_BuyExactOutputIncludesFeeInTotalFwaPaid() (gas: 513479)\n[PASS] test_CallbackFromManagerWithoutClaimReverts() (gas: 36787)\n[PASS] test_ClaimBeforeFeesIsNoop() (gas: 37441)\n[PASS] test_ClaimIncludesDonatedFwaClaims() (gas: 344370)\n[PASS] test_ClaimInsideAnExistingUnlockRevertsWithoutLosingFees() (gas: 349458)\n[PASS] test_ClaimsAboveSignedDeltaLimitRemainClaimableInChunks() (gas: 406508)\n[PASS] test_ClaimsCannotBeStolenByAnOperatorOrAllowance() (gas: 250825)\n[PASS] test_DirectCallbacksRequireManager() (gas: 101627)\n[PASS] test_DustBuyRoundsFeeDown() (gas: 339135)\n[PASS] test_FailedPayoutPreservesAllClaimsAndCanRetry() (gas: 454025)\n[PASS] test_FeeAndRecipientCannotBeChanged() (gas: 188763)\n[PASS] test_FwaMockRejectsOrdinaryTransferButClaimSucceeds() (gas: 360952)\n[PASS] test_InitializationCannotBeFrontRun() (gas: 49536)\n[PASS] test_LiquidityHasNoHookFeeAndCanBeRemoved() (gas: 152484)\n[PASS] test_PartialExactInputBuyRevertsAndRollsBack() (gas: 161984)\n[PASS] test_PartialExactInputSellOnlyTaxesActualFwaOutput() (gas: 215811)\n[PASS] test_PartialExactOutputBuyOnlyTaxesActualFwaInput() (gas: 196865)\n[PASS] test_PartialExactOutputSellRevertsAndRollsBack() (gas: 126282)\n[PASS] test_PayoutReentrancyCannotClaimTwice() (gas: 391211)\n[PASS] test_PermissionlessClaimPaysOnlyFixedRecipientAndRepeatIsNoop() (gas: 788207)\n[PASS] test_PermissionsMatchActualMinedAddress() (gas: 34997)\n[PASS] test_RejectsOtherFeeTickSpacingCurrencyAndHook() (gas: 189810)\n[PASS] test_RejectsZeroAndOutOfRangeAmounts() (gas: 115377)\n[PASS] test_SellExactInputChargesFivePercentOfGrossFwaOutput() (gas: 529072)\n[PASS] test_SellExactOutputReceivesRequestedNetFwa() (gas: 528495)\n[PASS] test_SingleSidedLaunchSeedsWithoutFwaAndFirstBuyCanFundItsFee() (gas: 988086)\n[PASS] test_SwapCallbacksRejectDifferentPoolEvenFromManager() (gas: 57749)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 73.67ms (105.57ms CPU time)\n\nRan 12 tests for test/DCAHookEdges.t.sol:DCAHookEdgesFwa0Test\n[PASS] testFuzz_GrossFeeHasBoundedRemainderOverEntireUint256Domain(uint256) (runs: 1000, μ: 9822, ~: 9822)\n[PASS] testFuzz_NetInversionIsExactAndMinimalThroughSignedBoundary(uint256) (runs: 1000, μ: 29692, ~: 29471)\nLogs:\n  Bound result 82821657953799259156785779138547916836\n\n[PASS] testFuzz_SenderAndHookDataCannotChangeFixedBuyFee(address,bytes) (runs: 1000, μ: 38981, ~: 38979)\n[PASS] test_AfterSwapRejectsWrongFwaSignsForAllFourModes() (gas: 150207)\n[PASS] test_AllInvalidAmountEdgesRejectedByBothCallbacks() (gas: 851089)\n[PASS] test_BeforeSwapAcceptsSignedEdgesWithoutNarrowingOrPoolFeeOverride() (gas: 50529)\n[PASS] test_FailedSecondSwapRollsBackFirstSwapAndItsFees() (gas: 629964)\n[PASS] test_FeeRoundingPinnedBoundaries() (gas: 144932)\n[PASS] test_FwaClaimIgnoresUnrelatedCurrencyClaims() (gas: 357704)\n[PASS] test_InitializedTickCrossingChargesFwaAndPreservesPoolFees() (gas: 1679914)\n[PASS] test_LargestRepresentableNetAcceptedAndNextWeiRejected() (gas: 33983)\n[PASS] test_RemovingAllLiquidityCannotConsumeAccruedFees() (gas: 773074)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 77.14ms (49.08ms CPU time)\n\nRan 31 tests for test/DCAHook.t.sol:DCAHookFwaCurrency0Test\n[PASS] testFuzz_FeeConservationAcrossSwapModes(bool,bool,uint256) (runs: 256, μ: 524170, ~: 522724)\nLogs:\n  Bound result 103094670755116822665\n\n[PASS] testFuzz_RoundingInverseIsMinimalAndExactlyFivePercent(uint256) (runs: 256, μ: 13896, ~: 13675)\nLogs:\n  Bound result 127\n\n[PASS] test_BatchedSwapsCollectOncePerSwapAndSettle() (gas: 357149)\n[PASS] test_BuyExactInputChargesFivePercentOfFwaPaidIn() (gas: 525785)\n[PASS] test_BuyExactOutputIncludesFeeInTotalFwaPaid() (gas: 523411)\n[PASS] test_CallbackFromManagerWithoutClaimReverts() (gas: 36787)\n[PASS] test_ClaimBeforeFeesIsNoop() (gas: 37441)\n[PASS] test_ClaimIncludesDonatedFwaClaims() (gas: 350672)\n[PASS] test_ClaimInsideAnExistingUnlockRevertsWithoutLosingFees() (gas: 355760)\n[PASS] test_ClaimsAboveSignedDeltaLimitRemainClaimableInChunks() (gas: 406508)\n[PASS] test_ClaimsCannotBeStolenByAnOperatorOrAllowance() (gas: 257127)\n[PASS] test_DirectCallbacksRequireManager() (gas: 101436)\n[PASS] test_DustBuyRoundsFeeDown() (gas: 346307)\n[PASS] test_FailedPayoutPreservesAllClaimsAndCanRetry() (gas: 460327)\n[PASS] test_FeeAndRecipientCannotBeChanged() (gas: 188763)\n[PASS] test_FwaMockRejectsOrdinaryTransferButClaimSucceeds() (gas: 367254)\n[PASS] test_InitializationCannotBeFrontRun() (gas: 49536)\n[PASS] test_LiquidityHasNoHookFeeAndCanBeRemoved() (gas: 152484)\n[PASS] test_PartialExactInputBuyRevertsAndRollsBack() (gas: 168120)\n[PASS] test_PartialExactInputSellOnlyTaxesActualFwaOutput() (gas: 209754)\n[PASS] test_PartialExactOutputBuyOnlyTaxesActualFwaInput() (gas: 202712)\n[PASS] test_PartialExactOutputSellRevertsAndRollsBack() (gas: 120268)\n[PASS] test_PayoutReentrancyCannotClaimTwice() (gas: 397513)\n[PASS] test_PermissionlessClaimPaysOnlyFixedRecipientAndRepeatIsNoop() (gas: 794501)\n[PASS] test_PermissionsMatchActualMinedAddress() (gas: 34997)\n[PASS] test_RejectsOtherFeeTickSpacingCurrencyAndHook() (gas: 189810)\n[PASS] test_RejectsZeroAndOutOfRangeAmounts() (gas: 115344)\n[PASS] test_SellExactInputChargesFivePercentOfGrossFwaOutput() (gas: 516342)\n[PASS] test_SellExactOutputReceivesRequestedNetFwa() (gas: 518375)\n[PASS] test_SingleSidedLaunchSeedsWithoutFwaAndFirstBuyCanFundItsFee() (gas: 1000479)\n[PASS] test_SwapCallbacksRejectDifferentPoolEvenFromManager() (gas: 57558)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 99.72ms (67.41ms CPU time)\n\nRan 5 tests for test/Deployment.t.sol:DeploymentTest\n[PASS] test_InvalidConstructorArgumentsRevert() (gas: 5417)\n[PASS] test_NoExternalCallsEvenIfTokenIsNotYetDeployed() (gas: 3960430)\n[PASS] test_PreparationDeploysExactPredictedAddressOnEmptyChain() (gas: 101709516)\n[PASS] test_PreparationRejectsMissingAddressesAndExhaustedSearch() (gas: 1707581)\n[PASS] test_WrongHookAddressBitsAreRejected() (gas: 251808)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 107.37ms (113.79ms CPU time)\n\nRan 1 test for test/DCAInvariant.t.sol:DCAInvariantFwa1Test\n[PASS]\nDCAInvariantFwa1Test invariants:\n[PASS] invariant_ConservationOfBothTokensAndFixedSupply\n[PASS] invariant_FeeClaimsPlusPayoutsEqualAllAccruedFees\n[PASS] invariant_TransientAccountingAlwaysSettled\n DCAInvariantFwa1Test invariants (runs: 128, calls: 4096, reverts: 0)\n\n╭------------+----------+-------+---------+----------╮\n| Contract   | Selector | Calls | Reverts | Discards |\n+====================================================+\n| FeeHandler | claim    | 2042  | 0       | 0        |\n|------------+----------+-------+---------+----------|\n| FeeHandler | swap     | 2054  | 0       | 0        |\n╰------------+----------+-------+---------+----------╯\n\nLogs:\n  Bound result 17554\n  Bound result 99999999999999999986\n  Bound result 8388608\n  Bound result 8869\n  Bound result 5993\n  Bound result 74290013753961911625\n  Bound result 72899659870336909783\n  Bound result 190000\n  Bound result 9500\n  Bound result 95\n  Bound result 14152153360440411183\n  Bound result 10713\n  Bound result 5670\n  Bound result 2480602608\n  Bound result 1900000\n  Bound result 40000000000000000000\n  Bound result 5777\n  Bound result 99999999999999999987\n  Bound result 64014128573373259750\n  Bound result 9173\n  Bound result 58200579663861103263\n  Bound result 86492983446555097237\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.33s (1.29s CPU time)\n\nRan 1 test for test/DCAInvariant.t.sol:DCAInvariantFwa0Test\n[PASS]\nDCAInvariantFwa0Test invariants:\n[PASS] invariant_ConservationOfBothTokensAndFixedSupply\n[PASS] invariant_FeeClaimsPlusPayoutsEqualAllAccruedFees\n[PASS] invariant_TransientAccountingAlwaysSettled\n DCAInvariantFwa0Test invariants (runs: 128, calls: 4096, reverts: 0)\n\n╭------------+----------+-------+---------+----------╮\n| Contract   | Selector | Calls | Reverts | Discards |\n+====================================================+\n| FeeHandler | claim    | 2042  | 0       | 0        |\n|------------+----------+-------+---------+----------|\n| FeeHandler | swap     | 2054  | 0       | 0        |\n╰------------+----------+-------+---------+----------╯\n\nLogs:\n  Bound result 18738\n  Bound result 99999999999999999986\n  Bound result 8388608\n  Bound result 164\n  Bound result 3101934468\n  Bound result 74290013753961911625\n  Bound result 72899659870336909783\n  Bound result 190000\n  Bound result 9500\n  Bound result 95\n  Bound result 18085701753396713898\n  Bound result 1752\n  Bound result 777\n  Bound result 2526\n  Bound result 1900000\n  Bound result 40000000000000000000\n  Bound result 49036548309537115383\n  Bound result 99999999999999999987\n  Bound result 64014128573373259750\n  Bound result 6430\n  Bound result 58200579663861103263\n  Bound result 40219786528354012312\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.34s (1.27s CPU time)\n\nRan 2 tests for test/DCATokenStateful.t.sol:DCATokenStatefulTest\n[PASS]\nDCATokenStatefulTest invariants:\n[PASS] invariant_AllowancesMatchApprovalsAndSuccessfulSpendsOnly\n[PASS] invariant_BalancesMatchIndependentLedgerAndEntireSupply\n DCATokenStatefulTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭------------------+----------------------+-------+---------+----------╮\n| Contract         | Selector             | Calls | Reverts | Discards |\n+======================================================================+\n| DCALedgerHandler | approve              | 2406  | 0       | 0        |\n|------------------+----------------------+-------+---------+----------|\n| DCALedgerHandler | invalidReceiver      | 2275  | 0       | 0        |\n|------------------+----------------------+-------+---------+----------|\n| DCALedgerHandler | overdraw             | 2333  | 0       | 0        |\n|------------------+----------------------+-------+---------+----------|\n| DCALedgerHandler | overdrawWithApproval | 2341  | 0       | 0        |\n|------------------+----------------------+-------+---------+----------|\n| DCALedgerHandler | overspendAllowance   | 2401  | 0       | 0        |\n|------------------+----------------------+-------+---------+----------|\n| DCALedgerHandler | transfer             | 2267  | 0       | 0        |\n|------------------+----------------------+-------+---------+----------|\n| DCALedgerHandler | transferFrom         | 2361  | 0       | 0        |\n╰------------------+----------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 887\n  Bound result 30\n  Bound result 0\n  Bound result 492\n  Bound result 0\n  Bound result 50304760195986885\n  Bound result 1000000000000000000000000\n  Bound result 70000000000000000000\n  Bound result 663\n  Bound result 0\n  Bound result 0\n  Bound result 263\n  Bound result 0\n  Bound result 0\n  Bound result 6739\n  Bound result 2\n  Bound result 0\n  Bound result 562\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 136\n  Bound result 229\n  Bound result 302\n  Bound result 127\n  Bound result 121\n  Bound result 500\n  Bound result 2\n  Bound result 210\n  Bound result 100\n  Bound result 97\n  Bound result 18\n  Bound result 146\n  Bound result 2646531670\n  Bound result 17\n  Bound result 13\n  Bound result 84528276139485027126\n  Bound result 5707\n  Bound result 7263\n  Bound result 259\n  Bound result 20000000000000000000\n  Bound result 2592286112\n  Bound result 0\n  Bound result 28\n  Bound result 318\n  Bound result 84528276139485032873\n\n[PASS] test_LedgerExercisesFullSupplySelfTransfersAndFailureRecovery() (gas: 1385456)\nLogs:\n  Bound result 1000000000000000000000000000\n  Bound result 1000000000000000000000000000\n  Bound result 1000000000000000000000000000\n  Bound result 1\n  Bound result 1\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 1000000000000000000000000000\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 4.38s (4.38s CPU time)\n\nRan 2 tests for test/DCAHookStateful.t.sol:DCAHookStatefulFwa1Test\n[PASS]\nDCAHookStatefulFwa1Test invariants:\n[PASS] invariant_AllAccruedFwaRemainsBackedAndBelongsOnlyToRecipient\n[PASS] invariant_BothTokensConservedAcrossAllActors\n[PASS] invariant_ManagerIsLockedWithoutUnsettledDebts\n[PASS] invariant_PriceLiquidityAndMandatoryPoolFeesMatchControl\n DCAHookStatefulFwa1Test invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭----------------------+---------------------+-------+---------+----------╮\n| Contract             | Selector            | Calls | Reverts | Discards |\n+=========================================================================+\n| DCAAccountingHandler | changeLiquidity     | 2067  | 0       | 0        |\n|----------------------+---------------------+-------+---------+----------|\n| DCAAccountingHandler | claim               | 2074  | 0       | 0        |\n|----------------------+---------------------+-------+---------+----------|\n| DCAAccountingHandler | donate              | 2006  | 0       | 0        |\n|----------------------+---------------------+-------+---------+----------|\n| DCAAccountingHandler | dustSwap            | 2039  | 0       | 0        |\n|----------------------+---------------------+-------+---------+----------|\n| DCAAccountingHandler | rejectedPartialFill | 2070  | 0       | 0        |\n|----------------------+---------------------+-------+---------+----------|\n| DCAAccountingHandler | rejectedPayout      | 2084  | 0       | 0        |\n|----------------------+---------------------+-------+---------+----------|\n| DCAAccountingHandler | roundTrip           | 2081  | 0       | 0        |\n|----------------------+---------------------+-------+---------+----------|\n| DCAAccountingHandler | swap                | 1963  | 0       | 0        |\n╰----------------------+---------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 5028546948348111\n  Bound result 13909\n  Bound result 1500010000000000000000001\n  Bound result 22\n  Bound result 5707034227454543997024\n  Bound result 70953128166646647882\n  Bound result 800609966319808273809209\n  Bound result 1000\n  Bound result 1500000000000000000006307\n  Bound result 60\n  Bound result 1\n  Bound result 38\n  Bound result 701677998005761449288662\n  Bound result 12135\n  Bound result 614283754\n  Bound result 40\n  Bound result 1500000000000000000015084\n  Bound result 40\n  Bound result 8755\n  Bound result 1000\n  Bound result 1000\n  Bound result 8\n  Bound result 2729606089896910948218\n  Bound result 1080558875762766131689936\n  Bound result 20\n  Bound result 1290192557480659227888694\n  Bound result 1911\n  Bound result 40\n  Bound result 31\n  Bound result 1500000000000000000000021\n  Bound result 7\n  Bound result 999000000\n  Bound result 15\n  Bound result 4\n  Bound result 16\n  Bound result 10000000000000000000000\n  Bound result 40\n  Bound result 40\n  Bound result 1\n  Bound result 5177\n\n[PASS] test_AllHandlerPathsAndSwapModesReachMeaningfulStates() (gas: 3250845)\nLogs:\n  Bound result 10000000000000000000000\n  Bound result 10000000000000000000000\n  Bound result 10000000000000000000000\n  Bound result 10000000000000000000000\n  Bound result 1\n  Bound result 17000000000000000000\n  Bound result 500000000000000000000000\n  Bound result 100000000000000000000\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 8.95s (8.92s CPU time)\n\nRan 2 tests for test/DCAHookStateful.t.sol:DCAHookStatefulFwa0Test\n[PASS]\nDCAHookStatefulFwa0Test invariants:\n[PASS] invariant_AllAccruedFwaRemainsBackedAndBelongsOnlyToRecipient\n[PASS] invariant_BothTokensConservedAcrossAllActors\n[PASS] invariant_ManagerIsLockedWithoutUnsettledDebts\n[PASS] invariant_PriceLiquidityAndMandatoryPoolFeesMatchControl\n DCAHookStatefulFwa0Test invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭----------------------+---------------------+-------+---------+----------╮\n| Contract             | Selector            | Calls | Reverts | Discards |\n+=========================================================================+\n| DCAAccountingHandler | changeLiquidity     | 2067  | 0       | 0        |\n|----------------------+---------------------+-------+---------+----------|\n| DCAAccountingHandler | claim               | 2074  | 0       | 0        |\n|----------------------+---------------------+-------+---------+----------|\n| DCAAccountingHandler | donate              | 2006  | 0       | 0        |\n|----------------------+---------------------+-------+---------+----------|\n| DCAAccountingHandler | dustSwap            | 2039  | 0       | 0        |\n|----------------------+---------------------+-------+---------+----------|\n| DCAAccountingHandler | rejectedPartialFill | 2070  | 0       | 0        |\n|----------------------+---------------------+-------+---------+----------|\n| DCAAccountingHandler | rejectedPayout      | 2084  | 0       | 0        |\n|----------------------+---------------------+-------+---------+----------|\n| DCAAccountingHandler | roundTrip           | 2081  | 0       | 0        |\n|----------------------+---------------------+-------+---------+----------|\n| DCAAccountingHandler | swap                | 1963  | 0       | 0        |\n╰----------------------+---------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 5028546948348111\n  Bound result 10605\n  Bound result 1500010000000000000000001\n  Bound result 29\n  Bound result 2305843009213693953\n  Bound result 70953128166646647882\n  Bound result 800609966319808273809209\n  Bound result 1000\n  Bound result 1500000000000000000006307\n  Bound result 60\n  Bound result 28\n  Bound result 38\n  Bound result 701677998005761449288662\n  Bound result 16610\n  Bound result 2753\n  Bound result 40\n  Bound result 1500000000000000000002256\n  Bound result 40\n  Bound result 8757\n  Bound result 1000\n  Bound result 1000\n  Bound result 8\n  Bound result 2729606089896910948218\n  Bound result 1080558875762766131689936\n  Bound result 20\n  Bound result 1290192557480659227888694\n  Bound result 4450\n  Bound result 40\n  Bound result 4\n  Bound result 1500000000000000000000021\n  Bound result 7\n  Bound result 999000000\n  Bound result 15\n  Bound result 5\n  Bound result 16\n  Bound result 10000000000000000000000\n  Bound result 22\n  Bound result 40\n  Bound result 1\n  Bound result 2448\n\n[PASS] test_AllHandlerPathsAndSwapModesReachMeaningfulStates() (gas: 3257819)\nLogs:\n  Bound result 10000000000000000000000\n  Bound result 10000000000000000000000\n  Bound result 10000000000000000000000\n  Bound result 10000000000000000000000\n  Bound result 1\n  Bound result 17000000000000000000\n  Bound result 500000000000000000000000\n  Bound result 100000000000000000000\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 9.22s (9.18s CPU time)\n\nRan 12 test suites in 9.22s (25.65s CPU time): 111 tests passed, 0 failed, 0 skipped (111 total tests)\n","passed":true},{"durationMs":65,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"DCAHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"DCAHook.claimFees()\",\"DCAHook.unlockCallback(bytes)\",\"DCAToken.approve(address,uint256)\",\"DCAToken.transfer(address,uint256)\",\"DCAToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"DEPENDENCIES.json\":130,\"README.md\":117,\"SECURITY.md\":39,\"foundry.toml\":19,\"remappings.txt\":4,\"script/PrepareHook.s.sol\":20,\"src/DCAHook.sol\":208,\"src/DCAToken.sol\":14,\"src/HookMiner.sol\":21,\"test/ADVERSARIAL_TESTS.md\":36,\"test/DCAHook.t.sol\":391,\"test/DCAHookEdges.t.sol\":225,\"test/DCAHookStateful.t.sol\":317,\"test/DCAInvariant.t.sol\":113,\"test/DCAToken.t.sol\":126,\"test/DCATokenEdges.t.sol\":110,\"test/DCATokenStateful.t.sol\":172,\"test/Deployment.t.sol\":98,\"test/helpers/HookTestBase.sol\":101,\"test/helpers/PoolRouter.sol\":112,\"test/helpers/RestrictedFWA.sol\":43},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"53b6750595aa704e937586c33d05293a7cadcbb8bacc7d89ff8229afddd3b1e7","verifiedTreeHash":"e2b39cc0e697e834b02255d1cd7271abad5578ac","verifierVersion":"0.1.0+7ff5db2c"}]}