Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

SelfPeggingAsset

Git Source

Inherits: Initializable, ReentrancyGuardUpgradeable, OwnableUpgradeable

Author: Nuts Finance Developer

The SelfPeggingAsset pool provides a way to swap between different tokens

The SelfPeggingAsset contract allows users to trade between different tokens, with prices determined algorithmically based on the current supply and demand of each token

State Variables

FEE_DENOMINATOR

This is the denominator used for calculating transaction fees in the SelfPeggingAsset contract.

uint256 private constant FEE_DENOMINATOR = 10 ** 10;

DEFAULT_FEE_ERROR_MARGIN

This is the maximum error margin for calculating transaction fees in the SelfPeggingAsset contract.

uint256 private constant DEFAULT_FEE_ERROR_MARGIN = 100_000;

DEFAULT_YIELD_ERROR_MARGIN

This is the maximum error margin for calculating transaction yield in the SelfPeggingAsset contract.

uint256 private constant DEFAULT_YIELD_ERROR_MARGIN = 10_000;

MAX_A

This is the maximum value of the amplification coefficient A.

uint256 private constant MAX_A = 10 ** 6;

INITIAL_MINT_MIN

This is minimum initial mint

uint256 private constant INITIAL_MINT_MIN = 100_000;

DEFAULT_DECAY_PERIOD

This is the default decay period

uint256 private constant DEFAULT_DECAY_PERIOD = 5 minutes;

DEFAULT_RATE_CHANGE_SKIP_PERIOD

This is the default rate change skip period

uint256 private constant DEFAULT_RATE_CHANGE_SKIP_PERIOD = 1 days;

tokens

This is an array of addresses representing the tokens currently supported by the SelfPeggingAsset contract.

address[] public tokens;

precisions

This is an array of uint256 values representing the precisions of each token in the SelfPeggingAsset contract. The precision of each token is calculated as 10 ** (18 - token decimals).

uint256[] public precisions;

balances

This is an array of uint256 values representing the current balances of each token in the SelfPeggingAsset contract. The balances are converted to the standard token unit (10 ** 18).

uint256[] public balances;

exchangeRateDecimals

uint256[] public exchangeRateDecimals;

mintFee

This is the fee charged for adding liquidity to the SelfPeggingAsset contract.

uint256 public mintFee;

swapFee

This is the fee charged for trading assets in the SelfPeggingAsset contract. swapFee = swapFee * FEE_DENOMINATOR

uint256 public swapFee;

redeemFee

This is the fee charged for removing liquidity from the SelfPeggingAsset contract. redeemFee = redeemFee * FEE_DENOMINATOR

uint256 public redeemFee;

offPegFeeMultiplier

This is the off peg fee multiplier. offPegFeeMultiplier = offPegFeeMultiplier * FEE_DENOMINATOR

uint256 public offPegFeeMultiplier;

poolToken

This is the address of the ERC20 token contract that represents the SelfPeggingAsset pool token.

ISPAToken public poolToken;

totalSupply

The total supply of pool token minted by the swap. It might be different from the pool token supply as the pool token can have multiple minters.

uint256 public totalSupply;

paused

This is a state variable that represents whether or not the SelfPeggingAsset contract is currently paused.

bool public paused;

A

These is a state variables that represents the amplification coefficient A.

uint256 public A;

rampAController

RampAController contract address for gradual A changes

IRampAController public rampAController;

exchangeRateProviders

Exchange rate provider for the tokens

IExchangeRateProvider[] public exchangeRateProviders;

feeErrorMargin

Fee error margin.

uint256 public feeErrorMargin;

yieldErrorMargin

Yield error margin.

uint256 public yieldErrorMargin;

exchangeRateFeeFactor

The fee factor for rate change fee

uint256 public exchangeRateFeeFactor;

decayPeriod

The time (in seconds) over which the multiplier decays back to 1x after being raised.

uint256 public decayPeriod;

rateChangeSkipPeriod

The time (in seconds) after which the multiplier is skipped when the rate is changed.

uint256 public rateChangeSkipPeriod;

lastActivity

