Skip to content

Synthetic Asset

Bette edited this page Oct 22, 2019 · 1 revision

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 fToken
  • token: the account of a fToken, e.g. address of deployed fEUR or fJPY
  • pool: the account of a liquidity pool chosen by the user
  • baseTokenAmount: amount of DAI to exchange
  • return: 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 DAI
  • token: the account of a fToken, e.g. address of deployed fEUR or fJPY
  • pool: the account of a liquidity pool chosen by the user
  • flowTokenAmount: amount of fToken to exchange
  • return: 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 liquidator
  • token: the account of a fToken, e.g. address of deployed fEUR or fJPY
  • pool: the account of a liquidity pool chosen by the user
  • flowTokenAmount: amount of fToken to exchange
  • return: 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 fJPY
  • flowTokenAmount: 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 fJPY
  • flowTokenAmount: amount of fToken to withdraw
  • return: 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 fJPY
  • flowTokenAmount: 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 pool
  • return collaterals: collaterals locked in unit of DAI
  • return 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())