[ADD] SwapOut Dex Aggregation

Merged Heimdall requested to merge dex-test-ex into develop

What is this PR?

This PR make necessary changes to THORNode and Bifrost to support Dex Aggregation

What is Dex Aggregation?

Right now , if you want to swap from BTC -> some ERC20 tokens that are not listed in THORChain , you can do so by

  1. Swap BTC->ETH.ETH
  2. Use Uniswap/Sushiswap or other DEXs to swap ETH.ETH -> the asset you want These can be done using two seperate transactions.

Dex Aggregation is a new feature which will allow user to swap BTC-> any ERC20 asset that is not list on THORChain using a DEX Aggregation contract, which wrap Uniswap/SushiSwap or other DEXs, and this can be done using one transaction

Aggregate Smart Contract

If someone want to add support to Swap out asset using SushiSwap , they will need to create a SushiSwap Dex Aggregation contract , the contract will need to implement a method call swapOut(address,address,uint256)

  1. Final token address
  2. To address
  3. minimum amount for price protection , if minimum amount is 0, means no price protection

A sample implementation of swapOut https://gitlab.com/thorchain/ethereum/eth-router/-/blob/master/contracts/THORChain_Aggregator.sol#L69

Note: Aggregate Smart Contract need to be whitelist by THORChain before it can be used

Swap Memo

In order to support SwapOut DEX Aggregation feature , a few more field added into swap memo.

SWAP:ASSET:DESTADDR:LIM:AFFILIATE:FEE:DEX Aggregator Addr:Final Asset Addr:MinAmountOut

Parameter Nodes Conditions
SWAP The swap handler also s, =
:ASSET The asset identifier. Can be shortened.
:DESTADDR The destination address to send to. Can use THORName.
:LIM The trade limit ie, set 100000000 to get a minimum of 1 full asset, else a refund. Optional
:AFFILIATE The affiliate address. RUNE is sent to Affiliate. Optional. Must be THORName or THOR Address.
:FEE The affiliate fee. Limited from 0 to 1000 Basis Points.
:DEX Aggregator Addr DEX Aggregator address Can use the last x characters of the address to fuzz match it
:Final Asset Addr Final Asset address The asset can be any, don't need to be list in THORChain
:minAmountOut For price protection

Additional ObserveTxIn field

In order to support SwapOut Dex Aggregation feature safely , a few more fields have been added into tx out item

    "chain": "ETH",
    "to_address": "0x3fd2d4ce97b082d4bce3f9fee2a3d60668d2f473",
    "vault_pub_key": "tthorpub1addwnpepq02wq8hwgmwge6p9yzwscyfp0kjv823kres7l7tcv89nn2zfu3jguu5s4qa",
    "coin": {
      "asset": "ETH.ETH",
      "amount": "19053206"
    "memo": "OUT:EA7D80B3EB709319A6577AF6CF4DEFF67975D4F5A93CD8817E7FF04A048D1C5C",
    "max_gas": [
        "asset": "ETH.ETH",
        "amount": "240000",
        "decimals": 8
    "gas_rate": 3,
    "in_hash": "EA7D80B3EB709319A6577AF6CF4DEFF67975D4F5A93CD8817E7FF04A048D1C5C",
    "aggregator": "0x69800327b38A4CeF30367Dec3f64c2f2386f3848",    <-------------------- NEW
    "aggregator_target_asset": "0x0a44986b70527154e9F4290eC14e5f0D1C861822", <-------------------- NEW
    "aggregator_target_limit": "1000" <-------------------- NEW , but optional

Also the same fields have been added to ObservedTx so THORNode can verify that bifrost did send out the transaction per instruction, use the aggregator per instructed , and pass target asset and target limit to the aggregator correctly

How to swap out with dex aggregator?

If i want to swap RUNE to random ERC20 asset that is not list on THORChain , but is list on SushiSwap for example

thornode tx thorchain deposit 200000000000 RUNE '=:ETH.ETH:0x3fd2d4ce97b082d4bce3f9fee2a3d60668d2f473::::2386f3848:0x0a44986b70527154e9F4290eC14e5f0D1C861822' --chain-id thorchain --node tcp://$THORNODE_IP:26657 --from {from user} --keyring-backend=file --yes --gas 20000000


  1. Swap asset is ETH.ETH
  2. 2386f3848 is the last nine characters of the aggregator contract address
  3. 0x0a44986b70527154e9F4290eC14e5f0D1C861822 is the final asset address
  4. Keep in mind SwapOut is best effort, when aggregator contract failed to perform the requested swap , then user will get ETH.ETH instead of the final asset it request
Edited by Heimdall

Merge request reports