Tapio Protocol

Tapio is a liquidity aggregator that acts as the middle layer between self-pegging assets and downstream DeFi applications. Liquidity is a cornerstone of DeFi and represents the most significant use case for self-pegging assets when paired with complementary tokens. However, once these assets are utilized in liquidity pools and the resulting LP token is obtained, the journey often stalls, leaving limited options for further use. Additionally, the ecosystem faces heavy fragmentation of self-pegging asset liquidity, with individual protocols employing distinct reward mechanisms, token models, and architectures—resulting in an increasingly fragmented and inefficient landscape.

Introducing the Tapio LP Token—the first utility-focused LP token designed for the self-pegging asset ecosystem. Serving as both a liquidity aggregator and an arbitrage hub, it fundamentally operates as a rebasing LP token that represents diverse stable pools within Tapio Finance. These pools include pairings between self-pegging assets and their complements, such as:

  • stETH-ETH
  • USDT-USDC
  • rETH-wstETH

Unlike traditional liquidity pools in DEXs, the Tapio LP Token you receive after depositing assets is pegged to the underlying assets and can be seamlessly used within DeFi or as a medium of exchange, just like any other asset. The Tapio LP Token also accrues underlying token rewards and fees generated by the pools—such as swaps, redemptions, and more—delivering an attractive real yield APR even before engaging in further DeFi activities.

For added flexibility, the Tapio LP Token can be wrapped into a wrapped LP token, adopting an "interest rate" model that simplifies integration and cross-chain usage.

As a synthetic asset protocol, Tapio Finance dynamically adjusts the pricing curves of self-pegging asset pools, enabling efficient swaps and arbitrage opportunities. This ensures the stability of tapETH while unlocking excellent use cases for Tapio's liquidity pools.

Overview

In Tapio, users can:

  • Create new AMM pools using Factory.
  • Mint, swap and redeem tokens in pools.
  • Wrap and unwrap LP tokens.

The protocol is built using modular, upgradeable components and is based on CurveFi's StableSwap algorithm. This design ensuring the system can adapt and scale with evolving protocol requirements.

Contracts

Tapio uses several core contracts to facilitate management of pools and it's functionality:

SelfPeggingAssetFactory

The SelfPeggingAssetFactory contract automates the deployment of new pools, simplifying their creation and management. All pools deployed through the Factory are governed by Pike's governance system.

SelfPeggingAsset

The SelfPeggingAsset conttract represents a AMM pool. It allows users to swap, mint and redeem tokens of the pool. It implements the StableSwap algorithm.

LPToken

The LPToken is an ERC20 rebase token issued by StableSwap pools to liquidity providers.

LPToken balances are dynamic and reflect the holder's share of the total LPToken supply managed by the protocol. Since account shares are not normalized, the contract tracks the total sum of all shares to compute each account's token balance using the formula:

shares[account] * _totalSupply / _totalShares

Here, _totalSupply represents the total amount of LPToken managed by the protocol.

WLPToken

The WLPToken is an ERC4626 standard token that represents an account's share of the total LPToken supply. Unlike LPToken, which dynamically updates balances based on staking rewards and swap fees, WLPToken balances only change during transfers.

Designed as a "power user" token, WLPToken caters to DeFi protocols that do not support rebasable tokens. The contract serves as a trustless wrapper, accepting LPToken and minting WLPToken in return. When users choose to unwrap, the contract burns their WLPToken and returns the corresponding locked LPToken.

Usage

This is a list of the most frequently needed commands.

Build

Build the contracts:

$ forge build

Clean

Delete the build artifacts and cache directories:

$ forge clean

Compile

Compile the contracts:

$ forge build

Coverage

Get a test coverage report:

$ forge coverage

Deploy to Testnet

Deploy to Base Testnet:

$ forge script ./script/Testnet.s.sol -vvv --rpc-url basesepolia --broadcast

Before deploying make sure you configure the neccessary variables in .env file. To just test the scripts with just a dry run remove the --broadcast flag.

Verifying Contracts on Testnet Explorer

Here is an example on how to verify a contract on base sepolia:

$ forge verify-contract <contract-address> <contract-name> --watch --etherscan-api-key <basescan-api-key>  --chain-id 84532 --constructor-args <encoded-constructor-args>

You can find the contract name and constructor args in the broadcast directory. To encode the constructor args you can use: https://abi.hashex.org/

Format

Format the contracts:

$ forge fmt

Gas Usage

Get a gas report:

$ forge test --gas-report

Lint

Lint the contracts:

$ yarn run lint

Test

Run the tests:

$ forge test

Generate test coverage and output result to the terminal:

$ yarn run test:coverage

