Search projects, hackathons, sponsors and tech

    ← All projects

    stETHer

    Uniswap v4 hook implementing dynamic fees and proper rebasing token handling

    About

    I created a new type of AMM that works completely differently from traditional pools. Instead of the usual x*y=k curve that causes slippage, I use x+y=k which enables perfect 1:1 swaps when the pool is balanced. The magic happens with my dynamic fee system - I charge zero fees for ETH→stETH swaps (encouraging staking) but apply increasing fees for stETH→ETH swaps as the pool gets imbalanced. This naturally keeps the pool stable while generating revenue that funds incentives to bring it back into balance. The pool also properly handles rebasing tokens like stETH, so liquidity providers don't lose their staking yield just because they're providing liquidity.

    How it's made

    The core innovation is using x + y = k instead of the traditional x * y = k formula. This means when the pool is balanced, you can swap 100 ETH for exactly 100 stETH with zero slippage - something impossible with regular AMMs. I implemented this as a Uniswap v4 hook that intercepts swaps and applies my custom logic. The fee structure is intentionally asymmetric: ETH → stETH: Always 0% (I want to encourage staking) stETH → ETH: Dynamic fees that increase as the pool gets unbalanced Dynamic Fee Tiers The fees automatically adjust based on how much ETH is left in the pool: Pool has 70-80% ETH: 0.1% fee (balanced, low fee) Pool has 60-70% ETH: 0.5% fee (slightly unbalanced) Pool has 50-60% ETH: 1.0% fee (getting concerning) Pool has 40-50% ETH: 2.0% fee (significantly unbalanced) Pool has <40% ETH: 5.0% fee (emergency mode) This creates natural economic pressure to keep the pool balanced - as ETH gets scarce, it becomes more expensive to withdraw, which encourages people to deposit more ETH instead. Rebasing Token Support One of the trickiest parts was handling stETH properly. Regular AMMs break when you add rebasing tokens because the balances change over time. I solved this with a shares-based accounting system that preserves the underlying yield. My test stETH implementation gives 5% APY, and crucially, LPs don't lose this yield when they provide liquidity. The rebasing happens continuously based on time elapsed. LP Token System I built a proper ERC20 LP token that represents your share of the pool. When you add liquidity, you get LP tokens. When you remove liquidity, you burn your LP tokens and get back your proportional share of the pool PLUS any fees that accumulated while you were providing liquidity. The cool part is that fees automatically compound - instead of needing to manually claim them, they just increase the value of your LP position over time. Revenue Sharing Here's where it gets interesting economically. When fees are collected, they're split: 90% goes to liquidity providers (you earn fees for providing liquidity) 10% goes to the protocol But here's the clever bit - those protocol fees don't just sit there. They fund incentives for ETH→stETH swaps. So when the pool gets unbalanced (too much stETH, not enough ETH), we can use the accumulated protocol fees to give people a small bonus for depositing ETH. The Self-Balancing Loop This creates a beautiful self-balancing system: Pool gets unbalanced (too much stETH) stETH→ETH swaps become more expensive (higher fees) Higher fees generate more protocol revenue Protocol revenue funds incentives for ETH deposits People deposit ETH to get the bonus Pool rebalances naturally The system is completely sustainable because it only spends what it earns. Self-Balancing: Incentives funded by fees collected from the opposite direction Rate Limiting: Incentives capped at 0.1% and only when sufficient protocol fees exist Sustainability: System only spends what it earns, ensuring long-term viability Technical Features Smart Contract Components Main Pool Contract (Counter.sol): Core AMM logic and Uniswap v4 hook integration LP Token (ConstantSumLP.sol): ERC20 token for liquidity provider shares Revenue Manager (RevenueManager.sol): Fee calculation and distribution Rebasing Token (StETH.sol): Mock stETH with 5% APY for testing Key Functions addLiquidity(): Add liquidity and receive LP tokens removeLiquidity(): Burn LP tokens and withdraw assets + accumulated fees beforeSwap(): Uniswap v4 hook that implements constant-sum swaps with dynamic fees claimFees(): Allow LPs to claim accumulated fees rebase(): Update stETH balances based on time-based yield Testing Suite 74 Tests Total covering all functionality Unit Tests: Individual contract functionality Rebasing Tests: Time-based yield mechanics Fee Distribution Tests: Multi-LP scenarios