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
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
Name | Type | Description |
---|---|---|
<none> | uint256 | The exchange rate of the token. |
exchangeRateDecimals
Returns the exchange rate decimals.
function exchangeRateDecimals() external view returns (uint256);
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | The exchange rate decimals of the token. |
ILPToken
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
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
Name | Type | Description |
---|---|---|
spa | address | Address of the SPA contract |
wlp | address | Address of the wrapped LP token contract |
receiver | address | Address to receive the wrapped LP tokens |
minMintAmount | uint256 | Minimum amount of LP tokens to receive |
amounts | uint256[] | Array of token amounts to add |
Returns
Name | Type | Description |
---|---|---|
wlpAmount | uint256 | Amount 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
Name | Type | Description |
---|---|---|
spa | address | Address of the SPA contract |
wlp | address | Address of the wrapped LP token contract |
receiver | address | Address to receive the tokens |
wlpAmount | uint256 | Amount of wrapped LP tokens to redeem |
minAmountsOut | uint256[] | Minimum amounts of tokens to receive |
proportional | bool | If true, withdraws proportionally; if false, uses minAmountsOut |
Returns
Name | Type | Description |
---|---|---|
amounts | uint256[] | 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
Name | Type | Description |
---|---|---|
spa | address | Address of the SPA contract |
wlp | address | Address of the wrapped LP token contract |
receiver | address | Address to receive the tokens |
wlpAmount | uint256 | Amount of wrapped LP tokens to redeem |
tokenIndex | uint256 | Index of the token to receive |
minAmountOut | uint256 | Minimum amount of token to receive |
Returns
Name | Type | Description |
---|---|---|
amount | uint256 | Amount of token received |
recoverERC20
Recover tokens accidentally sent to this contract
function recoverERC20(address token, uint256 amount, address to) external;
Parameters
Name | Type | Description |
---|---|---|
token | address | Address of the token to recover |
amount | uint256 | Amount to recover |
to | address | Address 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
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
Inherits: IERC20
Functions
getExchangeRate
Get the exchange rate
function getExchangeRate() external view returns (uint256);
ConstantExchangeRateProvider
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
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
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
Inherits: ERC4626Upgradeable
Functions
initialize
function initialize(IERC20 token) public initializer;
MockExchangeRateProvider
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
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
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
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
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
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
Name | Type | Description |
---|---|---|
spa | address | Address of the SPA contract |
wlp | address | Address of the wrapped LP token contract |
receiver | address | Address to receive the wrapped LP tokens |
minMintAmount | uint256 | Minimum amount of LP tokens to receive |
amounts | uint256[] | Array of token amounts to add |
Returns
Name | Type | Description |
---|---|---|
wlpAmount | uint256 | Amount 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
Name | Type | Description |
---|---|---|
spa | address | Address of the SPA contract |
wlp | address | Address of the wrapped LP token contract |
receiver | address | Address to receive the tokens |
wlpAmount | uint256 | Amount of wrapped LP tokens to redeem |
minAmountsOut | uint256[] | Minimum amounts of tokens to receive |
proportional | bool | If true, withdraws proportionally; if false, uses minAmountsOut |
Returns
Name | Type | Description |
---|---|---|
amounts | uint256[] | 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
Name | Type | Description |
---|---|---|
spa | address | Address of the SPA contract |
wlp | address | Address of the wrapped LP token contract |
receiver | address | Address to receive the tokens |
wlpAmount | uint256 | Amount of wrapped LP tokens to redeem |
tokenIndex | uint256 | Index of the token to receive |
minAmountOut | uint256 | Minimum amount of token to receive |
Returns
Name | Type | Description |
---|---|---|
amount | uint256 | Amount of token received |
recoverERC20
Recover tokens accidentally sent to this contract
function recoverERC20(address token, uint256 amount, address to) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
token | address | Address of the token to recover |
amount | uint256 | Amount to recover |
to | address | Address 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
error InsufficientAllowance(uint256 currentAllowance, uint256 amount);
InsufficientBalance
error InsufficientBalance(uint256 currentBalance, uint256 amount);
LPToken
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
Name | Type | Description |
---|---|---|
<none> | uint256 | amount 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
Name | Type | Description |
---|---|---|
<none> | uint256 | amount 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 _recipient
account.
The _amount
argument is the amount of tokens, not shares.
function transfer(address _recipient, uint256 _amount) external returns (bool);
Returns
Name | Type | Description |
---|---|---|
<none> | bool | a 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
Name | Type | Description |
---|---|---|
<none> | bool | a 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
Name | Type | Description |
---|---|---|
<none> | bool | a 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
Name | Type | Description |
---|---|---|
_amount | uint256 | The amount of lost tokens. |
isBuffer | bool | The flag to indicate whether to use the buffer or not. |
withDebt | bool | The 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
Name | Type | Description |
---|---|---|
_pool | address | The address of the pool to add. |
removePool
Removes a pool from the list of pools.
function removePool(address _pool) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
_pool | address | The address of the pool to remove. |
name
Returns the name of the token.
function name() external view returns (string memory);
Returns
Name | Type | Description |
---|---|---|
<none> | string | the name of the token. |
symbol
Returns the symbol of the token.
function symbol() external view returns (string memory);
Returns
Name | Type | Description |
---|---|---|
<none> | string | the 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
Name | Type | Description |
---|---|---|
<none> | uint256 | the 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
Name | Type | Description |
---|---|---|
<none> | uint256 | the 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
Name | Type | Description |
---|---|---|
<none> | uint256 | the amount of shares owned by _account . |
decimals
Returns the decimals of the token.
function decimals() external pure returns (uint8);
Returns
Name | Type | Description |
---|---|---|
<none> | uint8 | the number of decimals for getting user representation of a token amount. |
getPeggedTokenByShares
function getPeggedTokenByShares(uint256 _sharesAmount) public view returns (uint256);
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | the amount of lpToken that corresponds to _sharesAmount token shares. |
getSharesByPeggedToken
function getSharesByPeggedToken(uint256 _lpTokenAmount) public view returns (uint256);
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | the 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
Name | Type | Description |
---|---|---|
<none> | uint256 | the 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
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
Name | Type | Description |
---|---|---|
_tokens | address[] | The tokens in the pool. |
_precisions | uint256[] | The precisions of each token (10 ** (18 - token decimals)). |
_fees | uint256[] | The fees for minting, swapping, and redeeming. |
_offPegFeeMultiplier | uint256 | The off peg fee multiplier. |
_poolToken | ILPToken | The address of the pool token. |
_A | uint256 | The initial value of the amplification coefficient A for the pool. |
_exchangeRateProviders | IExchangeRateProvider[] |
mint
Mints new pool token.
function mint(uint256[] calldata _amounts, uint256 _minMintAmount) external nonReentrant returns (uint256);
Parameters
Name | Type | Description |
---|---|---|
_amounts | uint256[] | Unconverted token balances used to mint pool token. |
_minMintAmount | uint256 | Minimum amount of pool token to mint. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | The 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
Name | Type | Description |
---|---|---|
_i | uint256 | Token index to swap in. |
_j | uint256 | Token index to swap out. |
_dx | uint256 | Unconverted amount of token _i to swap in. |
_minDy | uint256 | Minimum token _j to swap out in converted balance. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | Amount of swap out. |
redeemProportion
Redeems pool token to underlying tokens proportionally.
function redeemProportion(
uint256 _amount,
uint256[] calldata _minRedeemAmounts
)
external
nonReentrant
returns (uint256[] memory);
Parameters
Name | Type | Description |
---|---|---|
_amount | uint256 | Amount of pool token to redeem. |
_minRedeemAmounts | uint256[] | Minimum amount of underlying tokens to get. |
Returns
Name | Type | Description |
---|---|---|
<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
Name | Type | Description |
---|---|---|
_amount | uint256 | Amount of pool token to redeem. |
_i | uint256 | Index of the token to redeem to. |
_minRedeemAmount | uint256 | Minimum amount of the underlying token to redeem to. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | Amount received. |
redeemMulti
Redeems underlying tokens.
function redeemMulti(
uint256[] calldata _amounts,
uint256 _maxRedeemAmount
)
external
nonReentrant
returns (uint256[] memory);
Parameters
Name | Type | Description |
---|---|---|
_amounts | uint256[] | Amounts of underlying tokens to redeem to. |
_maxRedeemAmount | uint256 | Maximum of pool token to redeem. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256[] | Amounts received. |
setMintFee
Updates the mint fee.
function setMintFee(uint256 _mintFee) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
_mintFee | uint256 | The new mint fee. |
setSwapFee
Updates the swap fee.
function setSwapFee(uint256 _swapFee) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
_swapFee | uint256 | The new swap fee. |
setRedeemFee
Updates the redeem fee.
function setRedeemFee(uint256 _redeemFee) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
_redeemFee | uint256 | The new redeem fee. |
setOffPegFeeMultiplier
Updates the off peg fee multiplier.
function setOffPegFeeMultiplier(uint256 _offPegFeeMultiplier) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
_offPegFeeMultiplier | uint256 | The 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
Name | Type | Description |
---|---|---|
_account | address | Address to update admin role. |
_allowed | bool | Whether the address is granted the admin role. |
updateA
Update the A value.
function updateA(uint256 _A) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
_A | uint256 | The 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
Name | Type | Description |
---|---|---|
_amount | uint256 | Amount of pool token to redeem. |
_i | uint256 | Index of the underlying token to redeem to. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | The amount of single token that will be redeemed. |
<none> | uint256 | The 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
Name | Type | Description |
---|---|---|
_amounts | uint256[] | Unconverted token balances. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | The amount of pool token that needs to be redeemed. |
<none> | uint256 | The 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
Name | Type | Description |
---|---|---|
_amounts | uint256[] | Unconverted token balances. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | The amount of pool tokens to be minted. |
<none> | uint256 | The 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
Name | Type | Description |
---|---|---|
_i | uint256 | Token index to swap in. |
_j | uint256 | Token index to swap out. |
_dx | uint256 | Unconverted amount of token _i to swap in. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | Unconverted amount of token _j to swap out. |
<none> | uint256 | The 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
Name | Type | Description |
---|---|---|
_amount | uint256 | Amount of pool tokens to redeem. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256[] | An array of the amounts of each token to redeem. |
<none> | uint256 | The 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
Name | Type | Description |
---|---|---|
isFee | bool | Whether to collect fee or yield. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | The 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
Name | Type | Description |
---|---|---|
<none> | uint256[] | The balances of underlying tokens. |
<none> | uint256 | The total supply of pool tokens. |
_getD
Computes D given token balances.
function _getD(uint256[] memory _balances) internal view returns (uint256);
Parameters
Name | Type | Description |
---|---|---|
_balances | uint256[] | Normalized balance of each token. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | D The SelfPeggingAsset invariant. |
_getY
Computes token balance given D.
function _getY(uint256[] memory _balances, uint256 _j, uint256 _D) internal view returns (uint256);
Parameters
Name | Type | Description |
---|---|---|
_balances | uint256[] | Converted balance of each token except token with index _j. |
_j | uint256 | Index of the token to calculate balance. |
_D | uint256 | The target D value. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | Converted 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
Name | Type | Description |
---|---|---|
xpi | uint256 | The liquidity before or first asset liqidity. |
xpj | uint256 | The liqduity after or second asset liquidity. |
_fee | uint256 | The base fee value. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | The 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
Name | Type | Description |
---|---|---|
buyer | address | is the address of the account that made the swap. |
swapAmount | uint256 | is the amount of the token swapped by the buyer. |
amounts | uint256[] | is an array containing the amounts of each token received by the buyer. |
feeAmount | uint256 | is 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
Name | Type | Description |
---|---|---|
provider | address | is the address of the liquidity provider. |
mintAmount | uint256 | is the amount of liquidity tokens minted to the provider in exchange for their contribution. |
amounts | uint256[] | is an array containing the amounts of each token contributed by the provider. |
feeAmount | uint256 | is 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
Name | Type | Description |
---|---|---|
provider | address | is the address of the liquidity provider. |
mintAmount | uint256 | is the amount of liquidity tokens minted to the provider in exchange for their contribution. |
amounts | uint256[] | 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
Name | Type | Description |
---|---|---|
provider | address | is the address of the liquidity provider. |
redeemAmount | uint256 | is the amount of liquidity tokens redeemed by the provider. |
amounts | uint256[] | is an array containing the amounts of each token received by the provider. |
feeAmount | uint256 | is 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
Name | Type | Description |
---|---|---|
feeAmount | uint256 | is the amount of fee collected. |
totalSupply | uint256 | is 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
Name | Type | Description |
---|---|---|
feeAmount | uint256 | is the amount of yield collected. |
totalSupply | uint256 | is the total supply of LP token. |
AModified
This event is emitted when the A parameter is modified.
event AModified(uint256 A);
Parameters
Name | Type | Description |
---|---|---|
A | uint256 | is the new value of the A parameter. |
MintFeeModified
This event is emitted when the mint fee is modified.
event MintFeeModified(uint256 mintFee);
Parameters
Name | Type | Description |
---|---|---|
mintFee | uint256 | is the new value of the mint fee. |
SwapFeeModified
This event is emitted when the swap fee is modified.
event SwapFeeModified(uint256 swapFee);
Parameters
Name | Type | Description |
---|---|---|
swapFee | uint256 | is the new value of the swap fee. |
RedeemFeeModified
This event is emitted when the redeem fee is modified.
event RedeemFeeModified(uint256 redeemFee);
Parameters
Name | Type | Description |
---|---|---|
redeemFee | uint256 | is 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
Name | Type | Description |
---|---|---|
offPegFeeMultiplier | uint256 | is 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
Name | Type | Description |
---|---|---|
margin | uint256 | is the new value of the margin. |
YieldMarginModified
This event is emitted when the fee margin is modified.
event YieldMarginModified(uint256 margin);
Parameters
Name | Type | Description |
---|---|---|
margin | uint256 | is the new value of the margin. |
MaxDeltaDModified
This event is emitted when the max delta D is modified.
event MaxDeltaDModified(uint256 delta);
Parameters
Name | Type | Description |
---|---|---|
delta | uint256 | is 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
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
Name | Type | Description |
---|---|---|
governor | address | is 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
Name | Type | Description |
---|---|---|
poolToken | address | is the pool token created. |
selfPeggingAsset | address | |
wrappedPoolToken | address |
MintFeeModified
This event is emitted when the mint fee is updated.
event MintFeeModified(uint256 mintFee);
Parameters
Name | Type | Description |
---|---|---|
mintFee | uint256 | is the new value of the mint fee. |
SwapFeeModified
This event is emitted when the swap fee is updated.
event SwapFeeModified(uint256 swapFee);
Parameters
Name | Type | Description |
---|---|---|
swapFee | uint256 | is the new value of the swap fee. |
RedeemFeeModified
This event is emitted when the redeem fee is updated.
event RedeemFeeModified(uint256 redeemFee);
Parameters
Name | Type | Description |
---|---|---|
redeemFee | uint256 | is 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
Name | Type | Description |
---|---|---|
offPegFeeMultiplier | uint256 | is 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
Name | Type | Description |
---|---|---|
A | uint256 | is 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
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
Name | Type | Description |
---|---|---|
assets | uint256 | Amount of lpToken to deposit. |
receiver | address | Address to receive the minted shares. |
Returns
Name | Type | Description |
---|---|---|
shares | uint256 | Amount 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
Name | Type | Description |
---|---|---|
shares | uint256 | Amount of shares to mint. |
receiver | address | Address to receive the minted shares. |
Returns
Name | Type | Description |
---|---|---|
assets | uint256 | The 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
Name | Type | Description |
---|---|---|
assets | uint256 | Amount of lpToken to withdraw. |
receiver | address | Address to receive the lpToken. |
owner | address | Address whose shares will be burned. |
Returns
Name | Type | Description |
---|---|---|
shares | uint256 | Burned 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
Name | Type | Description |
---|---|---|
shares | uint256 | Amount of shares to redeem. |
receiver | address | Address to receive the lpToken. |
owner | address | Address whose shares will be burned. |
Returns
Name | Type | Description |
---|---|---|
assets | uint256 | Amount of lpToken withdrawn. |
name
Returns the name of the token.
function name() public view override(ERC20Upgradeable, IERC20Metadata) returns (string memory);
Returns
Name | Type | Description |
---|---|---|
<none> | string | The name of the token. |
symbol
Returns the symbol of the token.
function symbol() public view override(ERC20Upgradeable, IERC20Metadata) returns (string memory);
Returns
Name | Type | Description |
---|---|---|
<none> | string | The 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
Name | Type | Description |
---|---|---|
assets | uint256 | Amount of lpToken. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | The equivalent shares. |
convertToAssets
Converts an amount of shares to the equivalent amount of lpToken.
function convertToAssets(uint256 shares) public view override returns (uint256);
Parameters
Name | Type | Description |
---|---|---|
shares | uint256 | Amount of shares. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | The 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
Name | Type | Description |
---|---|---|
owner | address | Address of the account. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | The 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
Name | Type | Description |
---|---|---|
assets | uint256 | Amount of lpToken to deposit. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | The 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
Name | Type | Description |
---|---|---|
shares | uint256 | Amount of shares to mint. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | The 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
Name | Type | Description |
---|---|---|
shares | uint256 | Amount of shares to redeem. |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | The number of assets that would be withdrawn. |
Errors
ZeroAmount
error ZeroAmount();
InsufficientAllowance
error InsufficientAllowance();