diff --git a/docs/integrations/Bitcoin.md b/docs/integrations/Bitcoin.md new file mode 100644 index 00000000..5da1adbe --- /dev/null +++ b/docs/integrations/Bitcoin.md @@ -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`. diff --git a/docs/integrations/Ethereum.md b/docs/integrations/Ethereum.md new file mode 100644 index 00000000..3a563859 --- /dev/null +++ b/docs/integrations/Ethereum.md @@ -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. diff --git a/docs/integrations/Instructions.md b/docs/integrations/Instructions.md new file mode 100644 index 00000000..5f497ee4 --- /dev/null +++ b/docs/integrations/Instructions.md @@ -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): 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): 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. diff --git a/docs/integrations/Monero.md b/docs/integrations/Monero.md new file mode 100644 index 00000000..be5b635d --- /dev/null +++ b/docs/integrations/Monero.md @@ -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`.