Below is a detailed example execution of AnyHedge on Bitcoin Cash.
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
B) Contract parameters
The intent of the contract can be described with a few settings.
hedge_valueFixed 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_bchThe 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_dropA 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_blockThe 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_blockThe contract can be redeemed on or after this block. This is a reliable proxy for a maturity date from hours to years.
oracle_pubkeyHedge 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
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)
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.
After funding the contract, there are 3 different types of redemption that Hedge and Short can do: maturity, liquidation and mutual redemption.
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
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_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
In order to calculate Short's satoshis, the contract un-truncates
hedge_satoshis_out_hightruncation down to the low truncation range of
In addition to the un-truncation of
hedge_satoshis_out_hightruncation, we also recover some precision when there is a difference between
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
short_satoshis_out_lowtrunc = total_satoshis_lowtruncation - hedge_satoshis_out_lowtruncation = 199,988,003 satoshis (truncated)
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
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
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.
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
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
The contract performs payout with calculations as above but with the different
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
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.
We take the reliability of our protocols very seriously, so we had a third party do a mathematical analysis of the AnyHedge protocol.