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;

DEFAULT_MAX_DELTA_D

This is the maximum error margin for updating A in the SelfPeggingAsset contract.

uint256 private constant DEFAULT_MAX_DELTA_D = 100_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;

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;

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.

ILPToken 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;

admins

This is a mapping of accounts that have administrative privileges over the SelfPeggingAsset contract.

mapping(address => bool) public admins;

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;

exchangeRateProviders

Exchange rate provider for the tokens

IExchangeRateProvider[] public exchangeRateProviders;

feeErrorMargin

Fee error margin.

uint256 public feeErrorMargin;

yieldErrorMargin

Yield error margin.

uint256 public yieldErrorMargin;

maxDeltaD

Max delta D.

uint256 public maxDeltaD;

Functions

initialize

Initializes the SelfPeggingAsset contract with the given parameters.

function initialize(
    address[] memory _tokens,
    uint256[] memory _precisions,
    uint256[] memory _fees,
    uint256 _offPegFeeMultiplier,
    ILPToken _poolToken,
    uint256 _A,
    IExchangeRateProvider[] memory _exchangeRateProviders
)
    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.
_poolTokenILPTokenThe address of the pool token.
_Auint256The initial value of the amplification coefficient A for the pool.
_exchangeRateProvidersIExchangeRateProvider[]

mint

Mints new pool token.

function mint(uint256[] calldata _amounts, uint256 _minMintAmount) external nonReentrant 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 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
    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 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
    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.

pause

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

function pause() external;

unpause

Unpause mint/swap/redeem actions.

function unpause() external;

setAdmin

Updates the admin role for the address.

function setAdmin(address _account, bool _allowed) external onlyOwner;

Parameters

NameTypeDescription
_accountaddressAddress to update admin role.
_allowedboolWhether the address is granted the admin role.

updateA

Update the A value.

function updateA(uint256 _A) external onlyOwner;

Parameters

NameTypeDescription
_Auint256The new A value.

donateD

Update the exchange rate provider for the token.

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

updateFeeErrorMargin

update fee error margin.

function updateFeeErrorMargin(uint256 newValue) external onlyOwner;

updateYieldErrorMargin

update yield error margin.

function updateYieldErrorMargin(uint256 newValue) external onlyOwner;

updateMaxDeltaDMargin

update yield error margin.

function updateMaxDeltaDMargin(uint256 newValue) external onlyOwner;

distributeLoss

Distribute losses by rebasing negatively

function distributeLoss() external onlyOwner;

rebase

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

function rebase() external 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, uint256);

Parameters

NameTypeDescription
_amountuint256Amount of pool tokens to redeem.

Returns

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

getTokens

Returns the array of token addresses in the pool.

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

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.

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.

_getD

Computes D given token balances.

function _getD(uint256[] memory _balances) internal view returns (uint256);

Parameters

NameTypeDescription
_balancesuint256[]Normalized balance of each token.

Returns

NameTypeDescription
<none>uint256D The SelfPeggingAsset invariant.

_getY

Computes token balance given D.

function _getY(uint256[] memory _balances, uint256 _j, uint256 _D) internal view 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.

Returns

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

_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.

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 LP 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 LP token.

AModified

This event is emitted when the A parameter is modified.

event AModified(uint256 A);

Parameters

NameTypeDescription
Auint256is the new value of the A parameter.

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.

MaxDeltaDModified

This event is emitted when the max delta D is modified.

event MaxDeltaDModified(uint256 delta);

Parameters

NameTypeDescription
deltauint256is the new value of the delta.

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();

AccountIsZero

Error thrown when the account address is zero

error AccountIsZero();

PastBlock

Error thrown when the block number is an past block

error PastBlock();

NoLosses

Error thrown when there is no loss

error NoLosses();

NotAdmin

Error thrown when the account is not an admin

error NotAdmin();

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);

SameTokenInTokenOut

Error thrown in and out token are the same

error SameTokenInTokenOut(uint256 tokenInIndex, uint256 tokenOutIndex);

ImbalancedPool

Error thrown when the pool is imbalanced

error ImbalancedPool(uint256 oldD, uint256 newD);