๐Ÿ’ต Market Making

Current pool types on the DODO platform include:

  • DODO V2 Market Maker Pools - for professional market makers
  • DODO V2 Single-Token Pools - any user can participate, a unilateral initial liquidity solution
  • DODO V2 Pegged Pools - any user can participate, for synthetic assets
  • DODO V1 Standard Pools - any user can participate, dual currency model

DODO V2 Market Maker Pools #

The DODO V2's Market Maker Pools can be independently marketed by market makers with their own funds, and the Market Maker Pool configuration can be flexibly modified during the market making process. The modifiable factors include the transaction commission rate, the current external guide price I, the curve slippage factor k, as well as the pool's capital size.

All these modifications are made by the accounts that trigger smart contracts to effect dynamic on-chain market-making adjustments.

How it Works #

Market makers can achieve dynamic market-making adjustments by calling the resetDODOPrivatePool method in DODO V2Proxy02 (see the Contract Information page for the address), as defined below๏ผš

function resetDODOPrivatePool(
        address dppAddress,
        uint256[] memory paramList, //0 - newLpFeeRate, 1 - newI, 2 - newK
        uint256[] memory amountList, //0 - baseInAmount, 1 - quoteInAmount, 2 - baseOutAmount, 3- quoteOutAmount
        uint8 flag, // 0 - ERC20, 1 - baseInETH, 2 - quoteInETH, 3 - baseOutETH, 4 - quoteOutETH
        uint256 minBaseReserve,
        uint256 minQuoteReserve,
        uint256 deadLine
) external;

Parameters#

  • dppAddress: private pool contract address
  • paramList: pass in the transaction fee rate, external guide price, curve slippage factor in order, where:
    • Transaction fee rate: the unit is 18 bits, the range is [0, 1e18], where 1e18 represents 100%.
    • External guide price: the unit is 18 bits - baseToken unit + quoteToken unit, the external guide price is the ratio of the base token price to the quote token price.
    • Sliding point system: the unit is 18 bits, the range is [0, 1e18], representing the degree of price curve fluctuation, where 0 is equivalent to the constant selling price, 1e18 is the UniSwap-like AMM price curve
  • amountList: pass in baseInAmount, quoteInAmount, baseOutAmount, quoteOutAmount in order (all in their respective units). The first two represent the number of base and quote tokens to be deposited into the private pool, and the tokens need to be authorized to the DODOApprove contract before they are deposited. Thus, the size of the private pool can be adjusted dynamically.
  • flag: mainly used for exchanges between ETH and WETH, where๏ผš
    • 0 means both base and quote are ERC20 tokens
    • 1 means the transferred base token is ETH, so the contract will automatically convert ETH to WETH
    • 2 means the transferred quote token is ETH, so the contract will automatically convert ETH to WETH
    • 3 means the extracted base token is WETH, so the contract will automatically convert WETH to ETH
    • 4 means the extracted quote token is WETH, so the contract will automatically convert WETH to ETH
  • minBaseReserve and minQuoteReserve are primarily used to reduce front-running trading arbitrage. When the market-making account initiates a trade and modifies the private pool parameters, it may cause a change in the pool price. Therefore, during the time interval between sending out the trade and actually executing it on the chain, robots may front-run the arbitrage. After setting these two parameters, if the existing funds of one party in the pool are less than the set value when the transaction is executed on-chain, the transaction will be reverted by the contract to reduce arbitrage risks.
  • deadline: transaction time limit, after the timeout contract revert

DODOV2Proxy ABI๏ผš

[
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "dppAddress",
        "type": "address"
      },
      {
        "internalType": "uint256[]",
        "name": "paramList",
        "type": "uint256[]"
      },
      {
        "internalType": "uint256[]",
        "name": "amountList",
        "type": "uint256[]"
      },
      {
        "internalType": "uint8",
        "name": "flag",
        "type": "uint8"
      },
      {
        "internalType": "uint256",
        "name": "minBaseReserve",
        "type": "uint256"
      },
      {
        "internalType": "uint256",
        "name": "minQuoteReserve",
        "type": "uint256"
      },
      {
        "internalType": "uint256",
        "name": "deadLine",
        "type": "uint256"
      }
    ],
    "name": "resetDODOPrivatePool",
    "outputs": [],
    "stateMutability": "payable",
    "type": "function"
  }
]

DODO V2 Single-Token and Pegged Pools #

The DODO Single-Token and Pegged Pools are market-making pools that anyone can participate in, and due to the flexible design of DODO, the same pair can have different pools with different parameters, when the user participates in market making, he/she fills the base and quoteassets according to the current ratio of the pool, and gets the amount of shares assets minted by the pool.

Note: shares represent the market maker's share of the asset pool. It is a token in ERC 20 format and can be traded freely. Each public pool corresponds to one type of shares.

 function buyShares(
    address to
 ) external returns (uint256 shares, uint256 baseInput, uint256 quoteInput)

This function enables the injection of liquidity into the pool and requires the market maker to construct a transaction with two operations, the first operation is to deposit tokens into the pool contract in proportion to the pool's current base and quote, and the second operation is to take the shares receiving address as an argument to trigger buyShares. before the end of the transaction, it is recommended that the market maker perform a quantity check on the baseInput and quoteInput to ensure that the transaction is executed safely.

 function sellShares(
     uint256 shareAmount,
     address to,
     uint256 baseMinAmount,
     uint256 quoteMinAmount,
     bytes calldata data,
     uint256 deadline
 ) external returns (uint256 baseAmount, uint256 quoteAmount)

This function enables the extraction of liquidity from the pool, the market maker can directly call the pool corresponding to the function to execute the transaction, where the parameters passed in include the number of shares removed, the address of the funds received, and the baseMinAmount (the minimum number of base expected to be received), quoteMinAmount (the minimum number of quote expected to be received) used for slippage protection. data is generally set to empty, if not empty, the function will be executed at the end of the execution, the implementation of external contract calls to achieve additional functions such as WETH to ETH, the final deadline for the transaction issued after the effective time, the timeout automatically fails to protect the safe execution of the transaction.

DODO V1 Single Currency Market Making #

DODOV1 uses external prophecy machine price guidance for market making, and therefore supports single currency to provide liquidity, involving the following functions:

function depositBaseTo(address to, uint256 amount) external returns (uint256);

function depositQuoteTo(address to, uint256 amount) external returns (uint256);

These two functions enable the injection of one-sided liquidity into the pool, requiring the market maker to construct a transaction with two actions, the first to authorize the injected tokens to the pool, and the second to trigger depositBaseTo or depositQuoteTo

function withdrawBase(uint256 amount) external returns (uint256);

function withdrawQuote(uint256 amount) external returns (uint256);

These two functions enable the withdrawal of one-sided liquidity from the pool.

Note: PMM will issue a recharge bonus or charge a withdrawal fee when the system deviates significantly from equilibrium and the amount of recharges or withdrawals is large. In general, market makers do not need to pay attention to these two components. Of course, traders are more than welcome to top up to earn rewards when the system is out of balance, and then withdraw when the system is balanced to avoid being charged a commission. However, some MEV bots can take this as advantage, making sandwich attack to the LP who is withdrawing liquidity, and gain from the penalty charge. Thus, we don't recommend you to direct call withdraw methods on DODO V1 contract. Instead, you should use our DODOV1Proxy contract to withdraw liquidity.

You can call the below methods on DODOV1Proxy to withdraw liquidity. The parameter minReceive can mitigate MEV bots' attack. If the return amount is less than minReceive, the transaction will be reverted.

function withdrawBase(address pool, uint256 amount, uint256 minReceive) external returns (uint256)

function withdrawQuote(address pool, uint256 amount, uint256 minReceive) external returns (uint256)

function withdrawAllBase(address pool, uint256 minReceive) external returns (uint256)

function withdrawAllQuote(address pool, uint256 minReceive) external returns (uint256)

Deployed DODOV1Proxy contract address:

NetworkAddress
ETH0x8dD0Fea5FA2f7df535F87f312641Cc15d8B151BA
BSC0x4Fc222194862081866FC636893DDeCB3E4341A10
Arbitrum0x49186E32fEd50fd6B5604A2618c7B0b03Cd41414
Polygon0x58E27C46c162F2a781d750BbE1119E1b2DfE82e0