Concepts
Last updated
Last updated
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
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.
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.
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.
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.
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
.
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.
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
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:
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:
If a Nana's PriceAsset
refers to another Nana
, only edicts transferred with position=0 will be used for validation (see ).