An incentivized scheme for fixed token Future markets

TL;DR

There are two groups of users: A) those who want more coins, B) those who want a higher price (less BCH liquidity). Together they can create a market where they work together toward their individual goals.


Introduction

With the advent of CashTokens, it is now possible to control and track tokens from smart contracts such as the Wrapped BCH contract by @dagurval .

Similar to a wBCH token, creating timelocked futures tokens would also be trivial by modifying the wrapOrUnwrap() function of WrapBCH into placeOrRedeem() to control Bitcoin Cash Futures fungible tokens, locked until some blocktime.

A Futures issuer could send a supply of 21M fungible tokens each representing one coin locked until some block height in the future to the above contract and let anyone encumber coins by swapping them into the contract in return for a tradable token―redeemable at a later date.


A complicated token placement to market loop

It stands to reason, from an intuitive market perspective, that beyond the initial novelty, a Future should eventually sell at a discount to a normal liquid coin―it being less useful immediately. So the person who encumbered the coin will immediately have created a token that will probably then sell for less than what was input. The coin locker might always expect to lose money in the locking process itself.

From the buyer’s perspective however, they’d essentially be buying BCH at a discount; there’s financial incentive for a buyer to buy futures below the face value of the locked coin.

However, the locker that releases tokens from the FutureBCH holding contract however would have a real asset at some price, so they could presumably receive some proceeds from the sale.

A lone locker, or the general practice locking coins to release the Futures, could create a liquid market where the price of a Future token started out below 100%, maybe 90% face value, to gradually increase reaching parity when the locktime was reached.

So the locker could loop some liquidity repeatedly in a geometric series where the sum of the amount locked would be the proportional to one minus the discount.

The amount that could be locked given a sacrificial amount at some market price would be a the sum of a geometric series:

image

image

So a locker with 1 coin, selling Futures at a rate of 0.9 BCH per futureBCH could cause a total of 10 coins to be locked.

A locker with 1 coin able to sell futures at a price of 0.95 BCH per futureBCH could cause 20 coins to be locked… etc.

At 0.99 BCH per futureBCH, one BCH could incentivize locking of 100 BCH. So although it’s literally throwing away coins on leverage, the effect on market liquidity could have an outsized impact if the discount was thin (if buyers were willing to buy futureBCH very near the face value of the underlying coin).

The net result of the extreme case is that the locker paid the buyer a coupon of 1 BCH to lock 100 BCH over the course of hundreds of trades through loops. If the net result is that someone will get paid a coupon for locking a large amount of coins, it’s possible to skip the looping of a geometric series, and the market and just create contracts holding come coupon funds where holders could harvest the coupon incentives at various rates.


So to place BCH and release Futures tokens, there is unnecessary complexity in the amount of “looping” involved, and the margins on the tokens would have to be very tight (+~98%) making trading the Futures on current dexes a non-starter because the fees (~0.3%) should be several hundred sats, or in the thousands when the futures near maturity or the holder will lose their incentive to trade such a narrowly priced asset.


A simplified approach; Skipping the dex and discount loop

If the party incentivizing the creation of the encumbered futures can come to terms with the fact they’re essentially just paying people to save, then the whole rigmarole, the looping, as well as a necessary stop on the open market can be skipped, and Alice can just go take a coupon in one transaction with one tiny transaction fee:

Input Output
FutureBCH(900000).function.placeOrRedeem(false) 1 FutureBCH => 1 BCH
aliceTemplate.unlockP2PKH() 99.8M sats => 1 FutureBCH
Coupon(900000).function.apply() 200k sats -

One really simple and extremely flexible way to specify an arbitrary coupon down to the millionth of a percent would be to just have the FutureCoupon contract only spend a single output and restrict locking to whole coins.

So if someone wanted to offer a coupon of 100k sat for locking 100M sats, they could send a utxo (or stream of them) at the Coupon contract, and they’d eventually get harvested as maturity date for the FutureContract approached.

For a CashScript 0.10.0-next generated Bitauth dubugging URL authenticaion template click HERE

In CashScript, using BIP65’s OP_CHECKLOCKTIMEVERIFY for a fixed locktime in blocks.

pragma cashscript ^0.10.0;

// Future BCH fungible token vault
//
//      Inputs: 00-covenant
//      Outputs: 00-covenant
//
//     [WIP] 2024-02-19 
//
//      enforcing token Category prevents coupons from being 
//        claimed on from random tokens sent to contract
// 

contract FutureBCH(int locktime, bytes tokenCategory) {

    function placeOrRedeem(bool isRedeem) {

        //  Flow
        //  00 contract    ->  00 contract
        //  01 userPkh     =>  01 userPkh
        //  02 coupons     ^

        // enforce BIP65 timelocks and the direction of the swap 
        if(isRedeem){
          // tokens may be redeemed in any amount after the future has matured
          require(tx.time >= locktime);
          require(tx.inputs[1].tokenCategory == tokenCategory);
        } else{
          // otherwise, only whole coins may be "placed" or locked
          // And the token id must match a pre-configured token
          require(tx.inputs[0].tokenAmount == 100000000);
          require(tx.inputs[0].tokenCategory == tokenCategory);
          require(tx.inputs[1].value == 100000000);
          require(tx.outputs[1].tokenCategory == tokenCategory);
        }

        // Enforce that this contract lives on
        require(
          tx.outputs[this.activeInputIndex].lockingBytecode 
          == 
          tx.inputs[this.activeInputIndex].lockingBytecode, 
          "locking bytecode index mismatch"
          );

        require(
          tx.inputs[this.activeInputIndex].tokenAmount + 
          tx.inputs[this.activeInputIndex].value 
          == 
          tx.outputs[this.activeInputIndex].tokenAmount + 
          tx.outputs[this.activeInputIndex].value,
         "summation mismatch"
         );
    }
}

A coupon contract isn’t necessarily specific to being used for futures. To restrict spending of a utxo toward a single contract seems straight-forward:

pragma cashscript ^0.10.0;

// Restrict output of any utxo to a preconfigured address

contract Coupon(
  // Locking bytecode the coupon will be applied to
  bytes destinationLockingBytecode
){
  function apply() {
    // Require all utxos be spent atomically
    require(tx.inputs.length == 1);
    require(tx.outputs.length == 1);

    // assure at the entire amount minus a transaction fee
    // goes to the intended output 
    int appliedAmount = tx.inputs[0].value - 1500;
    require(tx.outputs[0].value >= appliedAmount);

    // Check that the first output 
    // sends to the intended recipient. 
    require(
      tx.outputs[0].lockingBytecode 
      == destinationLockingBytecode
    );
  }
}

Given the bitcoin reward schedule, it might make sense to align contract expiration with intervals pertaining to block rewards. i.e. 210,000 cycle multi-year periods, 1000 block increments for weeklies, etc.


Market Example

Bob sends a small output as a coupon for Alice to place coins in a timelock. The coupon acts as a standing irrevocable bid in an open ended auction terminating at contract expiration. Once Alice places her coin in the vault, it may only be withdrawn after expiration for a corresponding amount of tokens. However, if Alice wants liquidity in the meantime, she may then sell her dated futures tokens on the open market.

Bob may send 1000 sats toward a coupon to lock 100M sats for 1000 blocks (1 week). This is not incentive for Alice to open a wallet or move coins, so the coupon is left unused.

Bob, frustrated and impatient, might dispense an array of UTXOs to the coupon contract in increments of 10k (20k, 30k, … 200k) until Alice decides that 0.2M sats is sufficient incentive to place 100M sats for one week. The process of locking is easy enough, she takes the 190k sat coupon too.

BANG! Price discovery. Alice has decided with the help of Bob, that the prevailing spot rate of interest on Bitcoin Cash futures will be 0.19% on the week, or an annualized rate of 10.374%.

The following day, with 900 blocks until expiration, the 180k and 170k coupons are exceed the 0.19% rate, and Charlie locks two coins taking those coupons.

With this simple standing auction, Alice and Charlie locked a total of 400M sats for a nominal interest rate of 10% APR, and Bob has cause 400M coins to become locked until payday for the low low price of 2.1M sats.

It is conceivable, if the week continues, that new buyers may collect the smaller coupons closer to expiration and Bob may cause 21 BCH to be locked with his 2.1M sats by the end of the week. If not, unclaimed coupons may be collected after the contract lock time has been exceeded.


This is an adaptation of some thoughts of how to do futures (w/o tokens)… @emergent_reasons.

Anyway, I’ve tried to go through the potential market dynamics and game theory. I think the quickest way to deep liquidity with these assets is to skip the DEX and load the incentive explicitly as a coupon.

3 Likes

Coupon incentive failure and recovery with standing irrevocable bids.

The coupon approach leads to a novel effect as the time to redemption approaches.

Presume Bob, or the coupon issuer, is doing a one dollar lulz to incentivize Alice to lock a whole coin. Once a coupon issuer sends an output to the coupon contract, it cannot be undone or retracted. A coupon that was too low cannot be revised upward, the coupon incentive auction fails.

However, since the number of blocks to expiration is decreasing, the effective rate of return on every coupon is increasing inversely proportional to the number of blocks remaining. Eventually, the incentive to lock a coin is simply the coupon over one block, then, after the specified blocktime, there is no timelock necessary and the coupon is entirely MEV or anyone-can-spend―as long as it passes through the Vault contract.

For example, there are 100M sats in a coin, and about 53k block in a year―so a annualized rate of 1% translates to a coupon rate of about 19 sats per coin per block. Suppose the market price of one coin is $300, and one dollar is about 330k sats.

If Bob were to issue a coupon for a contract expiring a year from now, a coupon offering 0.3% return may not incentivize Alice (or anyone) to lock a coin. Or another way to put it, a coupon with a rate of 6.3 sats per coin per block may be too low to incentivize the market.

However, eight months on, assuming no one claimed it, Bob’s 330k coupon would still exist as a “coupon” for futures redeemable in about four months. The rate of return on the same “coupon” has tripled to about 19 sats per coin per block and it’s headed northward. Two months, a week, one day prior to expiration, the rate would be 38, 330 and 12.3k sats per coin per block, respectively. One block prior to expiration, the “coupon no one wanted” would pay 330k sats for someone to lock one BCH for a single block.

Throughout the irrevocable bid lulz process, Bob never has to interact or do anything to incrementally boost the rate of return on his coupon bid. Once the coupon is placed, it becomes a matter of when, rather than if, it will be claimed.

1 Like

This is a super fantastic idea. I would use it on both sides probably.

I’m happy to donate a few sats to incentivise rising BCH TVL, and incentivise people to learn & practice self custody.

I’d also love to get a yield just for locking coins that are going to sit anyway.

What kind of UI is going to come with the Flipstarter proposal? Hopefully something snazzy, the idea is already great but if it has a nice UI and a cool progress bar showing TVL rising and stuff I’ll be super impressed.

Also, this will be a killer app to get onto DeFi Llama tracking once it is ready.

There’s a couple different roles, and the UI kind of starts at the contract level.

For degens:

People are going to open some wallet connected webapp and be presented with a table of free money. With some potentially stupid rates at the outset of the app.

They’ll be able to toggle between their preferred rate display method (APR, compounded APR*, sats per block etc.) Degens will be able to pick coupons up manually, or set a rate to collect any coupon at a certain threshold.

Once we get a degen or two into auto-degen couponing, they’re going to start looking at the rate history chart and realize there are other people more or less degen than them, and they can work out together what the market rate should be for coupon takers.

This is just a data table or a list, sorted by rate with some warnings to keep them from locking their coins a crazy amount of time accidentally. Every contract expiration will be shown with the blocktime, and the estimated calendar date of maturation.

They’re going to get something like a yield curve chart and table to stare at, with the latest rate for each expiration in one place.

For coupon writers:

Coupon writers drop sats onto a separate contract to incentivze locking a specific amount in a specific future. They’re spending pennies, but they’re important people. And it has to be clear how much they’re spending and how that relates to the current rate.

Currently, I’m taking the discrete value constraint out of the Vault and moving it to the Coupon. With that UI, I think people can write coupons for different placement amounts (0.1 BCH, 1, 10, 100, etc) all for the same Future contract. So that will make the coupon writing a bit more interesting.

Since every coupon contract is identical except for the date and the placement amount, we don’t need to have any sort of record keeping for the parameters of the coupons.

Since the return on coupons gradually increases over time, it’s really cheap to just lowball everything and let the rate of return double as the time halves. Whales are busy. So they might want batch actions to:

  • write 10 or 100 coupons at a particular date,
  • write at a certain rate across a range of dates,
  • or write a range of rates for one date.

We have to see what tools whales want. But they probably want a bill to review confirmation with fiat amounts.

For Futures Set writers:

Futures set writers have to decide which dates contracts are set to (blocks). And assure that the 21M supply of an FT is funded to the contract, and that it matches the tokenId for the contract.

@bitcoincashautist came up with a clever way to commission tokens from a blueprint contract. Ideally, it would be as simple as anyone calling a function that would commission the contract for the next period and fund the FTs “automatically”.

I’d like writing a new futures set to be as easy as someone seeing the futures only go up to block 1,050,000 and clicking ‘next set’ commission the set for block 1,060,000, but I’m not sure if that’s possible.

There’s legal and security issues that will go away forever if it’s just all on chain. If that’s possible, since only one or two people would need to write futures, that’d be a no UI UI. i.e. A cli and a cron job to “click” next. With a backup “next set” button on the webapp.

Part of the utility of the futures the standardness and regularity. Designers have to consider liquidity offerings would have to create a healthy market.

The sets have to get sparser as they get further out. A set might mature every 10k blocks, and another parallel set might be going every 1000 blocks “weeklies”. So if someone wanted to hodl til the next halving, the 10k chain might be up to block 1,050k, but weeklies wouldn’t need to be generated that high up for another three years.

Ideally, someone competent who understood the staging would start one of these machine sets (1k/10k) and not have to ever do set writing again. If everyone is just using the same dates, it will concentrate liquidity.

1 Like