Skip to content

Proposal: Composable Transactions #149

@kroggen

Description

@kroggen

COMPOSABLE TRANSACTIONS

It is a method to call many contracts in a single transaction.

All the process is atomic. If some of the calls fail, all the transaction is rolled back.

It is used in cases where the user desires to process many things at the same time atomically.

Use Cases

1: Purchase airplane tickets and hotel reservation from different contracts, only if both succeed. If some of the purchases fail, the other is reverted (the user does not want one of them if the other is not acquired).

2: Swap token and buy something with it. If the purchase fails, the user does not want that token.

3: Swap tokens using a split route. If one of the routes fail, revert the other(s). Also check the minimum output in the transaction itself (by adding individual outputs) and revert if not satisfied.

4: Swap to an exact amount of the output token when using a multi-hop route, by either: a. doing a reverse swap of the surplus amount, or b. querying a contract for the right amount to send (between approved range) in the same transaction.

5: Add liquidity to a pool (2 tokens) in a single transaction

6: Trustless swap or purchase - check if the purchased token was received, otherwise revert the transaction

7: Transferring tokens (fungible and/or non-fungible) to multiple recipients at the same time

8: Transferring different tokens (fungible and/or non-fungible) to one recipient in a single transaction

9: Mint many non-fungible tokens (NFTs) in a single transaction

10: Approve contract B to use contract A (token) and then call a function on contract B that handles the resources on contract A (eg: approve and swap, approve and add liquidity) on a single transaction

11: Approve, use resource, and remove approval on a single transaction, with the guarantee that no other operation would happen in between while the resource/token is approved to contract B

Implementation

It may be possible to implement it with backwards compatibility with existing transactions, by adding a new transaction type:

type: COMPOSABLE_CALL
recipient: <empty>
amount: 0

And then the call information is stored in the payload in JSON format.

It would be a list of calls processed in order

[
  <call 1>
  <call 2>
  <call 3>
]

Each call containing the contract address, function to call, and arguments:

[
  [contract, function, arg1, arg2, arg3...],
  [contract, function, arg1, arg2, arg3...],
  [contract, function, arg1, arg2, arg3...]
]

Example uses:

Buy 2 products or services on a single transaction:

[
  ["<token 1>","transfer","<amount 1>","<shop 1>","buy","product 1"],
  ["<token 2>","transfer","<amount 2>","<shop 2>","buy","product 2"],
]

Acquire token2 via swap and buy a product/service with it:

[
  ["<token 1>","transfer","<amount 1>","<swap pair>","swap",{"exact_output":"<amount 2>"}],
  ["<token 2>","transfer","<amount 2>","<shop>","buy","product"],
]

Add liquidity to a swap pair:

[
  ["<token 1>","transfer","<amount 1>","<swap_pair>","store_token"],
  ["<token 2>","transfer","<amount 2>","<swap_pair>","add_liquidity"],
]

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions