Introduce and analyze Fixed Forex contract

林瑋宸 Albert Lin
4 min readJul 4, 2021

Recently Andre Cronje, Defi KOL, announce the new project: Fixed Forex. It is a new project, so the document is not complete, just only introducing an article on Medium。 Fixed Forex include some features, include

  • 0 governance (or multisig)
  • 0 configuration
  • 0 fees
  • 0 value extraction
  • Gentle liquidations
  • Dynamic minting caps based on on-chain liquidity
  • Dynamic LTVs based on on-chain protocols

I am very interested in this project, so I take a look at the contract code and do some research. Try to understand how to implement these features and the contract how work. Before we go through the contract, there is some information about the contract below. By the way, I can not sure the FixedUSD contract can represent all FixedForex contracts or not. But it is the only FixedForex contract I can survey. Maybe other FixedForex contracts will differ from the FixedUSD contract.

FixedUSD:
- Address: 0x92fc8e6efdf389e2527d14393b15f543f9a03420
- config:
- oracle = 0xDA7a001b254CD22e46d3eAB04d937489c93174C3
- stable = DAI
- router = SushiSwapRouter
- aavev2 = 0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9
- iron back = 0xAB1c342C7bf5Ec5F02ADEA1c2270670bCa144CbB
- unitProcotol = 0x203153522B9EAef4aE17c6e99851EE7b2F7D312E

What are Loan-to-value ratios?

Loan to Value Ratio (LTV) is how lenders describe the amount you need to borrow to buy a particular property. In a nutshell: it’s the amount you need to borrow, calculated as a percentage of the property’s ‘lender-assessed value’.

Let’s talk about FixedForex how to work by mint operation and liquidate operation.

How to mint FUSD

There are two ways to mint FUSD. one is the mint() function, another is mintArb() .

function mint(address asset, uint amount, uint minted)

function mint(address asset, uint amount, uint minted)
- asset: collateral asset
- amount: collateral asset amount, only mint if amount is zero
- minted: minted FUSD amount, only add collateral if minted is zero

You can mint FUSD with your collateral through mint() of contract. For example, using USDT as collateral to mint FUSD. The main flow will be :

  1. Transfer USDT from sender to FixedUSD contract
  2. Add amount to sender USDT collateral call collateral[sender][USDT] and total USDT collateral call collaterals[USDT]
  3. Add minted to sender USDT credit call credit[sender][USDT] and total USDT credit call credit[USDT]. credit[sender][USDT] means how much FUSD is mined under sender USDT collateral. credit[USDT]means how much FUSD is mined under total USDT collateral.
  4. Check collaterals[USDT]credit[USDT]. Calculate the equivalent DAI value under collaterals[USDT] through Sushiswap. credit[USDT] means how much FUSD is minted under the USDT collateral.
  5. Calculate sender’s mint FUSD power under USDT collateral. More detail in below.
  6. Check sender mint FUSD power ≥ credit[sender][USDT]
  7. mint minted amount FUSD to sender

How to calculate the sender’s mint FUSD power under the single collateral asset value?

  1. Get USDT to USD rate through Oracle
  2. Get asset LTV. It will get LTV from 3 protocols now. Iron bank, AaveV2, and Unit Protocol. Choose max LTV as asset LTV
  3. Max mint FUSD = rate * sender collateral amount * LTV

function mintArb(uint amount)

function mintArb(uint amount) external
- amount: DAI amount

Another way is mintArb(). But it is easier than mint(). You just deposit DAI to mint FUSD. Deposit 1 DAI then get 1 FUSD(1 DAI = 1 FUSD).

Step:

  1. Transfer DAI form sender to FixedUSD contract
  2. Mint amount FUSD to sender

How to Liquidate

function liquidate(address owner, address asset, uint max)

function liquidate(address owner, address asset, uint max)
- owner: Who will be liquidiated
- asset: Liquidiated asset
- max: The maximum FUSD you want to pay

Main Step: (We still supposed USDT as collateral.)

  1. Get total USDT amount of owner as collateral, call nomial .
  2. Get the minted FUSD power of USDT amount, call backend .
  3. Get minted FUSD of sender under USDT collateral, call debt .
  4. Check debtbackend .
  5. Calculate how much FUSD needs to be repaid, call repayment. It will get the LTV of USDT and depend on the LTV level to calculate repayment .
repayment:
LTV = 60 => min(3.1 * (debt-backend), debt)
LTV = 65 => min(3.7 * (debt-backend), debt)
LTV = 70 => min(4.6 * (debt-backend), debt)
LTV = 75 => min(6.1 * (debt-backend), debt)
LTV = 80 => min(9.1 * (debt-backend), debt)
LTV = 85 => min(18.1 * (debt-backend), debt)
LTV >= 90 => debt

8. Check repaymentmax

9. Calculate how much USDT needs to pay for the Liquidator, call payment. More detail in below.

10. Burn Liquidator’s FUSD

11. Update collateral information

12. Send payment USDT to Liquidator

How to calculate how much collateral can be got by Liquidator

  1. Get USDT to USD rate by Oracle , (rate == 1)
  2. Get LookupLiq = rate * nomial * (_LIQUIDATION_VALUE/_BASE == 0.9)
  3. payment = (repayment * nomial) / (rate * nomial * 0.9) = 1.11 * repayment

Summary

It tries to make a stable coin from another angle. no token, no fee, no governance. It is like a more experimental project and no audit. FixedForex is a very interesting project. But I think there are a few things to be noticed.

  • The Oracle can provide different rates like USD, EUR, ZAR, JPY, CNY, etc. Need to notice how to oracle work.
  • Any asset can be as collateral if the asset is collateral on aaveV2, iron bank, or Unit Protocol.
  • It will also update Calculate LTV and Liquidity to cache. But the cache timeout is 1 day. It could be non-sync with Market.
  • mintArb() allow user deposit DAI to mint FUSD (FUSD: DAI = 1: 1)。 It helps to stabilize the FUSD price. It also could help Liquidator to mint FUSD to liquidate.

--

--