Collateral Settler - Revoking a Collateral
Letting stable holders, HAs and SLPs claim and redeem a portion of remaining collateral

1. Introduction

The CollateralSettlerERC20 is here to settle the positions associated to a collateral for a given stablecoin if this collateral is revoked for this stablecoin. If a collateral is revoked for a stablecoin, it means that SLPs and HAs cannot open or close their positions on it and that it is impossible to use it to issue stablecoins or to redeem this collateral against the stablecoin.
To start working, a CollateralSettlerContract must be activated by the StableMaster which freezes oracle values for HAs and exchange rates for SLPs.
After trigger, the collateral settlement works in two periods: the claim period and the redeem period. In the claim period, user can send their agTokens, SLPs can send their sanTokens, and HAs can simply notify that they own a perpetual. They can also send governance tokens along with that to see a portion of their claim being treated preferably. In the case of HAs and SLPs, the contract computes the value of the claim in the collateral that is being settled. In the case of users, the contract just stores the amount of stablecoins sent.
After this period and after having converted user claims in stablecoins to a collateral value using a fresher oracle value, the contract computes the total amount of claims and computes a base amount to redistribute to each type of actor based on how much is to distribute and then everyone can come and redeem what is owed to them. In the computation of the base amount to each category, users with just governance token claims, then users, then LPs with governance token claims and last simple LPs are handled in this order. If a category cannot be reimbursed its full claim, then the following category cannot redeem any collateral.
Note that this contract is also involved for the emergency shutdown process of a stablecoin: this process can indeed be seen as a collateral settlement for all the accepted collateral types of the protocol. The thing is that, in this situation, owners of stablecoins can come and redeem the collateral of their choice, meaning every token holders could redeem the same collateral thus affecting SLPs and HAs for this collateral but enabling SLPs and HAs of other collateral types to get their full claim or at least a higher portion of it. In such a rare event, some off-chain coordination would be required to make sure that there are no large imbalances as for where stable holders redeem collateral. To prevent such events where users all claim the same collateral, this contract is pausable.

2. Contract Details


Implements ICollateralSettler, Pausable and AccessControl.


References to Contracts

The following contracts correspond to the contracts associated to the collateral that is closed
  • perpetualManager : Address of the PerpetualManager
  • sanToken: Address of the SanToken
  • agToken: Address of the AgToken
  • poolManager: Address of the PoolManager
  • underlyingToken: Collateral of interest
  • angle: Governance token of the protocol
  • oracle: Address of the Oracle contract corresponding to the pool being closed. It is used to fetch the price at which stablecoins are going to be converted in collateral at the end of the settlement period
  • collatBase: this is not a reference to a contract, but this represents the base used in the collateral implementation

Governance Parameters

The following parameters have to be chosen by governance before the activation of the contract:
  • proportionalRatioGovUser: Used to compute the portion of the user claim that is going to be considered as a claim for governance tokens for a unit amount of governance tokens brought. This ratio should be between an amount of governance tokens and an amout of stablecoins
  • proportionalRatioGovLP: Used to compute the portion of the HA or SLP claim that is going to be considered as a claim for governance tokens for a unit amount of governance tokens brought
  • claimTime: Time after the trigger in which users and LPs can come and claim their collateral

Activation Variables

The following variables are set when the contract is activated by the triggerSettlement function, they cannot be changed after that.
  • oracleValueHA: Value of the oracle at settlement trigger time used to compute HA claims
  • sanRate: Exchange rate between sanTokens and collateral at settlement trigger time
  • maxStablecoinsClaimable: Maximum number of stablecoins that can be claimed using this collateral type. The reason for this parameter is that in case of generalized collateral settlement where all collateral types are settled, it prevents users from all claiming the same collateral thus penalizing HAs and SLPs of this collateral and advantaging HAs and SLPs of other collateral types. This parameter is set equal to the stocksUsers for this collateral type at the time of activation
  • amountToRedistribute: Total amount of collateral to redistribute. This parameter can still be adjusted by governance during the claim period
  • startTimestamp : Time at which settlement was triggered
  • oracleValueUsers: This value is not defined at the activation of the contract, it is just computed at the end of the claim period. It is the value of the oracle used to settle users. The reason for using a different value than for HAs is that the real value of the oracle could change during the claim time. In case of the revokation of a single collateral, there could be if we used the same value as HAs arbitrages among users seeing that the value of the oracle at which they are going to be settled differ from the current oracle value. Or in case of multiple collateral being revoked at the same time, users could see a bargain in a collateral and all come to redeem one collateral in particular

Accounting Variables

The following variables are here to help keep track of the claims of each user and to be able to compute how much each one is going to get once claim period is done. Here in the term LP, both SLPs and HAs are included.
  • totalUserClaims: Sum of the claims of users which did not bring governance tokens (expressed in stablecoin value)
  • totalUserClaimsWithGov: Sum of the claims of users which brought governance tokens (expressed in stablecoin value)
  • totalLpClaims: Sum of the claims from LPs (expressed in collateral)
  • totalLpClaimsWithGov: Sum of the claims from LPs which had governance tokens (expressed in collateral)
  • baseAmountToUserGov: Ratio between what can be given and the claim for each user with gov tokens. It is going to be updated (like the quantities below) at the end of the claim period.
  • baseAmountToUser: Ratio between what can be given and the claim for each user
  • baseAmountToLpGov: Ratio between what can be given and the claim for each LP with gov tokens
  • baseAmountToLp: Ratio between what can be given and the claim for each LP
  • baseAmountToEachComputed: Number to see if the setAmountToRedistributeEach function has already been called. This function can only be called once throughout the lifetime of the contract


  • userClaims: Mapping between an address and a claim (in collateral) for a stable holder
  • userClaimsWithGov: Mapping between an address and a claim and number of gov tokens due to a user
  • lpClaims: Mapping between the address of a LP and a claim
  • lpClaimsWithGov: Mapping between the address of a LP, its claim and the number of gov tokens brought
  • haClaimCheck: Mapping to check whether a HA perpetual has already been redeemed

Access Control

  • GOVERNOR_ROLE: Given the importance of collateral settlement for the protocol and the need for decentralization in the process, it would not make sense to introduce a GUARDIAN_ROLE here
  • STABLEMASTER_ROLE: The StableMaster contract is the only one able to activate the contract

3. Key Mechanisms & Concepts

Activation Function


function triggerSettlement(uint256 _oracleValue, uint256 _sanRate, uint256 _stocksUsers) external;
Activates settlement for this contract and stores the activation values. This function is to be called by the StableMaster contract after governance called revokeCollateral
  • _oracleValue: Value of the oracle that will be used for the settlement to get the price of the concerned collateral with respect to that of the stablecoin
  • _sanRate: Value of the sanRate at time of settlement to be able to convert an amount of sanTokens to an amount of collateral
  • _stocksUsers: Maximum amount of stablecoins that will be redeemable by users for this collateral

Claim Functions


function claimUser(address dest, uint256 amountAgToken, uint256 amountGovToken) external;
Allows a user to claim collateral for a dest address by sending agTokens and gov tokens (optional). The more gov tokens a user sent, the more preferably it ends up being treated during the redeem period
  • dest: Address of the user to claim collateral for
  • amountAgToken: Amount of agTokens sent
  • amountGovToken: Amount of governance sent


function claimHA(uint256 perpetualID, uint256 amountGovToken) external;
Allows a HA to claim collateral by sending a perpetualID and gov tokens (optional). The contract automatically recognizes the beneficiary of the perpetual.
If the perpetual of the HA should be liquidated then, this HA will not be able to get a claim on the remaining collateral.
  • perpetualID: Perpetual owned by the HA
  • amountGovToken: Amount of governance sent


function claimSLP(address dest, uint256 amountSanToken, uint256 amountGovToken) external;
Allows a SLP to claim collateral for an address dest by sending sanTokens and gov tokens (optional).
  • dest: Address to claim collateral for
  • amountSanToken: Amount of sanTokens sent
  • amountGovToken: Amount of governance tokens sent

Redeem Functions


function setAmountToRedistributeEach() external;
Computes the base amount each category of claim will get after the claim period has ended. This function can only be called once. It is at the level of this function that the waterfall between the different categories of stakeholders and of claims is executed.


function redeemCollateral() external;
Lets a user or a LP redeem the corresponding share of collateral. This function will need to be called after the setAmountToRedistributeEach function has been called. The entry point to redeem is the same for users, HAs and SLPs.
A user, HA or SLP will obviously be able to redeem only once its collateral.

Governance Functions

The following functions are only callable by governance:


function setAmountToRedistribute(uint256 newAmountToRedistribute) external;
Changes the amount that can be redistributed with this contract. This function should typically be called after the settlement trigger if this contract receives more collateral.


function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external;
Recovers leftover tokens from the contract or tokens that were mistakenly sent to the contract. It can be used after the setAmountToDistributeEach function has been called to allocate the surplus of the contract elsewhere.
  • tokenAddress: Address of the token to recover
  • to: Address to send the remaining tokens to
  • amountToRecover: Amount to recover from the contract


function setProportionalRatioGov(uint64 _proportionalRatioGovUser, uint64 _proportionalRatioGovLP) external;
Changes the proportion of governance tokens ratio that should be used to compute the claims with governance tokens. This function can only be called before the contract is activated
  • _proportionalRatioGovUser: New ratio for users
  • _proportionalRatioGovLP: New Ratio for LPs (both SLPs and HAs)


function pause() external;
Pauses pausable methods, that is all the claim and redeem methods.


function unpause() external;
Unpauses paused methods.