Add Loyalty Volatility Dynamic Fee Hook hook on base#626
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Review: hooks/base/0xaa226363fb5b8718d125357ddc6539a82489e0c4.json
Contract: LoyaltyVolatilityHook — verified source on Base (chainId 8453). Source analysis performed against .sources/src_LoyaltyVolatilityHook.sol and supporting libraries.
Flags — PASS
Address 0xe0c4 → binary 1110 0000 1100 0100. Lowest 14 bits:
| Bit | Flag | Expected | File |
|---|---|---|---|
| 13 | beforeInitialize | true | true ✓ |
| 12 | afterInitialize | false | false ✓ |
| 11 | beforeAddLiquidity | false | false ✓ |
| 10 | afterAddLiquidity | false | false ✓ |
| 9 | beforeRemoveLiquidity | false | false ✓ |
| 8 | afterRemoveLiquidity | false | false ✓ |
| 7 | beforeSwap | true | true ✓ |
| 6 | afterSwap | true | true ✓ |
| 5 | beforeDonate | false | false ✓ |
| 4 | afterDonate | false | false ✓ |
| 3 | beforeSwapReturnsDelta | false | false ✓ |
| 2 | afterSwapReturnsDelta | true | true ✓ |
| 1 | afterAddLiquidityReturnsDelta | false | false ✓ |
| 0 | afterRemoveLiquidityReturnsDelta | false | false ✓ |
Confirmed by getHookPermissions() in source.
Properties — PASS
- dynamicFee: true ✓ —
beforeSwapcalls_computeSwapFee()which returns a fee withLPFeeLibrary.OVERRIDE_FEE_FLAGset viaFeeMath.withOverrideFlag(). The fee varies per swap based on tick volatility and loyalty holdings. - upgradeable: false ✓ — No proxy patterns, no
delegatecall, no mutable implementation storage, noSELFDESTRUCT. - requiresCustomSwapData: false ✓ —
hookDataparameter inbeforeSwapis declared but completely ignored; swaps work normally without any hookData. - vanillaSwap: false ✓ — Correct;
dynamicFeeis true andafterSwapReturnsDeltais true. - swapAccess: "none" ✓ —
beforeSwaphas no per-caller access control (only a pool-enabled check that applies universally).
Metadata — ISSUES FOUND
chainId: 8453 ✓ — matches chains.json for Base.
verifiedSource: true ✓ — confirmed by source_meta.json.
name: ❌ "Loyalty Volatility Dynamic Fee Hook" contains a double space between "Loyalty" and "Volatility". This is a typo and should read "Loyalty Volatility Dynamic Fee Hook".
description: ❌ Minor inaccuracy — the description states the developer fee is "extracted from the output currency", but the source code takes the fee from the unspecified currency (specifiedTokenIs0 ? key.currency1 : key.currency0). For exact-output swaps, the unspecified currency is actually the input token, not the output. The description should say "unspecified currency" instead of "output currency".
Required Changes
- Fix the double space in
name:"Loyalty Volatility Dynamic Fee Hook" - Fix
description: replace "output currency" with "unspecified currency" (or "the unspecified token in each swap")
There was a problem hiding this comment.
Review: hooks/base/0xaa226363fb5b8718d125357ddc6539a82489e0c4.json
Address Flags
Address suffix 0xe0c4 = 0b1110_0000_1100_0100. Masking to 14 bits:
| Bit | Flag | Expected | JSON |
|---|---|---|---|
| 13 | beforeInitialize | true | true ✓ |
| 12 | afterInitialize | false | false ✓ |
| 11 | beforeAddLiquidity | false | false ✓ |
| 10 | afterAddLiquidity | false | false ✓ |
| 9 | beforeRemoveLiquidity | false | false ✓ |
| 8 | afterRemoveLiquidity | false | false ✓ |
| 7 | beforeSwap | true | true ✓ |
| 6 | afterSwap | true | true ✓ |
| 5 | beforeDonate | false | false ✓ |
| 4 | afterDonate | false | false ✓ |
| 3 | beforeSwapReturnsDelta | false | false ✓ |
| 2 | afterSwapReturnsDelta | true | true ✓ |
| 1 | afterAddLiquidityReturnsDelta | false | false ✓ |
| 0 | afterRemoveLiquidityReturnsDelta | false | false ✓ |
All 14 flags match. Confirmed by getHookPermissions() in source.
Properties
- dynamicFee: true ✓ —
beforeSwapcomputes a fee and returns it withFeeMath.withOverrideFlag(finalFee), which ORs inLPFeeLibrary.OVERRIDE_FEE_FLAGto activate the dynamic LP fee override path. - upgradeable: false ✓ — Contract uses only immutable storage (
poolManager,developerFeeRecipient), no proxy pattern, nodelegatecall, noSELFDESTRUCT. - requiresCustomSwapData: false ✓ — The
hookDataparameter inbeforeSwapis unnamed and never read. Swaps function correctly with empty hookData. - vanillaSwap: false ✓ — Correctly false:
afterSwapReturnsDelta=true(developer fee skim viapoolManager.take) anddynamicFee=trueboth disqualify vanilla classification. - swapAccess: "none" ✓ —
beforeSwapperforms no access control (no caller check, no timestamp gate, no governance flag). Any address may swap freely.
Metadata
- chainId 8453 ✓ — Matches
baseinchains.json. - verifiedSource: true ✓ — Confirmed by
source_meta.json("verified": true). - name ✓ — "Loyalty Volatility Dynamic Fee Hook" is a readable expansion of the on-chain contract name
LoyaltyVolatilityHook, supported by the NatSpec@notice: "Dynamic LP fees based on tick volatility and ERC-20/ERC-721 loyalty holdings". No promotional or endorsement language. - description ✓ — Every claim is substantiated by the source:
- "adjusts the swap fee based on recent tick volatility" →
FeeMath.computeVolatilityDeltatracking tick differences across blocks. - "configurable gamma and tick-delta threshold" →
PoolConfig.gammaandthetaThreshold. - "grants a discount to swappers holding... ERC-20 or ERC-721 loyalty token above a threshold" →
LoyaltyVerifier.computeLoyaltyDelta. - "fixed 0.01% developer fee" →
DEVELOPER_FEE_BIPS = 1(1 bip = 0.01%). - "extracted from the unspecified currency on every swap via afterSwapReturnsDelta" →
afterSwapcallingpoolManager.takeand returning the delta. - "Fee bounds and loyalty parameters are configurable per pool by the pool owner" →
updatePoolConfiggated bymsg.sender != config.owner.
- "adjusts the swap fee based on recent tick volatility" →
No audit claims, safety guarantees, or marketing language present. All verified.
Summary
Dynamic LP fee hook that adjusts the swap fee based on recent tick volatility (using configurable gamma and tick-delta threshold) and grants a discount to swappers holding a configured ERC-20 or ERC-721 loyalty token above a threshold. A fixed 0.01% developer fee is extracted from the output currency on every swap via afterSwapReturnsDelta. Fee bounds and loyalty parameters are configurable per pool by the pool owner.
Flags
Properties
Warnings
Closes #625