Skip to content

Instantly share code, notes, and snippets.

@corollari
Last active October 11, 2020 22:06
Show Gist options
  • Save corollari/6db9530ca45062e05e82f7c53417929f to your computer and use it in GitHub Desktop.
Save corollari/6db9530ca45062e05e82f7c53417929f to your computer and use it in GitHub Desktop.
Options on Bitcoin

Building blocks

Let's start by describing it's main building block: the ability to make a reedem script (scriptPubKey in BTC terms) have access to the transaction that is attempting to spend it. This is achievable through several ways:

  • BCH forked in OP_CHECKDATASIG some time ago to enable scripts encumbered by an oracle, but this enabled the construction of covenants as described in [1]
  • Elements/Liquid directly forked in the opcode OP_CHECKSIGFROMSTACK proposed in [1], thus enabling the covenants described in that paper
  • It's possible to check transaction contents by generating a signature for them inside the script and checking that against the real contents through OP_CHECKSIG ([2] describes how to do that for Schnorr signatures, but it is easily adaptable to ECDSA signatures)
    • This would actually be viable on BTC if OP_CHECKSIG could be made to perform primitive operations (such as AND, comparisons...) but I believe that I have mathematically proved that this is impossible (intuition: CHECKSIG does an equality check between curve points, and given that those points form a field, only direct equality between elements can be checked, making it impossible to split a set into two sets with a cardinality higher than 1 with a single operation)
    • Satoshi's BTC had opcodes such as OP_CAT that would make this viable, but these have been disabled, so it turns out that this would have worked fine on the first versions of Bitcoin but not with the current ones
    • Because both Elements and BCH have re-introduced some of the disabled opcodes that would have made this viable, it's also possible to access the spending tx this way instead of through the opcodes mentioned above

Main protocol

Once we have this in place, we can create our first option by following this protocol:

  1. Use an atomic swap to sync these two operations:
  • User pays fee to underwriter
  • Underwriter sends tokenized USD [3] to an address that is encumbered by the script:
    • After X+K blocks:
      • Send to underwriter
    • After X blocks:
      • If tx sends Y BTC to underwriter, send to user
  1. When the option reaches maturity the user can exercise it by sending a transaction that:
  • Sends BTC to underwriter
  • Spends the UTXO created on step 1 and sends it to the user's wallet
  1. If the user doesn't exercise it on time the underwriter can just spend it to itself

Reduction of capital requirement

As it is, this protocol requires locking 100% of the collateral for as long as the option stays in effect, but it would also be possible to reduce the capital requirement quite substantially by changing the protocol to make the underwriter lock only 30-50% initially and, at option expiration, make it provide the rest of the payment in case the user decides to exercise the option. More concretely, this new protocol would look like:

  1. Atomic Swap:
  • User pays fee to underwriter
  • Underwriter sends 50% of the option's collateral in BTC to an address encumbered by the script:
    • After X+K blocks:
      • Send to underwriter
    • After X blocks:
      • If tx has an UTXO that spends 100% of the option's value in BTC, consolidate all UTXOs (150% value) and send it to another address encumbered by the following script:
        • If tx sends the required USD to the user, send the BTC UTXO to the underwriter
        • After K blocks:
          • Send all the value to the user, the extra 50% acts as a punishment for the underwriter
  1. When the option reaches maturity the user can exercise it by sending a transaction that adds BTC to the money locked by the underwriter previously and moves it into another state
  2. After the funds have moved to the "exercised" state, the underwriter will have to provide the promised USD to the user in exchange for BTC, as not doing so will result in them losing the initial 50% deposit

As you have probably already noticed, the downside of this system is that it would require an external oracle along with a re-balancing mechanism to prevent situations where losing the initial deposit is the rational choice for underwriters. Furthemore, it would introduce the assumption that price must not change by over X% within a pre-defined timespan.

Porting it over BTC

This scheme could also be ported over to BTC by using covenants that are constructed through a ceremony where a key is initially created through 2-party ECDSA key creation, which is then used to sign a few transactions that spend different combinations of UTXOs held by underwriter and user.
This would work, but it could be quite messy, as it would require the user to not spend at least one of the UTXO that it used during the ceremony until the day when the option expires (it's also possible to sign a new set of transactions with some new UTXOs before the expiration date, but that further complicates the protocol).

Another option would be going for a atomic-swap-based protocol, but that would require locking both user and underwriter funds, which kind of defeats the point of having an option.

Making it tradeable

As you may have realised, the big problem with all these protocols is that the options that come out of them are not easily tradeable between users.

One way to add tradeability would be by adding a semi-trusted third-party into the protocol that would do a job very similar to the one done by the central party on statechains[4], which when combined with a 2p MPC scheme[5] would reduce the trust model to "3rd party is honest up to the last transfer OR no previous owner cooperates with the 3rd party to steal options". This trust model still places a lot of trust on that 3rd party so it's not that great, but it's better than fully trusting a 3rd party.

Improvements

  • The initial atomic swap for the fee could be easily improved by baking it into the protocol.

References

[1]: Enhancing Bitcoin Transactions with Covenants, Russell O’Connor and Marta Piekarska, https://fc17.ifca.ai/bitcoin/papers/bitcoin17-final28.pdf

[2] https://bitcoincovenants.com/#signature-construction, disclaimer: this is my own research

[3] I've looked into OmniLayer, which is the protocol used to move USDT on the Bitcoin network and they essentially only use BTC transactions for serialization and propagation (the payload is encoded in the txs in a way that is invisible to BTC nodes) so it won't be possible to apply BTC's script to these, instead some sort of USD colored coin needs to be used, for example SLP's USDT on BCH

[4] Statechains, Ruben Somsen, https://github.com/RubenSomsen/rubensomsen.github.io/blob/master/img/statechains.pdf

[5] https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-March/017714.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment