You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Right now, it's generally not possible to do an atomic DEX arbitrage. This issue addresses the simplest scenario, two AMMs, and follow-up issues will address the issues with swapping between things like predicate-based order books.
Scenario
An arbitrageur would like to arbitrage the price of an asset across two AMMs. To do this, they'll need to execute a swap on one AMM, receive the resulting assets, and then provide them to the second AMM to execute the second swap.
Generally, a script would simply execute both swaps. However, it's not possible for the output of the first swap to be re-used as an input for the second swap directly from a script.
A workaround solution is to deploy a smart contract that can receive the funds from the first swap, and then call the second swap. However, requiring this smart contract to be deployed diminishes the advantages of having transaction scripts. Given that arbitrageurs would likely deploy one contract and re-use it for all arbitrage trades, this would reduce the ability to execute these arbitrage trades in parallel.
Solution
TRF opcode: Transfer coins to free balance
The FuelVM currently has two token transfer opcodes: TR transfers balance from the current context to the balance of a smart contract, and TRO transfers balance from the current context to a variable output coin.
A new opcode, TRF, would transfer balance from the current context to the "free balance".
Description
Transfer $rA coins with asset ID at $rB to the free balance.
Operation
transferfree($rA, MEM[$rB, 32]);
Syntax
trf $rA, $rB
Encoding
0x00 rA rB -
Effects
Balance tree read, balance tree write
Panic if:
$rB + 32 overflows
$rB + 32 > VM_MAX_RAM
Called from an external context
In an internal context, if $rA is greater than the balance of asset ID MEM[$rB, 32] of output with contract ID MEM[$fp, 32]
$rA == 0
There are already MAX_INPUTS free balances, of which none are 0
Append a receipt to the list of receipts, modifying tx.receiptsRoot:
name
type
description
type
ReceiptType
ReceiptType.TransferFree
from
byte[32]
Contract ID of current context
amount
uint64
Amount of coins transferred.
asset_id
byte[32]
asset ID of coins transferred.
pc
uint64
Value of register $pc.
is
uint64
Value of register $is.
Increase MEM[balanceOfStart(MEM[$rB, 32]), 8] by $rA. Decrease asset ID MEM[$rB, 32] balance of output with contract ID MEM[$fp, 32] by $rA.
This modifies the balanceRoot field of the appropriate output(s).
Sway
This change would be accommodated in the Sway standard library as follows:
Problem
Right now, it's generally not possible to do an atomic DEX arbitrage. This issue addresses the simplest scenario, two AMMs, and follow-up issues will address the issues with swapping between things like predicate-based order books.
Scenario
An arbitrageur would like to arbitrage the price of an asset across two AMMs. To do this, they'll need to execute a swap on one AMM, receive the resulting assets, and then provide them to the second AMM to execute the second swap.
Generally, a script would simply execute both swaps. However, it's not possible for the output of the first swap to be re-used as an input for the second swap directly from a script.
A workaround solution is to deploy a smart contract that can receive the funds from the first swap, and then call the second swap. However, requiring this smart contract to be deployed diminishes the advantages of having transaction scripts. Given that arbitrageurs would likely deploy one contract and re-use it for all arbitrage trades, this would reduce the ability to execute these arbitrage trades in parallel.
Solution
TRF
opcode: Transfer coins to free balanceThe FuelVM currently has two token transfer opcodes:
TR
transfers balance from the current context to the balance of a smart contract, andTRO
transfers balance from the current context to a variable output coin.A new opcode,
TRF
, would transfer balance from the current context to the "free balance".transferfree($rA, MEM[$rB, 32]);
trf $rA, $rB
0x00 rA rB -
Panic if:
$rA
is greater than the balance of asset IDMEM[$rB, 32]
of output with contract IDMEM[$fp, 32]
MAX_INPUTS
free balances, of which none are 0Append a receipt to the list of receipts, modifying tx.receiptsRoot:
ReceiptType.TransferFree
Increase
MEM[balanceOfStart(MEM[$rB, 32]), 8]
by$rA
. Decrease asset IDMEM[$rB, 32]
balance of output with contract IDMEM[$fp, 32]
by$rA
.This modifies the balanceRoot field of the appropriate output(s).
Sway
This change would be accommodated in the Sway standard library as follows:
The
Identity
enum would add an elementScript
:The
transfer
function would be updated to include this new Identity value:And the function
transfer_to_script
would be added:The text was updated successfully, but these errors were encountered: