Skip to content

StabilityPool

Overview

StabilityPool is a core contract of the RAAC protocol that acts as the first line of defence for the LendingPool during liquidations. Users can deposit rToken (currently rcrvUSD) into the pool and receive a 1 : 1 representation called deToken. These deposits are used to repay the debt of unhealthy borrowers that are liquidated through a dedicated strategy contract.

In return, depositors maintain exposure to the underlying rToken and can withdraw it at any time while the contract is not paused.

Token Mechanics & Yield Distribution

The StabilityPool maintains a 1:1 relationship between rToken and deToken:

  • rToken is the yield-bearing token deposited by users
  • deToken is the representation token minted 1:1 for deposits
  • deToken increases in value as the underlying rToken accrues yield from the lending pool
  • This ensures depositors earn the normal yield from the lending pool while maintaining their position in the StabilityPool

Staking deToken for Additional Yield

After receiving deToken from the StabilityPool, users can further stake their deToken in the Curve lending pool.
This provides exposure to Curve LP tokens, which can then be staked in the RAAC Gauge to earn protocol emissions and rental yield.
This layered staking approach allows depositors to maximize their yield by participating in both Curve and RAAC incentive programs.

Flow:

  1. Deposit rToken into StabilityPool → receive deToken (1:1)
  2. Stake deToken in Curve lending pool → receive Curve LP tokens
  3. Stake Curve LP tokens in RAAC Gauge → earn emissions & rental yield

This mechanism is optional and designed for users seeking additional yield opportunities beyond the base StabilityPool rewards.


Purpose

  • Accept user deposits of rToken and issue deToken (1 : 1 peg)
  • Provide liquidity that covers borrower debt during liquidations
  • Delegate the actual liquidation logic to the liquidation module
  • Maintain a list of managers allowed to trigger liquidations
  • Route seized collateral to the RWA Vault and handle accounting via the Treasury contract
  • Support flexible configuration of how collateral proceeds are split (mint, burn, swap, liquidity)

Manager-Only Liquidations & No Incentives

Only delegated managers (not the general public) are permitted to trigger liquidations in the StabilityPool.
There is no direct incentivization for performing liquidations—this is a deliberate design choice due to the large size and complexity of the underlying assets.

Liquidations are expected to be carried out timely by managers to ensure sufficient liquidity is available in the Curve LP to process liquidations efficiently.
Managers are responsible for monitoring the system and considering factors such as gas fees and current slippage before executing a liquidation.
This approach helps maintain protocol stability and avoids unnecessary or poorly-timed liquidations that could negatively impact the system or its users.

Withdrawal Timelock Mechanism

The StabilityPool implements a withdrawal timelock to prevent panic withdrawals during liquidations:

  • Users must request withdrawal via requestWithdraw() before they can withdraw
  • A timelock duration must pass before the withdrawal becomes available
  • Users have a limited time window to execute their withdrawal after the timelock expires
  • Depositing cancels any pending withdrawal request
  • This mechanism ensures liquidity stability during critical liquidation periods

Timelock Configuration: - withdrawTimelockDuration: Time before withdrawal becomes available (default: 30 minutes) - withdrawTimelockDelay: Time window to execute withdrawal after timelock expires (default: 2 days) - Both parameters are configurable by the owner


Key Functions

