This paper refers to the fixed Ethereum deployment using LendingHookV3, with liquidation hardening (two-step request + delay + swap-block cooldown).
Reference exploit transaction (legacy path): 0x8deefbea62c3966ba2a81e7e3ef328f9dd09ca90b66a23fed8c5eda0c3ab4820 ->
Use only the verified contracts listed in section 07 below.
Liquidity that does work.
l20p is a Uniswap V4 hook that turns LP depth into borrowable capital  without burning tokens, without oracles, without a separate lending market.
Every AMM pool carries a silent cost: idle capital. The ETH locked in a Uniswap V4 pool to back l20p trades is doing one job  sitting there waiting to be swapped against. When no one is buying, that ETH earns nothing but the slim swap fee.
Meanwhile, l20p holders who want liquidity have to sell  pushing the price down, paying the spread, and giving up their position. There is no native way to hold and borrow at the same time inside the pool.
A Uniswap V4 hook gives us lifecycle callbacks on every pool operation. We use beforeSwap, afterSwap, beforeAddLiquidity, and beforeRemoveLiquidity to turn the hook itself into the sole LP  and to intercept part of the pool's ETH reserves for lending.
The result: idle ETH sitting in the pool  capital that would otherwise just back trades  is lent out against locked l20p collateral. The pool is simultaneously an AMM and a lending market. No second contract, no oracle, no governance token.
When borrowers repay, ETH is injected back as single-sided LP in the band above the current spot  the pool heals itself. When a position is liquidated, collateral l20p is sold through the same pool and the ETH proceeds refill the exact band the borrow originally came from.
l20p uses a standard constant-product curve K = (V + x) · y where:
- V = 20 ETH  virtual ETH (phantom reserves at launch)
- x  real ETH in the pool
- y  real l20p in the pool
- K = 20,000,000 (1M l20p × 20 ETH)
The pool is divided into 100 bands, each spanning 30 ETH of pool depth. Band i covers pool ETH [30i, 30(i+1)].
l20pi = K / (V + 30i) − K / (V + 30(i+1))
Sum across all bands = K/V = 1,000,000 l20p ✓
Each band maps to a Uniswap V4 tick range via the inverse sqrtPrice formula. Higher pool ETH → lower V4 price → lower tick. So band 0 has the highest tick (lowest ETH depth) and band 99 the lowest.
ethAtSqrtPrice(p) = √(K · 10¹â¸) · 2â¹â¶ / p − V
The liquidation threshold is 150% of debt value. The liquidation price in pool-ETH space is:
This is where the bound band is chosen  the band containing the liquidation price. ETH is drawn from that band, and repayments restore it.
1 · Seed. At deploy, the hook seeds all 100 bands with single-sided l20p positions. The pool starts with ETH = 0; all liquidity is l20p-only, fully above spot.
2 · Buy. A user sends ETH → l20p. The hook's beforeSwap deducts a 1% fee and routes it to the FeeCollector. The V4 pool price moves down the curve as bands are crossed.
3 · Borrow. A l20p holder calls borrow(collateral).
The hook locks the l20p, computes 40% of collateral value as debt,
finds the bound band (the band at the predicted liquidation price),
and removes ETH-side liquidity from it. Net ETH (after 1% origination fee)
is transferred to the borrower.
4 · Repay. The borrower calls repay(band){value: eth}.
ETH is deposited back as single-sided LP in the bound band (or the
next-best band above spot). l20p collateral is returned pro-rata.
5 · Liquidate. If collateral value drops below 150% of debt,
anyone calls liquidate(user, band). The hook sells
the collateral l20p via an internal V4 swap, pays a 1%-of-debt
bounty to the liquidator (capped at 0.01 ETH), and refills the
bound band with remaining ETH proceeds.
No swap routing. l20p does not include a front-end swap router. To buy or sell l20p, use Uniswap directly with the token address on Ethereum mainnet.
Same-block protection. Borrowing and liquidating are blocked in the same block as a swap. This prevents flash-loan manipulation of the spot price.
Band depth. Each band has finite liquidity. If all ETH in a band is borrowed out, no further borrows can draw from it. Users are directed to the nearest available band.
No external oracle. The liquidation price is derived purely from the pool's own constant-product math. The hook is only as secure as the pool's own liquidity depth against manipulation.
Uniswap V4 hook trust model. The hook is the sole authorized LP. Third-party LP positions are rejected. All ETH in the pool is under hook control. Audit the contract before using.
| Parameter | Value | Notes |
|---|---|---|
| LTV | 40% | Max borrow / collateral value |
| Liquidation threshold | 150% | collateral / debt value |
| Origination fee | 1% | of gross debt, to FeeCollector |
| Swap fee | 1% | on ETH in/out, to FeeCollector |
| Liquidation bounty | 1% | of debt, capped at 0.01 ETH |
| Virtual ETH (V) | 20 ETH | phantom reserves at launch |
| Band width | 30 ETH | each band spans 30 ETH of depth |
| Bands | 100 | covers 0–3,000 ETH of pool depth |
| Tick spacing | 60 | Uniswap V4 pool configuration |
| Repay cooldown | 2 blocks | after opening position |
| Min collateral | 0.1 ETH value | in l20p at spot price |
| Contract | Address |
|---|---|
Chain: Ethereum mainnet (chain ID 1)