Tracks the last time a transaction occurred in the SelfPeggingAsset contract.

uint256 public lastActivity;

feeStatusByToken

Mapping of token index -> TokenFeeStatus

mapping(uint256 => TokenFeeStatus) public feeStatusByToken;

Functions

syncRamping

modifier syncRamping();

constructor

constructor();

initialize

Initializes the SelfPeggingAsset contract with the given parameters.

function initialize(
    address[] memory _tokens,
    uint256[] memory _precisions,
    uint256[] memory _fees,
    uint256 _offPegFeeMultiplier,
    ISPAToken _poolToken,
    uint256 _A,
    IExchangeRateProvider[] memory _exchangeRateProviders,
    address _rampAController,
    uint256 _exchangeRateFeeFactor,
    address _keeper
)
    public
    initializer;

Parameters

NameTypeDescription
_tokensaddress[]The tokens in the pool.
_precisionsuint256[]The precisions of each token (10 ** (18 - token decimals)).
_feesuint256[]The fees for minting, swapping, and redeeming.
_offPegFeeMultiplieruint256The off peg fee multiplier.
_poolTokenISPATokenThe address of the pool token.
_Auint256The initial value of the amplification coefficient A for the pool.
_exchangeRateProvidersIExchangeRateProvider[]The exchange rate providers for the tokens.
_rampAControlleraddressThe address of the RampAController contract.
_exchangeRateFeeFactoruint256
_keeperaddress

mint

Mints new pool token.

function mint(
    uint256[] calldata _amounts,
    uint256 _minMintAmount
)
    external
    nonReentrant
    syncRamping
    returns (uint256);

Parameters

NameTypeDescription
_amountsuint256[]Unconverted token balances used to mint pool token.
_minMintAmountuint256Minimum amount of pool token to mint.

Returns

NameTypeDescription
<none>uint256The amount of pool tokens minted.

swap

Exchange between two underlying tokens.

function swap(
    uint256 _i,
    uint256 _j,
    uint256 _dx,
    uint256 _minDy
)
    external
    nonReentrant
    syncRamping
    returns (uint256);

Parameters

NameTypeDescription
_iuint256Token index to swap in.
_juint256Token index to swap out.
_dxuint256Unconverted amount of token _i to swap in.
_minDyuint256Minimum token _j to swap out in converted balance.

Returns

NameTypeDescription
<none>uint256Amount of swap out.

redeemProportion

Redeems pool token to underlying tokens proportionally.

function redeemProportion(
    uint256 _amount,
    uint256[] calldata _minRedeemAmounts
)
    external
    nonReentrant
    syncRamping
    returns (uint256[] memory);

Parameters

NameTypeDescription
_amountuint256Amount of pool token to redeem.
_minRedeemAmountsuint256[]Minimum amount of underlying tokens to get.

Returns

NameTypeDescription
<none>uint256[]An array of the amounts of each token to redeem.

redeemSingle

Redeem pool token to one specific underlying token.

function redeemSingle(
    uint256 _amount,
    uint256 _i,
    uint256 _minRedeemAmount
)
    external
    nonReentrant
    syncRamping
    returns (uint256);

Parameters

NameTypeDescription
_amountuint256Amount of pool token to redeem.
_iuint256Index of the token to redeem to.
_minRedeemAmountuint256Minimum amount of the underlying token to redeem to.

Returns

NameTypeDescription
<none>uint256Amount received.

redeemMulti

Redeems underlying tokens.

function redeemMulti(
    uint256[] calldata _amounts,
    uint256 _maxRedeemAmount
)
    external
    nonReentrant
    syncRamping
    returns (uint256[] memory);

Parameters

NameTypeDescription
_amountsuint256[]Amounts of underlying tokens to redeem to.
_maxRedeemAmountuint256Maximum of pool token to redeem.

Returns

NameTypeDescription
<none>uint256[]Amounts received.

setMintFee

Updates the mint fee.

function setMintFee(uint256 _mintFee) external onlyOwner;

Parameters

NameTypeDescription
_mintFeeuint256The new mint fee.

setSwapFee

Updates the swap fee.

function setSwapFee(uint256 _swapFee) external onlyOwner;

Parameters

NameTypeDescription
_swapFeeuint256The new swap fee.

setRedeemFee

Updates the redeem fee.

function setRedeemFee(uint256 _redeemFee) external onlyOwner;

Parameters

NameTypeDescription
_redeemFeeuint256The new redeem fee.

setOffPegFeeMultiplier

Updates the off peg fee multiplier.

function setOffPegFeeMultiplier(uint256 _offPegFeeMultiplier) external onlyOwner;

Parameters

NameTypeDescription
_offPegFeeMultiplieruint256The new off peg fee multiplier.

setExchangeRateFeeFactor

Updates the exchange rate fee factor.

function setExchangeRateFeeFactor(uint256 _exchangeRateFeeFactor) external onlyOwner;

Parameters

NameTypeDescription
_exchangeRateFeeFactoruint256The new exchange rate fee factor.

setDecayPeriod

Updates the decay period.

function setDecayPeriod(uint256 _decayPeriod) external onlyOwner;

Parameters

NameTypeDescription
_decayPerioduint256The new decay period.

setRateChangeSkipPeriod

Updates the rate change skip period.

function setRateChangeSkipPeriod(uint256 _rateChangeSkipPeriod) external onlyOwner;

Parameters

NameTypeDescription
_rateChangeSkipPerioduint256The new rate change skip period.

pause

Pause mint/swap/redeem actions. Can unpause later.

function pause() external onlyOwner;

unpause

Unpause mint/swap/redeem actions.

function unpause() external onlyOwner;

donateD

Update the exchange rate provider for the token.

function donateD(
    uint256[] calldata _amounts,
    uint256 _minDonationAmount
)
    external
    nonReentrant
    syncRamping
    returns (uint256);

updateFeeErrorMargin

update fee error margin.

function updateFeeErrorMargin(uint256 newValue) external onlyOwner;

updateYieldErrorMargin

update yield error margin.

function updateYieldErrorMargin(uint256 newValue) external onlyOwner;

distributeLoss

Distribute losses by rebasing negatively

function distributeLoss() external onlyOwner;

rebase

This function allows to rebase SPAToken by increasing his total supply from the current stableSwap pool by the staking rewards and the swap fee.

function rebase() external syncRamping returns (uint256);

getRedeemSingleAmount

Computes the amount when redeeming pool token to one specific underlying token.

function getRedeemSingleAmount(uint256 _amount, uint256 _i) external view returns (uint256, uint256);

Parameters

NameTypeDescription
_amountuint256Amount of pool token to redeem.
_iuint256Index of the underlying token to redeem to.

Returns

NameTypeDescription
<none>uint256The amount of single token that will be redeemed.
<none>uint256The amount of pool token charged for redemption fee.

getRedeemMultiAmount

Compute the amount of pool token that needs to be redeemed.

function getRedeemMultiAmount(uint256[] calldata _amounts) external view returns (uint256, uint256);

Parameters

NameTypeDescription
_amountsuint256[]Unconverted token balances.

Returns

NameTypeDescription
<none>uint256The amount of pool token that needs to be redeemed.
<none>uint256The amount of pool token charged for redemption fee.

getMintAmount

Compute the amount of pool token that can be minted.

function getMintAmount(uint256[] calldata _amounts) external view returns (uint256, uint256);

Parameters

NameTypeDescription
_amountsuint256[]Unconverted token balances.

Returns

NameTypeDescription
<none>uint256The amount of pool tokens to be minted.
<none>uint256The amount of fees charged.

getSwapAmount

Computes the output amount after the swap.

function getSwapAmount(uint256 _i, uint256 _j, uint256 _dx) external view returns (uint256, uint256);

Parameters

NameTypeDescription
_iuint256Token index to swap in.
_juint256Token index to swap out.
_dxuint256Unconverted amount of token _i to swap in.

Returns

NameTypeDescription
<none>uint256Unconverted amount of token _j to swap out.
<none>uint256The amount of fees charged.

getRedeemProportionAmount

Computes the amounts of underlying tokens when redeeming pool token.

