the ten defenses
Each defense corresponds to a property the protocol promises and a test that proves it. The numbering is chronological — D1–D5 close the single-block flash-loan class that drained Uniperp; D6–D10 close the multi-block follow-up class; M-01 + M-02 close MEV and gas-bomb edge cases.
pre-open price gate
openLong reverts if |spotTick − twapTick| > 5000 ticks at the start of the call. The single most important defense — it removes the attacker's ability to open against a manipulated spot in the same tx that manipulated it.
TWAP observes everything
Every swap — including internal hook-initiated leveraged buys, closes, and liquidations — writes an observation to the TWAP ring buffer. Same-block pumps poison their own TWAP, so the spot/TWAP gap closes quickly.
(retired)
The original per-block borrow-only cap was strictly dominated by D7 (curve-advance cap). Retired in v0.1.
symmetric liquidation cooldown
Liquidation skips positions younger than LIQ_COOLDOWN_BLOCKS = 2 — the same gate as user-close. No asymmetric exit path.
donate blocked
beforeDonate is registered and reverts. Anyone trying to donate tokens to the pool (which would skew the active band's fee accumulator) gets blocked.
post-open price gate
After the open's leveraged buy executes, spot must STILL be within deviation of TWAP. Chains opens against each other within a block — second open in a block has less budget than the first.
per-block curve-advance cap
MAX_CURVE_ADVANCE_PER_BLOCK = 5 ETH. Total curve-advancing ETH per block (direct buys + opens combined) is capped. Forces both legs of a multi-block attack to spread across many blocks, each requiring TWAP catch-up.
absolute borrow ceiling
Total outstanding band borrow can't exceed MAX_TOTAL_BORROW = 200 ETH at any time. Even if D7 is somehow beaten, this caps absolute capital at risk to abandoned positions.
bad-debt auto-pause
When totalBadDebtETH > 5 ETH, new opens auto-revert. Closes and liquidations continue so users can exit. Owner heals via donateAndRefillBands.
funding rate on positions
50% APR on debt, virtual accrual. Even with no price movement, an abandoned lev-5 position becomes liquidatable in ~1 year. Closes the 'open and never close' exit path that made the original Uniperp drain profitable.
liquidation sandwich defer
If current spot has drifted from TWAP by more than 1500 ticks at scan time, the scan exits early. Once arbitrage closes the gap, the next external swap re-triggers fairly. Bots can't sandwich a forced sell.
gas-cap on staking call
staking.notifyReward is called with gas: 100_000. A malicious staking that consumes all gas can no longer starve the catch handler via the 1/64 rule.