Reactor - Yield on Idle Treasury Assets
Reactor - Yield on idle treasury assets
This contract associated to Angle Borrowing Module is not yet available and will soon be open-sourced.

1. Introduction

Reactor contracts are contracts which allow people to deposit collateral which is then automatically added in a vault, and used to borrow stablecoins. They all work with an associated VaultManager and rely on a specific yield strategy on the borrowed stablecoins. Yield obtained is then split between the protocol and depositors of collateral.
The idea is that Reactor contracts should mostly be used for more risky collateral assets and VaultManager, for which only whitelisted addresses can open vaults and borrow stablecoins.
The advantage of using Reactor contracts rather than directly the VaultManager is that there is a bigger protection against liquidations. Debt position is directly managed by the Reactor which can pull agTokens invested in strategies as needed if the position is getting close to liquidation, or which can borrow more agTokens for more yield if position is getting healthy.
All such contracts implement a common BaseReactor contract, which conforms to the IERC4626 for yield bearing assets. Yield from these contracts is given in stablecoins.

2. Contract Details


Implements ERC20, IERC4626, IERC721ReceiverUpgradeable.


  • asset: Reference to the asset controlled by this reactor. It should be the collateral of the associated `VaultManager``
  • stablecoin: Reference to the stablecoin this reactor handles
  • oracle: Oracle giving the price of the asset with respect to the stablecoin
  • treasury: Treasury contract handling access control
  • vaultManager: VaultManager contract on which this contract has a vault. While the oracle and treasury references can be automatically fetched from this address
  • vaultID: ID of the vault handled by this contract. Reactor contract only handle one specific vault
  • vaultManagerDust: Dust parameter for the stablecoins in a vault in VaultManager


  • lowerCF: Lower value of the collateral factor (inverse of the collateral ratio), below this value, the reactor can borrow stablecoins
  • targetCF: Value of the collateral factor targeted by this vault. Each time the reactor borrows or repays stablecoins, it tries to arrive at this target value
  • upperCF: Value of the collateral factor above which stablecoins should be repaid to avoid liquidations
  • surplusManager: Address in charge of the surplus of the protocol
  • protocolInterestShare: Share of the gains going to the protocol


  • protocolInterestAccumulated: Protocol fee surplus
  • protocolDebt: Loss accumulated and to be repercuted on the protocol's P&L
  • claimableRewards: Rewards (in stablecoin) claimable by depositors of the reactor
  • currentLoss: Loss (in stablecoin) accumulated by the reactor: it's going to prevent the reactor from repaying its debt
  • rewardsAccumulator: Used to track rewards accumulated by all depositors of the reactor
  • claimedRewardsAccumulator: Tracks rewards already claimed by all depositors
  • lastTime: Last time rewards were claimed in the reactor
  • lastDebt: Last known stable debt to the VaultManager


  • lastTimeOf: Maps an address to the last time it claimed its rewards
  • rewardsAccumulatorOf: Maps an address to a quantity depending on time and shares of the reactors used to compute the rewards an address can claim

3. Key Mechanisms & Concepts

IERC4626 Functions

This contract contains all the common functions of the IERC4626 interface, such as deposit, mint, withdraw, redeem, previewMint, ...
Some things to note is that upon calling one of the deposit, mint, withdraw or redeem functions, the contract automatically rebalances the strategy which means that it automatically deposits or withdraws collateral from the VaultManager and then pushes or pulls funds from or to the strategy. The withdrawal functions also automatically claim stablecoin rewards which accrued to an address.
It is impossible to withdraw more assets than what's in the vault. As such if the vault of the reactor is liquidated, then it is possible that people can only redeem less collateral than what they brought. In this situation, this would be compensated by a stablecoin gain (the stablecoins repaid by the liquidator).
All the logic to interact with vaults goes through the _rebalance internal function (which has a wrapper built on top of).

rebalance Logic

function rebalance() external;
This function rebalances the underlying vault. It calls the internal _rebalance function which is called at each deposit or withdraw function. Based on an amount of assets to withdraw or an amount of assets received (which are 0 when this function is entered through the rebalance function), this function adds or removes collateral from the associated vault of the reactor.
It also computes what could be the amount of stablecoins controlled by the reactor based on the targetCF. If after adding or removing collateral, the collateral factor of the reactor goes above or below the upperCF or the lowerCF, then stablecoins can be actually borrowed/repaid by the reactor.
Borrowed stablecoins are pushed to the yield strategy. Repaid stablecoins are pulled from the yield strategy.

Governance and Keeper Functions

This contract has some functions available for governance and keepers to change some parameters.
There are two permissionless keeper functions to change the reference to the oracle or to the treasury contract, or to change the dust parameter by just reading what's in the associated VaultManager contract:
  • setOracle
  • setTreasury
  • setDust
There is another function callable by anyone to push the fees taken by the protocol to the surplus manager contract: pushProtocolFees.
Other functions available just to governance are:
  • setUint64: to modify collateral factors
  • recoverERC20: to recover tokens mistakenly sent. This function can notably be used to handle partial liquidation and debt repayment in case it is needed: in this case governance can withdraw assets, swap in stablecoins to repay debt
  • setSurplusManager: to change the address responsible for handling the surplus of the protocol