function getRedeemProportionAmount(uint256 _amount) external view returns (uint256[] memory);

Parameters

NameTypeDescription
_amountuint256Amount of pool tokens to redeem.

Returns

NameTypeDescription
<none>uint256[]An array of the amounts of each token to redeem.

getTokens

Returns the array of token addresses in the pool.

function getTokens() external view returns (address[] memory);

getCurrentA

Get the current A value from the controller if set, or use the local value

function getCurrentA() public view returns (uint256);

Returns

NameTypeDescription
<none>uint256The current A value

_updateMultiplierForToken

Updates the fee multiplier for token i if there's a significant rate change.

function _updateMultiplierForToken(uint256 i) internal;

_syncTotalSupply

function _syncTotalSupply() internal;

collectFeeOrYield

Collect fee or yield based on the token balance difference.

function collectFeeOrYield(bool isFee) internal returns (uint256);

Parameters

NameTypeDescription
isFeeboolWhether to collect fee or yield.

Returns

NameTypeDescription
<none>uint256The amount of fee or yield collected.

_currentMultiplier

Computes current multiplier for a given TokenFeeStatus.

function _currentMultiplier(TokenFeeStatus memory st) internal view returns (uint256);

_currentMultiplier

function _currentMultiplier(uint256 index) internal view returns (uint256);

isInactive

Indicates if the pool is inactive based on latest token fee status

function isInactive(uint256 raisedAt) internal view returns (bool);

_volatilityFee

Calculate extra fee from volatility between tokens i, j

function _volatilityFee(uint256 _i, uint256 _j, uint256 _baseFee) internal view returns (uint256);

_volatilityFee

Calculate extra fee from volatility for i

function _volatilityFee(uint256 _i, uint256 _baseFee) internal view returns (uint256);

getUpdatedBalancesAndD

Return the amount of fee that's not collected.

function getUpdatedBalancesAndD() internal view returns (uint256[] memory, uint256);

Returns

NameTypeDescription
<none>uint256[]The balances of underlying tokens.
<none>uint256The total supply of pool tokens.

_updateBalancesForDeposit

Updates token balances for a deposit by adding amounts adjusted for exchange rates and precisions.

function _updateBalancesForDeposit(
    uint256[] memory _balances,
    uint256[] calldata _amounts
)
    internal
    view
    returns (uint256[] memory);

Parameters

NameTypeDescription
_balancesuint256[]Current balances of tokens in the pool.
_amountsuint256[]Amounts of tokens to deposit.

Returns

NameTypeDescription
<none>uint256[]Updated balances after deposit.

_updateBalancesForWithdrawal

Updates token balances for a withdrawal by subtracting amounts adjusted for exchange rates and precisions.

function _updateBalancesForWithdrawal(
    uint256[] memory _balances,
    uint256[] calldata _amounts
)
    internal
    view
    returns (uint256[] memory);

Parameters

NameTypeDescription
_balancesuint256[]Current balances of tokens in the pool.
_amountsuint256[]Amounts of tokens to withdraw.

Returns

NameTypeDescription
<none>uint256[]Updated balances after withdrawal.

_calcSwapFee

Calculates the swap fee based on token balances and dynamic fee adjustment.

function _calcSwapFee(
    uint256 i,
    uint256 j,
    uint256 prevBalanceI,
    uint256 newBalanceI,
    uint256 oldBalanceJ,
    uint256 newBalanceJ,
    uint256 dy
)
    internal
    view
    returns (uint256);

Returns

NameTypeDescription
<none>uint256Fee amount in output token units (token decimals).

_dynamicFee

Calculates the dynamic fee based on liquidity imbalances.

function _dynamicFee(uint256 xpi, uint256 xpj, uint256 _fee) internal view returns (uint256);

Parameters

NameTypeDescription
xpiuint256The liquidity before or first asset liqidity.
xpjuint256The liqduity after or second asset liquidity.
_feeuint256The base fee value.

Returns

NameTypeDescription
<none>uint256The dynamically adjusted fee.

_getD

Computes D given token balances.

function _getD(uint256[] memory _balances, uint256 _A) internal pure returns (uint256);

