Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transfer coins to free balance opcode #526

Open
dmihal opened this issue Oct 19, 2023 · 0 comments
Open

Transfer coins to free balance opcode #526

dmihal opened this issue Oct 19, 2023 · 0 comments

Comments

@dmihal
Copy link
Contributor

dmihal commented Oct 19, 2023

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 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:

The Identity enum would add an element Script:

pub enum Identity {
    Address: Address,
    ContractId: ContractId,
    Script: (),
}

The transfer function would be updated to include this new Identity value:

pub fn transfer(to: Identity, asset_id: AssetId, amount: u64) {
    match to {
        Identity::Address(addr) => transfer_to_address(addr, asset_id, amount),
        Identity::ContractId(id) => force_transfer_to_contract(id, asset_id, amount),
        Identity::Script => transfer_to_script(asset_id, amount),
    };
}

And the function transfer_to_script would be added:

pub fn transfer_to_script(asset_id: AssetId, amount: u64) {
    asm(r1: amount, r2: asset_id) {
        trf r1 r2;
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant