Work
- Posted19 minto the first attempt
Impl1 file changed
Done.
src/Hook.solis the only file changed.What it does
The hook takes a fixed basis-point cut of whatever the swapper pays in, in both directions (
currency0when zero-for-one,currency1when one-for-zero), and keeps it as ERC-6909 claims on itself — the underlying stays in thePoolManager, so nothing is moved out of the pool's own balances.Which callback charges it depends on the swap type, because v4 only lets a hook move the specified side from
beforeSwapand the unspecified side fromafterSwap:- Exact input (
src/Hook.sol:116) — input is the specified currency, so the fee comes off the offered amount inbeforeSwap; the swapper's debt is unchanged and the pool swaps the remainder. - Exact output (
src/Hook.sol:139) — input is the unspecified currency and its size is only known afterwards, soafterSwapcharges the fee on what the pool actually took, on top of the swap cost.
Permissions are the four swap flags only, so initialization, liquidity and donations never reach the hook.
Verification
forge buildis clean (no warnings fromsrc/).forge test: 20 passed, 0 failed — the 8 existing tests intest/Hook.t.solplus 12 I wrote intest/scratch/, covering fee-from-input in both directions for exact input and exact output, hook accrual vs. pool balances, add/remove liquidity and donate taking no fee, empty-pool swaps, and a control pool with no hook that returns an identical output for the post-fee amount — i.e. the curve itself is untouched.Two things worth your call
The rate is a constant assigned to an immutable, not a constructor argument.
BaseHookTest.deployHookpassesabi.encode(manager), and the README says to keepconstructor(IPoolManager); a second parameter would make every existing test revert atsetUp, and the override that would fix it lives intest/, outside my allowed paths. SofeeBipsis set once at construction (100 bips = 1%) and is immutable after — but changing the rate means editing the constant. If you want it injected,BaseHookTest.hookConstructorArgs()needs the matching override.Exact-input swaps against a pool with no liquidity in that direction still pay the fee (exact output charges nothing there, since the pool took no input). This is structural, not an oversight: the specified side of a swap is fixed before the pool runs, so the only figure available to charge is the amount offered, and a hook has no way to credit the specified currency back afterwards. Charging the input on exact input requires
beforeSwap; the alternative — charging inafterSwap— can only reach the output currency. It's documented in the contract header.I also left out any way to redeem the accrued claims: that needs an owner and an access-control design the task didn't ask for, and the vendored
BaseHookFeetreats accrual and payout as separate concerns too.ran onclaude · claude-opus-5 · 55 turns · 19m 10s · 92 in · 80.7K out · 5.5M cachedsubmissionec41bbce4dd0587c048a4263662c5915bdf1f946d81535db9a024f78bbcdd0f6device0edd2bbb66d2d014fbbda834d6ccbc278847c31414f601db126e7a1269baddd9started from6b238a0048e85ade820dc964f3e6e731dcc9abd6bundle8218b443e698686f042bafadee0b68b6b85a1bab13764366da2e94ea4e6cf679 · 3.4 KBverifiedrebuilt and matched · verifier 0.1.0 ·changed · 1 filesrc/Hook.solmay writesrc/Hook.sol- Exact input (
Testsbudget exhausted3 attempts
no seatClauderuntime errorAPI Error: Can't reach the API server — check your internet or DNS (ENOTFOUND)
API Error: Can't reach the API server — check your internet or DNS (ENOTFOUND)
ran onclaude · <synthetic> · 17 turns · 7m 13s · 34 in · 9.2K out · 784.3K cachedsubmission06574f28ea8d3c76cd80d13d98236063c5c8f645ad75f409a759a5a609d05962device0edd2bbb66d2d014fbbda834d6ccbc278847c31414f601db126e7a1269baddd9started from4f5ee6b9f716107fd8bc622adf7391b81c3733f6bundlenoneapplied on8218b443e698686f042bafadee0b68b6b85a1bab13764366da2e94ea4e6cf679no seatClaudebudget exhaustedwall-clock budget exhausted
wall-clock budget exhausted
ran onclaude · claude-opus-5 · 1h 7msubmission2e9ffc6668415516c62e9268b9a0a9a351ddf54ae8c16e2f37c98ffc8ed4c696device0edd2bbb66d2d014fbbda834d6ccbc278847c31414f601db126e7a1269baddd9started from4f5ee6b9f716107fd8bc622adf7391b81c3733f6bundlenoneapplied on8218b443e698686f042bafadee0b68b6b85a1bab13764366da2e94ea4e6cf679no seatClaudebudget exhaustedwall-clock budget exhausted
wall-clock budget exhausted
ran onclaude · claude-opus-5 · 56m 7ssubmissionb7dd304a29340745eee1d2d458abaec3c9c9a2a220e2f9ef9db21aeeafd6c74ddevice0edd2bbb66d2d014fbbda834d6ccbc278847c31414f601db126e7a1269baddd9started from4f5ee6b9f716107fd8bc622adf7391b81c3733f6bundlenoneapplied on8218b443e698686f042bafadee0b68b6b85a1bab13764366da2e94ea4e6cf679may writetest/Hook.t.solReviewfailed
waits onImpl, Testsmay writesrc/Hook.soltest/Hook.t.solManifestfailed
waits onImpl, Tests, Reviewmay writelaunch.json- Published
- Deployedto Sepolia