Document Instructions and various network's integrations

Tracking issue: https://github.com/serai-dex/serai/issues/57
This commit is contained in:
Luke Parker 2022-07-21 03:14:29 -04:00
parent 194c5acebb
commit ae3525ca2c
4 changed files with 216 additions and 0 deletions

View file

@ -0,0 +1,23 @@
# Bitcoin
### Addresses
Bitcoin addresses are an enum, defined as follows:
- `p2pkh`: 20-byte hash.
- `p2sh`: 20-byte hash.
- `p2wpkh`: 20-byte hash.
- `p2wsh`: 32-byte hash.
- `p2tr`: 32-byte key.
### In Instructions
Bitcoin In Instructions are present via the transaction's last output in the
form of `OP_RETURN`, and accordingly limited to 80 bytes. `origin` is
automatically set to the transaction's first input's address, if recognized.
If it's not recognized, an address of the multisig's current Bitcoin address is
used, causing any failure to become a donation.
### Out Instructions
Out Instructions ignore `data`.

View file

@ -0,0 +1,16 @@
# Ethereum
### Addresses
Ethereum addresses are 20-byte hashes.
### In Instructions
Ethereum In Instructions are present via being appended to the calldata
transferring funds to Serai. `origin` is automatically set to the party from
which funds are being transferred. For an ERC20, this is `from`. For ETH, this
is the caller. `data` is limited to 255 bytes.
### Out Instructions
`data` is limited to 255 bytes.

View file

@ -0,0 +1,153 @@
# Instructions
Instructions have two forms, In and Out. For a transaction originating on a
connected network, an In Instruction must be provided, which may embed an Out
Instruction. For a transaction originating on Serai, only an Out Instruction is
allowed. Additionally, short hand forms are provided to minimize representations
on connected networks.
Instructions are interpreted according to their non-Serai network. Addresses
have no validation performed, beyond being a valid enum entry (when applicable)
of the correct length, unless otherwise noted. If the processor is instructed to
act on invalid data, or send to itself, it will drop the entire instruction.
### Serialization
- Numbers are exclusively unsigned and encoded as compact integers under
SCALE. If omitted, `0`.
- Enums are prefixed by an ordinal byte of their type, followed by their
actual values.
- Vectors are prefixed by their length. If omitted, `vec![]`.
- Instruction fields are numbered and sequentially encoded, each prefixed by
an ordinal byte. All other fields are sequentially encoded with no markers.
Certain fields may be omitted depending on the network in question.
### In Instructions
- `origin` (Address): Address from the network of origin which sent funds in.
- `target` (Address): The ink! contract to transfer the incoming funds to.
- `data` (Vec<u8>): The data to call the target with.
Networks may automatically provide `origin`. If they do, the instruction may
still provide `origin`, overriding the automatically provided value. If no
`origin` is provided, the instruction is dropped.
Upon receiving funds, the respective Serai Asset contract is called, minting the
appropriate amount of coins, and transferring them to the specified target with
the attached data.
If the transaction fails, funds are scheduled to be returned to `origin`.
### Out Instructions
- `destination` (Network, Address): Address to receive funds to.
- `data` (Vec<u8>): The data to call the target with.
If the network is Serai, this is a transfer. Else, it's a withdrawal to the
specified address with the specified data. Asset contracts perform no validation
on these fields.
### Shorthand
All In Instructions are encoded as Shorthand. Shorthand is an enum which expands
to an In Instruction.
##### Raw
Raw Shorthand encodes a raw In Instruction with no further processing. This In
Instruction is serialized as if it was top-level.
##### Swap
- `coin` (Coin): Coin to swap funds for.
- `minimum` (Amount): Minimum amount of `coin` to receive.
- `out` (Out Instruction): Final destination for funds.
which expands to:
```
In Instruction {
target: Router,
data: swap(Incoming Asset, out, minimum)
}
```
where `swap` is a function which:
- Swaps the incoming funds for SRI.
- Swaps the SRI for `coin`.
- Checks the amount of `coin` received is greater than `minimum`.
- Executes `out` with the amount of `coin` received.
For a Bitcoin to Monero swap, Swap Shorthand is expected to generally take:
- 1 byte to identify as Swap
- 1 byte for `coin`
- 4 bytes for `minimum`
- 1 byte for `out`'s `destination` field label
- 1 byte for `out`'s `destination`'s network
- 65 bytes for `out`'s `destination`'s address
Or 73 bytes.
##### Add Liquidity
- `minimum` (Amount): Minimum amount of SRI to receive.
- `gas` (Amount): Amount of SRI to send to `address` to cover gas in the
future.
- `address` (Address): Account to give the created liquidity tokens.
which expands to:
```
In Instruction {
target: Router,
data: swap_and_add_liquidity(Incoming Asset, address, minimum, gas)
}
```
where `swap_and_add_liquidity` is a function which:
- Swaps half of the incoming funds for SRI.
- Checks the amount of SRI received is greater than `minimum`.
- Calls `swap_and_add_liquidity` with the amount of SRI received - `gas`, and
a matching amount of the incoming asset.
- Transfers any leftover funds to `address`.
For adding liquidity from Bitcoin, Add Liquidity Shorthand is expected to
generally take:
- 1 byte to identify as Add Liquidity
- 5 bytes for `minimum`
- 1/4 bytes for `gas`.
- 32 bytes for `address`.
Or 39/42 bytes, depending on whether or not the Serai address already has gas.
### Examples
All examples are assumed to be from Bitcoin.
##### Pong Example
```
In Instruction {
target: Bitcoin Asset Contract,
data: Withdraw(Out Instruction { destination: (Bitcoin, Bitcoin Sender) })
}
```
would cause the created seraiBTC to be transferred to the Bitcoin Asset Contract
and withdrawn to the Bitcoin Sender.
##### Wrap Example
```
In Instruction {
target: Serai Address
}
```
would cause the created seraiBTC to be transferred to the specified Serai
address for usage on Serai.

View file

@ -0,0 +1,24 @@
# Monero
### Addresses
Monero addresses are an enum, defined as follows:
- `standard`: 32-byte key, 32-byte key.
- `subaddress`: 32-byte key, 32-byte key.
- `featured`: 1-byte flags, 32-byte key, 32-byte key.
This definition of Featured Addresses is non-standard given the flags are
intended to be a VarInt, yet as of now, only half of the bits are used, with no
further planned features. Accordingly, it should be fine to fix its length,
which makes it comply with expectations present here. If needed, another enum
entry for a 2-byte flags Featured Address could be added.
### In Instructions
Monero In Instructions are present via `tx.extra`, specifically via inclusion
in a `TX_EXTRA_TAG_PADDING` tag, and accordingly limited to 255 bytes.
### Out Instructions
Out Instructions ignore `data`.