Parameters

NameTypeDescription
_balancesuint256[]Normalized balance of each token.
_Auint256

Returns

NameTypeDescription
<none>uint256D The SelfPeggingAsset invariant.

_getY

Computes token balance given D.

function _getY(uint256[] memory _balances, uint256 _j, uint256 _D, uint256 _A) internal pure returns (uint256);

Parameters

NameTypeDescription
_balancesuint256[]Converted balance of each token except token with index _j.
_juint256Index of the token to calculate balance.
_Duint256The target D value.
_Auint256

Returns

NameTypeDescription
<none>uint256Converted balance of the token with index _j.

Events

TokenSwapped

This event is emitted when a token swap occurs.

event TokenSwapped(address indexed buyer, uint256 swapAmount, uint256[] amounts, uint256 feeAmount);

Parameters

NameTypeDescription
buyeraddressis the address of the account that made the swap.
swapAmountuint256is the amount of the token swapped by the buyer.
amountsuint256[]is an array containing the amounts of each token received by the buyer.
feeAmountuint256is the amount of transaction fee charged for the swap.

Minted

This event is emitted when liquidity is added to the SelfPeggingAsset contract.

event Minted(address indexed provider, uint256 mintAmount, uint256[] amounts, uint256 feeAmount);

Parameters

NameTypeDescription
provideraddressis the address of the liquidity provider.
mintAmountuint256is the amount of liquidity tokens minted to the provider in exchange for their contribution.
amountsuint256[]is an array containing the amounts of each token contributed by the provider.
feeAmountuint256is the amount of transaction fee charged for the liquidity provision.

Donated

This event is emitted when liquidity is added to the SelfPeggingAsset contract.

event Donated(address indexed provider, uint256 mintAmount, uint256[] amounts);

Parameters

NameTypeDescription
provideraddressis the address of the liquidity provider.
mintAmountuint256is the amount of liquidity tokens minted to the provider in exchange for their contribution.
amountsuint256[]is an array containing the amounts of each token contributed by the provider.

Redeemed

This event is emitted when liquidity is removed from the SelfPeggingAsset contract.

event Redeemed(address indexed provider, uint256 redeemAmount, uint256[] amounts, uint256 feeAmount);

Parameters

NameTypeDescription
provideraddressis the address of the liquidity provider.
redeemAmountuint256is the amount of liquidity tokens redeemed by the provider.
amountsuint256[]is an array containing the amounts of each token received by the provider.
feeAmountuint256is the amount of transaction fee charged for the liquidity provision.

FeeCollected

This event is emitted when transaction fees are collected by the SelfPeggingAsset contract.

event FeeCollected(uint256 feeAmount, uint256 totalSupply);

Parameters

NameTypeDescription
feeAmountuint256is the amount of fee collected.
totalSupplyuint256is the total supply of SPA token.

YieldCollected

This event is emitted when yield is collected by the SelfPeggingAsset contract.

event YieldCollected(uint256 feeAmount, uint256 totalSupply);

Parameters

NameTypeDescription
feeAmountuint256is the amount of yield collected.
totalSupplyuint256is the total supply of SPA token.

RampAControllerUpdated

This event is emitted when the RampAController is set or updated.

event RampAControllerUpdated(address indexed _rampAController);

MintFeeModified

This event is emitted when the mint fee is modified.

event MintFeeModified(uint256 mintFee);

Parameters

NameTypeDescription
mintFeeuint256is the new value of the mint fee.

SwapFeeModified

This event is emitted when the swap fee is modified.

event SwapFeeModified(uint256 swapFee);

Parameters

NameTypeDescription
swapFeeuint256is the new value of the swap fee.

RedeemFeeModified

This event is emitted when the redeem fee is modified.

event RedeemFeeModified(uint256 redeemFee);

Parameters

NameTypeDescription
redeemFeeuint256is the new value of the redeem fee.

OffPegFeeMultiplierModified

This event is emitted when the off peg fee multiplier is modified.

event OffPegFeeMultiplierModified(uint256 offPegFeeMultiplier);

Parameters

NameTypeDescription
offPegFeeMultiplieruint256is the new value of the off peg fee multiplier.

FeeMarginModified

This event is emitted when the fee margin is modified.

event FeeMarginModified(uint256 margin);

Parameters

NameTypeDescription
marginuint256is the new value of the margin.

YieldMarginModified

This event is emitted when the fee margin is modified.

event YieldMarginModified(uint256 margin);

Parameters

NameTypeDescription
marginuint256is the new value of the margin.

ExchangeRateFeeFactorModified

This event is emitted when the exchange rate fee factor is modified.

event ExchangeRateFeeFactorModified(uint256 factor);

Parameters

NameTypeDescription
factoruint256is the new value of the factor.

DecayPeriodModified

This event is emitted when the decay period is modified.

event DecayPeriodModified(uint256 decayPeriod);

Parameters

NameTypeDescription
decayPerioduint256is the new value of the decay period.

RateChangeSkipPeriodModified

This event is emitted when the rate change skip period is modified.

event RateChangeSkipPeriodModified(uint256 rateChangeSkipPeriod);

Parameters

NameTypeDescription
rateChangeSkipPerioduint256is the new value of the rate change skip period.

PoolPaused

This event is emitted when the pool is paused.

event PoolPaused();

PoolUnpaused

This event is emitted when the pool is unpaused.

event PoolUnpaused();

Errors

InputMismatch

Error thrown when the input parameters do not match the expected values.

error InputMismatch();

NoFees

Error thrown when fees are not set

error NoFees();

FeePercentageTooLarge

Error thrown when the fee percentage is too large.

error FeePercentageTooLarge();

TokenNotSet

Error thrown when the token address is not set.

error TokenNotSet();

ExchangeRateProviderNotSet

Error thrown when the exchange rate provider is not set.

error ExchangeRateProviderNotSet();

PrecisionNotSet

Error thrown when the precision is not set.

error PrecisionNotSet();

DuplicateToken

Error thrown when the tokens are duplicates.

error DuplicateToken();

PoolTokenNotSet

Error thrown when the pool token is not set.

error PoolTokenNotSet();

ANotSet

Error thrown when the A value is not set.

error ANotSet();

InvalidAmount

Error thrown when the amount is invalid.

error InvalidAmount();

Paused

Error thrown when the pool is paused.

error Paused();

ZeroAmount

Error thrown when the amount is zero.

error ZeroAmount();

SameToken

Error thrown when the token is the same.

error SameToken();

InvalidIn

Error thrown when the input token is invalid.

error InvalidIn();

InvalidOut

Error thrown when the output token is invalid.

error InvalidOut();

InvalidMins

Error thrown when the amount is invalid.

error InvalidMins();

InvalidToken

Error thrown when the token is invalid.

error InvalidToken();

LimitExceeded

Error thrown when the limit is exceeded.

error LimitExceeded();

NotPaused

Error thrown when the pool is not paused.

error NotPaused();

NoLosses

Error thrown when there is no loss

error NoLosses();

InsufficientDonationAmount

Error thrown donation amount is insufficient

error InsufficientDonationAmount();

InsufficientMintAmount

Error thrown insufficient mint amount

error InsufficientMintAmount(uint256 mintAmount, uint256 minMintAmount);

InsufficientSwapOutAmount

Error thrown insufficient swap out amount

error InsufficientSwapOutAmount(uint256 outAmount, uint256 minOutAmount);

InsufficientRedeemAmount

Error thrown insufficient redeem amount

error InsufficientRedeemAmount(uint256 redeemAmount, uint256 minRedeemAmount);

MaxRedeemAmount

Error thrown when redeem amount is max

error MaxRedeemAmount(uint256 redeemAmount, uint256 maxRedeemAmount);

Structs

TokenFeeStatus

*Data structure for each token's fee status:

  • lastRate: last recorded exchange rate for this token.
  • multiplier: current multiplier (scaled by FEE_DENOMINATOR).
  • raisedAt: timestamp when the multiplier was last raised.*
struct TokenFeeStatus {
    uint256 lastRate;
    uint256 multiplier;
    uint256 raisedAt;
}