Synthetic Asset - laminar-protocol/flow-protocol-ethereum GitHub Wiki
Introduction
Assets supported by the Flow Protocols are implemented as fToken ERC-20 compliant smart contracts. The Flow Synthetic Asset Protocol is the control protocol for minting fTokens and for depositing fTokens to earn interest. There can be multiple liquidity pool available for each fToken, and users could choose at their own discretion based on spread and/or other factors. Users would primarily interact with the Flow Synthetic Asset Protocol to mint, redeem, deposit, withdraw, liquidate a position.
Flow Synthetic Asset Protocol
Mint
The mint function transfers users' USD into the fToken's collateral, then transfers the over collateral amount from selected liquidity pool into the collateral, and puts a certain amount into money market to start accumulating interest. The number of fToken minted is determined by the ask price of the designated pool. The amount to put into the money market is calculated based on minimum liquidity requirement.
function mint(FlowToken token, LiquidityPoolInterface pool, uint baseTokenAmount) returns (uint)
msg.sender
: the account supplying DAI in exchange for fTokentoken
: the account of a fToken, e.g. address of deployed fEUR or fJPYpool
: the account of a liquidity pool chosen by the userbaseTokenAmount
: amount of DAI to exchangereturn
: amount of fToken minted
Before supplying DAI, users must first approve the Flow Synthetic Asset Protocol to access their DAI balance.
Web3
await usd.approve(protocol.address, constants.MAX_UINT256, { from: alice });
const buy = (addr: string, amount: number) => () => protocol.mint(fToken.address, liquidityPool.address, amount, { from: addr });
Redeem
The redeem function returns the USD base token to user based on the bid price of chosen liquidity pool, refunds the collateral amount of this position to the pool plus any interest earned during the period.
function redeem(FlowToken token, LiquidityPoolInterface pool, uint flowTokenAmount) returns (uint)
msg.sender
: the account supplying fToken in exchange for DAItoken
: the account of a fToken, e.g. address of deployed fEUR or fJPYpool
: the account of a liquidity pool chosen by the userflowTokenAmount
: amount of fToken to exchangereturn
: amount of DAI
Maximum Amount that can be Minted/Redeemed
Max Amount that can be Minted
Max amount of fToken can be minted for a given liquidity pool, is equal to
maxMint = liquidity / additionalCollateralRatio
All liquidity is converted and managed as iToken e.g. iUSD in the money market.
liquidity = iToken.balanceOf(poolAddress)
Each liquidity pool can set a higher collateral ratio than the fToken default for extra security.
additionalCollateralRatio = pool.getAdditionalCollateralRatio();
Max Amount that can be Redeemed
Max amount of fToken can be sold to a given liquidity pool, is equal to total fToken minted by the pool
{collateral, minted} = fToken.getPosition(poolAddress)
maxRedeem = minted;
Liquidate
When actual collateral ratio is less than the liquidation ratio, then the positions are open for public liquidation. The liquidate function sells given amount of fToken for DAI, transfers the DAI and a small amount of incentive reward to the liquidator, and refunds the pool with remaining collateral. For example, if liquidation ratio is at 5%, then when public liquidation is open, the position is still over-collateralized, say at 4.9%. Then the incentive will be taken out of the 4.9% collateral, while the remaining returns to the pool.
function liquidate(FlowToken token, LiquidityPoolInterface pool, uint flowTokenAmount) returns (uint)
msg.sender
: the liquidatortoken
: the account of a fToken, e.g. address of deployed fEUR or fJPYpool
: the account of a liquidity pool chosen by the userflowTokenAmount
: amount of fToken to exchangereturn
: amount of DAI exchanged plus incentive
Deposit
The deposit function mints certain amount of interest share for the user to account for interest accumulated hereafter.
function deposit(FlowToken token, uint flowTokenAmount)
token
: the account of a fToken, e.g. address of deployed fEUR or fJPYflowTokenAmount
: amount of fToken to deposit
Interest Earned
Interest earned for a given account is equal to
interest earned in DAI = interestShares * interestShareExchangeRate / 10^18 - interestDebit
function interestShareExchangeRate() public view returns (uint)
mapping (address => uint) public interestShares
mapping (address => uint) public interestDebits
Withdraw
The withdraw function returns fToken plus interest earned in DAI to user
function withdraw(FlowToken token, uint flowTokenAmount) returns (uint)
token
: the account of a fToken, e.g. address of deployed fEUR or fJPYflowTokenAmount
: amount of fToken to withdrawreturn
: withdrawn fToken plus interest earned
Additional Collateral Ratio
The getAdditionalCollateralRatio functions returns the maximum of two - the fToken's default collateral ratio and the designated liquidity pool's collateral ratio. A liquidity can set a higher collateral ratio than default for extra security.
function getAdditionalCollateralRatio(FlowToken token, LiquidityPoolInterface pool)
token
: the account of a fToken, e.g. address of deployed fEUR or fJPYflowTokenAmount
: amount of fToken to withdraw
fToken
Get Position
The getPosition function returns the collaterals and minted fToken for a given liquidity pool.
function getPosition(address poolAddr) external view returns (uint collaterals, uint minted)
poolAddr
: the account of a liquidity poolreturn collaterals
: collaterals locked in unit of DAIreturn minted
: amount of fToken minted from given pool
Get Deposited Amount
The deposits map returns total deposited fToken amount for a given account.
mapping (address => uint) public deposits
Default Collateral Ratio
The defaultCollateralRatio is the default additional collateral ratio for the fToken. For example, if the defaultCollateralRatio is 10%, when minting $100 worth fToken, then additional $10 is required from the liquidity pool to over-collateralized the fToken position.
Percentage.Percent public defaultCollateralRatio;
Liquidation Collateral Ratio
The liquidationCollateralRatio is the threshold below which the fToken positions will be open to public liquidation.
Percentage.Percent public liquidationCollateralRatio;
Extreme Collateral Ratio
The extremeCollateralRatio is the threshold below which all available collateral from liquidity pool will be rewarded to the liquidator as extra layer of protection.
Percentage.Percent public extremeCollateralRatio;
Actual Collateral Ratio
The actual collateral ratio given current price feed from oracle is equal to
actualCollateralRatio = collaterals / (minted * oracle.getPrice())