This repository has been archived by the owner on Jul 19, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #53 from ayo-klaytn/mkt-v2
mkt-v2 content added
- Loading branch information
Showing
8 changed files
with
435 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
--- | ||
title: 🎗 NFT Royalty | ||
sidebar_label: Introduction | ||
--- | ||
|
||
## Introduction <a id="Introduction"></a> | ||
|
||
In general, the creators of a unique asset (NFT) profit from the asset's initial sale. However, this unique asset may appreciate in value over time, and the creator may not benefit from this increase in value. NFT Royalties is based on this approach, in which creators are continuously rewarded for the value of their work after a subsequent sale beyond the initial sale. | ||
|
||
## Definition of NFT Royalties <a id="Definition of NFT Royalties"></a> | ||
NFT royalties are payments made to the original creator of a digital asset for each time that asset is resold. This means that when this asset is sold, a certain percentage is paid to the creator as a reward for the asset's value. | ||
|
||
For example, a creator may have published an asset on the Marketplace and initially sold it for 10,000 KLAY. Simultaneously, the creator included a 10% NFT royalty percentage for subsequent sales. Thus, if the buyer resells and earns 100,000 KLAY from the resale, the original creator will receive 10% (10,000 KLAY). | ||
|
||
Isn't that cool? NFT royalties let creators passively earn from their work. | ||
|
||
## How does it work? <a id="How does it work"></a> | ||
When creatives use NFT Royalty for subsequent sales, they will continue to earn money from their work. The creator usually specifies the royalty policy at the platform or on-chain level. | ||
|
||
Typically, the procedure is as follows: | ||
* NFT is minted with a royalty percentage added by a creator, either on the platform or on the blockchain. | ||
* When there is a subsequent sale, the creator is paid | ||
|
||
## NFT Marketplaces and NFT Royalties <a id="NFT Marketplaces and NFT Royalties"></a> | ||
Marketplaces determine whether the royalty details in a NFT smart contract will be implemented or not. This brings us to the fact that not all marketplaces honor NFT royalties. Further, because of the peculiarities of different NFT platforms, there exist unique royalty payment implementations that are not easily usable by other marketplaces. Thus, making royalty policies from other marketplaces or platforms not automatically transferrable. | ||
|
||
For example, if an NFT with a royalty policy is sold on Rarible and then listed on OpenSea, the original creator will not be paid from subsequent sales because the royalty policy was not transferred. ERC2981 was created in response to the need to standardize royalty payment across all platforms. The ERC2981 standard addresses this issue by allowing accurate royalty payments to be implemented regardless of the marketplace where the NFT is sold or resold. | ||
|
||
This standard is implemented by ensuring that marketplaces and individuals retrieve royalty payment information via royaltyInfo(), which specifies how much to pay to the creator address for a given sale price. To learn more about this standard, check this guide | ||
|
||
|
||
This standard is applicable in the metaverse, where NFT royalties can be attached to in-game items and collectibles, digital accessories, virtual lands, and so on. | ||
|
||
## Code Sample <a id="Code Sample"></a> | ||
|
||
```javascript | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.4; | ||
|
||
import "@klaytn/contracts/KIP/token/KIP17/KIP17.sol"; | ||
import "@klaytn/contracts/KIP/token/KIP17/extensions/KIP17URIStorage.sol"; | ||
import "@klaytn/contracts/access/Ownable.sol"; | ||
import "@klaytn/contracts/utils/Counters.sol"; | ||
import "@klaytn/contracts/token/common/ERC2981.sol"; | ||
|
||
contract MyToken is KIP17, KIP17URIStorage, Ownable, ERC2981 { | ||
using Counters for Counters.Counter; | ||
|
||
Counters.Counter private _tokenIdCounter; | ||
|
||
constructor() KIP17("MyToken", "MTK") {} | ||
|
||
function safeMint(address to, string memory uri) public onlyOwner { | ||
uint256 tokenId = _tokenIdCounter.current(); | ||
_tokenIdCounter.increment(); | ||
_safeMint(to, tokenId); | ||
_setTokenURI(tokenId, uri); | ||
} | ||
|
||
function mintNFTWithRoyalty(address recipient, string memory uri, address royaltyReceiver, uint96 feeNumerator) | ||
public | ||
onlyOwner | ||
returns (uint256) | ||
{ | ||
uint256 tokenId = _tokenIdCounter.current(); | ||
_tokenIdCounter.increment(); | ||
_safeMint(recipient, tokenId); | ||
_setTokenURI(tokenId, uri); | ||
_setTokenRoyalty(tokenId, royaltyReceiver, feeNumerator); | ||
|
||
return tokenId; | ||
} | ||
|
||
// The following functions are overrides required by Solidity. | ||
|
||
function _burn(uint256 tokenId) internal override(KIP17, KIP17URIStorage) { | ||
super._burn(tokenId); | ||
} | ||
|
||
function tokenURI(uint256 tokenId) | ||
public | ||
view | ||
override(KIP17, KIP17URIStorage) | ||
returns (string memory) | ||
{ | ||
return super.tokenURI(tokenId); | ||
} | ||
|
||
function supportsInterface(bytes4 interfaceId) | ||
public | ||
view | ||
override(KIP17, ERC2981) | ||
returns (bool) | ||
{ | ||
return super.supportsInterface(interfaceId); | ||
} | ||
} | ||
|
||
``` | ||
|
||
## Important Note <a id="Important Note"></a> | ||
|
||
The code above is a standardized implementation of retrieving royalty payment information from a KIP17 contract. It shows how royalty information can be set for a single token id using the **_setTokenRoyalty** in the **mintNFTWithRoyalty** function. Similarly, royalty information can be specified globally for all tokens using **_setDefaultRoyalty**. | ||
|
||
Further, royalty is specified as a fraction of Sale Price: | ||
|
||
(salePrice * feeNumerator) / _feeDenominator() | ||
|
||
**_feeDenominator()** is specified in basis point by default. This value defaults to 10,000 but is overridable. Also the feeNumerator as specified in **mintNFTWithRoyalty** function is calculated in basis point. Take for instance if you want to set the royalty percentage to 10%, the **feeNumerator** will be 10/100 * 10000 = 1000 | ||
|
||
To get more insight of how it works under the hood, check out this [codebase](https://github.com/klaytn/klaytn-contracts/blob/master/contracts/token/common/ERC2981.sol). | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
72 changes: 72 additions & 0 deletions
72
docs/klaytn-contracts/nft-with-operator-filter/introduction.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
--- | ||
title: 🎨 NFT with Operator Filter | ||
sidebar_label: Introduction | ||
--- | ||
|
||
## Introduction <a id="Introduction"></a> | ||
Developers and creators need a sustainable means by which they are rewarded for the valuable work they create overtime. However, this has been made possible with the advent of royalties. This piece of innovation - NFT Royalty however faces a major limitation. The number of marketplaces that do not respect creator fees have been rapidly increasing, and creators, in turn, have seen their effective creator fees severely diminished; this stands as one major limitation. | ||
|
||
In order to counter this, an on-chain enforcement tool - [Operator Filter](https://github.com/ProjectOpenSea/operator-filter-registry) was introduced by OpenSea to prevent the sale of your NFTs using marketplaces that do not respect creator earnings. To put things in perspective, this mechanism is built atop of the EIP2981 NFT Royalty Standard to ensure that creators always receive their royalties when their NFTs are sold. And on the other hand, if someone attempts to trade an NFT using an operator filter in a marketplace that does not honor creator earnings, the NFT transfer will be blocked. | ||
|
||
To get more insight of how it works under the hood, check out this codebase. | ||
|
||
## Code Sample <a id="Code Sample"></a> | ||
|
||
```javascript | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.4; | ||
|
||
import "@klaytn/contracts/KIP/token/KIP17/KIP17.sol"; | ||
import "@klaytn/contracts/KIP/token/KIP17/extensions/KIP17URIStorage.sol"; | ||
import "@klaytn/contracts/access/Ownable.sol"; | ||
import "@klaytn/contracts/utils/Counters.sol"; | ||
import "operator-filter-registry/src/DefaultOperatorFilterer.sol"; | ||
|
||
contract MyToken is KIP17, KIP17URIStorage, Ownable, DefaultOperatorFilterer { | ||
using Counters for Counters.Counter; | ||
Counters.Counter private _tokenIdCounter; | ||
|
||
constructor() KIP17("MyToken", "MTK") {} | ||
|
||
function safeMint(address to, string memory uri) public onlyOwner { | ||
uint256 tokenId = _tokenIdCounter.current(); | ||
_tokenIdCounter.increment(); | ||
_safeMint(to, tokenId); | ||
_setTokenURI(tokenId, uri); | ||
} | ||
|
||
// The following functions are overrides required by Solidity. | ||
|
||
function _burn(uint256 tokenId) internal override(KIP17, KIP17URIStorage) { | ||
super._burn(tokenId); | ||
} | ||
|
||
function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) { | ||
super.setApprovalForAll(operator, approved); | ||
} | ||
|
||
function approve(address operator, uint256 tokenId) public override onlyAllowedOperatorApproval(operator) { | ||
super.approve(operator, tokenId); | ||
} | ||
|
||
function transferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) { | ||
super.transferFrom(from, to, tokenId); | ||
} | ||
|
||
function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) { | ||
super.safeTransferFrom(from, to, tokenId); | ||
} | ||
|
||
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public override onlyAllowedOperator(from) { | ||
super.safeTransferFrom(from, to, tokenId, data); | ||
} | ||
|
||
function tokenURI(uint256 tokenId) public view override(KIP17, KIP17URIStorage) returns (string memory) { | ||
return super.tokenURI(tokenId); | ||
} | ||
|
||
} | ||
|
||
``` | ||
From the code above, you can observe that the transfer, transferfrom, approve and setApproval function makes use of the onlyAllowedOperator and onlyAllowedOperatorApproval modifier respectively. This implies that only filtered operators i.e allowed platform smart-contract or delegate can execute transfers from or approvals. | ||
|
5 changes: 0 additions & 5 deletions
5
docs/klaytn-contracts/payment-splitter-and-vesting/introduction.md
This file was deleted.
Oops, something went wrong.
4 changes: 0 additions & 4 deletions
4
docs/klaytn-contracts/payment-splitter-and-vesting/sdks-and-tutorials.md
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
--- | ||
title: 💸 Payment Splitter Contract | ||
sidebar_label: Introduction | ||
--- | ||
|
||
## Introduction <a id="Introduction"></a> | ||
|
||
Revenue sharing has traditionally been done manually, or through intermediaries, etc. in business environments when numerous parties are involved. This procedure has been hampered by delays, ineffectiveness, and even disputes between beneficiaries. Leveraging blockchain and smart contracts, this can be prevented by using the payment splitter contract. Payments can be automated with payment splitter contracts, ensuring that each party receives their just portion in an exact and transparent manner. | ||
|
||
In practice, when you create a project on the blockchain, the need to distribute smart-contract earnings to team members may arise. For example, a metaverse NFT marketplace project. This project may earn fees from trading (sell, buy, transfer, and so on), and each team member or stakeholder has a share. The Payment Splitter contract can be used to distribute each stakeholder's portion. | ||
|
||
The Payment Splitter contract enables a group of people to split payments (native tokens and ERC20 tokens) in a secure and transparent manner. This split is made possible by providing the *payee* and the *share* in the contract. The payee is the person to whom you want to pay a certain amount, and the share is the percentage amount the payee will receive. It should be noted that the shares can be distributed in any random ratio or in equal parts. | ||
|
||
With the use of payment splitter contracts, | ||
* The payee does not have to remind the payer of the amount owed on a regular basis. | ||
* The payee cannot withdraw more than they are owed | ||
* Transparency is promoted among team members. | ||
|
||
## How it works <a id="How it works"></a> | ||
|
||
From all payments made to the contract, each payee will be able to take away the sum that is payable to them. The payment splitter contract follows the [pull method](https://river.com/learn/pull-system-vs-push-system/), which means that payee can safely pull funds out of the contract by calling the release function. | ||
|
||
This is how a payment splitter contract works on a high level: | ||
|
||
1. Connect with other contracts which accumulates tokens (both ERC20 and native token) itself. | ||
2. Add payee with share point on the contract | ||
3. Contract receives payment | ||
4. Tokens released to payees based on their shares by calling the release function | ||
|
||
To learn more about Payment Splitter, check out the [Payment Splitter Repository](https://github.com/klaytn/klaytn-contracts/blob/master/contracts/finance/PaymentSplitter.sol). | ||
|
||
## Usecase <a id="Usecase"></a> | ||
|
||
If revenue sharing is required, the payment splitter contract can be integrated with other contracts. The following are some examples of how a contract can accumulate tokens for itself before releasing them to payees: | ||
|
||
1. Token Launch contract is getting fee from the transaction(sell, buy, transfer, etc) | ||
2. DeFi contract is getting the fee from the user's deposit and stake. | ||
3. NFT Mint contract has some minting price and the contract is getting tokens from the minting transaction. | ||
4. NFT Marketplace contract is getting fee from the tradings(sell, buy, transfer, etc) | ||
5. Team wants to distribute tokens to team members as monthly pay-check | ||
6. A DEX wants to consolidate and distribute trading fees to certain participants | ||
|
||
For the aforementioned scenarios, the contracts must include functions for withdrawing accumulated tokens or releasing them to payees with shares. Using PaymentSplitter, the above contracts don’t need to have those functions; just connect with PaymentSplitter, add payees with shares and release it to the payees. | ||
|
||
|
||
|
Oops, something went wrong.