Ordering of trades on Cauldron
Cauldron trades follow a directed acyclic graph (DAG) model, where every trade is directly linked to a previous transaction.
flowchart LR
utxo2([
UTXO:
txid: ac..b2
n: 0
])
utxo3([
UTXO:
txid: 40..24
n: 0
])
utxob([
UTXO:
txid: 9f..32 n: 5
])
trade2[
Transaction A:
1 token
↓
99 sats
]
trade3[
Transaction B:
199 sats
↓
2 token
]
unspent1([
Unspent LP utxo
])
unspent2([
Unspent LP utxo
])
utxo2 --> trade2 --> utxo3
utxo3 --> trade3
utxob --> trade3
trade3 --> unspent1
trade3 --> unspent2
Every liquidity pool has a local state that gets updated with every transaction that interracts with it.
Having trades ordered in a DAG with a local state has several benefits:
-
You know the exact price -- When performing the trade, you know the exact price you'll pay, including slippage. It is not effected by other interactions with a global state. There is no front-running.
-
You know the transaction will succeed or not happen at all -- If your transaction is accepted by a miner, your trade will happen. If it's not accepted, it is simply dropped and you don't pay a network fee.
-
No waiting on block confirmation -- You instantly know the result of a trade, and can continue to perform new actions based on the result. For example transfering them to a wallet. There is no waiting on a block confirmation.
A downside is that miners may choose to drop transactions, or select a conflicting transaction. In this case, also all transactions after a dropped transaction will also be dropped. See article about pending transactions.
Comparison to EVM
Contracts on EVM operate with a global state. The order the miners chooses to accept a transaction within a block matters.
Consider the following transaction order within Block A
:
flowchart TB
subgraph "Block A"
trade1["TX A: Buy 10 token"]
trade2["TX B: Sell 10 token"]
trade3["TX C: Buy 1 token"]
end
In this block, there is a 10 token buy before a sell. Miners could also choose to order the transactions like this:
flowchart TB
subgraph "Block A (alternative)"
trade2["TX B: Sell 10 token"]
trade1["TX A: Buy 10 token"]
trade3["TX C: Buy 1 token"]
end
Because the transactions are not in a DAG, but operate on a global state, the sell order will not be as profitable for the seller if the miner chooses the second transaction order, than if first. This is because the buy order (TX A
) now happens after the sell order (TX B
).
The seller can mitigate this by setting a limitation on allowed slippage and cancel the sell. However, the transaction will still be accepted and mined and the seller will have to pay the network fee, regardless.