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

Product POC: P2P Swap #7

Closed
nud3l opened this issue Sep 7, 2023 · 1 comment
Closed

Product POC: P2P Swap #7

nud3l opened this issue Sep 7, 2023 · 1 comment
Labels

Comments

@nud3l
Copy link
Contributor

nud3l commented Sep 7, 2023

Abstract

Create a P2P marketplace to allow anyone to swap BTC, BRC20s, and ERC20s (including WETH) without a third party.

Motivation

Building out BOB is best done in combination with a use case from which we can draw conclusions which additional features or improvements we need to make to the base layer.

P2P swaps are one of the earliest use cases of cross-chain communication and have the advantage that users can swap directly without giving up custody to anyone. There's currently no P2P swap for BTC and BRC20s that is both cheap and works without a custodian.

Specification

Target time: end of September 2023

Hackathon-level implementation of the P2P swap. The goal of this project is to understand the complexities of developing the P2P marketplace by delivering a usable deployment of the P2P on a testnet rollup that allows swapping testnet BTC, BRC20s, and ERC20s. Mocking of complex parts of the application is highly encouraged to deliver a usable app.

User Requirements

  • Users MUST be able to swap BTC with ERC20s (including WETH)
  • Users MUST be able to swap BTC with BRC20s
  • Users MUST be able to swap BRC20s with other BRC20s
  • Users MUST be able to swap ERC20s with ERC20s
  • Users MUST be able to pay for transaction fees in BTC
  • Users MUST be able to pay for transaction fees in ETH
  • Users MUST NOT give custody of their assets to any other party to achieve the swap

These functions MUST be available for the PoC level.

Protocol Requirements

  • Swaps with BTC or BRC20s MUST be confirmed with a transaction inclusion proof. At the PoC level, tx inclusion proofs MAY use a mocked BTC relay.

Protocol

The protocol follows a simple OTC trade logic for the POC stage. In the future, more complex schemes including off-chain order books, Dutch auctions, and other mechanisms will be explored.

The protocol consists of three parts:

  1. Placing an order: a user selects an asset to sell and the price they are willing to accept. Users can only select tokens to sell that can be locked on the rollup (ERC20s). If users select to buy BTC or BRC20s, they also have to enter a BTC address.
  2. Filling an order: a user fills an existing order by sending the tokens (ERC20s, BTC, BRC20s) requested in the order. Users can partially fill an order, e.g., when an offer specifies to buy 1 BTC for 20 ETH, a user can send 0.5 BTC.
  3. Withdrawing an order: a user withdraws an unfilled order.

Placing an order

  1. User specifies the ERC20 token sell and the amount
  2. User specifies the token to buy and the amount
  3. If the user seeks to buy BTC or BRC20s, the user also enters a BTC address
  4. User submits the order on-chain locking the tokens to sell.

Filling an order

  1. User selects the existing orders (e.g., from a table)
  2. User enters the amount of tokens they are selling
  3. User sees the amount of tokens they are receiving as determined by the price given by the user that created the order
  4. User fills the order by submitting a transaction:
    a. If the user is selling an ERC20, the ERC20 is directly transferred to the user that created the order and order is (partially) filled.
    b. If the user is selling BTC or a BRC20, the user reserves part of the order instantly and has then 6 hours to fill the order on Bitcoin. Once the BTC/BRC20 transaction is sent, a transaction inclusion proof verifies the correctness of sending the BTC/BRC20 and then marks the order as (partially) filled.

It is yet unclear how we ensure unique BTC transactions for proofs.

Withdrawing an order

  1. If there's no pending fulfillments (when sending BTC/BRC20s), a user can withdraw their orders at any time.

Security

  • It is yet unclear how we ensure unique BTC transactions for proofs.
@nud3l nud3l added the roadmap label Sep 7, 2023
@nud3l nud3l changed the title Meta: P2P Swap Product POC: P2P Swap Sep 11, 2023
@sander2
Copy link
Contributor

sander2 commented Oct 3, 2023

It is yet unclear how we ensure unique BTC transactions for proofs.

We had some discussions on the last week. To summarize:

The problems we need to address, are:

  • (1) Double spends: we need to prevent a txo from being used as proof for multiple swaps. This should be relatively straightforward: we can maintain a list of "used" outputs. Whenever an output is being used in a proof, we mark it as used and prevent future proofs from using it.
  • (2) Using pre-existing payments: We should record the relay height at the time when the order was placed, and not allow payments that are older than that. That will avoid a scenario like this (as long as the relay is kept up to date):
    • Alice places an order to buy 1 BTC for 1 WETH. It supplies the address x.
    • Bob sees an existing transfer of 0.1 BTC to x. Bob accepts order for 0.1 BTC
    • Bob uses the existing payment as proof for his transfer
    • Bob receives 0.1 WETH for free.
  • (3) TX stealing: we need to prevent people from using payment not belonging to them. For example, we need to avoid the following scenario:
    • Alice wants to buy 1 BTC for 1 WETH
    • Bob and Charlie both accept for 0.5 BTC
    • Bob sends 0.5 BTC
    • Charlie uses Bob's transfer to get 0.5 WETH
    • Charlie happy, Bob sad

Number 3 is the most difficult to address. We discussed various (non-)possibilities:

  • The OKD system on interlay only works because the vault is automated and can auto-import addresses. On Bob, we could use zkvm to generate deposit addresses if we can generate a secure id from solidity. However, it'd be a problem to get users to import the generated addresses.
  • Similarly to the point above, OP_RETURN only works on interlay because of automation in the vaults. Many wallets don't have op_return support.
  • It might be an option to use taproot transactions to embed extra data. However, also this depends on wallet support, and it is not very user friendly.
  • If we want to support users that make transfers directly from their CEX wallets, then we have very limited options. The only two variables that can be set are then the bitcoin address and the amount.
  • It helps to specify very precise trade volumes, e.g. 1.00000123 BTC rather than 1 BTC. But we've seen that users are not good at sending precise amounts since many wallets subtract fees from the entered amount.

In the end, the most straightforward way to move forward is to disallow partial fulfillment altogether, and to require fresh bitcoin addresses every time. The first restriction is very limiting from a usability perspective.. The second restriction could also be a limiting factor, since some CEX wallets have a limit on how many fresh addresses they can generate.

It was agreed that the poc can be without partial fulfillment, but that we do need to think about a solution in the longer term:

Partial fulfillment is definitely a desirable feature - PoC can be without but we definitely should try to ship it in the next version then because that's pretty standard order book feature

@nud3l nud3l closed this as completed Oct 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants