DeFiChain Basics: The DeFiChain DEX

solros
BLOCK6
Published in
6 min readApr 25, 2022

After my first more general post about the mechanics of decentralized exchanges, I will put extra focus on DeFiChain in this one and explain some details that are specific to DeFiChain.

What are the “max price” and the “slippage tolerance”?

When submitting a pool swap transaction, you have the option to specify a maximal price that you are willing to pay. The transaction will not be added to a block and hence the swap will not be executed if the price is higher. If a swap with a max price is executed, you will get at least

output ≥ input • (1-fee) / maxPrice

So if you want to swap 1000 DUSD to dTSLA for a max price of 1100 DUSD, the swap fee in the TSLA-DUSD pool is 0.4% and you will get at least 1000 • 0.996 / 1100 = 0.90545455 dTSLA if the swap is executed.

Note that it may happen that you can only swap a smaller amount than you want to swap at your set max price. In such a situation, an order on a centralized exchanges would only be partially execute. On a DEX, however, there are no partial executions. The swap will not go through. You can then of course try again with a smaller amount.

It is also important and interesting to note that while on a centralized exchange there is always a “buy” and a “sell” direction for each trading pair, a DEX is symmetric and both sides are equal. You always buy! (Also you always sell — but the price is defined from a buyer’s perspective.) If you are used to thinking in min prices for selling, you simply need to use the inverse as a max price. For example, if you want to sell TSLA to DUSD for a price of at least 1000 DUSD, you need to set the max price to 1/1000 since you want to pay at most 1/1000 TSLA for one DUSD.

You can only explicitly set the max price via the CLI, but the Light Wallet and the Desktop Wallet since version 2.12.0 offer a simpler alternative — the slippage tolerance. This is specified in percent and defines how much more than the estimated price you are willing to pay. (Note that the estimated amount that is displayed in the app already accounts for fees and slippage caused by your own swap. So the slippage tolerance only needs to allow for the additional slippage caused by other transactions.)

What does “Price is higher than indicated.” mean?

Sometimes — in particular, when you are using the Light Wallet — you may get the above error message. This means that the swap cannot be executed with your set max price.

Most of the time the reason is that there is a huge shift in the pool (by one or more big transactions) coming into the next block and hence the new price will be so far from the previous one that it is outside your slippage tolerance. Usually it is enough to just wait for one block and then try again (but remember to check the new price first since it may have moved more than you expected). In very volatile times, it may take longer. For example, right after some new dToken pools are created, the prices are usually extremely volatile because of the low liquidity and hence it is difficult to get any swap through.

Always use a max price!

Before version 2.12.0 you could not set the max price at all via the Desktop Wallet unless you used the CLI. (Check out the end of this post for the CLI commands.)

Swapping without a max price is extremely dangerous — and there are actual bots exploiting unknowing users who do this. I go into the the details of these attacks in this post, but the short takeaway should be: Unless you really know what you are doing and have a good reason for not using a max price, I would not recommend swapping any bigger amount without setting one (or a slippage tolerance in the Light Wallet).

Since this is so important, let me repeat this again: Do NOT do a huge swap without a max price! Otherwise, you will get hurt!

What about the swap fees?

On DeFiChain, there are different kinds of fees for using a DEX, that are deducted from your input: Each swap always incurs a 0.2% fee that is paid out (in the input token) to the liquidity providers as commission. On some of the pools there are additional fees that get burnt.

Here is a breakdown of the fees for all pools:

  • The crypto-DFI pools (with the exception of BTC-DFI) only have the 0.2% commission: ETH-DFI, USDC-DFI, USDT-DFI, BCH-DFI, LTC-DFI, DOGE-DFI
  • For the BTC-DFI pool, there is an additional 0.1% fee that will be burnt as dBTC in order to remove the excess dBTC produced by the atomic swap exploit. (See here for the DFIP that introduced the fee.) So the total fee is 0.3%.
  • The DUSD-DFI pool has an additional 0.1% fee on DUSD, that will be burnt to reduce the DUSD supply and keep the value of DUSD stable. (See here for the DFIP that introduced the fee.) The total fee is 0.3%.
  • All of the dStock-DUSD pools have an additional 0.2% fee. 0.1% will be burnt as DUSD (introduced with this DFIP), the other 0.1% will be burnt as the dStock (introduced with this DFIP). Hence the total fee is 0.4%.

What is a composite swap?