Function Description Access Parameters
initialize Initializes the upgradeable proxy instance initializer _rToken, _deToken, _crvUSDToken, _lendingPool, _treasury, _liquidationStrategyProxy, _initialOwner
deposit Deposit rToken and mint the same amount of deToken public scaledAmount – rToken to deposit (scaled amount from RToken.balanceOf)
requestWithdraw Request withdrawal with timelock to prevent panic withdrawals during liquidations public amount – deToken amount to withdraw (0 to cancel)
withdraw Burn deToken and withdraw the same amount of rToken (after timelock expires) public deTokenAmount – deToken to burn
liquidateBorrower Delegate call to the liquidation module to liquidate unhealthy positions manager or owner poolAdapter, vaultAdapter, user, data, minSharesOut
collectDust Collect dust tokens from the stability pool owner token, recipient, amount
setRWAVault Update the vault receiving seized collateral owner _rwaVault
setLiquidationModule Update liquidation module owner _liquidationProxy
setLiquidationVaultTokenSplit Configure split of liquidation proceeds (mint/burn/swap/liquidity). Must sum to 10000 bps manager or owner mintBps, burnBps, swapBps, liquidityBps
setLiquidationSwap Update contract used for swapping collateral owner _liquidationSwap
setFeeCollector Update the fee collector address owner _feeCollector
setWithdrawTimelockDuration Set the duration of the withdrawal timelock owner _withdrawTimelockDuration
setWithdrawTimelockDelay Set the delay period for withdrawal timelock expiration owner _withdrawTimelockDelay
addManager Grant manager rights owner manager
removeManager Revoke manager rights owner manager
pause / unpause Emergency circuit-breaker owner
View Functions Query manager list, deposits, balances, and timelock status view

Accounting Simplicity

deToken is always minted/burned 1 : 1 with rToken, ensuring no internal exchange rate math or interest accrual.


View Functions

Function Description Parameters Returns
getManagerList Get list of all manager addresses address[] – manager list
isAddressManager Check if an address is a manager manager – address to check bool – true if manager
getUserDeposit Get deposit amount for a specific user user – user address uint256 – deposit amount
getTotalDeposits Get total deposits in the pool uint256 – total deposits
balanceOf Get balance of a user (alias for getUserDeposit) user – user address uint256 – user balance
getPoolIndex Get current pool index from lending pool uint256 – pool index
getRawTotalDeposits Get raw total supply of deToken uint256 – raw total
getUserIndex Get user's index for interest calculation user – user address uint256 – user index
getScaledDeposit Get scaled deposit amount for a user (with interest) user – user address uint256 – scaled amount
isUserDepositInSameBlock Check if user deposited in the current block (prevents same-block withdraw) user – user address bool – true if same block

Expand to View Implementation Details
  • Built with OpenZeppelin’s upgradeable modules: Initializable, OwnableUpgradeable, PausableUpgradeable.
  • Protected with ReentrancyGuard.
  • Uses SafeERC20 for secure transfers.
  • Liquidations executed via delegatecall to the liquidation module → upgradeable strategies without fund migration.
  • Manager addresses stored on-chain for easy enumeration.
  • Configurable LiquidationVaultTokenSplit provides flexible handling of collateral proceeds.
Expand to View Interactions
  • RToken: ERC20 deposited by users (e.g. rcrvUSD)
  • DEToken: ERC20 representing depositor shares
  • LendingPool: queried for borrower debt
  • Liquidation Module: delegate-called liquidation logic
  • Treasury: receives protocol fees
  • RWA Vault: stores seized collateral (NFTs/tokens)
  • Compliance Registry: blocks blacklisted addresses

Additional Features & Notes

  1. Upgradeable & Pausable – owner can pause all state-changing functions.
  2. Manager Role – multiple addresses can act on behalf of the pool without ownership transfer.
  3. 1 : 1 Accounting – deToken ↔ rToken peg is fixed.
  4. Flexible Liquidation Flow – new strategies can be deployed with no downtime.
  5. Withdrawal Timelock – prevents panic withdrawals during liquidations.
  6. Dust Collection – owner can collect excess tokens (only delta between deToken and rToken for rToken).
  7. Same-Block Protection – prevents deposit and withdrawal in the same block.
  8. Compliance Integration – blacklisted addresses cannot interact with the pool.

Liquidation Responsibility

Liquidation is only triggered through the liquidation module. Managers and owners must ensure correct configuration, as seized collateral flows directly to the RWA Vault.

Dust Collection Safety

The collectDust function has built-in safety for rToken: - Only the delta between deToken total supply and rToken balance can be collected - This prevents accidental removal of user funds - Other tokens can be collected in full (use with caution)