Generate test coverage with lcov report (you'll have to open the ./coverage/index.html file in your browser, to do so simply copy paste the path):

$ yarn run test:coverage:report

Scope

src/
├── LPToken.sol
├── SelfPeggingAsset.sol
├── SelfPeggingAssetFactory.sol
├── WLPToken.sol
├── interfaces
│   ├── IExchangeRateProvider.sol
│   └── ILPToken.sol
├── misc
│   ├── ConstantExchangeRateProvider.sol
│   ├── ERC4626ExchangeRate.sol
│   ├── OracleExchangeRate.sol
│   └── reth
│       ├── RocketTokenExchangeRateProvider.sol
│       └── RocketTokenRETHInterface.sol
└── mock
    ├── MockERC4626Token.sol
    ├── MockExchangeRateProvider.sol
    ├── MockOracle.sol
    ├── MockToken.sol
    ├── MockTokenERC4626.sol
    └── WETH.sol

License

This project is licensed under MIT.

Contents

IExchangeRateProvider

Git Source

Author: Nuts Finance Developer

Interface for tokens with exchange rate functionality

Functions

exchangeRate

Returns the exchange rate of the token.

function exchangeRate() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256The exchange rate of the token.

exchangeRateDecimals

Returns the exchange rate decimals.

function exchangeRateDecimals() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256The exchange rate decimals of the token.

ILPToken

Git Source

Inherits: IERC20

Author: Nuts Finance Developer

Interface for LP Token

Functions

addPool

Add a pool to the list of pools

function addPool(address _pool) external;

removePool

Remove a pool from the list of pools

function removePool(address _pool) external;

increaseAllowance

Increase the allowance of the spender

function increaseAllowance(address _spender, uint256 _addedValue) external returns (bool);

decreaseAllowance

Decrease the allowance of the spender

function decreaseAllowance(address _spender, uint256 _subtractedValue) external returns (bool);

addTotalSupply

Add the amount to the total supply

function addTotalSupply(uint256 _amount) external;

removeTotalSupply

Remove the amount from the total supply

function removeTotalSupply(uint256 _amount, bool isBuffer, bool withDebt) external;

transferShares

Transfer the shares to the recipient

function transferShares(address _recipient, uint256 _sharesAmount) external returns (uint256);

transferSharesFrom

Transfer the shares from the sender to the recipient

function transferSharesFrom(address _sender, address _recipient, uint256 _sharesAmount) external returns (uint256);

mintShares

Mint the shares to the account

function mintShares(address _account, uint256 _sharesAmount) external;

burnShares

Burn the shares from the account

function burnShares(uint256 _sharesAmount) external;

burnSharesFrom

Burn the shares from the account

function burnSharesFrom(address _account, uint256 _sharesAmount) external;

addBuffer

function addBuffer(uint256 _amount) external;

name

Name of the token

function name() external view returns (string memory);

symbol

Symbol of the token

function symbol() external view returns (string memory);

totalShares

Get the total amount of shares

function totalShares() external view returns (uint256);

totalRewards

Get the total amount of rewards

function totalRewards() external view returns (uint256);

sharesOf

Get the total shares of the account

function sharesOf(address _account) external view returns (uint256);

getSharesByPeggedToken

Get the shares corresponding to the amount of pooled eth

function getSharesByPeggedToken(uint256 _ethAmount) external view returns (uint256);

getPeggedTokenByShares

Add the amount of Eth corresponding to the shares

function getPeggedTokenByShares(uint256 _sharesAmount) external view returns (uint256);

IZap

Git Source

Interface for Zap contract

Defines functions to add and remove liquidity with wrapping/unwrapping in one transaction

Functions

zapIn

Add liquidity to SPA and automatically wrap LP tokens

function zapIn(
    address spa,
    address wlp,
    address receiver,
    uint256 minMintAmount,
    uint256[] calldata amounts
)
    external
    returns (uint256 wlpAmount);

Parameters

NameTypeDescription
spaaddressAddress of the SPA contract
wlpaddressAddress of the wrapped LP token contract
receiveraddressAddress to receive the wrapped LP tokens
minMintAmountuint256Minimum amount of LP tokens to receive
amountsuint256[]Array of token amounts to add

Returns

NameTypeDescription
wlpAmountuint256Amount of wrapped LP tokens minted

zapOut

Remove liquidity from SPA by unwrapping LP tokens first

function zapOut(
    address spa,
    address wlp,
    address receiver,
    uint256 wlpAmount,
    uint256[] calldata minAmountsOut,
    bool proportional
)
    external
    returns (uint256[] memory amounts);

Parameters

NameTypeDescription
spaaddressAddress of the SPA contract
wlpaddressAddress of the wrapped LP token contract
receiveraddressAddress to receive the tokens
wlpAmountuint256Amount of wrapped LP tokens to redeem
minAmountsOutuint256[]Minimum amounts of tokens to receive
proportionalboolIf true, withdraws proportionally; if false, uses minAmountsOut

Returns

NameTypeDescription
amountsuint256[]Array of token amounts received

zapOutSingle

Unwrap wLP tokens and redeem a single asset

function zapOutSingle(
    address spa,
    address wlp,
    address receiver,
    uint256 wlpAmount,
    uint256 tokenIndex,
    uint256 minAmountOut
)
    external
    returns (uint256 amount);

Parameters

NameTypeDescription
spaaddressAddress of the SPA contract
wlpaddressAddress of the wrapped LP token contract
receiveraddressAddress to receive the tokens
wlpAmountuint256Amount of wrapped LP tokens to redeem
tokenIndexuint256Index of the token to receive
minAmountOutuint256Minimum amount of token to receive

Returns

NameTypeDescription
amountuint256Amount of token received

recoverERC20

Recover tokens accidentally sent to this contract

function recoverERC20(address token, uint256 amount, address to) external;

Parameters

NameTypeDescription
tokenaddressAddress of the token to recover
amountuint256Amount to recover
toaddressAddress to send the tokens to

Events

ZapIn

event ZapIn(
    address indexed spa, address indexed user, address indexed receiver, uint256 wlpAmount, uint256[] inputAmounts
);

ZapOut

event ZapOut(
    address indexed spa,
    address indexed user,
    address indexed receiver,
    uint256 wlpAmount,
    uint256[] outputAmounts,
    bool proportional
);

Contents

Contents

RocketTokenExchangeRateProvider

Git Source

Inherits: IExchangeRateProvider, Initializable, ReentrancyGuardUpgradeable

Rocket Token exchange rate.

State Variables

rocketToken

Rocket Token contract

RocketTokenRETHInterface private rocketToken;

Functions

initialize

Initialize the contract

function initialize(RocketTokenRETHInterface _rocketToken) public initializer;

exchangeRate

Get the exchange rate

function exchangeRate() external view returns (uint256);

exchangeRateDecimals

Get the exchange rate decimals

function exchangeRateDecimals() external pure returns (uint256);

Errors

RocketTokenNotSet

Error thrown when the Rocket Token is not set

error RocketTokenNotSet();

RocketTokenRETHInterface

Git Source

Inherits: IERC20

Functions

getExchangeRate

Get the exchange rate

function getExchangeRate() external view returns (uint256);

ConstantExchangeRateProvider

Git Source

Inherits: IExchangeRateProvider

Constant exchange rate provider.

Functions

exchangeRate

Get the exchange rate

function exchangeRate() external pure returns (uint256);

exchangeRateDecimals

Get the exchange rate decimals

function exchangeRateDecimals() external pure returns (uint256);

ERC4626ExchangeRate

Git Source

Inherits: IExchangeRateProvider

ERC4626 exchange rate.

State Variables

token

ERC4626 token

IERC4626 public token;

Functions

constructor

Initialize the contract

constructor(IERC4626 _token);

exchangeRate

Get the exchange rate

function exchangeRate() external view returns (uint256);

exchangeRateDecimals

Get the exchange rate decimals

function exchangeRateDecimals() external view returns (uint256);

OracleExchangeRate

Git Source

Inherits: IExchangeRateProvider

Oracle exchange rate.

State Variables

oracle

Oracle address

address public oracle;

rateFunc

Rate function signature

bytes public rateFunc;

decimalsFunc

Decimals function signature

bytes public decimalsFunc;

Functions

constructor

Initialize the contract

constructor(address _oracle, bytes memory _rateFunc, bytes memory _decimalsFunc);

exchangeRate

Get the exchange rate

function exchangeRate() external view returns (uint256);

exchangeRateDecimals

Get the exchange rate decimals

function exchangeRateDecimals() external view returns (uint256);

Errors

InternalCallFailed

Error thrown when the internal call failed

error InternalCallFailed();

Contents

MockERC4626Token

Git Source

Inherits: ERC4626Upgradeable

Functions

initialize

function initialize(IERC20 token) public initializer;

MockExchangeRateProvider

Git Source

Inherits: IExchangeRateProvider

Mock exchange rate.

State Variables

rate

uint256 private rate;

decimals

uint256 private decimals;

Functions

constructor

constructor(uint256 _rate, uint256 _decimals);

newRate

function newRate(uint256 _rate) external;

exchangeRate

function exchangeRate() external view returns (uint256);

exchangeRateDecimals

function exchangeRateDecimals() external view returns (uint256);

MockOracle

Git Source

State Variables

_rate

uint256 internal _rate = 1e18;

Functions

setRate

function setRate(uint256 newRate) external;

rate

function rate() external view returns (uint256);

decimals

function decimals() external pure returns (uint256);

MockToken

Git Source

Inherits: ERC20

Mock ERC20 token.

State Variables

_dec

uint8 private _dec;

Functions

constructor

constructor(string memory _name, string memory _symbol, uint8 _decimals) ERC20(_name, _symbol);

mint

function mint(address account, uint256 amount) public;

burn

function burn(address account, uint256 amount) public;

decimals

function decimals() public view override returns (uint8);

MockTokenERC4626

Git Source

Inherits: ERC20

Mock ERC20 token.

State Variables

_dec

uint8 private _dec;

Functions

constructor

constructor(string memory _name, string memory _symbol, uint8 _decimals) ERC20(_name, _symbol);

mint

function mint(address account, uint256 amount) public;

burn

function burn(address account, uint256 amount) public;

decimals

function decimals() public view override returns (uint8);

totalAssets

function totalAssets() public view returns (uint256);

WETH9

Git Source

State Variables

name

string public name = "Wrapped Ether";

symbol

string public symbol = "WETH";

decimals

uint8 public decimals = 18;

balanceOf

mapping(address => uint256) public balanceOf;

allowance

mapping(address => mapping(address => uint256)) public allowance;

Functions

deposit

function deposit() public payable;

withdraw

function withdraw(uint256 wad) public;

totalSupply

function totalSupply() public view returns (uint256);

approve

function approve(address guy, uint256 wad) public returns (bool);

transfer

function transfer(address dst, uint256 wad) public returns (bool);

transferFrom

function transferFrom(address src, address dst, uint256 wad) public returns (bool);

Events

Approval

event Approval(address indexed src, address indexed guy, uint256 wad);

Transfer

event Transfer(address indexed src, address indexed dst, uint256 wad);

Deposit

event Deposit(address indexed dst, uint256 wad);

Withdrawal

event Withdrawal(address indexed src, uint256 wad);

Errors

InsufficientBalance

error InsufficientBalance();

NoAllowance

error NoAllowance();

Contents

Zap

Git Source

Inherits: IZap, Ownable, ReentrancyGuard

A helper contract to simplify liquidity provision and removal in Tapio

Allows users to add/remove liquidity with automatic wrapping/unwrapping in 1 tx

SPA and wLP addresses are passed as parameters to each function

Functions

constructor

constructor() Ownable(msg.sender);

zapIn

Add liquidity to SPA and automatically wrap LP tokens

function zapIn(
    address spa,
    address wlp,
    address receiver,
    uint256 minMintAmount,
    uint256[] calldata amounts
)
    external
    nonReentrant
    returns (uint256 wlpAmount);

Parameters

NameTypeDescription
spaaddressAddress of the SPA contract
wlpaddressAddress of the wrapped LP token contract
receiveraddressAddress to receive the wrapped LP tokens
minMintAmountuint256Minimum amount of LP tokens to receive
amountsuint256[]Array of token amounts to add

Returns

NameTypeDescription
wlpAmountuint256Amount of wrapped LP tokens minted

zapOut

Remove liquidity from SPA by unwrapping LP tokens first

function zapOut(
    address spa,
    address wlp,
    address receiver,
    uint256 wlpAmount,
    uint256[] calldata minAmountsOut,
    bool proportional
)
    external
    nonReentrant
    returns (uint256[] memory amounts);

Parameters

NameTypeDescription
spaaddressAddress of the SPA contract
wlpaddressAddress of the wrapped LP token contract
receiveraddressAddress to receive the tokens
wlpAmountuint256Amount of wrapped LP tokens to redeem
minAmountsOutuint256[]Minimum amounts of tokens to receive
proportionalboolIf true, withdraws proportionally; if false, uses minAmountsOut

Returns

NameTypeDescription
amountsuint256[]Array of token amounts received

zapOutSingle

Unwrap wLP tokens and redeem a single asset

function zapOutSingle(
    address spa,
    address wlp,
    address receiver,
    uint256 wlpAmount,
    uint256 tokenIndex,
    uint256 minAmountOut
)
    external
    nonReentrant
    returns (uint256 amount);

Parameters

NameTypeDescription
spaaddressAddress of the SPA contract
wlpaddressAddress of the wrapped LP token contract
receiveraddressAddress to receive the tokens
wlpAmountuint256Amount of wrapped LP tokens to redeem
tokenIndexuint256Index of the token to receive
minAmountOutuint256Minimum amount of token to receive

Returns

NameTypeDescription
amountuint256Amount of token received

recoverERC20

Recover tokens accidentally sent to this contract

function recoverERC20(address token, uint256 amount, address to) external onlyOwner;

Parameters

NameTypeDescription
tokenaddressAddress of the token to recover
amountuint256Amount to recover
toaddressAddress to send the tokens to

_mint

Call SPA's mint function

function _mint(address spa, uint256[] calldata amounts, uint256 minMintAmount) internal returns (uint256);

_deposit

Call WLPToken's deposit function

function _deposit(address wlp, uint256 assets, address receiver) internal returns (uint256);

_redeem

Call WLPToken's redeem function

function _redeem(address wlp, uint256 shares, address receiver) internal returns (uint256);

_redeemProportion

Call SPA's redeemProportion function

function _redeemProportion(
    address spa,
    uint256 amount,
    uint256[] calldata minAmountsOut
)
    internal
    returns (uint256[] memory);

_redeemSingle

Call SPA's redeemSingle function

function _redeemSingle(
    address spa,
    uint256 amount,
    uint256 tokenIndex,
    uint256 minAmountOut
)
    internal
    returns (uint256);

_redeemMulti

Call SPA's redeemMulti function

function _redeemMulti(
    address spa,
    uint256[] calldata amounts,
    uint256 maxRedeemAmount
)
    internal
    returns (uint256[] memory);

_getTokens

Get the tokens from SPA

function _getTokens(address spa) internal view returns (address[] memory);

_getPoolToken

Get the LP token from SPA

function _getPoolToken(address spa) internal view returns (address);

_revertBytes

Helper function to revert with the same error message as the original call

function _revertBytes(bytes memory data) internal pure;

Errors

ZeroAmount

error ZeroAmount();

InvalidParameters

error InvalidParameters();

CallFailed

error CallFailed();

InsufficientAllowance

Git Source

error InsufficientAllowance(uint256 currentAllowance, uint256 amount);

InsufficientBalance

Git Source

error InsufficientBalance(uint256 currentBalance, uint256 amount);

LPToken

Git Source

Inherits: Initializable, OwnableUpgradeable, ILPToken

Author: Nuts Finance Developer

ERC20 token minted by the StableSwap pools.

LPToken is ERC20 rebase token minted by StableSwap pools for liquidity providers. LPToken balances are dynamic and represent the holder's share in the total amount of lpToken controlled by the protocol. Account shares aren't normalized, so the contract also stores the sum of all shares to calculate each account's token balance which equals to: shares[account] * _totalSupply / _totalShares where the _totalSupply is the total supply of lpToken controlled by the protocol.

State Variables

INFINITE_ALLOWANCE

Constant value representing an infinite allowance.

uint256 internal constant INFINITE_ALLOWANCE = ~uint256(0);

BUFFER_DENOMINATOR

Constant value representing the denominator for the buffer rate.

uint256 public constant BUFFER_DENOMINATOR = 10 ** 10;

NUMBER_OF_DEAD_SHARES

Constant value representing the number of dead shares.

uint256 public constant NUMBER_OF_DEAD_SHARES = 1000;

totalShares

The total amount of shares.

uint256 public totalShares;

totalSupply

The total supply of lpToken

uint256 public totalSupply;

totalRewards

The total amount of rewards

uint256 public totalRewards;

shares

The mapping of account shares.

mapping(address => uint256) public shares;

allowances

The mapping of account allowances.

mapping(address => mapping(address => uint256)) private allowances;

pools

The mapping of pools.

mapping(address => bool) public pools;

bufferPercent

The buffer rate.

uint256 public bufferPercent;

bufferAmount

The buffer amount.

uint256 public bufferAmount;

tokenName

The token name.

string internal tokenName;

tokenSymbol

The token symbol.

string internal tokenSymbol;

bufferBadDebt

The bad debt of the buffer.

uint256 public bufferBadDebt;

Functions

initialize

function initialize(string memory _name, string memory _symbol) public initializer;

transferShares

Moves _sharesAmount token shares from the caller's account to the _recipient account.

The _sharesAmount argument is the amount of shares, not tokens.

function transferShares(address _recipient, uint256 _sharesAmount) external returns (uint256);

Returns

NameTypeDescription
<none>uint256amount of transferred tokens. Emits a TransferShares event. Emits a Transfer event.

transferSharesFrom

Moves _sharesAmount token shares from the _sender account to the _recipient account.

The _sharesAmount argument is the amount of shares, not tokens.

function transferSharesFrom(address _sender, address _recipient, uint256 _sharesAmount) external returns (uint256);

Returns

NameTypeDescription
<none>uint256amount of transferred tokens. Emits a TransferShares event. Emits a Transfer event. Requirements: - the caller must have allowance for _sender's tokens of at least getPeggedTokenByShares(_sharesAmount).

mintShares

Mints shares for the _account and transfers them to the _account.

function mintShares(address _account, uint256 _tokenAmount) external;

burnShares

Burns shares from the _account.

function burnShares(uint256 _tokenAmount) external;

burnSharesFrom

Burns shares from the _account.

function burnSharesFrom(address _account, uint256 _tokenAmount) external;

transfer

Moves _amount tokens from the caller's account to the _recipientaccount.

The _amount argument is the amount of tokens, not shares.

function transfer(address _recipient, uint256 _amount) external returns (bool);

Returns

NameTypeDescription
<none>boola boolean value indicating whether the operation succeeded. Emits a Transfer event. Emits a TransferShares event.

approve

Sets _amount as the allowance of _spender over the caller's tokens.

The _amount argument is the amount of tokens, not shares.

function approve(address _spender, uint256 _amount) external returns (bool);

Returns

NameTypeDescription
<none>boola boolean value indicating whether the operation succeeded. Emits an Approval event.

transferFrom

Moves _amount tokens from _sender to _recipient using the allowance mechanism. _amount is then deducted from the caller's allowance.

The _amount argument is the amount of tokens, not shares.

function transferFrom(address _sender, address _recipient, uint256 _amount) external returns (bool);

Returns

NameTypeDescription
<none>boola boolean value indicating whether the operation succeeded. Emits a Transfer event. Emits a TransferShares event. Emits an Approval event indicating the updated allowance. Requirements: - the caller must have allowance for _sender's tokens of at least _amount.

increaseAllowance

Atomically increases the allowance granted to _spender by the caller by _addedValue. This is an alternative to approve that can be used as a mitigation for problems described in: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/b709eae01d1da91902d06ace340df6b324e6f049/contracts/token/ERC20/IERC20.sol#L57 Emits an Approval event indicating the updated allowance.

function increaseAllowance(address _spender, uint256 _addedValue) external returns (bool);

decreaseAllowance

Atomically decreases the allowance granted to _spender by the caller by _subtractedValue. This is an alternative to approve that can be used as a mitigation for problems described in: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/b709eae01d1da91902d06ace340df6b324e6f049/contracts/token/ERC20/IERC20.sol#L57 Emits an Approval event indicating the updated allowance.

function decreaseAllowance(address _spender, uint256 _subtractedValue) external returns (bool);

setBuffer

This function is called by the owner to set the buffer rate.

function setBuffer(uint256 _buffer) external onlyOwner;

setSymbol

This function is called by the owner to set the token symbol.

function setSymbol(string memory _symbol) external onlyOwner;

addTotalSupply

This function is called only by a stableSwap pool to increase the total supply of LPToken by the staking rewards and the swap fee.

function addTotalSupply(uint256 _amount) external;

removeTotalSupply

This function is called only by a stableSwap pool to decrease the total supply of LPToken by lost amount.

function removeTotalSupply(uint256 _amount, bool isBuffer, bool withDebt) external;

Parameters

NameTypeDescription
_amountuint256The amount of lost tokens.
isBufferboolThe flag to indicate whether to use the buffer or not.
withDebtboolThe flag to indicate whether to add the lost amount to the buffer bad debt or not.

addBuffer

This function is called only by a stableSwap pool to increase the total supply of LPToken

function addBuffer(uint256 _amount) external;

addPool

Adds a pool to the list of pools.

function addPool(address _pool) external onlyOwner;

Parameters

NameTypeDescription
_pooladdressThe address of the pool to add.

removePool

Removes a pool from the list of pools.

function removePool(address _pool) external onlyOwner;

Parameters

NameTypeDescription
_pooladdressThe address of the pool to remove.

name

Returns the name of the token.

function name() external view returns (string memory);

Returns

NameTypeDescription
<none>stringthe name of the token.

symbol

Returns the symbol of the token.

function symbol() external view returns (string memory);

Returns

NameTypeDescription
<none>stringthe symbol of the token.

balanceOf

Balances are dynamic and equal the _account's share in the amount of the total lpToken controlled by the protocol. See sharesOf.

function balanceOf(address _account) external view returns (uint256);

Returns

NameTypeDescription
<none>uint256the amount of tokens owned by the _account.

allowance

This value changes when approve or transferFrom is called.

function allowance(address _owner, address _spender) external view returns (uint256);

Returns

NameTypeDescription
<none>uint256the remaining number of tokens that _spender is allowed to spend on behalf of _owner through transferFrom. This is zero by default.

sharesOf

function sharesOf(address _account) external view returns (uint256);

Returns

NameTypeDescription
<none>uint256the amount of shares owned by _account.

decimals

Returns the decimals of the token.

function decimals() external pure returns (uint8);

Returns

NameTypeDescription
<none>uint8the number of decimals for getting user representation of a token amount.

getPeggedTokenByShares

function getPeggedTokenByShares(uint256 _sharesAmount) public view returns (uint256);

Returns

NameTypeDescription
<none>uint256the amount of lpToken that corresponds to _sharesAmount token shares.

getSharesByPeggedToken

function getSharesByPeggedToken(uint256 _lpTokenAmount) public view returns (uint256);

Returns

NameTypeDescription
<none>uint256the amount of shares that corresponds to _lpTokenAmount protocol-controlled lpToken.

_transfer

Moves _amount tokens from _sender to _recipient. Emits a Transfer event. Emits a TransferShares event.

function _transfer(address _sender, address _recipient, uint256 _amount) internal;

_approve

Sets _amount as the allowance of _spender over the _owner s tokens. Emits an Approval event.

function _approve(address _owner, address _spender, uint256 _amount) internal;

_spendAllowance

Updates owner s allowance for spender based on spent amount. Does not update the allowance amount in case of infinite allowance. Revert if not enough allowance is available. Might emit an {Approval} event.

function _spendAllowance(address _owner, address _spender, uint256 _amount) internal;

_transferShares

Moves _sharesAmount shares from _sender to _recipient.

function _transferShares(address _sender, address _recipient, uint256 _sharesAmount) internal;

_mintShares

Creates _sharesAmount shares and assigns them to _recipient, increasing the total amount of shares.

function _mintShares(address _recipient, uint256 _tokenAmount) internal returns (uint256 newTotalShares);

_burnShares

Destroys _sharesAmount shares from _account's holdings, decreasing the total amount of shares.

function _burnShares(address _account, uint256 _tokenAmount) internal returns (uint256 newTotalShares);

_emitTransferEvents

Emits Transfer and TransferShares events.

function _emitTransferEvents(address _from, address _to, uint256 _tokenAmount, uint256 _sharesAmount) internal;

_emitTransferAfterMintingShares

Emits Transfer and TransferShares events after minting shares.

function _emitTransferAfterMintingShares(address _to, uint256 _sharesAmount) internal;

_sharesOf

function _sharesOf(address _account) internal view returns (uint256);

Returns

NameTypeDescription
<none>uint256the amount of shares owned by _account.

Events

TransferShares

Emitted when shares are transferred.

event TransferShares(address indexed from, address indexed to, uint256 sharesValue);

SharesMinted

Emitted when shares are minted.

event SharesMinted(address indexed account, uint256 tokenAmount, uint256 sharesAmount);

SharesBurnt

Emitted when shares are burnt.

event SharesBurnt(address indexed account, uint256 tokenAmount, uint256 sharesAmount);

RewardsMinted

Emitted when rewards are minted.

event RewardsMinted(uint256 amount, uint256 actualAmount);

PoolAdded

Emitted when a pool is added.

event PoolAdded(address indexed pool);

PoolRemoved

Emitted when a pool is removed.

event PoolRemoved(address indexed pool);

SetBufferPercent

Emitted when the buffer rate is set.

event SetBufferPercent(uint256);

BufferIncreased

Emitted when the buffer is increased.

event BufferIncreased(uint256, uint256);

BufferDecreased

Emitted when the buffer is decreased.

event BufferDecreased(uint256, uint256);

NegativelyRebased

Emitted when there is negative rebase.

event NegativelyRebased(uint256, uint256);

SymbolModified

Emitted when the symbol is modified.

event SymbolModified(string);

Errors

AllowanceBelowZero

Error thrown when the allowance is below zero.

error AllowanceBelowZero();

OutOfRange

Error thrown when array index is out of range.

error OutOfRange();

NoPool

Error thrown when the pool is not added.

error NoPool();

InvalidAmount

Error thrown when the amount is invalid.

error InvalidAmount();

InsufficientBuffer

Error thrown when the buffer is insufficient.

error InsufficientBuffer();

ApproveFromZeroAddr

Error thrown when the sender's address is zero.

error ApproveFromZeroAddr();

ApproveToZeroAddr

Error thrown when the recipient's address is zero.

error ApproveToZeroAddr();

ZeroAddress

Error thrown when the address is zero.

error ZeroAddress();

TransferToLPTokenContract

Error thrown when transferring to the lpToken contract.

error TransferToLPTokenContract();

MintToZeroAddr

Error thrown when minting to the zero address.

error MintToZeroAddr();

BurnFromZeroAddr

Error thrown when burning from the zero address.

error BurnFromZeroAddr();

PoolAlreadyAdded

Error thrown when the pool is already added.

error PoolAlreadyAdded();

PoolNotFound

Error thrown when the pool is not found.

error PoolNotFound();

InsufficientSupply

Error thrown when the supply is insufficient.

error InsufficientSupply();

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

SelfPeggingAssetFactory

Git Source

Inherits: UUPSUpgradeable, OwnableUpgradeable

Author: Nuts Finance Developer

The StableSwap Application provides an interface for users to interact with StableSwap pool contracts

The StableSwap Application contract allows users to mint pool tokens, swap between different tokens, and redeem pool tokens to underlying tokens. This contract should never store assets.

State Variables

governor

This is the account that has governor control over the protocol.

address public governor;

mintFee

Default mint fee for the pool.

uint256 public mintFee;

swapFee

Default swap fee for the pool.

uint256 public swapFee;

redeemFee

Default redeem fee for the pool.

uint256 public redeemFee;

offPegFeeMultiplier

Default off peg fee multiplier for the pool.

uint256 public offPegFeeMultiplier;

A

Default A parameter for the pool.

uint256 public A;

selfPeggingAssetBeacon

Beacon for the SelfPeggingAsset implementation.

address public selfPeggingAssetBeacon;

lpTokenBeacon

Beacon for the LPToken implementation.

address public lpTokenBeacon;

wlpTokenBeacon

Beacon for the WLPToken implementation.

address public wlpTokenBeacon;

constantExchangeRateProvider

Constant exchange rate provider.

ConstantExchangeRateProvider public constantExchangeRateProvider;

Functions

initialize

Initializes the StableSwap Application contract.

function initialize(
    address _governor,
    uint256 _mintFee,
    uint256 _swapFee,
    uint256 _redeemFee,
    uint256 _offPegFeeMultiplier,
    uint256 _A,
    address _selfPeggingAssetBeacon,
    address _lpTokenBeacon,
    address _wlpTokenBeacon,
    ConstantExchangeRateProvider _constantExchangeRateProvider
)
    public
    initializer;

setGovernor

Set the govenance address.

function setGovernor(address _governor) external onlyOwner;

setMintFee

Set the mint fee.

function setMintFee(uint256 _mintFee) external onlyOwner;

setSwapFee

Set the swap fee.

function setSwapFee(uint256 _swapFee) external onlyOwner;

setRedeemFee

Set the redeem fee.

function setRedeemFee(uint256 _redeemFee) external onlyOwner;

setOffPegFeeMultiplier

Set the off peg fee multiplier.

function setOffPegFeeMultiplier(uint256 _offPegFeeMultiplier) external onlyOwner;

setA

Set the A parameter.

function setA(uint256 _A) external onlyOwner;

createPool

Create a new pool.

function createPool(CreatePoolArgument memory argument) external;

_authorizeUpgrade

Authorisation to upgrade the implementation of the contract.

function _authorizeUpgrade(address) internal override onlyOwner;

Events

GovernorModified

This event is emitted when the governor is modified.

event GovernorModified(address governor);

Parameters

NameTypeDescription
governoraddressis the new value of the governor.

PoolCreated

This event is emitted when a new pool is created.

event PoolCreated(address poolToken, address selfPeggingAsset, address wrappedPoolToken);

Parameters

NameTypeDescription
poolTokenaddressis the pool token created.
selfPeggingAssetaddress
wrappedPoolTokenaddress

MintFeeModified

This event is emitted when the mint fee is updated.

event MintFeeModified(uint256 mintFee);

Parameters

NameTypeDescription
mintFeeuint256is the new value of the mint fee.

SwapFeeModified

This event is emitted when the swap fee is updated.

event SwapFeeModified(uint256 swapFee);

Parameters

NameTypeDescription
swapFeeuint256is the new value of the swap fee.

RedeemFeeModified

This event is emitted when the redeem fee is updated.

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

event OffPegFeeMultiplierModified(uint256 offPegFeeMultiplier);

Parameters

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

AModified

This event is emitted when the A parameter is updated.

event AModified(uint256 A);

Parameters

NameTypeDescription
Auint256is the new value of the A parameter.

Errors

InvalidAddress

Error thrown when the address is invalid

error InvalidAddress();

InvalidValue

Error thrown when the value is invalid

error InvalidValue();

InvalidOracle

Error thrown when the oracle is invalid

error InvalidOracle();

InvalidFunctionSig

Error thrown when the function signature is invalid

error InvalidFunctionSig();

Structs

CreatePoolArgument

Parameters for creating a new pool

struct CreatePoolArgument {
    address tokenA;
    address tokenB;
    TokenType tokenAType;
    address tokenAOracle;
    bytes tokenARateFunctionSig;
    bytes tokenADecimalsFunctionSig;
    TokenType tokenBType;
    address tokenBOracle;
    bytes tokenBRateFunctionSig;
    bytes tokenBDecimalsFunctionSig;
}

Enums

TokenType

Token type enum

enum TokenType {
    Standard,
    Oracle,
    Rebasing,
    ERC4626
}

WLPToken

Git Source

Inherits: ERC4626Upgradeable

It's an ERC4626 standard token that represents the account's share of the total supply of lpToken tokens. WLPToken token's balance only changes on transfers, unlike lpToken that is also changed when staking rewards and swap fee are generated. It's a "power user" token for DeFi protocols which don't support rebasable tokens. The contract is also a trustless wrapper that accepts lpToken tokens and mints wlpToken in return. Then the user unwraps, the contract burns user's wlpToken and sends user locked lpToken in return.

State Variables

lpToken

ILPToken public lpToken;

Functions

initialize

function initialize(ILPToken _lpToken) public initializer;

deposit

Deposits lpToken into the vault in exchange for shares.

function deposit(uint256 assets, address receiver) public override returns (uint256 shares);

Parameters

NameTypeDescription
assetsuint256Amount of lpToken to deposit.
receiveraddressAddress to receive the minted shares.

Returns

NameTypeDescription
sharesuint256Amount of shares minted.

mint

Mints shares for a given amount of assets deposited.

function mint(uint256 shares, address receiver) public override returns (uint256 assets);

Parameters

NameTypeDescription
sharesuint256Amount of shares to mint.
receiveraddressAddress to receive the minted shares.

Returns

NameTypeDescription
assetsuint256The amount of lpToken deposited.

withdraw

Withdraws lpToken from the vault in exchange for burning shares.

function withdraw(uint256 assets, address receiver, address owner) public override returns (uint256 shares);

Parameters

NameTypeDescription
assetsuint256Amount of lpToken to withdraw.
receiveraddressAddress to receive the lpToken.
owneraddressAddress whose shares will be burned.

Returns

NameTypeDescription
sharesuint256Burned shares corresponding to the assets withdrawn.

redeem

Redeems shares for lpToken.

function redeem(uint256 shares, address receiver, address owner) public override returns (uint256 assets);

Parameters

NameTypeDescription
sharesuint256Amount of shares to redeem.
receiveraddressAddress to receive the lpToken.
owneraddressAddress whose shares will be burned.

Returns

NameTypeDescription
assetsuint256Amount of lpToken withdrawn.

name

Returns the name of the token.

function name() public view override(ERC20Upgradeable, IERC20Metadata) returns (string memory);

Returns

NameTypeDescription
<none>stringThe name of the token.

symbol

Returns the symbol of the token.

function symbol() public view override(ERC20Upgradeable, IERC20Metadata) returns (string memory);

Returns

NameTypeDescription
<none>stringThe symbol of the token.

convertToShares

Converts an amount of lpToken to the equivalent amount of shares.

function convertToShares(uint256 assets) public view override returns (uint256);

Parameters

NameTypeDescription
assetsuint256Amount of lpToken.

Returns

NameTypeDescription
<none>uint256The equivalent shares.

convertToAssets

Converts an amount of shares to the equivalent amount of lpToken.

function convertToAssets(uint256 shares) public view override returns (uint256);

Parameters

NameTypeDescription
sharesuint256Amount of shares.

Returns

NameTypeDescription
<none>uint256The equivalent lpToken.

maxWithdraw

Returns the maximum amount of assets that can be withdrawn by owner.

function maxWithdraw(address owner) public view override returns (uint256);

Parameters

NameTypeDescription
owneraddressAddress of the account.

Returns

NameTypeDescription
<none>uint256The maximum amount of lpToken that can be withdrawn.

previewDeposit

Simulates the amount of shares that would be minted for a given amount of assets.

function previewDeposit(uint256 assets) public view override returns (uint256);

Parameters

NameTypeDescription
assetsuint256Amount of lpToken to deposit.

Returns

NameTypeDescription
<none>uint256The number of shares that would be minted.

previewMint

Simulates the amount of assets that would be needed to mint a given amount of shares.

function previewMint(uint256 shares) public view override returns (uint256);

Parameters

NameTypeDescription
sharesuint256Amount of shares to mint.

Returns

NameTypeDescription
<none>uint256The number of assets required.

previewRedeem

Simulates the amount of assets that would be withdrawn for a given amount of shares.

function previewRedeem(uint256 shares) public view override returns (uint256);

Parameters

NameTypeDescription
sharesuint256Amount of shares to redeem.

Returns

NameTypeDescription
<none>uint256The number of assets that would be withdrawn.

Errors

ZeroAmount

error ZeroAmount();

InsufficientAllowance

error InsufficientAllowance();