On DeFiChain, there are only pools for swapping DFI with other cryptos (such as dBTC or dETH), for swapping DUSD with stock tokens and for swapping DUSD with DFI. Here you can see how the tokens are connected. (Note that the picture only shows a subset of the stock tokens — and the list keeps growing.) Each arrow represents one pool.

However, you can also swap tokens that are not directly connected by going through multiple pools. For example, to swap TSLA to AMZN, you need to go TSLA→DUSD and then DUSD→AMZN. To get from BTC to AAPL, you need three pools: BTC→DFI, DFI→DUSD, DUSD→AAPL. A composite swap does all of those swaps in one go.

The max price for the composite swap should be the product of the max prices for the individual swaps. For example, assume you want to swap USDC to AAPL. The pool path is USDC→DFI, DFI→DUSD, DUSD→AAPL. If your max price for swapping USDC to DFI is 4, the max price for DFI→DUSD is 1/4 and the max price for DUSD→APPL is 180, then your max price for the composite swap is the product:

4 USDC/DFI * 1/4 DFI/DUSD * 180 DUSD/APPL = 180 USDC/AAPL

Unfortunately, you will have to pay fees for every pool on the way. In the worst case, this will be 1% (for example for BTC→AAPL: 0.3% + 0.3% + 0.4% — of course when you’re super precise, the fees act multiplicatively, but for such small numbers adding them up gives almost the same result).

What are the CLI commands?

The command to do a pool swap is very aptly called poolswap. The syntax is:

poolswap {"from":"str","tokenFrom":"str","amountFrom":n,"to":"str","tokenTo":"str","maxPrice":n}

For example, to swap 1 AMZN to DUSD with a max price of 1/3,300 (i.e., you want to sell your AMZN for no less than 3,300 DUSD) you would do:

poolswap {"from":"your_address","tokenFrom":"AMZN","amountFrom":1,"to":"your_address","tokenTo":"DUSD","maxPrice":0.00030303}

The max price is optional, but as I’ve explained above you shouldn’t omit it.

The command for a composite swap is compositeswap and has the exact same syntax as the poolswap command. The difference between the two commands is that you can only do poolswap if there is a direct connection between the two tokens you want to swap. However, you can always use compositeswap for every swap. The only disadvantage is that the composite swap will cost slightly more fees because the serialized transaction is a bit longer as it also contains the list of pools to use.

To retrieve the current DEX price using the CLI, you need the command getpoolpair to get information on the pool. For example:

> getpoolpair TSLA-DUSD
{
"18": {
"symbol": "TSLA-DUSD",
"name": "dTSLA-Decentralized USD",
"status": true,
"idTokenA": "16",
"idTokenB": "15",
"dexFeePctTokenA": 0.00100000,
"dexFeeInPctTokenA": 0.00100000,
"dexFeePctTokenB": 0.00100000,
"dexFeeOutPctTokenB": 0.00100000,
"dexFeeInPctTokenB": 0.00100000,
"dexFeeOutPctTokenA": 0.00100000,
"reserveA": 7873.73753224,
"reserveB": 8762889.69646574,
"commission": 0.00200000,
"totalLiquidity": 259681.89149890,
"reserveA/reserveB": 0.00089853,
"reserveB/reserveA": 1112.92631492,
"tradeEnabled": true,
"ownerAddress": "8UAhRuUFCyFUHEPD7qvtj8Zy2HxF5HH5nb",
"blockCommissionA": 0.00000000,
"blockCommissionB": 0.00000000,
"rewardPct": 0.00000000,
"rewardLoanPct": 0.04912800,
"creationTx": "25564a73d7a3a34d27f9c73ee28c84f2db4c2c424020882106b6c6928c70756b",
"creationHeight": 1367578
}
}

The most interesting entries here are:

  • "reserveA": 7873.73753224 and "reserveB": 8762889.69646574 gives us the amounts of token A (here: TSLA) and token B (here: DUSD) in the pool,
  • "reserveA/reserveB:0.00089853 and "reserveB/reserveA:1112.92631492: The ratios of the amounts define the prices. One DUSD costs 0.00089853 TSLA and one TSLA costs 1112.92631492 DUSD.

Contents distributed by Learn.Block6.tech

👉 Telegram — Fresh ideas

👉 Twitter — Latest articles

👉 LinkTr.ee

--

--

solros
BLOCK6
Writer for

Mathematician with a passion for optimization, Python, and blockchain. Likes to teach technical things since that’s the best way to learn them yourself.