A decentralized foreign exchange protocol optimized for stablecoins and any erc20 tokens.
DFX v3 is an update from DFX protocol v2 with some additional features including more decentralization, support of any erc20 tokens and mathematical calculation accuracy.
There are two major parts to the protocol: Assimilators and Curves. Assimilators allow the AMM to handle pairs of different value while also retrieving reported oracle prices for respective currencies. Curves allow the custom parameterization of the bonding curve with dynamic fees, halting bounderies, etc.
Assimilators are a key part of the protocol, it converts all amounts to a "numeraire" which is essentially a base value used for computations across the entire protocol. This is necessary as we are dealing with pairs of different values. AssimilatorFactory is responsible for deploying new AssimilatorV3.
Oracle price feeds are also piped in through the assimilator as they inform what numeraire amounts should be set. Since oracle price feeds report their values in USD, all assimilators attempt to convert token values to a numeraire amount based on USD.
High level overview.
Name | Description |
---|---|
Weights | Weighting of the pair (only 50/50) |
Alpha | The maximum and minimum allocation for each reserve |
Beta | Liquidity depth of the exchange; The higher the value, the flatter the curve at the reported oracle price |
Delta/Max | Slippage when exchange is not at the reported oracle price |
Epsilon | Fixed fee |
Lambda | Dynamic fee captured when slippage occurs |
In order to prevent anti-slippage being greater than slippate, DFX V3 requires deployers to set Lambda to 1(1e18).
For a more in-depth discussion, refer to section 3 of the shellprotocol whitepaper
The main changes between V3 and the original code can be found in the following files:
- All the assimilators
AssimilatorV3.sol
CurveFactoryV3.sol
CurveMath.sol
ProportionalLiquidity.sol
Swaps.sol
Structs.sol
In the original implementation, all pools are assumed to be baskets of like-valued tokens. In our implementation, all pools are assumed to be pairs of different-valued FX stablecoins or any erc20 token pairs
This is achieved by having custom assimilators that normalize the foreign currencies to their USD counterparts. We're sourcing our FX price feed from chainlink oracles. See above for more information about assimilators.
Withdrawing and depositing related operations will respect the existing LP ratio. As long as the pool ratio hasn't changed since the deposit, amount in ~= amount out (minus fees), even if the reported price on the oracle changes. The oracle is only here to assist with efficient swaps.
Flashloans live in every curve contract produced by the CurveFactory. DFX curve flash function is based on the the flashloan model in UniswapV2. The user calling flash function must conform to the IFlash.sol
interface. It must containing their own logic along with code to return the correct amount of tokens requested along with its respective fee. Flash function will check for the balances of the curve before and after to ensure that the correct amount of fees has been sent to the treasury as well as funds returned back to the curve.
-
Install Foundry
-
Download all dependencies.
forge install
-
Run Ethereum mainnet forked testnet on your local in one terminal:
anvil -f https://polygon-mainnet.g.alchemy.com/v2/${key} --fork-block-number 44073000
-
In another terminal, run 3 test script:
forge test --match-contract V3Test -vvv -f http://127.0.0.1:8545