Skip to content

DelleonMcglone/dynamic-fee

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DynamicFee Hook — Nezlobin's Directional Fee Framework

A Uniswap v4 hook that protects LPs from toxic arbitrage by charging asymmetric fees based on whether swaps move the pool price toward or away from the Chainlink oracle price.

How It Works

  1. Get Oracle Price — Fetch current price from Chainlink (ETH/USD, LINK/USD)
  2. Get Pool Price — Derive from current sqrtPriceX96
  3. Calculate Deviation|poolPrice - oraclePrice| / oraclePrice in basis points
  4. Classify Zone — TIGHT (0-1%), NORMAL (1-3%), ELEVATED (3-5%), HIGH (5-10%), EXTREME (>10%)
  5. Determine Direction — Does swap move price TOWARD or AWAY from oracle?
  6. Apply Asymmetric Fee — Lower fee for stabilizing trades, higher for arbitrage

Fee Matrix (basis points)

Zone Toward Oracle Away from Oracle
TIGHT (0-1%) 5 10
NORMAL (1-3%) 10 30
ELEVATED (3-5%) 20 50
HIGH (5-10%) 30 100
EXTREME (>10%) 50 200

Max fee cap: 200 bps (2%)

Architecture

src/
├── DynamicFee.sol              # Main hook — beforeSwap returns dynamic fee
├── base/
│   └── BaseHook.sol            # Minimal base hook with permission validation
└── libraries/
    ├── OracleManager.sol       # Chainlink integration (staleness checks, decimal normalization)
    ├── DeviationMonitor.sol    # Deviation calculation and zone classification
    └── FeeCalculator.sol       # Fee matrix lookup

Hook Permissions

Hook Enabled Purpose
beforeSwap Yes Calculate and return dynamic fee with OVERRIDE_FEE_FLAG
afterSwap Yes Update zone tracking, emit ZoneTransition events

Build & Test

forge install
forge build
forge test -vvv
forge coverage

Deployed Contracts (Base Sepolia)

Contract Address BaseScan
DynamicFee Hook 0x9788B8495ebcEC1C1D1436681B0F56C6fc0140c0 view
tWETH (Mock) 0x839Cc782708f1768F0F7591eA0c7D08290ba2a3c view
tUSDC (Mock) 0x8b6de320b93c2f8dEE5C9392A001E03CE6cc8Fe6 view
tLINK (Mock) 0x16538c37818d580F7f919D4583D7935C8624567E view
PoolModifyLiquidityTest 0x9f12E9d064398e07153Ca7E1401C71343edB772B view
PoolSwapTest 0xF778eF19F4A0065430C55a7cD09d287368947C29 view
Uniswap v4 PoolManager 0x05E73354cFDd6745C338b50BcFDfA3Aa6fA03408 view

Deployed Contracts (Unichain Sepolia)

Contract Address Uniscan
DynamicFee Hook 0xa5eCBF949D964760f3F7805f59eb4AAc1f2500c0 view
Uniswap v4 PoolManager 0x00B036B58a818B1BC34d502D3fE730Db729e62AC view

Deploy transaction: 0xcc6aca…

Deployed Contracts (Arc Testnet)

Arc is Circle's USDC-native L1 (USDC is the gas token). Uniswap v4 is not pre-deployed on Arc testnet, so script/DeployArc.s.sol stands up the full v4 stack (PoolManager + test routers), deploys freely-mintable mock USDC (6 dp) and mock cirBTC (8 dp), deploys the DynamicFee hook to a CREATE2 address carrying the beforeSwap/afterSwap flags, then creates and seeds a single dynamic-fee USDC/cirBTC pool and runs warm-up swaps.

Contract Address ArcScan
DynamicFee Hook 0xA1Be807481F532c074380FCcF05be5e2A3ec80C0 view
USDC (mock, 6dp) 0xFE3f00877d20Fb599351182EAef78DE3EF531dF6 view
cirBTC (mock, 8dp) 0xAeE5a58b0ae058bfd358CeeB72e4804C16d94F5E view
Uniswap v4 PoolManager 0x7eA87A5919C119DC95855A0BE227fd3241c998F0 view
PoolModifyLiquidityTest 0xdD225f3B7b621287657B490B3bC945E3ecfC8EbA view
PoolSwapTest 0xAa096011E6604df33762d611cbBdaA0671F19Bdb view

Hook deploy (CREATE2): 0x5f22bd… · Deployer: 0xceeD79dBB39bA3C6Cddb57eb6343BE25FfD6dd56 · Pool: USDC/cirBTC (dynamic fee, tickSpacing 60)

Network Details

Deploy

# Fund the deployer with testnet USDC (gas) from https://faucet.circle.com
export ARC_TESTNET_RPC_URL=https://rpc.testnet.arc.network
forge script script/DeployArc.s.sol:DeployArc \
  --rpc-url arc_testnet --broadcast -vv

Key Transactions

Deployment

Action Transaction
Deploy tWETH 0x0eeded…
Deploy tUSDC 0xf7451c…
Deploy tLINK 0x7ca07c…
Deploy DynamicFee Hook (CREATE2) 0x73dbaf…
Deploy LiquidityRouter 0x6dd591…
Deploy SwapRouter 0xa8cf52…

Pool Creation & Liquidity

Action Transaction
Configure ETH/USDC pool 0xfa7cad…
Initialize ETH/USDC pool 0x16d5c1…
Add liquidity ETH/USDC 0x4a1bfa…
Configure LINK/USDC pool 0xaea5ce…
Initialize LINK/USDC pool 0x791a48…
Add liquidity LINK/USDC 0xc37d54…
Configure ETH/LINK pool 0xa369f3…
Initialize ETH/LINK pool 0x7cb552…
Add liquidity ETH/LINK 0x4bd929…

Test Swaps

Test swaps have not yet been re-executed against the new hook deployment. Run script/TestSwap.s.sol against the new pools to populate this section.

Example Scenarios

Arbitrage Against Oracle (High Fee)

  • Oracle: ETH = $3000, Pool: ETH = $2900 (underpriced)
  • Swap: Buy ETH (moves price away from oracle)
  • Fee: 100+ bps (HIGH zone, AWAY direction)

Stabilizing Trade (Low Fee)

  • Oracle: ETH = $3000, Pool: ETH = $3100 (overpriced)
  • Swap: Sell ETH (moves price toward oracle)
  • Fee: 10-30 bps (incentivizing rebalance)

Network Details

  • Chain: Base Sepolia (Chain ID 84532)
  • PoolManager: 0x05E73354cFDd6745C338b50BcFDfA3Aa6fA03408
  • Deployer: 0xbaacDCFfA93B984C914014F83Ee28B68dF88DC87

License

MIT

About

Multi-signal dynamic fee hook that automatically adjusts swap fees based on volatility, volume, and pool state. Built as the enhancement layer of the Mantua.AI DeFi suite on Uniswap v4

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages