Skip to content

Instantly share code, notes, and snippets.

@adamkrellenstein
Last active August 2, 2024 16:29
Show Gist options
  • Save adamkrellenstein/3eb9fe4add4ecbfcfc392ae9ef04ae55 to your computer and use it in GitHub Desktop.
Save adamkrellenstein/3eb9fe4add4ecbfcfc392ae9ef04ae55 to your computer and use it in GitHub Desktop.
Fair Minting - Feature Specification

Fair Minting

Motivation

Fair Minting is a process whereby users are able to “mint” tokens in a decentralized manner. One user initiates the mint (either with or without a “premint”), and then other users are able to trigger it to create tokens for themselves. Fair Minting was likely inspired by the original Counterparty Proof-of-Burn mechanism, by which users sent BTC to an unspendable address and XCP tokens were generate for them automatically.

More recently, BRC-20 introduced a variant of the Fair Mint model that has been adopted by many fungible token protocols recently, including SRC-20 on Bitcoin Stamps. In this system, users are able to mint "for free" by paying only a miner fee: the term “fair mint” refers to the fact that the creator of the minting system is not enriched in the process, and that the minting process is decentralized

In 2023, Joe Looney introduced the ”XCP-20” Fair Mint model by setting up a dispenser on a burn address; its name is a tongue-in-cheek reference to BRC-20. Buyers, largely unaware that Counterparty existed—and this was not new in any way—sent massive amounts of Bitcoin to the burn address and received tokens in return. In this way, tokens got distributed, but the deployer was not directly enriched.

Design

Additional functionality may be added as well:

  • A “soft cap” mechanism, establishing a minimum amount of the token to be issued, optionally by a particular block height. (Before soft_cap_deadline_block payment will be escrowed trustlessly.)
  • A commission in the new token sent to the creator of the mint for each mint operation (proportional to the quantity minted)
  • A “Start Block” and “End Block”

Implementation Notes:

  • Fair Mints will be possible by issuers of extant assets as long as those assets do not have locked quantities.
  • The premint quantity will be credited to the issuer at the start_block.
  • If an asset can be reset it can also be Fair Minted, but fair minting itself would not first effect an asset reset.
  • If, after end_block the total quantity issued of the asset is less than hard_cap , then the future issuances or fair mints may be done on the asset until the the quantity issued equals hard_cap.
  • For the duration of the mint period, the state of description lock and quantity lock cannot be changed.

Implementation

It would be possible, to use the issuances.py contract and add the fair minting implementation to it. However, this contract is already 1000 lines long and it is preferable not to add complexity to it. New contracts will therefore be implemented but, to ensure maximum compatibility with other assets, the issuances and assets tables will be used: the creation of a fair minting will result in the creation of a line in the assets and issuances tables and then each fair mining will result in the creation of a line in the issuances table.

There will be two new contracts: fairminter.py and fairmint.py. These two contracts will respect the usual interface of all other contracts, that is to say the functions initialise(), validate(), compose(), unpack() and parse(). The first will allow the creation of a "mintable" asset and the second will allow users to "mint" this asset. After the minting period, a minted asset functions just like a locked issuance asset.

Function Signatures

  • fairminter.compose()

    • db: Database connection
    • asset: Asset to be minted
    • price: Price in XCP of each unit of asset, by default, 0
    • max_mint_per_tx: Amount minted if price is equal to 0; otherwise, maximum amount of asset that can be minted in a single transaction. If None, there is no limit.
    • description: Description of the asset
    • hard_cap: Maximum amount of asset to be minted, if None, no limit
    • burn_payment: If True, the payment asset is burned, otherwise it is sent to the source
    • premint_quantity: Amount of asset to be minted when the sale starts, if 0, no premint; preminted assets are sent to the source of the transaction
    • start_block: Block at which the sale starts, if None, the sale starts immediately
    • end_block: Block at which the sale ends, if None, the sale never ends
    • soft_cap: Minimum amount of asset to be minted, if None, no minimum; if the soft cap is not reached by the soft_cap_deadline_block, the sale is canceled, asset is revoked from all minters and all payments are refunded
    • soft_cap_deadline_block: Block at which the soft cap must be reached, required if soft_cap is not None
    • asset_parent: Asset to be used as parent for the new asset. If provided, the issued asset will be numeric with an asset_longname equal to <asset_parent>.<asset>. The source of the transaction must be the issuer of the parent asset
    • lock_description: If True, the description of the asset cannot be changed
    • lock_quantity:
    • minted_asset_commission: Commission to be paid in minted asset, a fraction of 1 (i.e., 0.05 is five percent); the commission is deducted from the asset received by the minter and sent to the Fair Minter owner
  • fairmint.compose()

    • db: Database connection
    • asset: Asset to be minted
    • quantity: Quantity of asset to be minted, by default mint_per_tx from the corresponding fairminter

API Changes

  • New Routes
    • Get All Fair Minters: /v2/fairminters
    • Get Fair Minter By Tx Hash: /v2/fairminters/<tx_hash>
    • Get Fair Minter By Asset: /v2/assets/<asset>/fairminter
    • Get Fair Minters By Address: /v2/addresses/<address>/fairminters
    • Get Mints By Fair Minter: /v2/fairminters/<tx_hash>/mints
    • Get Mints By Asset: /v2/assets/<asset>/mints
    • Get Mints By Address: /v2/addresses/<address>/mints

Database Changes

  • Afair_minted field will be added to the issuances table. This is the field that will be checked to prevent token issuance other than through fair minting.
  • A new table fairminters will be created with the following fields:
    1. tx_hash (Fair Minter identifier)
    2. block_index
    3. source (source of the transaction)
    4. asset
    5. parent_asset
    6. description
    7. price
    8. payment_asset
    9. hard_cap
    10. burn_payment
    11. max_mint_per_tx
    12. premint_quantity
    13. start_block
    14. end_block
    15. payment_asset_commission
    16. minted_asset_commission
    17. soft_cap
    18. soft_cap_deadline_block
    19. status (open, closed, cancelled, invalid: <reasons>)
  • A new table fairmints will be created with the following fields:
    1. tx_hash (Mint identifier)
    2. block_index
    3. fair_minter_tx_hash
    4. asset
    5. quantity
    6. payment_asset
    7. payment_quantity
    8. status (valid, invalid: <reasons>)

For each row in the fairminters and fairmints table a row will be added to the issuances table.

Credits

  • Ouziel Slama
  • Adam Krellenstein
  • mikeinspace
@loon3
Copy link

loon3 commented Aug 2, 2024

Initial thoughts...

  • Good idea, people love the fair mints.
  • Some will want to do a fair mint of assets they already have so should at least consider how that could be done (must hold full supply, etc).
  • Add BTC as an option and send it to the op_return output with counterparty message to provably burn.
  • Eliminate burn payment parameter by just setting commissions to zero. On further review, this doesn't make sense as burn/source option is independent of commission

@mikeinspace
Copy link

@loon3 "Some will want to do a fair mint of assets they already have so should at least consider how that could be done"

Isn't this just selling tokens similar to dispensers today or atomic swaps of tomorrow? Not opposed, just trying to understand the difference and how it would fall within a "fair mint" given that the seller is just selling stuff.

@pinnate-modo
Copy link

pinnate-modo commented Aug 2, 2024

So @loon3's suggestion RE: fair-minting existing assets has already been integrated into this spec; it's under "Implementation Notes" in the Design section.

Strong NACK on BTC burns. As I understand it, fair-mint-by-burning is niche use-case as it is, and BTC burns would be incompatible with the soft_cap parameter.

Burning is a 'network fee' so that minters have the option of mitigating Sybil attacks. All other Counterparty-specific fees are denominated in XCP, for the simple reason that XCP, not BTC, is Counterparty's native currency.

@pinnate-modo
Copy link

pinnate-modo commented Aug 2, 2024

@adamkrellenstein lock_quantity is currently undefined. It's a boolean, right?

@adamkrellenstein
Copy link
Author

yup

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment