Supplement

Below is a detailed example execution of AnyHedge on Bitcoin Cash.

  • imaginary_username (im_uname#102)
  • John Nieri (emergent_reasons#100)
  • Jonathan Silverblood (Jonathan#100)
  • Correspondence: anyhedge@generalprotocols.com

Introduction

As in the AnyHedge whitepaper, section "6. High level execution of AnyHedge", we describe AnyHedge in four steps with the US Dollar (USD) as the external asset. In detail, all price values are stored as US Cents, but written as US Dollars with 2 decimal places. In this description, we use an existing implementation of AnyHedge on Bitcoin Cash and describe all detailed steps as they occur both outside and inside the contract.

It is important to note that due to Bitcoin Cash script limitations, all price-related values are inverted compared to the convention described in the whitepaper, section "5. Regarding price orientation". For example

  • The implementation uses BCH prices (USD per BCH) instead of USD prices (BCH per USD).
  • The low boundary becomes the high boundary, and vice versa.
  • The USD Short becomes a BCH Long, but we have not reversed this naming convention.

A) Intent

B) Contract parameters

C) Funding

D) Redemption

A) Intent

The intent of the contract can be described with a few settings.

  • hedge_value Fixed Value that Hedge wants to preserve until Maturity. An example range for hedged US Cents or any external unit is [10 ~ 1,000,000,000].
  • start_price_units_per_bch The start price for the contract. Note that this is a BCH price (US cents per BCH), inverted from the rest of this paper. An example range for US cents per BCH or any Unit per BCH is [100 ~ 1,000,000]
  • largest_allowed_price_drop A percentage specifying how far the US cents per BCH price can decrease from the start price before liquidation. This determines the size of the Volatility Pool collateral that Short must provide. When the allowed drop is small, Short provides less BCH than Hedge, the impact of price changes is amplified for Short, and the contract has less resistance to volatility. When the allowed drop increases to 50%, Short and Hedge provide the same amount of BCH, the impact of price changes becomes comparable for both, and the contract has more resistance to volatility. Note that this is a US cents per BCH price drop, inverted from the rest of this paper. Additionally compared to a BCH per US cent price rise from low to high, the US cents per BCH price drop from high to low must be re-calculated as rise/(1+rise). That is, a 100% BCH per US cent price rise is equivalent to a 1/(1+1) = 50% US cents per BCH price drop. An example range is [1% ~ 50%].
  • start_block The contract can be liquidated on or after this block. We expect this block to be set very close to the funding transaction's block.
  • maturity_block The contract can be redeemed on or after this block. This is a reliable proxy for a maturity date from hours to years.
  • oracle_pubkey Hedge and Short must identify an oracle that they trust to provide reliable price data. This is the public key that Oracle uses to sign price messages.

Hedge and Short agree on the following intent.

hedge_value =                100,000 US cents (1,000.00 USD)
start_price_units_per_bch =  22,222 US cents per BCH; (222.22 USD per BCH, 0.000045 BCH per US cent)
largest_allowed_price_drop = 25%
start_block =                615644
maturity_block =             616652 (+1 week from start_block)
oracle_pubkey =              Public key provided by Oracle
redemption_addresses =       Addresses provided by Hedge and Short to receive funds at redemption

B) Contract parameters

Part of the final contract parameters can be calculated in a straightforward way.

  • liquidation_price_low_units_per_bch When the US cents per BCH price decreases, this is the earliest price that triggers liquidation. Note that this is a US cents per BCH price, inverted from the rest of this paper.

    liquidation_price_low_units_per_bch
      = round(start_price_bch_per_unit * (1 - largest_allowed_price_drop))
      = 16,667 US cents per BCH; (166.67 USD per BCH, 0.00006 BCH per US cent)
    
  • liquidation_price_high_units_per_bch When the US cents per BCH price increases, this is the earliest price that triggers liquidation. At the extreme, a US cents per BCH price increase consumes Hedge's BCH until 1 satoshi covers the entire hedge value. However here we use a fixed large increase (1,000%) that effectively avoids liquidation due to price increases, but also ensures that liquidation will work in such an extreme case. Note that this is a US cents per BCH price, inverted from the rest of this paper.

    liquidation_price_high_units_per_bch
      = round(start_price_units_per_bch * (1 + 10)); i.e. static 1,000% price rise
      = 244,442 US cents per BCH; (2,444.42 USD per BCH, 0.00000409 BCH per US cent)
    

The remaining contract parameters require additional complexity to make the contract work with large numbers.

  • hedge_satoshis_in This value is not stored in the contract but is required for funding and for further calculations. It is the primary amount of satoshis that Hedge must pay into the contract, ignoring any mining or other fees.

    hedge_satoshis_in
      = round(hedge_value * 10^8 / start_price_units_per_bch)
      = 450,004,500 satoshis
    
  • hedge_value_X_sats_per_bch_hightruncation This is fundamentally the original hedge_value. However this implementation uses two modifications to get around current Bitcoin Cash script limitations.

    First, Bitcoin Cash script currently has a division operator but lacks a multiplication operator. Therefore this implementation pre-computes a compound integer with the units units*satoshis_per_BCH so that a division by USD per BCH price will result in payout satoshis. First it pre-calculates an imprecise version of the compound number.

    imprecise_hedge_value_X_sats_per_bch
      = round(hedge_satoshis_in * start_price_units_per_bch)
      = 9,999,999,999,000 US cents*satoshis_per_BCH
    

    Second, math operation size limits require positive integers to be 2^31 - 1 = 2,147,483,647 or less. Direct use of imprecise_hedge_value_X_sats_per_bch would limit AnyHedge to (2^31 - 1) (units*satoshis_per_BCH) / 100,000,000 (satoshis_per_BCH) = about 21 units. This integer is too small and imprecise for financial transactions. Therefore this implementation uses a truncation scheme which sacrifices some precision for the ability to use much larger numbers. A minimal number of bytes, n_hightruncation_bytes, is truncated from imprecise_hedge_value_X_sats_per_bch so that the result fits within the 2^31 - 1 positive integer limit. With n_hightruncation_bytes <= 4, this implementation allows units up to (2^63 - 1) (units*satoshis_per_BCH) / 100,000,000 (satoshis_per_BCH) = about 92 billion units, for example 922 million USD when measured in US Cents. The result is a truncated number that has lost some precision from the original.

    n_hightruncation_bytes = 2
    hedge_value_X_sats_per_bch_hightruncation
      = floor(imprecise_hedge_value_X_sats_per_bch / 2^(n_hightruncation_bytes * 8))
      = 152,587,890 US cents*satoshis_per_BCH
    
  • total_satoshis_lowtruncation This is the combined pool of BCH that the Hedge and Short pay into the contract and that is split when the contract is redeemed. The size of the pool is calculated so that there is enough BCH to cover Hedge's value at the lowest allowed USD per BCH price. Again this implementation uses the truncation technique to allow larger numbers.

    For a simple integer, the largest value of 2^31 - 1 satoshis is about 21 BCH. With n_lowtruncation_bytes <= 4 of truncation similar to above, this implementation allows any scale of satoshis.

    First this implementation calculates a temporary number that will change after truncation.

    imprecise_total_satoshis
      = ceiling(hedge_value * 10^8 / liquidation_price_low_units_per_bch)
      = 599,988,001 satoshis
    

    Finally it performs the same truncation process as above.

    n_lowtruncation_bytes = 0
    total_satoshis_lowtruncation
      = floor(imprecise_total_satoshis / 2^(8 * n_lowtruncation_bytes))
      = 599,988,001 satoshis (no truncation)
    

The final set of values stored in the contract is as follows.

start_block =    615644
maturity_block = 616652 (+1 week from start_block)
oracle_pubkey = Public key provided by Oracle
redemption_addresses = Hedge and Short addresses

liquidation_price_low_units_per_bch
  = 16,667 US cents per BCH; (166.67 USD per BCH, 0.00006 BCH per US cent)
liquidation_price_high_units_per_bch
  = 244,442 US cents per BCH; (2,444.42 USD per BCH, 0.00000409 BCH per US cent)

n_hightruncation_bytes = 2
hedge_value_X_sats_per_bch_hightruncation
  = 152,587,890 US cents*satoshis_per_BCH

n_lowtruncation_bytes = 0
total_satoshis_lowtruncation
  = 599,988,001 satoshis (no truncation)

C) Funding

Hedge and Short pay into the AnyHedge contract as follows.

hedge_satoshis_in
  = round(hedge_value * 10^8 / start_price_units_per_bch)
  = 450,004,500 satoshis

short_satoshis_in
  = total_satoshis_lowtruncation * 2^(8 * n_lowtruncation_bytes) - hedge_satoshis_in
  = 149,983,501 satoshis

Due to bearish market conditions for USD relative to BCH at the time of contract creation, Short also agrees to pay a premium to Hedge as part of the funding transaction.

D) Redemption

After funding the contract, there are 3 different types of redemption that Hedge and Short can do: maturity, liquidation and mutual redemption.

D-1) Redemption under Maturity conditions

First we describe redemption at Maturity, the standard outcome.

After 1 week, the contract reaches Maturity where the the current block is equal to maturity_block, and can be matured. Oracle provides a message with a price, time stamp and intra-block sequence counter, and the contract verifies that the signature is valid against oracle_pubkey. In order to ensure that the contract is redeemed with the price at Maturity, the contract verifies that the time stamp in the message is for the maturity date. In order to uniquely identify the Maturity price, the contract further verifies that the message's intra-block sequence counter is for the first message of maturity_block.

  • end_price_units_per_bch In order to ensure a valid calculation of payout for Hedge's Fixed Value, the contract creates a new value end_price_units_per_bch which is clamped within the allowed boundaries of liquidation_price_low_units_per_bch and liquidation_price_high_units_per_bch. The price in the message is 25000 US cents per BCH; (0.00004 BCH per USD) and is already within the allowed boundaries. Therefore end_price_units_per_bch is equal to the message price.

    end_price_units_per_bch = 25000 US cents per BCH; (0.00004 BCH per USD)
    
  • hedge_satoshis_out_lowtruncation Operating within the high truncation range of hedge_value_X_sats_per_bch_hightruncation, the contract calculates the satoshis to be paid to Hedge based on the end_price_units_per_bch.

    In order to calculate Short's satoshis, the contract un-truncates hedge_satoshis_out_hightruncation down to the low truncation range of total_satoshis_lowtruncation.

    In addition to the un-truncation of hedge_satoshis_out_hightruncation, we also recover some precision when there is a difference between n_hightruncation_bytes and n_lowtruncation_bytes by un-truncating the modulo of the division above. This takes advantage of the relationship for positive integers where / indicates full precision division, // indicates integer division, and % indicates modulo operation.

    normal integer division
    (v/p) = (v//p) + (v%p)/p
    
    normal integer division with un-truncation
    (v/p)*2^x = (v//p)*2^x + ((v%p)/p)*2^x << this last term becomes zero for normal integer division
    
    however we can recover precision by re-arranging as
    (v/p)*2^x = (v//p)*2^x + ((v%p)*2^x)/p
    
    and then re-applying the integer division relationship:
    (v/p)*2^x = (v//p)*2^x + ((v%p)*2^x)//p + (((v%p)*2^x)%p)/p << this last term is still zero
    

    Specific calculations are described in detail below. Note that un-truncation is written as a multiplication but in the contract it is actually a concatenation of the appropriate number zeroes onto the low bytes.

    hedge_satoshis_out_lowtrunc
      =   hedge_satoshis_out_lowtrunc_div_result
        + hedge_satoshis_out_lowtrunc_mod_result
    
      =   (hedge_value_X_sats_per_bch_hightruncation // end_price_units_per_bch) * 2^(8 * n_hightrunc_bytes)
    
        + (hedge_value_X_sats_per_bch_hightruncation %  end_price_units_per_bch) * 2^(8 * n_hightrunc_bytes)
                                                     // end_price_units_per_bch
      = 399,966,208
        +    33,790
      = 399,999,998 satoshis (truncated)
    
  • short_satoshis_out_lowtruncation Now operating within the low truncation range of total_satoshis_lowtruncation, the contract calculates the satoshis to be paid to Hedge based on the end_price_units_per_bch.

    short_satoshis_out_lowtrunc
      = total_satoshis_lowtruncation - hedge_satoshis_out_lowtruncation
      = 199,988,003 satoshis (truncated)
    
  • hedge_satoshis_out_unsafe and short_satoshis_out_unsafe The contract then un-truncates so that the output values are full size numbers.

    hedge_satoshis_out_unsafe
      = hedge_satoshis_out_lowtruncation * 2^(8 * n_lowtruncation_bytes)
      = 399,999,998 satoshis
    short_satoshis_out_unsafe
      = short_satoshis_out_lowtruncation * 2^(8 * n_lowtruncation_bytes)
      = 199,988,003 satoshis
    
  • hedge_satoshis_out and short_satoshis_out There is a clear possibility that either output value could be below the dust limit threshold required by rules on the Bitcoin Cash network. In order to ensure that outputs are always safe, the contract injects the dust limit of bytes into the lower bits.

    hedge_satoshis_out
      = hedge_satoshis_out_unsafe bitwise-OR 0x2202000000000000
      = 399,999,998
    short_satoshis_out
      = short_satoshis_out_unsafe bitwise-OR 0x2202000000000000
      = 199,988,003 satoshis
    

The contract then sends hedge_satoshis and short_satoshis to the respective addresses in redemption_addresses. Hedge receives BCH worth exactly their original hedge_value in USD and Short receives more BCH than their original collateral due to the decrease in price of USD during the contract period.

D-2) Redemption under liquidation conditions

Another possible outcome after funding is liquidation. In this case, there is unexpectedly high price volatility that consumes Short's Volatility Pool collateral.

After 4 days, before the contract reaches Maturity, Oracle provides a signed message and the contract validates it as above. Also as above, the contract creates a new value end_price_units_per_bch and clamps it within the allowed price range. The price in the message is 16,600 US cents per BCH; (166.00 USD per BCH, 0.00006024 BCH per US cent) which is less than liquidation_price_low_units_per_bch. Therefore end_price_units_per_bch is clamped to liquidation_price_low_units_per_bch, and liquidation becomes possible because the end price is at the boundary. In order to ensure that the contract is redeemed with a price that occurred before Maturity, the contract verifies that the time stamp in the message is after start_block and before maturity_block.

The contract performs payout with calculations as above but with the different end_price_units_per_bch.

end_price_units_per_bch = 16,667 US cents per BCH; (166.67 USD per BCH, 0.00006 BCH per US cent)

hedge_satoshis_out_lowtrunc
  =   hedge_satoshis_out_lowtrunc_div_result
    + hedge_satoshis_out_lowtrunc_mod_result

  =   (hedge_value_X_sats_per_bch_hightruncation // end_price_units_per_bch) * 2^(8 * n_hightrunc_bytes)

    + (hedge_value_X_sats_per_bch_hightruncation %  end_price_units_per_bch) * 2^(8 * n_hightrunc_bytes)
                                                 // end_price_units_per_bch
  = 599,982,080
    +     5,917
  = 599,987,997 satoshis (truncated)

short_satoshis_out_lowtrunc
  = total_satoshis_lowtruncation - hedge_satoshis_out_lowtruncation
  = 4 satoshis (truncated)

hedge_satoshis_out_unsafe
  = hedge_satoshis_out_lowtruncation * 2^(8 * n_lowtruncation_bytes)
  = 599,987,997 satoshis
short_satoshis_out_unsafe
  = short_satoshis_out_lowtruncation * 2^(8 * n_lowtruncation_bytes)
  = 4 satoshis

hedge_satoshis_out
  = hedge_satoshis_out_unsafe bitwise-OR 0x2202000000000000
  = 599,988,031
short_satoshis_out
  = short_satoshis_out_unsafe bitwise-OR 0x2202000000000000
  = 550 satoshis

D-3) Mutual redemption

The last redemption available to AnyHedge is a failsafe mechanism. Hedge and Short can pay out all funds in the contract in any way they want as long as they both agree.

After 2 days, Hedge would like to exit the contract early and agrees on a split and a fee with Short. In a single trustless transaction, they submit their signatures, split total_satoshis, and Hedge pays the agreed fee to Short.

Third party audit of mathematical soundness.

We take the reliability of our protocols very seriously, so we had a third party do a mathematical analysis of the AnyHedge protocol.

Read the results