diff --git a/kip-0013/kip-0013.md b/kip-0013/kip-0013.md new file mode 100644 index 0000000..ada939d --- /dev/null +++ b/kip-0013/kip-0013.md @@ -0,0 +1,116 @@ +--- +KIP: "0013" +Title: poly-fungible-v2 +Author: Stuart Popejoy stuart@kadena.io, Hee Kyun heekyun@kadena.io +Status: Draft +Type: Standard +Category: Pact +Created: 2021-02-02 +--- + +## Abstract + +Improve the Pact multi-token [poly-fungible-v1](https://github.com/kadena-io/KIPs/blob/master/kuip-0011/kip-0011.md) standard to encompass + +- a) token sales, +- b) Haber Content Integrity manifests +- c) pluggable token policies. + +Intended to support Kadena "Marmalade" NFT decentralized infrastructure, these allow enforceable sale standards that encompass royalties, sales in any coin, better NFT integrity and identification, and more. + +## Motivation + +While poly-fungibles/ERC-1155's can behave like "normal" coins, NFTs aren't tokens  -  the whole point of +"non-fungibility" is to indicate that this item can't be traded for another. In a coin-like token, +transfer is the main operation: money changes hands. For an NFT however, transferring it from one owner to another +leaves out a crucial step: the sale of the NFT. + +The problem with the ERC transfer-only model for NFTs appears whenever you want to do something beyond simply buying the +NFT from the current owner with no strings attached. For instance, an oft-touted feature of many NFTs is their ability +to pay a royalty to the original creator every time the artifact changes hands. + +One would think this means the blockchain makes it impossible to sell or transfer the NFT without collecting the +royalty. Unfortunately, it doesn't work this way with current Ethereum royalty standards like ERC-2981, supported by +exchanges like OpenSea or Nifty. Under ERC-2981, the NFT ledger exposes a function that takes a price and computes a +royalty and receiver for a given token. The enforcement is entirely handled by the exchange, such that they essentially +pinky-swear that whenever they make a sale, they will always call this function, and distribute funds accordingly, +before calling transfer to hand the NFT to the buyer. + +### Pacts for sales + +Kadena's smart contract language Pact has the critical missing feature: "pacts", which are multi-step processes defined +in the smart contract. With pacts, we can finally see what an enforceable NFT marketplace standard looks like. The first +step is **offer**, in which a seller lists an NFT for sale. This puts the NFT into a trustless escrow that can only be +released by later steps of the pact. The second step is **buy**, where a buyer executes some offsetting payment, and the +escrowed pact is transferred to the buyer. If the buyer never shows up, after a timeout the seller can "roll back" the +pact and **withdraw** the sale, transferring the NFT back to the seller from the escrow account. + +### Token policies + +The sale pact is the critical piece of logic that powers mintable marketplaces, since it introduces a fully autonomous +and enforceable way to offer tokens for sale within the standard. However, the token policy handles critical aspects of +the sale, such as how does money change hands? How might a royalty be implemented? And also, doesn't transfer still +undermine everything? + +Token policies don't just govern sales, but transfer, minting, and burning as well. This is necessary to make a truly +enforceable token policy: + +- Creation. The token policy is invoked when a token is created (this is distinct from minting, which actually + establishes ownership of the NFT). This is where something like a royalty rate or other "permanent" data would be + captured. + +- Minting. One thing about ERC-1155 (and poly-fungible-v1 too) is the lack of a way to lock down issuance. With the + minting policy, a token can declare itself to be a true 1-of-1, or limited series, or a fully fungible coin. + +- Burning. Burning is already a head-scratcher for NFTs, but can obviously make sense for fungible coins. Burn policies + allow prevention of burns in 1-of-1 and limited-series NFTs, as well as other rules a creator may desire. + +- Transfer. Transfer can finally be tamed with the transfer policy! For most NFTs it gets banned altogether, but it also + serves other use cases like transfer restrictions, minimum or maximum order sizes, etc. + +- Sale. Sale policies have separate operations for the offer and buy steps of the sale pact. Offer is where you might + quote a price, and buy is where an offsetting transaction can be executed. + +### Manifests + +Haber Content Manifests replace opaque and unverifiable NFT URIs with cryptographically verifiable on-chain data, +employing elements of Stuart Haber's Content Integrity designs. This can be anything from a simple Data URI or DID +(Decentralized Identifier) to any structured data, including image or document data on-chain. + +## Rationale/Discussion Items + +### Trustless escrow + +Pact's trustless escrow functionality is considered critical to make an enforceable sale standard. The token policy +works with the "offer" and "buy" steps to customize requirements for a given marketplace. + +### Withdraw timeouts + +Currently withdraws are not customizable and only offer a block timeout. + +### DIDs and Token Identifiers + +Manifests bear a content hash that can stand in as all or part of a verifiable ID for the NFT. A separate +standard will discuss an _address protocol_ (KIP-0012) for guaranteeing a token ID matches the manifest. Open +issues include the fact that the policy is not currently captured, perhaps an ID can identify the policy +as well. + +## Backwards Compatibility + +### poly-fungible-v1 + +Manifests in `create-token` and the `manifest` accessor break compatibility with `poly-fungible-v1`. + +## Specification + +- Interface: [poly-fungible-v2.pact](https://github.com/kadena-io/marmalade/blob/marmalade-rc1/pact/kip/poly-fungible-v2.pact) +- Interface: [token-policy-v1.pact](https://github.com/kadena-io/marmalade/blob/marmalade-rc1/pact/kip/token-policy-v1.pact) +- Implementation: [manifest.pact](https://github.com/kadena-io/marmalade/blob/marmalade-rc1/pact/kip/manifest.pact) + +## Reference Implementation + +- Marmalade RC1: [ledger.pact](https://github.com/kadena-io/marmalade/blob/marmalade-rc1/pact/ledger.pact) + +## References + +- EIP-1155: