Concepts

The entire rationale behind the creation of the Nanas is based on the implemention of two new concepts to the original Runes protocol: "priced mints" and "programs". In conjunction, these new integrations greatly expand the original utility of Runes through behaviour which is explained and rationalized through in this page.

All concepts implemented in this page aim to adhere to our Design philosophy

A Better Mint Function

I'll start with this: the original mint functionality of runes is smart.

Adding a way for other users to natively bring new Runes into circulation is a really good idea, and actually introduces a nice meta to the protocol. However, with the way mints are currently implemented on Runes, they leave it to forever be just be that - a meta. They propose no real utility to the protocol other than, well, degeneracy.

The idea behind priced mints is to expand on the original utility of a mint's terms by altering the original implementation on Runes with the introduction of a new price field.

struct Terms {
  amount: Option<u128>,
  cap: Option<u128>,
  height: (Option<u32>, Option<u32>),
  offset: (Option<u32>, Option<u32>),
  price: Option<PriceTerms>
}

struct NanaId{
  block: u32,
  tx: u16,
}

struct PriceTerms {
  asset: NanaId
  amount: u128
}

The price field

Originally proposed in https://github.com/ordinals/ord/issues/3794 and modified in this document, the price field would have the following effects on a mints terms:

When a new Nana is etched, it can optionally include a "price" field in an etch's mint terms. If not included the functionality of the mint terms is identical to runes.

If included, however, the following functionality would now be used:

-> For the following definition, Mint Output refers to the following:

The address owning the first NON-OP_RETURN transaction output of an Etch transaction or, in the case it’s provided, the address owning the transaction output specified by “pointer” of an Etch transaction. If pointer is an OP_RETURN output, the former is used (and if not provided, a rotten banana is produced and the etch is ignored)

During the processing of a Banana with an Etch, Mint Output would be a value saved by indexers in a Rune's details for evaluating future mints, along with PriceAsset (a value of type NanaId ) and PriceAmount (a value of type u128)

If PriceAsset is 0:0, native BTC is used in the check. Otherwise, the asset used refers to a Nana.

A Nana cannot have itself as a PriceAsset

A calls available unallocated nana payload is made up of

  • Any input Nanas into a banana

  • Any premined Nanas in an Etch

  • Any minted Nanas with mint

NIPs and edicts should be aware of this logic. For example, an edict with position=1 might not be valid with just nanas from input UTXOs, but the Call to the nip could potentially allocate Nanas to the unallocated nana payload needed to make them valid.

TLDR: A transaction minting a nana whose PriceAsset is a nana needs to have the transfer done in anything before the call (edicts with position=0 or mints)

Example: Consider a user wanting to mint and swap a nana with (NIP1) bananaswap in the same transaction. The first iterations swap will fail, because the nana requesting to be swapped has not been minted yet. However, in second iteration the swap will be sucessful because that nana is present in the unallocated Nana payload. Methods like these must error softly (returning a boolean for example) rather than letting the method error with the alloc() function, which would produce a rotten banana and stop processing before the second iteration has a chance of being processed.

During the etch and on any future mints, the price field would have the following effects:

  • A nana with the price field set in the mint terms requires that an amount of PriceAmount is being transferred of PriceAsset to Mint Output . (if PriceAsset is a nana) ,or in the case PriceAmount is 0 and PriceAsset is not BTC, that the transaction's sender has a UTXO whose balance of PriceAsset is any amount above 0 (essentially, that the transaction's sender owns any amount of PriceAsset ). Both of these are checked at the end of the first iteration.

  • An etch with a non-0 amount , a PriceAmount of 0, and a PriceAsset of 0:0 is considered invalid and produces a rotten banana ( checking the BTC balance of a sender is useless functionality that produces overhead to an indexer and a BTC node).

  • A Nana whose etch has mint terms with an amount of 0 and no price field specified is set as unmintable.

  • Etchings whose mint terms express a PriceAmount of 0, an amount of 0 grant a Nana special wrapping functionality instead. This behavior overrides other terms by ignoring cap , ignoring amount and inheriting divisibility from PriceAsset (for btc, this is 8). Any mint done to an asset with these set will use the amount of PriceAsset transferred to Mint Output as the actual amount minted.

Use Case 1: Wrapped BTC

These new mint terms would allow the creation of a nana that wraps native bitcoin to be used in programs (such as with (NIP1) bananaswap). The functionality of this could be as follows:

Imagine the following mint terms to an imaginary Nana called "NBTC" and a Mint Output set to an address controlled by a custodian.

{ 
  amount:  0,
  price: {
    asset: {
      block: 0,
      tx: 0
    },
    amount: 0
  }
}

The following mint terms would allow anyone to "wrap" any amount of bitcoin into a Nana (amount is expressed in satoshi on both the Nana and BTC).

Anytime someone wanted to wrap BTC in a nana, they could create a transaction sending any amount BTC to Mint Output with a banana mint field set to NBTC. Indexers would pick this transaction up, check the amount of BTC being transferred to Mint Output in the transaction,mint NBTC and add it to the unallocated nana buffer of the Banana included in said transaction, which can then be transferred through an edict or pointer.

To unwrap NBTC, the custodian would be listening for incoming Bitcoin transactions to check for transactions where BTC is being transferred to Mint Output in the form of a new UTXO (to pay for distribution fees) and any amount of NBTC is being burnt by transferring them to an OP_RETURN output - effectively removing the NBTC in the transaction from the circulation. The custodian would check how much NBTC was burnt and transfer that amount of BTC to the sender address, using the btc in utxo provided to cover fees.

-> Note: the indexer returns a JSON after processing a block with all nana events emitted in the block, including an object of Burn events mapped by TX HASHES. Custodians can use these to check for new burns.

Use Case 2: Decentralized launchpads and raises

The new price field allows for decentralized raises to take place, where anyone can raise BTC (or even another nana) by manipulating the price field. The functionality could be as follows:

Imagine the following mint terms expressing a raise for a new Nana called DOG .

{ 
  divisibility: 1
  cap: 1000
  amount: 500 ,
  price: {
    asset: {
      block: 0,
      tx: 0
    },
    amount: 100000
  }
}

The following mint would esentially serve as a raise for DOG that raises 1 BTC (100,000 SATOSHI * 1000 possible mints) to Mint Output . At the end of the raise if fully filled, a total of 500,000 DOG would be in circulation (1000 possible mints * 500 DOG per mint)

A raise's time period could also be set within the mint terms, by specifiying a block height and/or offset.

Usecase 3: Whitelisted mints

The protocol also allows for whitelisted mints by having two nanas: One act as an access naana that is fully premined to a party, and the other act as the Nana whose mint is whitelisted by checking if the whitelisted party has any of the access nana in their balance. The functionality for such could be as follows:

Imagine the folllowing mint terms for the access nana

{ 
  premine: 1,
  divisibility: 1,
  amount: 0
}

For the sake of simplicity, lets imagine the access nana's id is 1:1.

Now lets create a new Nana whose mint price term's merely check for the presence of this access Nana in the senders wallet before allowing a mint:

{
  divisibility: 6
  cap: 0
  amount: 1000000000000 ,
  price: {
    asset: {
      block: 1,
      tx: 1
    },
    amount: 0
  }
}

The following allows anyone with the access nana to mint this new Nana in chunks of 1 million.

Lets keep playing pretend and imagine this is for a stablecoin tied to the US dollar (NUSD or NanaUsd). A centralized custodian controlling NanaUSD would be able to mint NUSD in chunks of 1 million usd and slowly release into circulation as the recieve USD to back the stablecoin. A USD backed nana would allow anyone to trade nanas against USD on (NIP1) bananaswap natively on Bitcoin.

You could even wrap assets from other chains in this way (NanaETH, NanaDAI, etc) or even wrap assets from other protocols on Bitcoin (example.. runes and a runes bridge to nanas).

Programs and NIPs

This topic is so broad that I decided to give it its own page:

Programs

Last updated