PoolManager - Collateral Pools
Contract corresponding to the collateral pools of the protocol

1. Introduction

PoolManager contracts each correspond to a collateral pool of the protocol for a stablecoin of the protocol. Each contract manages a single ERC20 token. If the protocol has two stablecoins agUSD and agEUR each accepting USDC as collateral, then there will be two different PoolManager contracts: one for the USDC/agUSD pair, and one for the USDC/agEUR pair.
The collateral from each mint, deposit, openPerpetual or addToPerpetual transaction goes to this contract.
Angle lends part of its reserves, and handles lending at the PoolManager level. Each PoolManager manages its own internal collateral via strategies voted by the DAO. Those strategies are inspired from Yearn instead of interacting directly with Yearn. This choice was made for the protocol to keep full control on its reserves by removing a third party integration. PoolManager then reports back to StableMaster its gains accumulateInterest() or losses signalLoss().
This contract does not contain any state-changing externally available function.
The PoolManager contract is also the hub when it comes to transmitting changes to all the contracts that are concerned by stablecoin/collateral pair. For instance, if there is a change in a guardian address, then the PoolManager contract is the one propagating this change to the PerpetualManager , FeeManager and Strategy contracts.

2. Contract Details


Implements FunctionUtils, AccessControlUpgradeableand IPoolManager. The contract is upgradeable.


Immutable Parameters and References

  • token: Interface for the underlying token accepted by this contract, it cannot be modified
  • perpetualManager: Reference to the PerpetualManager for this collateral/stablecoin pair
  • stableMaster: Reference to the StableMaster contract corresponding to this PoolManager

Mutable Reference

  • feeManager: FeeManager contract for this collateral/stablecoin pair

Yield Strategy Parameters

  • strategies: All strategies invested in by the PoolManager. They are represented by a struct with the following parameters:
    • lastReport: Last time the strategy updated its position
    • totalStrategyDebt: Debt owed by the strategy to the PoolManager
    • debtRatio: The share of the total assets that the strategy has access to
  • totalDebt: Total amount lent by PoolManager to all strategies
  • debtRatio: Proportion of the funds managed dedicated to strategies
  • strategyList: List of the current strategies

Access Control


3. Key Mechanisms & Concepts

Getters - View Functions


function getBalance() external view returns (uint256);
Gets the current balance of this collateral manager. This balance does not take into account what has been lent to other protocols, and the function just returns the amount of underlying collateral that the contract currently owns.


function getTotalAsset() external view returns (uint256);
Gets the total amount of collateral that is controlled by this collateral manager. It includes the current balance of the protocol plus what has been lent to other protocols / strategies.


function estimatedAPR() external returns(uint256 apr);
Provides an estimated Annual Percentage Rate for SLPs based on lending to other protocols. This function is an estimation and is made for external use only. It does not take into account transaction fees which accrue to SLPs too.
This can be manipulated by a flash loan attack (SLP deposit/ withdraw) via _getTotalAssetwhen entering yous should make sure this hasn't be called by a flash loan and look at a mean of past APR.

StableMaster Functions

The following functions can only be called by the StableMaster contract propagating changes to its underlying contracts. The PoolManager takes into account these changes before propagating it to the underlying contracts.


function addGovernor(address _governor) external;
Adds a new governor address and echoes it to other contracts


function removeGovernor(address _governor) external;
Removes a governor address and echoes it to other contracts


function setGuardian(address _guardian, address guardian) external;
Changes the guardian address and echoes it to other contracts that interact with this manager
  • _guardian: New guardian address
  • guardian: Old guardian address to revoke


function revokeGuardian(address guardian) external;
Revokes the guardian address and echoes the change to other contracts that interact with this manager.


function setFeeManager(IFeeManager _feeManager) external;
Allows to propagate the change of keeper for the collateral/stablecoin pair

Governor-Only Function


function transferToSettlement(address tokenAddress, address to, uint256 amountToRecover) external;
Allows to recover any ERC20 token, including the token handled by this contract, and to send it to a contract.
As this function can be used to transfer funds to another contract, it is a GOVERNOR function.
In case the concerned token is the specific token handled by this contract, this function checks that the amount entered is not too big and approximates the surplus of the protocol. To esimate the amount of user claims on the concerned collateral, this function uses the stocksUsers for this collateral, but this is just an approximation as users can claim the collateral of their choice provided that they own a stablecoin.
  • tokenAddress: Address of the token to recover
  • to Address of the contract to send collateral to
  • amountToRecover: Amount of collateral to transfer

Guardian-Only Functions - Strategy Interactions

The following functions can only be called by an address having the GUARDIAN_ROLE, which means the DAO or the multisig if not yet revoked.


function updateStrategyDebtRatio(address strategy, uint256 _debtRatio) external;
Modifies the portion of the debt dedicated to the funds a strategy has access to.
The update has to be such that the debtRatio does not exceeds the 100% threshold as the manager cannot lend collateral that it does not own.
  • strategy: The address of the Strategy
  • _debtRatio: The share of the total assets that the strategy has access to


function setStrategyEmergencyExit(address strategy) external;
Triggers an emergency exit for a strategy and then harvests it to fetch all the funds


function addStrategy(address strategy, uint256 _debtRatio) external;
Implements the new strategy for the PoolManager. Multiple checks are made such that the contract must not already belong to the PoolManager but also that the tokens considered are consistent in both strategy and PoolManager contracts.
  • strategy: The address of the Strategy to add
  • _debtRatio: The share of the total assets that the strategy has access to


function revokeStrategy(address strategy) external;
Revokes the Strategy from PoolManager strategies. The normal way to revoke a strategy should go through in order:
  1. 1.
    strategy.debtRatio is set to 0.
  2. 2.
    strategy.harvest() has been called enough time to recover all capital gain/losses and the initial capital.
  3. 3.
    revokeStrategy() is called .
  • strategy: The address of the Strategy to revoke


function withdrawFromStrategy(IStrategy strategy, uint256 amount) external;
Withdraws a given amount from a Strategy. It may not recover amount from the strategy, as we may not be able to withdraw from the lending protocol the full amount. In this last case we only update the parameters by setting the loss as the gap between what has been asked and what has been returned.
  • strategy: The address of the Strategy
  • amount: The amount to withdraw

Strategy-Only Functions

The following functions can only be called by a Strategy or will only make sense if they are called by one of them. They are used by the strategies related to this PoolManager to either query information from the PoolManager or transmits information to it.


function creditAvailable() external returns(uint256);
Tells a strategy how much it can borrow from this PoolManager. Since this function is a view function, there is no need to have an access control logic.


function debtOutstanding() external returns(uint256);
Tells a strategy how much it owes to this PoolManager


function report(uint256 gain, uint256 loss, uint256 debtPayment) external;
Reports the gains or losses made by a strategy. This is the main contact point where the strategy interacts with the PoolManager. The strategy reports back what it has free, then the PoolManager contract "decides" whether to take some back or give it more. Note that the most it can take is gain + _debtPayment, and the most it can give is all of the remaining reserves. Anything outside of those bounds is abnormal behavior.
  • gain: Amount strategy has realized as a gain on its investment since its last report, and is free to be given back to PoolManager as earnings
  • loss: Amount strategy has realized as a loss on its investment since its last report, and should be accounted for on the PoolManager's balance sheet. The loss will reduce the debtRatio. The next time the strategy will harvest, it will pay back the debt in an attempt to adjust to the new debt limit.
  • debtPayment: Amount strategy has made available to cover outstanding debt