# Saturn Protocol: underflow withdrawal freeze and dual-tolerance extraction

Saturn Protocol sUSDat ERC4626 vault: arithmetic underflow in convertFromStrc freezes all withdrawals, and dual 20% tolerances let PROCESSOR extract 33.33% per conversion.

- Payout: Real-world hack
- Severity: critical
- Program: Saturn Protocol
- Credited: Innora Security Research (feng@innora.ai)
- Disclosed: 2026-04-14
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2026-04/SaturnProtocol_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20260414-saturnprotocol
- Tags: domain:web3 impact:dos impact:funds-loss kind:incident platform:defihacklabs sev:critical tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic vuln:dos

**Target:** ERC4626 vault (sUSDat) and SwapFacility conversion logic
**Root cause:** SAT-001: convertFromStrc computes strcBalance - getUnvestedAmount() which underflows (panic 0x11) when queued burns drop strcBalance below unvested rewards. SAT-002: _validateConversion applies toleranceBps=2000 independently to both price and amount checks, compounding to 1-(0.8/1.2)=33.33% extraction.
**Steps:**
1. Fork mainnet; confirm `toleranceBps()` returns 2000 on sUSDat proxy `0xD166...2Df7`.
2. SAT-001: as PROCESSOR call `transferInRewards(strcBalance/2)` to set vestingAmount.
3. As WithdrawQueue call `burnQueuedShares(0, strcBalance+1)` so strcBalance < getUnvestedAmount().
4. Call `convertFromStrc(1,1,100e8)` — reverts with panic 0x11, freezing withdrawals up to vestingPeriod (30 days).
5. SAT-002: as PROCESSOR call `convertFromUsdat` with price at oracle*1.2 and amount at expected*0.8 to extract 33.33% per call.
**How found:** Code review of ERC4626 vault conversion math: noticed getUnvestedAmount() ceiling division subtracted from strcBalance without guard, and that toleranceBps was applied twice (price and amount) rather than once, compounding the allowed deviation.
**Exploitation:** PROCESSOR_ROLE (0x09d6...729f) repeatedly calls convertFromUsdat maximizing both price and amount tolerances to siphon ~33.33% of each conversion; separately routine reward distribution plus queued redemption processing triggers the underflow freeze with no admin escape hatch.
**Escalation:** Repeated convertFromUsdat calls compound extraction; re-calling transferInRewards during freeze extends withdrawal lockout indefinitely.
**Insight:** When a tolerance/ slippage parameter is applied to multiple independent checks, multiply the deviations rather than assuming a single bound; and audit subtraction of time-prorated vesting amounts against mutable balances for underflow after external burns.
