Contents

Overview · For everyone

The peg pool

imdUSD trades against USDC in one Uniswap v4 pool. It opened at exactly $1, charges a 0.01% fee to trade near the peg, and adds a surcharge to any swap that pushes the price away from $1. The surcharge rules live in a v4 hook, PegFeeHook, which has no owner and nothing anyone can change.

PoolimdUSD / USDC, Uniswap v4, Ethereum mainnet
Pool id0x3cb8cc9c22f7da5c3169d4059131ddba9e61f68230977797c03a2f1214992035
Hook0x33cA5c16208EC08aC97d4f6315aaFA792A916044 (PegFeeHook, verified source)
Pool keycurrency0 imdUSD, currency1 USDC, fee 100 (0.01%), tick spacing 1
PoolManager0x000000000004444c5dc75cB358380D2e3dE08A90
TradeUniswap
Source and auditsgithub.com/fa11up/imdusd-peg-hook

Anyone can deploy a copy of the hook at another address and open a pool beside this one. Only the pool id above is the peg pool: pin it, not the token pair.

What a swap pays

Every swap pays the pool's fee, 0.01%, to the liquidity providers. A swap that ends with imdUSD more than 0.25% from $1, having pushed it that way, also pays a surcharge. The surcharge is priced from where the swap ends:

imdUSD price where the swap endsTotal fee (pool fee + surcharge)
$0.9975 to $1.00250.01%
$0.995 or $1.005about 0.72%
$0.99 or $1.01about 2.15%
$0.98 or $1.02 and beyond5%

Between 0.25% and 2% from $1 the surcharge rises in a straight line, and from 2% out the total stays at 5%. A swap that moves the price towards $1 pays only the 0.01% pool fee, however far from $1 it starts. So does any swap that ends inside the ±0.25% band.

Three consequences of pricing by the end price:

  • A sale split into steps pays less than one swap to the same price, about a third to a half less, because each step pays at its own end price. It never pays less than the pool fee.
  • A swap that crosses $1 is charged by where it lands, on its whole amount, even if it started further from $1 on the other side. Arbitrage that restores the peg stops at $1 and pays only the pool fee.
  • A trade placed just before yours can push your swap past the band's edge, so it pays the ramp. The surcharge goes to the Treasury, not to whoever placed that trade, and your swap's own price limit caps what you pay.

Why a surcharge

Below $1, imdUSD has a floor that does not depend on this pool: redemption swaps imdUSD for collateral, for a fee of 0.5% to 5% (see Redeem). A swap that pushes imdUSD to $0.98 or below pays 5%, the most redemption ever charges, so a large sale that would break the peg costs at least as much as redeeming would, while redemption itself pulls the price back towards $1. Above $1 the same surcharge applies to buying, and the cheaper source of imdUSD is borrowing it from the vault. The surcharge falls away as the price returns to the band.

Where the surcharge goes

The surcharge is taken in the currency on the swap's unspecified side: the output of an exact-input swap, the input of an exact-output one. The hook holds it as PoolManager claims (ERC-6909), which never moves a token during the swap, so no swap can fail on it. Anyone may call sweep(currency) on the hook to turn the claims into tokens at the imdUSD Treasury (0x6Ac8fF96Fb8DCF5d79A8eF1E59D9AC23f2BD27Bc). Liquidity providers earn the 0.01% pool fee only.

What the hook allows

PegFeeHook attaches to exactly one pool. Its beforeInitialize refuses any pool key other than imdUSD/USDC at fee 100, tick spacing 1, with this hook, and any opening price other than exactly $1. It has no owner, no settings and no storage: the fee, the band, the ramp, the Treasury and the tokens are fixed in the contract. Its address carries exactly the three hook permissions it uses: beforeInitialize, afterSwap and afterSwapReturnDelta.

Read-only helpers: stablePrice(sqrtPriceX96) gives imdUSD's price in USDC (1e18 = $1), feeFor(sqrtPriceX96, zeroForOne) gives the total fee in hundredths of a basis point for a swap ending at that price, and surchargeFor gives the surcharge alone.

Adding liquidity

The first position covers $0.9524 to $1.05. Anyone may add liquidity through Uniswap's PositionManager like any v4 pool, at any range. The first deposit was bounded at $1: each token's maximum was what a $1 position needs, so a pool pushed off the peg before it would have made the deposit revert rather than land at a moved price. Deposit the same way, with amount0Max and amount1Max set for the price you expect.

Audits

The hook went through three panel audits on the IdentityMD network, each with four specialists and a judge who reproduces every claim. The full record is audits/AUDIT-2026-10-10.md in the hook's repository.

RoundJobFindings (C/H/M/L/I)What changed
15648bda50/1/1/3/2The fee had been priced from the price before each swap, which a seller could route around. Redesigned around the end price.
23d492b200/0/2/3/3The surcharge was sent to the Treasury during the swap, so a refused transfer could stop swaps. It is now held as claims and swept separately.
3442fd6490/0/1/3/3No finding in the claims or the sweep. An empty-pool guard added in round 2 could be switched off, so it was removed: a bounded first deposit protects the pool instead.